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.user;
22  
23  import java.sql.PreparedStatement;
24  import java.sql.ResultSet;
25  import java.sql.SQLException;
26  import java.util.Collections;
27  import java.util.HashSet;
28  import java.util.Set;
29  import java.util.UUID;
30  import java.util.concurrent.TimeUnit;
31  
32  import org.efaps.db.Context;
33  import org.efaps.db.transaction.ConnectionResource;
34  import org.efaps.db.wrapper.SQLPart;
35  import org.efaps.db.wrapper.SQLSelect;
36  import org.efaps.util.EFapsException;
37  import org.efaps.util.cache.CacheLogListener;
38  import org.efaps.util.cache.CacheReloadException;
39  import org.efaps.util.cache.InfinispanCache;
40  import org.infinispan.Cache;
41  import org.slf4j.Logger;
42  import org.slf4j.LoggerFactory;
43  
44  /**
45   * TODO comment!
46   *
47   * @author The eFaps Team
48   * @version $Id$
49   */
50  public final class Company
51      extends AbstractUserObject
52  {
53      /**
54       * Needed for serialization.
55       */
56      private static final long serialVersionUID = 1L;
57  
58      /**
59       * Logging instance used in this class.
60       */
61      private static final Logger LOG = LoggerFactory.getLogger(Company.class);
62  
63      /**
64       * This is the SQL select statement to select a role from the database by ID.
65       */
66      private static final String SQL_ID = new SQLSelect().column("ID")
67                      .column("UUID")
68                      .column("NAME")
69                      .column("STATUS")
70                      .from("V_USERCOMPANY", 0)
71                      .addPart(SQLPart.WHERE).addColumnPart(0, "ID").addPart(SQLPart.EQUAL).addValuePart("?").toString();
72  
73      /**
74       * This is the SQL select statement to select a role from the database by Name.
75       */
76      private static final String SQL_NAME = new SQLSelect().column("ID")
77                      .column("UUID")
78                      .column("NAME")
79                      .column("STATUS")
80                      .from("V_USERCOMPANY", 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 UUID.
86       */
87      private static final String SQL_UUID = new SQLSelect().column("ID")
88                      .column("UUID")
89                      .column("NAME")
90                      .column("STATUS")
91                      .from("V_USERCOMPANY", 0)
92                      .addPart(SQLPart.WHERE).addColumnPart(0, "UUID").addPart(SQLPart.EQUAL).addValuePart("?")
93                      .toString();
94  
95      /**
96       * Name of the Cache by UUID.
97       */
98      private static final String UUIDCACHE = Company.class.getName() + ".UUID";
99  
100     /**
101      * Name of the Cache by ID.
102      */
103     private static final String IDCACHE = Company.class.getName() + ".ID";
104 
105     /**
106      * Name of the Cache by Name.
107      */
108     private static final String NAMECACHE = Company.class.getName() + ".Name";
109 
110     /**
111      * Use to mark not found and return <code>null</code>.
112      */
113     private static final Company NULL = new Company(0, null, null, false);
114 
115     /**
116      * The company belonging to this Consortiums.
117      */
118     private final Set<Long> consortiumIds = new HashSet<Long>();
119 
120     /**
121      * @param _id       id for this company
122      * @param _uuid     uuid for this company
123      * @param _name     name for this company
124      * @param _status    status for this company
125      */
126     private Company(final long _id,
127                     final String _uuid,
128                     final String _name,
129                     final boolean _status)
130     {
131         super(_id, _uuid, _name, _status);
132     }
133 
134     /**
135      * @param _consortiumId Consortium to add to this Company
136      */
137     protected void addConsortium(final Long _consortiumId)
138     {
139         this.consortiumIds.add(_consortiumId);
140     }
141 
142     /**
143      * Get the related Consortium (unmodifiable).
144      * @return the set of related Consortiums
145      */
146     public Set<Long> getConsortiums()
147     {
148         return Collections.unmodifiableSet(this.consortiumIds);
149     }
150 
151     /**
152      * {@inheritDoc}
153      */
154     @Override
155     public boolean hasChildPerson(final Person _person)
156     {
157         return _person.isAssigned(this);
158     }
159 
160     /**
161      * {@inheritDoc}
162      */
163     @Override
164     public boolean isAssigned()
165     {
166         boolean ret = false;
167         try {
168             if (Context.getThreadContext().getCompany() != null) {
169                 if (Context.getThreadContext().getCompany().getId() == getId()) {
170                     ret = hasChildPerson(Context.getThreadContext().getPerson());
171                 }
172             } else {
173                 ret = true;
174             }
175         } catch (final EFapsException e) {
176             Company.LOG.error("could not read Company or Person from Context ", e);
177         }
178         return ret;
179     }
180 
181     /**
182      * Method to initialize the Cache of this CacheObjectInterface.
183      */
184     public static void initialize()
185     {
186         if (InfinispanCache.get().exists(Company.UUIDCACHE)) {
187             InfinispanCache.get().<UUID, Company>getCache(Company.UUIDCACHE).clear();
188         } else {
189             InfinispanCache.get().<UUID, Company>getCache(Company.UUIDCACHE)
190                             .addListener(new CacheLogListener(Company.LOG));
191         }
192         if (InfinispanCache.get().exists(Company.IDCACHE)) {
193             InfinispanCache.get().<Long, Company>getCache(Company.IDCACHE).clear();
194         } else {
195             InfinispanCache.get().<Long, Company>getCache(Company.IDCACHE)
196                             .addListener(new CacheLogListener(Company.LOG));
197         }
198         if (InfinispanCache.get().exists(Company.NAMECACHE)) {
199             InfinispanCache.get().<String, Company>getCache(Company.NAMECACHE).clear();
200         } else {
201             InfinispanCache.get().<String, Company>getCache(Company.NAMECACHE)
202                             .addListener(new CacheLogListener(Company.LOG));
203         }
204     }
205 
206    /**
207     * Returns for given parameter <i>_id</i> the instance of class {@link Company}.
208     *
209     * @param _id    id to search in the cache
210     * @return instance of class {@link Company}
211     * @throws CacheReloadException on error
212     * @see #getCache
213     */
214     public static Company get(final long _id)
215         throws CacheReloadException
216     {
217         final Cache<Long, Company> cache = InfinispanCache.get().<Long, Company>getCache(Company.IDCACHE);
218         if (!cache.containsKey(_id) && !Company.getCompanyFromDB(Company.SQL_ID, _id)) {
219             cache.put(_id, Company.NULL, 100, TimeUnit.SECONDS);
220         }
221         final Company ret = cache.get(_id);
222         return ret.equals(Company.NULL) ? null : ret;
223     }
224 
225    /**
226     * Returns for given parameter <i>_name</i> the instance of class
227     * {@link Company}.
228     *
229     * @param _name   name to search in the cache
230     * @return instance of class {@link Company}
231     * @throws CacheReloadException on error
232     * @see #getCache
233     */
234     public static Company get(final String _name)
235         throws CacheReloadException
236     {
237         final Cache<String, Company> cache = InfinispanCache.get().<String, Company>getCache(Company.NAMECACHE);
238         if (!cache.containsKey(_name) && !Company.getCompanyFromDB(Company.SQL_NAME, _name)) {
239             cache.put(_name, Company.NULL, 100, TimeUnit.SECONDS);
240         }
241         final Company ret = cache.get(_name);
242         return ret.equals(Company.NULL) ? null : ret;
243     }
244 
245     /**
246      * Returns for given parameter <i>_uuid</i> the instance of class
247      * {@link Company}.
248      * @param _uuid UUI to search for
249      * @return instance of class {@link Company}
250      * @throws CacheReloadException on error
251      */
252     public static Company get(final UUID _uuid)
253         throws CacheReloadException
254     {
255         final Cache<UUID, Company> cache = InfinispanCache.get().<UUID, Company>getCache(Company.UUIDCACHE);
256         if (!cache.containsKey(_uuid)) {
257             Company.getCompanyFromDB(Company.SQL_UUID, String.valueOf(_uuid));
258         }
259         return cache.get(_uuid);
260     }
261 
262     /**
263      * @param _role Company to be cached
264      */
265     private static void cacheCompany(final Company _role)
266     {
267         final Cache<UUID, Company> cache4UUID = InfinispanCache.get().<UUID, Company>getIgnReCache(Company.UUIDCACHE);
268         cache4UUID.putIfAbsent(_role.getUUID(), _role);
269 
270         final Cache<String, Company> naCache = InfinispanCache.get().<String, Company>getIgnReCache(Company.NAMECACHE);
271         naCache.putIfAbsent(_role.getName(), _role);
272 
273         final Cache<Long, Company> idCache = InfinispanCache.get().<Long, Company>getIgnReCache(Company.IDCACHE);
274         idCache.putIfAbsent(_role.getId(), _role);
275     }
276 
277     /**
278      * @param _sql      SQL Statment to be execuetd
279      * @param _criteria filter criteria
280      * @return true if successful
281      * @throws CacheReloadException on error
282      */
283     private static boolean getCompanyFromDB(final String _sql,
284                                             final Object _criteria)
285         throws CacheReloadException
286     {
287         boolean ret = false;
288         ConnectionResource con = null;
289         try {
290             con = Context.getThreadContext().getConnectionResource();
291             PreparedStatement stmt = null;
292             try {
293                 stmt = con.getConnection().prepareStatement(_sql);
294                 stmt.setObject(1, _criteria);
295                 final ResultSet rs = stmt.executeQuery();
296                 if (rs.next()) {
297                     final long id = rs.getLong(1);
298                     final String uuid = rs.getString(2);
299                     final String name = rs.getString(3).trim();
300                     final boolean status = rs.getBoolean(4);
301 
302                     Company.LOG.debug("read company '" + name + "' (id = " + id + ")");
303                     final Company role = new Company(id, uuid, name, status);
304                     Company.cacheCompany(role);
305                     ret = true;
306                 }
307                 rs.close();
308             } finally {
309                 if (stmt != null) {
310                     stmt.close();
311                 }
312             }
313             con.commit();
314         } catch (final SQLException e) {
315             throw new CacheReloadException("could not read roles", e);
316         } catch (final EFapsException e) {
317             throw new CacheReloadException("could not read roles", e);
318         } finally {
319             if ((con != null) && con.isOpened()) {
320                 try {
321                     con.abort();
322                 } catch (final EFapsException e) {
323                     throw new CacheReloadException("could not read roles", e);
324                 }
325             }
326         }
327         return ret;
328     }
329 
330     @Override
331     public boolean equals(final Object _obj)
332     {
333         boolean ret;
334         if (_obj instanceof Company) {
335             ret = ((Company) _obj).getId() == getId();
336         } else {
337             ret = super.equals(_obj);
338         }
339         return ret;
340     }
341 
342     @Override
343     public int hashCode()
344     {
345         return  Long.valueOf(getId()).intValue();
346     }
347 }