1   /*
2    * Copyright 2003 - 2013 The eFaps Team
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   * Revision:        $Rev$
17   * Last Changed:    $Date$
18   * Last Changed By: $Author$
19   */
20  
21  package org.efaps.admin.access;
22  
23  import java.sql.PreparedStatement;
24  import java.sql.ResultSet;
25  import java.sql.SQLException;
26  import java.util.UUID;
27  
28  import org.efaps.admin.AbstractAdminObject;
29  import org.efaps.db.Context;
30  import org.efaps.db.transaction.ConnectionResource;
31  import org.efaps.db.wrapper.SQLPart;
32  import org.efaps.db.wrapper.SQLSelect;
33  import org.efaps.util.EFapsException;
34  import org.efaps.util.cache.CacheLogListener;
35  import org.efaps.util.cache.CacheReloadException;
36  import org.efaps.util.cache.InfinispanCache;
37  import org.infinispan.Cache;
38  import org.slf4j.Logger;
39  import org.slf4j.LoggerFactory;
40  
41  /**
42   * The class handles the caching for access types like "checkin" or
43   * "read".
44   *
45   * @author The eFaps Team
46   * @version $Id$
47   */
48  public final class AccessType
49      extends AbstractAdminObject
50  {
51      /**
52       * Needed for serialization.
53       */
54      private static final long serialVersionUID = 1L;
55  
56      /**
57       * Logging instance used in this class.
58       */
59      private static final Logger LOG = LoggerFactory.getLogger(AccessType.class);
60  
61      /**
62       * This is the SQL select statement to select a role from the database by
63       * ID.
64       */
65      private static final String SQL_ID = new SQLSelect()
66                      .column("ID")
67                      .column("UUID")
68                      .column("NAME")
69                      .from("T_ACCESSTYPE", 0)
70                      .addPart(SQLPart.WHERE).addColumnPart(0, "ID").addPart(SQLPart.EQUAL).addValuePart("?").toString();
71  
72      /**
73       * This is the SQL select statement to select a role from the database by
74       * Name.
75       */
76      private static final String SQL_NAME = new SQLSelect()
77                      .column("ID")
78                      .column("UUID")
79                      .column("NAME")
80                      .from("T_ACCESSTYPE", 0)
81                      .addPart(SQLPart.WHERE).addColumnPart(0, "NAME").addPart(SQLPart.EQUAL).addValuePart("?")
82                      .toString();
83  
84      /**
85       * This is the SQL select statement to select a role from the database by
86       * UUID.
87       */
88      private static final String SQL_UUID = new SQLSelect()
89                      .column("ID")
90                      .column("UUID")
91                      .column("NAME")
92                      .from("T_ACCESSTYPE", 0)
93                      .addPart(SQLPart.WHERE).addColumnPart(0, "UUID").addPart(SQLPart.EQUAL).addValuePart("?")
94                      .toString();
95  
96      /**
97       * Name of the Cache by UUID.
98       */
99      private static final String UUIDCACHE = AccessType.class.getName() + ".UUID";
100 
101     /**
102      * Name of the Cache by ID.
103      */
104     private static final String IDCACHE = AccessType.class.getName() + ".ID";
105 
106     /**
107      * Name of the Cache by Name.
108      */
109     private static final String NAMECACHE = AccessType.class.getName() + ".Name";
110 
111     /**
112      * This is the constructor.
113      *
114      * @param _id id of this access type
115      * @param _uuid universal unique identifier of this access type
116      * @param _name name of this access type
117      */
118     private AccessType(final long _id,
119                        final String _uuid,
120                        final String _name)
121     {
122         super(_id, _uuid, _name);
123     }
124 
125     /**
126      * The method checks, if the given object represents the same access type as
127      * this instance. Equals means, that the object to compare is not null, an
128      * instance of this class {@link AccessType} and both id's are the same.
129      *
130      * @param _toCompare object used to compare
131      * @return <i>true</i> if equals, otherwise <i>false</i>
132      */
133     @Override
134     public boolean equals(final Object _toCompare)
135     {
136         return (_toCompare != null)
137                         && (_toCompare instanceof AccessType)
138                         && (((AccessType) _toCompare).getId() == getId());
139     }
140 
141     /**
142      * @see java.lang.Object#hashCode()
143      * @return int hashCode
144      */
145     @Override
146     public int hashCode()
147     {
148         return (new Long(getId())).hashCode();
149     }
150 
151     /**
152      * Method to initialize the Cache of this CacheObjectInterface.
153      */
154     public static void initialize()
155     {
156         if (InfinispanCache.get().exists(AccessType.UUIDCACHE)) {
157             InfinispanCache.get().<UUID, AccessType>getCache(AccessType.UUIDCACHE).clear();
158         } else {
159             InfinispanCache.get().<UUID, AccessType>getCache(AccessType.UUIDCACHE)
160                             .addListener(new CacheLogListener(AccessType.LOG));
161         }
162         if (InfinispanCache.get().exists(AccessType.IDCACHE)) {
163             InfinispanCache.get().<Long, AccessType>getCache(AccessType.IDCACHE).clear();
164         } else {
165             InfinispanCache.get().<Long, AccessType>getCache(AccessType.IDCACHE)
166                             .addListener(new CacheLogListener(AccessType.LOG));
167         }
168         if (InfinispanCache.get().exists(AccessType.NAMECACHE)) {
169             InfinispanCache.get().<String, AccessType>getCache(AccessType.NAMECACHE).clear();
170         } else {
171             InfinispanCache.get().<String, AccessType>getCache(AccessType.NAMECACHE)
172                             .addListener(new CacheLogListener(AccessType.LOG));
173         }
174         AccessCache.initialize();
175     }
176 
177     /**
178      * Returns for given identifier in <i>_id</i> the cached instance of class
179      * AccessType.
180      *
181      * @param _id id of the search access type
182      * @return instance of class AccessType
183      * @throws CacheReloadException on error
184      */
185     public static AccessType getAccessType(final long _id)
186         throws CacheReloadException
187     {
188         final Cache<Long, AccessType> cache = InfinispanCache.get().<Long, AccessType>getCache(AccessType.IDCACHE);
189         if (!cache.containsKey(_id)) {
190             AccessType.getAccessTypeFromDB(AccessType.SQL_ID, _id);
191         }
192         return cache.get(_id);
193     }
194 
195     /**
196      * Returns for given name in <i>_name</i> the cached instance of class
197      * AccessType.
198      *
199      * @param _name name of the access type
200      * @return instance of class AccessType
201      * @throws CacheReloadException on error
202      */
203     public static AccessType getAccessType(final String _name)
204         throws CacheReloadException
205     {
206         final Cache<String, AccessType> cache = InfinispanCache.get()
207                         .<String, AccessType>getCache(AccessType.NAMECACHE);
208         if (!cache.containsKey(_name)) {
209             AccessType.getAccessTypeFromDB(AccessType.SQL_NAME, _name);
210         }
211         return cache.get(_name);
212     }
213 
214     /**
215      * Returns for given universal unique identifier in <i>_uuid</i> the cached
216      * instance of class AccessType.
217      *
218      * @param _uuid UUID of the access type
219      * @return instance of class AccessType
220      * @throws CacheReloadException on error
221      */
222     public static AccessType getAccessType(final UUID _uuid)
223         throws CacheReloadException
224     {
225         final Cache<UUID, AccessType> cache = InfinispanCache.get().<UUID, AccessType>getCache(AccessType.UUIDCACHE);
226         if (!cache.containsKey(_uuid)) {
227             AccessType.getAccessTypeFromDB(AccessType.SQL_UUID, String.valueOf(_uuid));
228         }
229         return cache.get(_uuid);
230     }
231 
232     /**
233      * @param _accessType AccessType to be cached
234      */
235     private static void cacheAccessType(final AccessType _accessType)
236     {
237         final Cache<UUID, AccessType> cache4UUID = InfinispanCache.get().<UUID, AccessType>getIgnReCache(
238                         AccessType.UUIDCACHE);
239         cache4UUID.putIfAbsent(_accessType.getUUID(), _accessType);
240 
241         final Cache<String, AccessType> nameCache = InfinispanCache.get().<String, AccessType>getIgnReCache(
242                         AccessType.NAMECACHE);
243         nameCache.putIfAbsent(_accessType.getName(), _accessType);
244         final Cache<Long, AccessType> idCache = InfinispanCache.get().<Long, AccessType>getIgnReCache(
245                         AccessType.IDCACHE);
246         idCache.putIfAbsent(_accessType.getId(), _accessType);
247     }
248 
249 
250     /**
251      * @param _sql      sql Statement to be executed
252      * @param _criteria filter criteria
253      * @return true if successful
254      * @throws CacheReloadException on error
255      */
256     private static boolean getAccessTypeFromDB(final String _sql,
257                                                final Object _criteria)
258         throws CacheReloadException
259     {
260         final boolean ret = false;
261         ConnectionResource con = null;
262         try {
263             con = Context.getThreadContext().getConnectionResource();
264             PreparedStatement stmt = null;
265             try {
266                 stmt = con.getConnection().prepareStatement(_sql);
267                 stmt.setObject(1, _criteria);
268                 final ResultSet rs = stmt.executeQuery();
269                 if (rs.next()) {
270                     final long id = rs.getLong(1);
271                     final String uuid = rs.getString(2);
272                     final String name = rs.getString(3);
273                     AccessType.LOG.debug("read AccessType  '{}' (id = {}))", name, id);
274                     final AccessType accessType = new AccessType(id, uuid, name);
275                     AccessType.cacheAccessType(accessType);
276                 }
277                 rs.close();
278             } finally {
279                 if (stmt != null) {
280                     stmt.close();
281                 }
282             }
283             con.commit();
284         } catch (final SQLException e) {
285             throw new CacheReloadException("could not read access types", e);
286         } catch (final EFapsException e) {
287             throw new CacheReloadException("could not read access types", e);
288         } finally {
289             if ((con != null) && con.isOpened()) {
290                 try {
291                     con.abort();
292                 } catch (final EFapsException e) {
293                     throw new CacheReloadException("could not abort transaction "
294                                     + "while reading access types", e);
295                 }
296             }
297         }
298         return ret;
299     }
300 }