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.common;
22  
23  import java.io.IOException;
24  import java.io.Serializable;
25  import java.io.StringReader;
26  import java.security.Provider;
27  import java.sql.PreparedStatement;
28  import java.sql.ResultSet;
29  import java.sql.SQLException;
30  import java.util.ArrayList;
31  import java.util.HashMap;
32  import java.util.List;
33  import java.util.Map;
34  import java.util.Properties;
35  import java.util.UUID;
36  
37  import org.efaps.admin.datamodel.Type;
38  import org.efaps.admin.user.Company;
39  import org.efaps.ci.CIAdminCommon;
40  import org.efaps.db.Context;
41  import org.efaps.db.Instance;
42  import org.efaps.db.transaction.ConnectionResource;
43  import org.efaps.db.wrapper.SQLPart;
44  import org.efaps.db.wrapper.SQLSelect;
45  import org.efaps.util.EFapsException;
46  import org.efaps.util.cache.CacheLogListener;
47  import org.efaps.util.cache.CacheObjectInterface;
48  import org.efaps.util.cache.CacheReloadException;
49  import org.efaps.util.cache.InfinispanCache;
50  import org.infinispan.Cache;
51  import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
52  import org.jasypt.encryption.pbe.config.StringPBEConfig;
53  import org.jasypt.properties.EncryptableProperties;
54  import org.jasypt.salt.SaltGenerator;
55  import org.slf4j.Logger;
56  import org.slf4j.LoggerFactory;
57  
58  /**
59   * The class handles the caching for system configurations with their attributes
60   * and links.
61   *
62   * @author The eFaps Team
63   * @version $Id$
64   */
65  public final class SystemConfiguration
66      implements CacheObjectInterface, Serializable
67  {
68      /**
69       * Used for serialization.
70       */
71      private static final long serialVersionUID = 1L;
72  
73      /**
74       * This is the SQL select statement to select the configs from the database
75       * by ID.
76       */
77      private static final String SQL_CONFIG = new SQLSelect()
78                      .column(0, "TYPEID")
79                      .column(0, "KEY")
80                      .column(0, "VALUE")
81                      .column(0, "COMPANYID")
82                      .from("T_CMSYSCONF", 0)
83                      .addPart(SQLPart.WHERE).addColumnPart(0, "ABSTRACTID").addPart(SQLPart.EQUAL).addValuePart("?")
84                      .toString();
85  
86      /**
87       * This is the SQL select statement to select a role from the database by
88       * ID.
89       */
90      private static final String SQL_ID = new SQLSelect()
91                      .column(0, "ID")
92                      .column(0, "NAME")
93                      .column(0, "UUID")
94                      .from("T_CMABSTRACT", 0)
95                      .addPart(SQLPart.WHERE).addColumnPart(0, "ID").addPart(SQLPart.EQUAL).addValuePart("?").toString();
96  
97      /**
98       * This is the SQL select statement to select a role from the database by
99       * Name.
100      */
101     private static final String SQL_NAME = new SQLSelect()
102                     .column(0, "ID")
103                     .column(0, "NAME")
104                     .column(0, "UUID")
105                     .from("T_CMABSTRACT", 0)
106                     .addPart(SQLPart.WHERE).addColumnPart(0, "NAME").addPart(SQLPart.EQUAL).addValuePart("?")
107                     .toString();
108 
109     /**
110      * This is the SQL select statement to select a role from the database by
111      * UUID.
112      */
113     private static final String SQL_UUID = new SQLSelect()
114                     .column(0, "ID")
115                     .column(0, "NAME")
116                     .column(0, "UUID")
117                     .from("T_CMABSTRACT", 0)
118                     .addPart(SQLPart.WHERE).addColumnPart(0, "UUID").addPart(SQLPart.EQUAL).addValuePart("?")
119                     .toString();
120 
121     /**
122      * Name of the Cache by UUID.
123      */
124     private static final String UUIDCACHE = SystemConfiguration.class.getName() + ".UUID";
125 
126     /**
127      * Name of the Cache by ID.
128      */
129     private static final String IDCACHE = SystemConfiguration.class.getName() + ".ID";
130 
131     /**
132      * Name of the Cache by Name.
133      */
134     private static final String NAMECACHE = SystemConfiguration.class.getName() + ".Name";
135 
136     /**
137      * Logging instance used in this class.
138      */
139     private static final Logger LOG = LoggerFactory.getLogger(SystemConfiguration.class);
140 
141     /**
142      * The configuration for the PBE used for jasypt.
143      */
144     private static final EFapsPBEConfig BPECONF = new EFapsPBEConfig();
145 
146     /**
147      * The encryptor for the PBE used for jasypt.
148      */
149     private static StandardPBEStringEncryptor ENCRYPTOR;
150 
151     /**
152      * The instance variable stores the id of this SystemAttribute.
153      *
154      * @see #getId()
155      */
156     private final long id;
157 
158     /**
159      * The instance variable stores the UUID of this SystemAttribute.
160      *
161      * @see #getUUID()
162      */
163     private final UUID uuid;
164 
165     /**
166      * The instance variable stores the Name of this SystemAttribute.
167      *
168      * @see #getName()
169      */
170     private final String name;
171 
172     /**
173      * Map with all attributes for this system configuration.
174      */
175     private final Map<Long, Map<String, String>> attributes = new HashMap<Long, Map<String, String>>();
176 
177     /**
178      * Map with all links for this system configuration.
179      */
180     private final Map<Long, Map<String, String>> links = new HashMap<Long, Map<String, String>>();
181 
182     /**
183      * Map with all object attributes for this system configuration.
184      */
185     private final Map<Long, Map<String, String>> objectAttributes = new HashMap<Long, Map<String, String>>();
186 
187     /**
188      * Constructor setting instance variables.
189      *
190      * @param _id id of the SystemConfiguration
191      * @param _uuid uuid of the SystemConfiguration
192      * @param _name name of the SystemConfiguration
193      */
194     private SystemConfiguration(final long _id,
195                                 final String _name,
196                                 final String _uuid)
197     {
198         this.id = _id;
199         this.uuid = UUID.fromString(_uuid);
200         this.name = _name;
201         this.attributes.put(new Long(0), new HashMap<String, String>());
202         this.links.put(new Long(0), new HashMap<String, String>());
203         this.objectAttributes.put(new Long(0), new HashMap<String, String>());
204     }
205 
206     /**
207      * Returns for given parameter <i>_id</i> the instance of class
208      * {@link SystemConfiguration}.
209      *
210      * @param _id id of the system configuration
211      * @return instance of class {@link SystemConfiguration}
212      * @throws CacheReloadException on error
213      */
214     public static SystemConfiguration get(final long _id)
215         throws CacheReloadException
216     {
217         final Cache<Long, SystemConfiguration> cache = InfinispanCache.get().<Long, SystemConfiguration>getCache(
218                         SystemConfiguration.IDCACHE);
219         if (!cache.containsKey(_id)) {
220             SystemConfiguration.getSystemConfigurationFromDB(SystemConfiguration.SQL_ID, _id);
221         }
222         return cache.get(_id);
223     }
224 
225     /**
226      * Returns for given parameter <i>_name</i> the instance of class
227      * {@link SystemConfiguration}.
228      *
229      * @param _name name of the system configuration
230      * @return instance of class {@link SystemConfiguration}
231      * @throws CacheReloadException on error
232      */
233     public static SystemConfiguration get(final String _name)
234         throws CacheReloadException
235     {
236         final Cache<String, SystemConfiguration> cache = InfinispanCache.get().<String, SystemConfiguration>getCache(
237                         SystemConfiguration.NAMECACHE);
238         if (!cache.containsKey(_name)) {
239             SystemConfiguration.getSystemConfigurationFromDB(SystemConfiguration.SQL_NAME, _name);
240         }
241         return cache.get(_name);
242     }
243 
244     /**
245      * Returns for given parameter <i>_uuid</i> the instance of class
246      * {@link SystemConfiguration}.
247      *
248      * @param _uuid uuid of the system configuration
249      * @return instance of class {@link SystemConfiguration}
250      * @throws CacheReloadException on error
251      */
252     public static SystemConfiguration get(final UUID _uuid)
253         throws CacheReloadException
254     {
255         final Cache<UUID, SystemConfiguration> cache = InfinispanCache.get().<UUID, SystemConfiguration>getCache(
256                         SystemConfiguration.UUIDCACHE);
257         if (!cache.containsKey(_uuid)) {
258             SystemConfiguration.getSystemConfigurationFromDB(SystemConfiguration.SQL_UUID, String.valueOf(_uuid));
259         }
260         return cache.get(_uuid);
261     }
262 
263     /**
264      * This is the getter method for the instance variable {@link #id}.
265      *
266      * @return value of instance variable {@link #id}
267      */
268     @Override
269     public long getId()
270     {
271         return this.id;
272     }
273 
274     /**
275      * This is the getter method for the instance variable {@link #uuid}.
276      *
277      * @return value of instance variable {@link #uuid}
278      */
279     @Override
280     public UUID getUUID()
281     {
282         return this.uuid;
283     }
284 
285     /**
286      * This is the getter method for the instance variable {@link #name}.
287      *
288      * @return value of instance variable {@link #name}
289      */
290     @Override
291     public String getName()
292     {
293         return this.name;
294     }
295 
296     /**
297      * Get a value from the maps. The following logic applies:
298      * <ol>
299      * <li>Check if a Context exists</li>
300      * <li>If a Context exist check if a company is given</li>
301      * <li>If a company is given, check for a company specific map</li>
302      * <li>If a company specific map is given search for the key in this map</li>
303      * <li>If any of the earlier point fails the value from the default map is
304      * returned</li>
305      * </ol>
306      *
307      * @param _key key the value is wanted for
308      * @param _map map the key will be search in for
309      * @return String value
310      * @throws EFapsException on error
311      */
312     private String getValue(final String _key,
313                             final Map<Long, Map<String, String>> _map)
314         throws EFapsException
315     {
316         Company company = null;
317         if (Context.isThreadActive()) {
318             company = Context.getThreadContext().getCompany();
319         }
320         final long companyId = company == null ? 0 : company.getId();
321         Map<String, String> innerMap;
322         if (_map.containsKey(companyId)) {
323             innerMap = _map.get(companyId);
324             if (!innerMap.containsKey(_key)) {
325                 innerMap = _map.get(new Long(0));
326             }
327         } else {
328             innerMap = _map.get(new Long(0));
329         }
330         return innerMap.get(_key);
331     }
332 
333     /**
334      * Returns for given <code>_key</code> the related link. If no link is found
335      * <code>null</code> is returned.
336      *
337      * @param _key key of searched link
338      * @return found link; if not found <code>null</code>
339      * @throws EFapsException on error
340      * @see #links
341      */
342     public Instance getLink(final String _key)
343         throws EFapsException
344     {
345         return Instance.get(getValue(_key, this.links));
346     }
347 
348     /**
349      * Returns for given <code>Instance</code> the related attribute value. If
350      * no attribute value is found <code>null</code> is returned.
351      *
352      * @param _instance Instance of searched objectattribute
353      * @return found attribute value; if not found <code>null</code>
354      * @throws EFapsException on error
355      * @see #objectAttributes
356      */
357     public String getObjectAttributeValue(final Instance _instance)
358         throws EFapsException
359     {
360         return getObjectAttributeValue(_instance.getOid());
361     }
362 
363     /**
364      * Returns for given <code>OID</code> the related attribute value. If no
365      * attribute value is found <code>null</code> is returned.
366      *
367      * @param _oid OID of searched objectattribute
368      * @return found attribute value; if not found <code>null</code>
369      * @throws EFapsException on error
370      * @see #objectAttributes
371      */
372     public String getObjectAttributeValue(final String _oid)
373         throws EFapsException
374     {
375         return getValue(_oid, this.objectAttributes);
376     }
377 
378     /**
379      * Returns for given <code>Instance</code> the related value as Properties.
380      * If no attribute is found an empty Properties is returned.
381      *
382      * @param _instance Instance of searched attribute
383      * @return Properties
384      * @throws EFapsException on error
385      * @see #objectAttributes
386      */
387     public Properties getObjectAttributeValueAsProperties(final Instance _instance)
388         throws EFapsException
389     {
390         return getObjectAttributeValueAsProperties(_instance.getOid());
391     }
392 
393     /**
394      * Returns for given <code>OID</code> the related value as Properties. If no
395      * attribute is found an empty Properties is returned.
396      *
397      * @param _key key of searched attribute
398      * @return Properties
399      * @throws EFapsException on error
400      * @see #objectAttributes
401      */
402     public Properties getObjectAttributeValueAsProperties(final String _key)
403         throws EFapsException
404     {
405         final Properties ret = new Properties();
406         final String value = getValue(_key, this.objectAttributes);
407         if (value != null) {
408             try {
409                 ret.load(new StringReader(value));
410             } catch (final IOException e) {
411                 throw new EFapsException(SystemConfiguration.class, "getObjectAttributeValueAsProperties", e);
412             }
413         }
414         return ret;
415     }
416 
417     /**
418      * Returns for given <code>_key</code> the related attribute value. If no
419      * attribute value is found <code>null</code> is returned.
420      *
421      * @param _key key of searched attribute
422      * @return found attribute value; if not found <code>null</code>
423      * @throws EFapsException on error
424      * @see #attributes
425      */
426     public String getAttributeValue(final String _key)
427         throws EFapsException
428     {
429         return getValue(_key, this.attributes);
430     }
431 
432     /**
433      * Returns for given <code>_key</code> the related boolean attribute value.
434      * If no attribute value is found <i>false</i> is returned.
435      *
436      * @param _key key of searched attribute
437      * @return found boolean attribute value; if not found <i>false</i>
438      * @throws EFapsException on error
439      * @see #attributes
440      */
441     public boolean getAttributeValueAsBoolean(final String _key)
442         throws EFapsException
443     {
444         final String value = getAttributeValue(_key);
445         return value == null ? false : Boolean.parseBoolean(value);
446     }
447 
448     /**
449      * Returns for given <code>_key</code> the related integer attribute value.
450      * If no attribute is found <code>0</code> is returned.
451      *
452      * @param _key key of searched attribute
453      * @return found integer attribute value; if not found <code>0</code>
454      * @throws EFapsException on error
455      * @see #attributes
456      */
457     public int getAttributeValueAsInteger(final String _key)
458         throws EFapsException
459     {
460         final String value = getAttributeValue(_key);
461         return value == null ? 0 : Integer.parseInt(value);
462     }
463 
464 
465     /**
466      * Returns for given <code>_key</code> the related value as Properties. If
467      * no attribute is found an empty Properties is returned.
468      *
469      * @param _key key of searched attribute
470      * @return Properties
471      * @throws EFapsException on error
472      * @see #attributes
473      */
474     public Properties getAttributeValueAsEncryptedProperties(final String _key)
475         throws EFapsException
476     {
477         final Properties properties = getAttributeValueAsProperties(_key, false);
478         final Properties props = new EncryptableProperties(properties, SystemConfiguration.ENCRYPTOR);
479         return props;
480     }
481 
482     /**
483      * Returns for given <code>_key</code> the related value as Properties. If
484      * no attribute is found an empty Properties is returned.
485      *
486      * @param _key key of searched attribute
487      * @param _concatenate is concatenate or not
488      * @return Properties
489      * @throws EFapsException on error
490      * @see #attributes
491      */
492     public Properties getAttributeValueAsEncryptedProperties(final String _key,
493                                                              final boolean _concatenate)
494         throws EFapsException
495     {
496         final Properties properties = getAttributeValueAsProperties(_key, _concatenate);
497         final StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
498         encryptor.setConfig(SystemConfiguration.getPBEConfig());
499         final Properties props = new EncryptableProperties(properties, encryptor);
500         return props;
501     }
502 
503     /**
504      * Returns for given <code>_key</code> the related value as Properties. If
505      * no attribute is found an empty Properties is returned.
506      *
507      * @param _key key of searched attribute
508      * @return Properties
509      * @throws EFapsException on error
510      * @see #attributes
511      */
512     public Properties getAttributeValueAsProperties(final String _key)
513         throws EFapsException
514     {
515         return getAttributeValueAsProperties(_key, false);
516     }
517 
518     /**
519      * Returns for given <code>_key</code> the related value as Properties. If
520      * no attribute is found an empty Properties is returned.
521      * Can concatenates Properties for Keys.<br/>
522      * e.b. Key, Key01, Key02, Key03
523      *
524      * @param _key key of searched attribute
525      * @param _concatenate  concatenate or not
526      * @return map with properties
527      * @throws EFapsException on error
528      */
529     public Properties getAttributeValueAsProperties(final String _key,
530                                                     final boolean _concatenate)
531         throws EFapsException
532     {
533         final Properties ret = new Properties();
534         final String value = getAttributeValue(_key);
535         if (value != null) {
536             try {
537                 ret.load(new StringReader(value));
538             } catch (final IOException e) {
539                 throw new EFapsException(SystemConfiguration.class, "getAttributeValueAsProperties", e);
540             }
541         }
542         if (_concatenate) {
543             for (int i = 1; i < 100; i++) {
544                 final String keyTmp = _key + String.format("%02d", i);
545                 final String valueTmp = getAttributeValue(keyTmp);
546                 final Properties propsTmp = new Properties();
547                 if (valueTmp != null) {
548                     try {
549                         propsTmp.load(new StringReader(valueTmp));
550                     } catch (final IOException e) {
551                         throw new EFapsException(SystemConfiguration.class, "getAttributeValueAsPropertiesConcat", e);
552                     }
553                 } else {
554                     break;
555                 }
556                 if (propsTmp.isEmpty()) {
557                     break;
558                 } else {
559                     ret.putAll(propsTmp);
560                 }
561             }
562         }
563         return ret;
564     }
565 
566     /**
567      * Reload the current SystemConfiguration by removing it from the Cache.
568      */
569     public void reload()
570     {
571         InfinispanCache.get().<UUID, SystemConfiguration>getCache(SystemConfiguration.UUIDCACHE).remove(this.uuid);
572         InfinispanCache.get().<Long, SystemConfiguration>getCache(SystemConfiguration.IDCACHE).remove(this.id);
573         InfinispanCache.get().<String, SystemConfiguration>getCache(SystemConfiguration.NAMECACHE).remove(this.name);
574     }
575 
576     /**
577      * Read the config.
578      * @throws CacheReloadException on error
579      */
580     private void readConfig()
581         throws CacheReloadException
582     {
583         ConnectionResource con = null;
584         try {
585             boolean closeContext = false;
586             if (!Context.isThreadActive()) {
587                 Context.begin();
588                 closeContext = true;
589             }
590             final List<Object[]> values = new ArrayList<Object[]>();
591             con = Context.getThreadContext().getConnectionResource();
592             PreparedStatement stmt = null;
593             try {
594                 stmt = con.getConnection().prepareStatement(SystemConfiguration.SQL_CONFIG);
595                 stmt.setObject(1, getId());
596                 final ResultSet rs = stmt.executeQuery();
597 
598                 while (rs.next()) {
599                     values.add(new Object[] {
600                                     rs.getLong(1),
601                                     rs.getString(2).trim(),
602                                     rs.getString(3).trim(),
603                                     rs.getLong(4)
604                     });
605                 }
606                 rs.close();
607             } finally {
608                 if (stmt != null) {
609                     stmt.close();
610                 }
611             }
612             con.commit();
613             if (closeContext) {
614                 Context.rollback();
615             }
616             for (final Object[] row : values) {
617                 final Long typeId = (Long) row[0];
618                 final String key = (String) row[1];
619                 final String value = (String) row[2];
620                 final Long companyId = (Long) row[3];
621                 final Type type = Type.get(typeId);
622                 final Map<Long, Map<String, String>> configMap;
623                 if (type.equals(CIAdminCommon.SystemConfigurationLink.getType())) {
624                     configMap = this.links;
625                 } else if (type.equals(CIAdminCommon.SystemConfigurationObjectAttribute.getType())) {
626                     configMap = this.objectAttributes;
627                 } else {
628                     configMap = this.attributes;
629                 }
630                 final Map<String, String> map;
631                 if (configMap.containsKey(companyId)) {
632                     map = configMap.get(companyId);
633                 } else {
634                     map = new HashMap<String, String>();
635                     configMap.put(companyId, map);
636                 }
637                 map.put(key, value);
638             }
639         } catch (final SQLException e) {
640             throw new CacheReloadException("could not read SystemConfiguration attributes", e);
641         } catch (final EFapsException e) {
642             throw new CacheReloadException("could not read SystemConfiguration attributes", e);
643         } finally {
644             if ((con != null) && con.isOpened()) {
645                 try {
646                     con.abort();
647                 } catch (final EFapsException e) {
648                     throw new CacheReloadException("could not read SystemConfiguration attributes", e);
649                 }
650             }
651         }
652     }
653 
654     /**
655      * Method to initialize the {@link #CACHE cache} for the system
656      * configurations.
657      */
658     public static void initialize()
659     {
660         if (InfinispanCache.get().exists(SystemConfiguration.UUIDCACHE)) {
661             InfinispanCache.get().<UUID, SystemConfiguration>getCache(SystemConfiguration.UUIDCACHE).clear();
662         } else {
663             InfinispanCache.get().<UUID, SystemConfiguration>getCache(SystemConfiguration.UUIDCACHE)
664                             .addListener(new CacheLogListener(SystemConfiguration.LOG));
665         }
666         if (InfinispanCache.get().exists(SystemConfiguration.IDCACHE)) {
667             InfinispanCache.get().<Long, SystemConfiguration>getCache(SystemConfiguration.IDCACHE).clear();
668         } else {
669             InfinispanCache.get().<Long, SystemConfiguration>getCache(SystemConfiguration.IDCACHE)
670                             .addListener(new CacheLogListener(SystemConfiguration.LOG));
671         }
672         if (InfinispanCache.get().exists(SystemConfiguration.NAMECACHE)) {
673             InfinispanCache.get().<String, SystemConfiguration>getCache(SystemConfiguration.NAMECACHE).clear();
674         } else {
675             InfinispanCache.get().<String, SystemConfiguration>getCache(SystemConfiguration.NAMECACHE)
676                             .addListener(new CacheLogListener(SystemConfiguration.LOG));
677         }
678 
679         SystemConfiguration.ENCRYPTOR = new StandardPBEStringEncryptor();
680         SystemConfiguration.ENCRYPTOR.setConfig(SystemConfiguration.getPBEConfig());
681     }
682 
683     /**
684      * @param _sysConfig SystemConfiguration to be cached
685      */
686     private static void cacheSytemConfig(final SystemConfiguration _sysConfig)
687     {
688         final Cache<UUID, SystemConfiguration> cache4UUID = InfinispanCache.get()
689                         .<UUID, SystemConfiguration>getIgnReCache(SystemConfiguration.UUIDCACHE);
690         cache4UUID.put(_sysConfig.getUUID(), _sysConfig);
691 
692         final Cache<String, SystemConfiguration> nameCache = InfinispanCache.get()
693                         .<String, SystemConfiguration>getIgnReCache(SystemConfiguration.NAMECACHE);
694         nameCache.put(_sysConfig.getName(), _sysConfig);
695 
696         final Cache<Long, SystemConfiguration> idCache = InfinispanCache.get()
697                         .<Long, SystemConfiguration>getIgnReCache(SystemConfiguration.IDCACHE);
698         idCache.putIfAbsent(_sysConfig.getId(), _sysConfig);
699     }
700 
701     /**
702      * @param _sql sql statement to be executed
703      * @param _criteria filter criteria
704      * @throws CacheReloadException on error
705      * @return false
706      */
707     private static boolean getSystemConfigurationFromDB(final String _sql,
708                                                         final Object _criteria)
709         throws CacheReloadException
710     {
711         boolean ret = false;
712         ConnectionResource con = null;
713         try {
714             boolean closeContext = false;
715             if (!Context.isThreadActive()) {
716                 Context.begin();
717                 closeContext = true;
718             }
719             SystemConfiguration sysConfig = null;
720             con = Context.getThreadContext().getConnectionResource();
721             PreparedStatement stmt = null;
722             try {
723                 stmt = con.getConnection().prepareStatement(_sql);
724                 stmt.setObject(1, _criteria);
725                 final ResultSet rs = stmt.executeQuery();
726                 if (rs.next()) {
727                     final long id = rs.getLong(1);
728                     final String name = rs.getString(2).trim();
729                     final String uuid = rs.getString(3).trim();
730                     SystemConfiguration.LOG.debug("read SystemConfiguration '{}' (id = {}), format = '{}'", name, id);
731                     sysConfig = new SystemConfiguration(id, name, uuid);
732                 }
733                 ret = true;
734                 rs.close();
735             } finally {
736                 if (stmt != null) {
737                     stmt.close();
738                 }
739             }
740             con.commit();
741             if (closeContext) {
742                 Context.rollback();
743             }
744             if (sysConfig != null) {
745                 sysConfig.readConfig();
746                 SystemConfiguration.cacheSytemConfig(sysConfig);
747             }
748         } catch (final SQLException e) {
749             throw new CacheReloadException("could not read SystemConfiguration", e);
750         } catch (final EFapsException e) {
751             throw new CacheReloadException("could not read SystemConfiguration", e);
752         } finally {
753             if ((con != null) && con.isOpened()) {
754                 try {
755                     con.abort();
756                 } catch (final EFapsException e) {
757                     throw new CacheReloadException("could not read SystemConfiguration", e);
758                 }
759             }
760         }
761         return ret;
762     }
763 
764     /**
765      * @return the BPE Configuration.
766      */
767     public static EFapsPBEConfig getPBEConfig()
768     {
769         return SystemConfiguration.BPECONF;
770     }
771 
772 
773     @Override
774     public boolean equals(final Object _obj)
775     {
776         boolean ret;
777         if (_obj instanceof SystemConfiguration) {
778             ret = ((SystemConfiguration) _obj).getId() == getId();
779         } else {
780             ret = super.equals(_obj);
781         }
782         return ret;
783     }
784 
785     @Override
786     public int hashCode()
787     {
788         return  Long.valueOf(getId()).intValue();
789     }
790 
791     /**
792      * Configuration class. Currently only the password is used. For all other
793      * <code>null</code>is returnred to use the default values from jasyprt.
794      */
795     public static final class EFapsPBEConfig
796         implements StringPBEConfig
797     {
798         /**
799          * Password.
800          */
801         private char[] password = null;
802 
803         /**
804          * Sets the password to be used for encryption.
805          * <p>
806          * Determines the result of: {@link #getPassword()} and
807          * {@link #getPasswordCharArray()}.
808          * </p>
809          *
810          * @param _password the password to be used.
811          */
812         public void setPassword(final String _password)
813         {
814             if (_password == null) {
815                 this.password = null;
816             } else {
817                 this.password = _password.toCharArray();
818             }
819         }
820 
821         @Override
822         public String getPassword()
823         {
824             return new String(this.password);
825         }
826 
827         @Override
828         public String getAlgorithm()
829         {
830             return null;
831         }
832 
833         @Override
834         public Integer getKeyObtentionIterations()
835         {
836             return null;
837         }
838 
839         @Override
840         public SaltGenerator getSaltGenerator()
841         {
842             return null;
843         }
844 
845         @Override
846         public String getProviderName()
847         {
848             return null;
849         }
850 
851         @Override
852         public Provider getProvider()
853         {
854             return null;
855         }
856 
857         @Override
858         public Integer getPoolSize()
859         {
860             return null;
861         }
862 
863         @Override
864         public String getStringOutputType()
865         {
866             return null;
867         }
868     }
869 }