View Javadoc
1   package fr.ifremer.quadrige2.core.config;
2   
3   /*-
4    * #%L
5    * Quadrige2 Core :: Quadrige2 Core Shared
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2017 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU Affero General Public License as published by
13   * the Free Software Foundation, either version 3 of the License, or
14   * (at your option) any later version.
15   * 
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   * 
21   * You should have received a copy of the GNU Affero General Public License
22   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23   * #L%
24   */
25  
26  
27  
28  
29  import com.google.common.base.Charsets;
30  import com.google.common.base.Splitter;
31  import com.google.common.collect.ImmutableSet;
32  import com.google.common.collect.Sets;
33  import fr.ifremer.quadrige2.core.dao.technical.Daos;
34  import fr.ifremer.quadrige2.core.dao.technical.hibernate.DateType;
35  import fr.ifremer.quadrige2.core.dao.technical.spring.Springs;
36  import fr.ifremer.quadrige2.core.exception.Quadrige2TechnicalException;
37  import org.apache.commons.lang3.ArrayUtils;
38  import org.apache.commons.lang3.StringUtils;
39  import org.apache.commons.logging.Log;
40  import org.apache.commons.logging.LogFactory;
41  import org.nuiton.config.ApplicationConfig;
42  import org.nuiton.config.ApplicationConfigHelper;
43  import org.nuiton.config.ApplicationConfigProvider;
44  import org.nuiton.config.ArgumentsParserException;
45  import org.nuiton.version.Version;
46  import org.springframework.beans.BeansException;
47  import org.springframework.beans.factory.BeanInitializationException;
48  import org.springframework.beans.factory.InitializingBean;
49  import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
50  import org.springframework.context.ApplicationContext;
51  import org.springframework.context.ApplicationContextAware;
52  import org.springframework.core.io.Resource;
53  import org.springframework.util.CollectionUtils;
54  
55  import java.io.File;
56  import java.io.IOException;
57  import java.io.InputStream;
58  import java.net.MalformedURLException;
59  import java.net.URL;
60  import java.util.*;
61  
62  import static org.nuiton.i18n.I18n.t;
63  
64  /**
65   * Access to configuration options
66   *
67   * @author Benoit Lavenier <benoit.lavenier@e-is.pro>
68   */
69  public class Quadrige2Configuration extends PropertyPlaceholderConfigurer implements ApplicationContextAware, InitializingBean {
70      /** Logger. */
71      private static final Log log = LogFactory.getLog(Quadrige2Configuration.class);
72  
73      private static final String DEFAULT_SHARED_CONFIG_FILE = "quadrige2-core-shared.config";
74  
75      /**
76       * Delegate application config.
77       */
78      protected final ApplicationConfig applicationConfig;
79  
80      private ApplicationContext appContext = null;
81      
82      private boolean isInitialize = false;
83      
84      private static Quadrige2Configuration instance;
85      
86      /**
87       * <p>Getter for the field <code>instance</code>.</p>
88       *
89       * @return a {@link fr.ifremer.quadrige2.core.config.Quadrige2Configuration} object.
90       */
91      public static Quadrige2Configuration getInstance() {
92          return instance;
93      }
94  
95      /**
96       * <p>Setter for the field <code>instance</code>.</p>
97       *
98       * @param instance a {@link fr.ifremer.quadrige2.core.config.Quadrige2Configuration} object.
99       */
100     public static void setInstance(Quadrige2Configuration instance) {
101         Quadrige2Configuration.instance = instance;
102     }
103 
104     protected final String[] optionKeyToNotSave;
105 
106     protected File configFile;
107 
108     /**
109      * <p>Constructor for Quadrige2Configuration.</p>
110      *
111      * @param applicationConfig a {@link org.nuiton.config.ApplicationConfig} object.
112      */
113     public Quadrige2Configuration(ApplicationConfig applicationConfig) {
114         super();
115         this.applicationConfig = applicationConfig;
116         this.optionKeyToNotSave = null;
117     }
118 
119     /**
120      * <p>Constructor for Quadrige2Configuration.</p>
121      *
122      * @param file a {@link java.lang.String} object.
123      * @param args a {@link java.lang.String} object.
124      */
125     public Quadrige2Configuration(String file, String... args) {
126         super();
127         this.applicationConfig = new ApplicationConfig();
128         this.applicationConfig.setEncoding(Charsets.UTF_8.name());
129         this.applicationConfig.setConfigFileName(file);
130 
131         // get all config providers
132         Set<ApplicationConfigProvider> providers =
133                 ApplicationConfigHelper.getProviders(null,
134                         null,
135                         null,
136                         true);
137 
138         // load all default options
139         ApplicationConfigHelper.loadAllDefaultOption(applicationConfig,
140                 providers);
141 
142         // Load actions
143         for (ApplicationConfigProvider provider : providers) {
144             applicationConfig.loadActions(provider.getActions());
145         }
146         
147         // Define Alias
148         addAlias(applicationConfig);
149 
150         // Override some external module default config (quadrige2)
151         overrideExternalModulesDefaultOptions(applicationConfig);
152 
153         // get all transient and final option keys
154         Set<String> optionToSkip =
155                 ApplicationConfigHelper.getTransientOptionKeys(providers);
156 
157         if (log.isDebugEnabled()) {
158             log.debug("Option that won't be saved: " + optionToSkip);
159         }
160         optionKeyToNotSave = optionToSkip.toArray(new String[optionToSkip.size()]);
161 
162         try {
163             applicationConfig.parse(args);
164 
165         } catch (ArgumentsParserException e) {
166             throw new Quadrige2TechnicalException(t("quadrige2.config.parse.error"), e);
167         }
168 
169         // TODO Review this, this is very dirty to do this...
170         File appBasedir = applicationConfig.getOptionAsFile(
171                 Quadrige2ConfigurationOption.BASEDIR.getKey());
172 
173         if (appBasedir == null) {
174             appBasedir = new File("");
175         }
176         if (!appBasedir.isAbsolute()) {
177             appBasedir = new File(appBasedir.getAbsolutePath());
178         }
179         if (appBasedir.getName().equals("..")) {
180             appBasedir = appBasedir.getParentFile().getParentFile();
181         }
182         if (appBasedir.getName().equals(".")) {
183             appBasedir = appBasedir.getParentFile();
184         }
185         if (log.isInfoEnabled()) {
186             log.info("Application basedir: " + appBasedir);
187         }
188         applicationConfig.setOption(
189                 Quadrige2ConfigurationOption.BASEDIR.getKey(),
190                 appBasedir.getAbsolutePath());
191     }
192 
193     /**
194      * Add alias to the given ApplicationConfig. <p/>
195      * This method could be override to add specific alias
196      *
197      * @param applicationConfig a {@link org.nuiton.config.ApplicationConfig} object.
198      */
199     protected void addAlias(ApplicationConfig applicationConfig) {
200         applicationConfig.addAlias("-u", "--option", Quadrige2ConfigurationOption.JDBC_USERNAME.getKey());
201         applicationConfig.addAlias("--user", "--option", Quadrige2ConfigurationOption.JDBC_USERNAME.getKey());
202         applicationConfig.addAlias("-p", "--option", Quadrige2ConfigurationOption.JDBC_PASSWORD.getKey());
203         applicationConfig.addAlias("--password", "--option", Quadrige2ConfigurationOption.JDBC_PASSWORD.getKey());
204         applicationConfig.addAlias("-db", "--option", Quadrige2ConfigurationOption.JDBC_URL.getKey());
205         applicationConfig.addAlias("--database", "--option", Quadrige2ConfigurationOption.JDBC_URL.getKey());
206 
207         applicationConfig.addAlias("--output", "--option", Quadrige2ConfigurationOption.LIQUIBASE_OUTPUT_FILE.getKey());
208         applicationConfig.addAlias("-f", "--option", Quadrige2ConfigurationOption.LIQUIBASE_FORCE_OUTPUT_FILE.getKey(), "true");
209         
210         applicationConfig.addAlias("--port", "--option", Quadrige2ConfigurationOption.SERVER_PORT.getKey());
211     }
212 
213     // Could be subclasses
214     /**
215      * <p>overrideExternalModulesDefaultOptions.</p>
216      *
217      * @param applicationConfig a {@link org.nuiton.config.ApplicationConfig} object.
218      */
219     protected void overrideExternalModulesDefaultOptions(ApplicationConfig applicationConfig) {
220         // Map synchro.persistence.XXX to quadrige2.persistence.XXX
221         Quadrige2Configurations.remapOptionsToPrefix(applicationConfig,
222                 "synchro.persistence",
223                 Quadrige2ConfigurationOption.values(),
224                 "quadrige2.persistence");
225 
226         // Map synchro.XXX to quadrige2.synchro.XXX
227         Quadrige2Configurations.remapOptionsToPrefix(applicationConfig,
228                 "synchro",
229                 Quadrige2ConfigurationOption.values(),
230                 "quadrige2.synchro");
231 
232         applicationConfig.setDefaultOption("synchro.tempQueryParameter.userId.column", "QUSER_ID");
233     }
234 
235     /** {@inheritDoc} */
236     @Override
237     public void setApplicationContext(ApplicationContext appContext) throws BeansException {
238         this.appContext = appContext;
239     }
240 
241     /** {@inheritDoc} */
242     @Override
243     public void afterPropertiesSet() throws Exception {
244 
245         if (isInitialize) {
246             return;
247         }
248         isInitialize = true;
249 
250         // Retrieve paths from configuration
251         String[] enumerationFilePaths = getEnumerationFilesPath();
252         if (ArrayUtils.isEmpty(enumerationFilePaths)) {
253             throw new BeanInitializationException(
254                     String.format(
255                             "No enumeration files path has been set in the configuration. This is required to initialize enumeration values. Please set the option [%s] in configuration file.",
256                             Quadrige2ConfigurationOption.DB_ENUMERATION_RESOURCE));
257         }
258         if (log.isDebugEnabled()) {
259             log.debug(String.format("Getting enumeration files from path: %s", Arrays.toString(enumerationFilePaths)));
260         }
261 
262         // For each path, retrieve corresponding resources
263         List<Resource> resources = Springs.getResourcesFromPaths(enumerationFilePaths, appContext, true);
264 
265         // Check if some files has been found
266         if (CollectionUtils.isEmpty(resources)) {
267             throw new BeanInitializationException(String.format("No enumeration files could be found from path %s",
268                     Arrays.toString(enumerationFilePaths)));
269         }
270         if (log.isDebugEnabled()) {
271             log.debug(String.format("%s enumeration files found from path: %s", resources.size(), Arrays.toString(enumerationFilePaths)));
272         }
273 
274         // Set enumeration default values (from enumeration file)
275         Quadrige2EnumerationHelper.reload(applicationConfig, resources);
276 
277         // Init the application version
278         initVersion(applicationConfig);
279 
280         // Init time zone
281         initTimeZone();
282     }
283 
284     /**
285      * Initialization default timezone, from configuration (mantis #24623)
286      */
287     protected void initTimeZone() {
288 
289         String dbTimeZone = applicationConfig.getOption(Quadrige2ConfigurationOption.DB_TIMEZONE.getKey());
290         if (StringUtils.isNotBlank(dbTimeZone)) {
291             if (log.isInfoEnabled()) {
292                 log.info(String.format("Using timezone [%s] for database", dbTimeZone));
293             }
294             DateType.setTimeZone(TimeZone.getTimeZone(dbTimeZone));
295         } else if (log.isInfoEnabled()) {
296             log.info(String.format("Using default timezone [%s] for database", System.getProperty("user.timezone")));
297         }
298     }
299 
300 
301     /**
302      * Make sure the version default value is the implementation version (using a properties file, filtered by Maven
303      * at build time). This avoid to manually update the version default value, in enumeration Quadrige2ConfigurationOption)
304      *
305      * @param applicationConfig a {@link org.nuiton.config.ApplicationConfig} object.
306      */
307     protected void initVersion(ApplicationConfig applicationConfig) {
308 
309         try {
310             // Load the properties file, from classpath
311             Properties sharedConfigFile = new Properties();
312             InputStream fis = getClass().getClassLoader().getResourceAsStream(DEFAULT_SHARED_CONFIG_FILE);
313             sharedConfigFile.load(fis);
314             fis.close();
315 
316             // If version property has been filled, use it as default version
317             String defaultVersion = applicationConfig.getOption(Quadrige2ConfigurationOption.VERSION.getKey());
318             String implementationVersion = sharedConfigFile.getProperty(Quadrige2ConfigurationOption.VERSION.getKey());
319             if (StringUtils.isNotBlank(implementationVersion)
320                     && StringUtils.isNotBlank(defaultVersion)
321                     && !Objects.equals(implementationVersion, defaultVersion)) {
322                 if (log.isDebugEnabled()) {
323                     log.debug(String.format("Replace default version option value [%s] with implementation value [%s] found in file [%s]",
324                             defaultVersion,
325                             implementationVersion,
326                             DEFAULT_SHARED_CONFIG_FILE));
327                 }
328                 applicationConfig.setDefaultOption(
329                         Quadrige2ConfigurationOption.VERSION.getKey(),
330                         implementationVersion);
331             }
332             else if (StringUtils.isNotBlank(implementationVersion)) {
333                 if (log.isInfoEnabled()) {
334                     log.info("Version: " + implementationVersion);
335                 }
336                 applicationConfig.setDefaultOption(
337                         Quadrige2ConfigurationOption.VERSION.getKey(),
338                         implementationVersion);
339             }
340             else if (StringUtils.isNotBlank(defaultVersion)) {
341                 if (log.isInfoEnabled()) {
342                     log.info("Version: " + defaultVersion);
343                 }
344             }
345             else if (log.isErrorEnabled()) {
346                 log.error(String.format("Could init version, from classpath file [%s]", DEFAULT_SHARED_CONFIG_FILE));
347             }
348         } catch (IOException e) {
349             log.warn(String.format("Could not load implementation version from file [%s]", DEFAULT_SHARED_CONFIG_FILE));
350         }
351 
352     }
353     
354     /**
355      * <p>Getter for the field <code>configFile</code>.</p>
356      *
357      * @return a {@link java.io.File} object.
358      */
359     public File getConfigFile() {
360         if (configFile == null) {
361             File dir = getBasedir();
362             if (dir == null || !dir.exists()) {
363                 dir = new File(applicationConfig.getUserConfigDirectory());
364             }
365             configFile = new File(dir, applicationConfig.getConfigFileName());
366         }
367         return configFile;
368     }
369 
370     /**
371      * <p>getBasedir.</p>
372      *
373      * @return a {@link java.io.File} object.
374      */
375     public File getBasedir() {
376         return applicationConfig.getOptionAsFile(Quadrige2ConfigurationOption.BASEDIR.getKey());
377     }
378 
379     /**
380      * <p>getDataDirectory.</p>
381      *
382      * @return a {@link java.io.File} object.
383      */
384     public File getDataDirectory() {
385         return applicationConfig.getOptionAsFile(Quadrige2ConfigurationOption.DATA_DIRECTORY.getKey());
386     }
387 
388     /**
389      * <p>Getter for the field <code>applicationConfig</code>.</p>
390      *
391      * @return a {@link org.nuiton.config.ApplicationConfig} object.
392      */
393     public ApplicationConfig getApplicationConfig() {
394         return applicationConfig;
395     }
396 
397     /** {@inheritDoc} */
398     @Override
399     protected String resolvePlaceholder(String placeholder, Properties props) {
400         if (applicationConfig == null) {
401             throw new Quadrige2TechnicalException(
402                     "Configuration.applicationConfig must not be null. Please initialize Configuration instance with a not null applicationConfig BEFORE starting Spring.");
403         }
404 
405         // Try to resolve placeholder from application configuration
406         String optionValue = applicationConfig.getOption(placeholder);
407         if (optionValue != null) {
408             return optionValue;
409         }
410 
411         // If not found in configuration, delegate to the default Spring mecanism
412         return super.resolvePlaceholder(placeholder, props);
413     }
414 
415     /**
416      * <p>getTempDirectory.</p>
417      *
418      * @return a {@link java.io.File} object.
419      */
420     public File getTempDirectory() {
421         return applicationConfig.getOptionAsFile(Quadrige2ConfigurationOption.TMP_DIRECTORY.getKey());
422     }
423     
424     /**
425      * <p>getDbDirectory.</p>
426      *
427      * @return a {@link java.io.File} object.
428      */
429     public File getDbDirectory() {
430         return applicationConfig.getOptionAsFile(Quadrige2ConfigurationOption.DB_DIRECTORY.getKey());
431     }
432 
433     /**
434      * <p>setDbDirectory.</p>
435      *
436      * @param dbDirectory a {@link java.io.File} object.
437      */
438     public void setDbDirectory(File dbDirectory) {
439         applicationConfig.setOption(Quadrige2ConfigurationOption.DB_DIRECTORY.getKey(), dbDirectory.getPath());
440     }
441 
442     /**
443      * <p>setJdbcUrl.</p>
444      *
445      * @param jdbcUrl a {@link java.lang.String} object.
446      */
447     public void setJdbcUrl(String jdbcUrl) {
448         applicationConfig.setOption(Quadrige2ConfigurationOption.JDBC_URL.getKey(), jdbcUrl);
449     }
450 
451     /**
452      * <p>getDbTimezone.</p>
453      *
454      * @return a {@link java.util.TimeZone} object.
455      */
456     public TimeZone getDbTimezone() {
457         String tz = applicationConfig.getOption(Quadrige2ConfigurationOption.DB_TIMEZONE.getKey());
458         return StringUtils.isNotBlank(tz) ? TimeZone.getTimeZone(tz) : TimeZone.getDefault();
459     }
460 
461     /**
462      * <p>getDbAttachmentDirectory.</p>
463      *
464      * @return a {@link java.io.File} object.
465      */
466     public File getDbAttachmentDirectory() {
467         return applicationConfig.getOptionAsFile(Quadrige2ConfigurationOption.DB_ATTACHMENT_DIRECTORY.getKey());
468     }
469 
470     /**
471      * <p>getCacheDirectory.</p>
472      *
473      * @return a {@link java.io.File} object.
474      */
475     public File getCacheDirectory() {
476         return applicationConfig.getOptionAsFile(Quadrige2ConfigurationOption.DB_CACHE_DIRECTORY.getKey());
477     }
478 
479     /**
480      * <p>getDbBackupDirectory.</p>
481      *
482      * @return a {@link java.io.File} object.
483      */
484     public File getDbBackupDirectory() {
485         return applicationConfig.getOptionAsFile(Quadrige2ConfigurationOption.DB_BACKUP_DIRECTORY.getKey());
486     }
487 
488     /**
489      * <p>getAdminEmail.</p>
490      *
491      * @return a {@link java.lang.String} object, the admin email.
492      */
493     public String getAdminEmail() {
494         return applicationConfig.getOption(Quadrige2ConfigurationOption.ADMIN_EMAIL.getKey());
495     }
496 
497     /**
498      * <p>getSynchroExportDirectoryByUser.</p>
499      *
500      * @param userId a int.
501      * @return a {@link java.io.File} object.
502      */
503     public File getSynchroExportDirectoryByUser(int userId) {
504         return new File(
505                 getSynchronizationDirectory(),
506                 new StringBuilder()
507                         .append(userId)
508                         .append(File.separator)
509                         .append("export")
510                         .toString());
511     }
512 
513     /**
514      * <p>getSynchroImportDirectoryByUser.</p>
515      *
516      * @param userId a int.
517      * @return a {@link java.io.File} object.
518      */
519     public File getSynchroImportDirectoryByUser(int userId) {
520         return new File(
521                 getSynchronizationDirectory(),
522                 new StringBuilder()
523                         .append(userId)
524                         .append(File.separator)
525                         .append("import")
526                         .toString());
527     }
528 
529     /**
530      * <p>useLiquibaseAutoRun.</p>
531      *
532      * @return a boolean.
533      */
534     public boolean useLiquibaseAutoRun() {
535         return applicationConfig.getOptionAsBoolean(Quadrige2ConfigurationOption.LIQUIBASE_RUN_AUTO.getKey());
536     }
537 
538     /**
539      * <p>getLiquibaseChangeLogPath.</p>
540      *
541      * @return a {@link java.lang.String} object.
542      */
543     public String getLiquibaseChangeLogPath() {
544         return applicationConfig.getOption(Quadrige2ConfigurationOption.LIQUIBASE_CHANGE_LOG_PATH.getKey());
545     }
546 
547     /**
548      * <p>getDbCreateScriptPath.</p>
549      *
550      * @return a {@link java.lang.String} object.
551      */
552     public String getDbCreateScriptPath() {
553         return applicationConfig.getOption(Quadrige2ConfigurationOption.DB_CREATE_SCRIPT_PATH.getKey());
554     }
555 
556     /**
557      * <p>getHibernateDialect.</p>
558      *
559      * @return a {@link java.lang.String} object.
560      */
561     public String getHibernateDialect() {
562         return applicationConfig.getOption(Quadrige2ConfigurationOption.HIBERNATE_DIALECT.getKey());
563     }
564 
565     /**
566      * <p>getHibernateClientQueriesFile.</p>
567      *
568      * @return a {@link java.lang.String} object.
569      */
570     public String getHibernateClientQueriesFile() {
571         return applicationConfig.getOption(Quadrige2ConfigurationOption.HIBERNATE_CLIENT_QUERIES_FILE.getKey());
572     }
573 
574     /**
575      * <p>getJdbcDriver.</p>
576      *
577      * @return a {@link java.lang.String} object.
578      */
579     public String getJdbcDriver() {
580         return applicationConfig.getOption(Quadrige2ConfigurationOption.JDBC_DRIVER.getKey());
581     }
582 
583     /**
584      * <p>getJdbcURL.</p>
585      *
586      * @return a {@link java.lang.String} object.
587      */
588     public String getJdbcURL() {
589         return applicationConfig.getOption(Quadrige2ConfigurationOption.JDBC_URL.getKey());
590     }
591 
592     /**
593      * <p>getJdbcCatalog.</p>
594      *
595      * @return a {@link java.lang.String} object.
596      */
597     public String getJdbcCatalog() {
598         return applicationConfig.getOption(Quadrige2ConfigurationOption.JDBC_SCHEMA.getKey());
599     }
600 
601     /**
602      * <p>getJdbcSchema.</p>
603      *
604      * @return a {@link java.lang.String} object.
605      */
606     public String getJdbcSchema() {
607         return applicationConfig.getOption(Quadrige2ConfigurationOption.JDBC_SCHEMA.getKey());
608     }
609 
610     /**
611      * <p>debugEntityLoad.</p>
612      *
613      * @return a boolean.
614      */
615     public boolean debugEntityLoad() {
616         return applicationConfig.getOptionAsBoolean(Quadrige2ConfigurationOption.DEBUG_ENTITY_LOAD.getKey());
617     }
618 
619     /**
620      * <p>getDbName.</p>
621      *
622      * @return a {@link java.lang.String} object.
623      */
624     public String getDbName() {
625         return applicationConfig.getOption(Quadrige2ConfigurationOption.DB_NAME.getKey());
626     }
627 
628     /**
629      * <p>getDbValidationQuery.</p>
630      *
631      * @return a {@link java.lang.String} object.
632      */
633     public String getDbValidationQuery() {
634         return applicationConfig.getOption(Quadrige2ConfigurationOption.DB_VALIDATION_QUERY.getKey());
635     }
636 
637     /**
638      * <p>getJdbcUsername.</p>
639      *
640      * @return a {@link java.lang.String} object.
641      */
642     public String getJdbcUsername() {
643         return applicationConfig.getOption(Quadrige2ConfigurationOption.JDBC_USERNAME.getKey());
644     }
645 
646     /**
647      * <p>getJdbcPassword.</p>
648      *
649      * @return a {@link java.lang.String} object.
650      */
651     public String getJdbcPassword() {
652         return applicationConfig.getOption(Quadrige2ConfigurationOption.JDBC_PASSWORD.getKey());
653     }
654 
655     /**
656      * <p>getJdbcBatchSize.</p>
657      *
658      * @return a int.
659      */
660     public int getJdbcBatchSize() {
661         return applicationConfig.getOptionAsInt(Quadrige2ConfigurationOption.JDBC_BATCH_SIZE.getKey());
662     }
663 
664     /**
665      * <p>getStatusCodeTemporary.</p>
666      *
667      * @return a {@link java.lang.String} object.
668      */
669     public String getStatusCodeTemporary() {
670         return applicationConfig.getOption(Quadrige2ConfigurationOption.STATUS_CODE_TEMPORARY.getKey());
671     }
672 
673     /**
674      * <p>getStatusCodeValid.</p>
675      *
676      * @return a {@link java.lang.String} object.
677      */
678     public String getStatusCodeValid() {
679         return applicationConfig.getOption(Quadrige2ConfigurationOption.STATUS_CODE_ENABLE.getKey());
680     }    
681 
682     /**
683      * <p>getVersion.</p>
684      *
685      * @return a {@link org.nuiton.version.Version} object.
686      */
687     public Version getVersion() {
688         return applicationConfig.getOptionAsVersion(Quadrige2ConfigurationOption.VERSION.getKey());
689     }
690 
691     /**
692      * <p>getI18nDirectory.</p>
693      *
694      * @return a {@link java.io.File} object.
695      */
696     public File getI18nDirectory() {
697         return applicationConfig.getOptionAsFile(
698                 Quadrige2ConfigurationOption.I18N_DIRECTORY.getKey());
699     }
700 
701     /**
702      * <p>getI18nLocale.</p>
703      *
704      * @return a {@link java.util.Locale} object.
705      */
706     public Locale getI18nLocale() {
707         return applicationConfig.getOptionAsLocale(
708                 Quadrige2ConfigurationOption.I18N_LOCALE.getKey());
709     }
710 
711     /**
712      * <p>setI18nLocale.</p>
713      *
714      * @param locale a {@link java.util.Locale} object.
715      */
716     public void setI18nLocale(Locale locale) {
717         applicationConfig.setOption(Quadrige2ConfigurationOption.I18N_LOCALE.getKey(), locale.toString());
718     }
719 
720 
721     /**
722      * <p>getImportDataTablesIncludes.</p>
723      *
724      * @return a {@link java.util.Set} object.
725      */
726     public Set<String> getImportDataTablesIncludes() {
727         String dataTablesStr = applicationConfig.getOption(Quadrige2ConfigurationOption.IMPORT_TABLES_DATA_INCLUDES.getKey());
728         Set<String> result = null;
729         if (StringUtils.isNotBlank(dataTablesStr)) {
730             result = ImmutableSet.<String> builder()
731                     .add(dataTablesStr.toUpperCase().split("\\s*,\\s*"))
732                     .build();
733         }
734         return result;
735     }
736 
737     /**
738      * <p>getImportReferentialTablesIncludes.</p>
739      *
740      * @return a {@link java.util.Set} object.
741      */
742     public Set<String> getImportReferentialTablesIncludes() {
743         String referentialTablesStr = applicationConfig.getOption(Quadrige2ConfigurationOption.IMPORT_TABLES_REFERENTIAL_INCLUDES.getKey());
744         Set<String> result = null;
745         if (StringUtils.isNotBlank(referentialTablesStr)) {
746             result = ImmutableSet.<String> builder().add(referentialTablesStr.split("\\s*,\\s*")).build();
747         }
748         return result;
749     }
750 
751     /**
752      * <p>isEnableImportTablesRules.</p>
753      *
754      * @return true if RULE_* table must be imported
755      */
756     public boolean isEnableImportTablesRules() {
757         return applicationConfig.getOptionAsBoolean(Quadrige2ConfigurationOption.IMPORT_TABLES_RULES_ENABLE.getKey());
758     }
759 
760     /**
761      * <p>getImportDataPkIncludes.</p>
762      *
763      * @return a {@link java.lang.String} object.
764      */
765     public String getImportDataPkIncludes() {
766         return applicationConfig.getOption(Quadrige2ConfigurationOption.IMPORT_DATA_PK_INCLUDES.getKey());
767     }
768 
769     /**
770      * <p>getImportNbYearDataHistory.</p>
771      *
772      * @return a int.
773      */
774     public int getImportNbYearDataHistory() {
775         return applicationConfig.getOptionAsInt(Quadrige2ConfigurationOption.IMPORT_NB_YEARS_DATA_HISTORY.getKey());
776     }
777 
778     /**
779      * <p>getExportDataUpdateDateDelayInSecond.</p>
780      *
781      * @return a int.
782      */
783     public int getExportDataUpdateDateDelayInSecond() {
784         return applicationConfig.getOptionAsInt(Quadrige2ConfigurationOption.EXPORT_DATA_UPDATE_DATE_DELAY.getKey());
785     }
786 
787     /**
788      * <p>getExportDataUpdateDateShortDelayInSecond.</p>
789      *
790      * @return a int.
791      */
792     public int getExportDataUpdateDateShortDelayInSecond() {
793         return applicationConfig.getOptionAsInt(Quadrige2ConfigurationOption.EXPORT_DATA_UPDATE_DATE_SHORT_DELAY.getKey());
794     }
795 
796     /**
797      * <p>getImportReferentialUpdateDateOffsetInSecond.</p>
798      *
799      * @return a int.
800      */
801     public int getImportReferentialUpdateDateOffsetInSecond() {
802         return applicationConfig.getOptionAsInt(Quadrige2ConfigurationOption.IMPORT_REFERENTIAL_UPDATE_DATE_OFFSET.getKey());
803     }
804 
805     /**
806      * <p>getImportReferentialStatusIncludes.</p>
807      *
808      * @return a {@link java.lang.String} object.
809      */
810     public String getImportReferentialStatusIncludes() {
811         return applicationConfig.getOption(Quadrige2ConfigurationOption.IMPORT_REFERENTIAL_STATUS_INCLUDES.getKey());
812     }
813 
814     /**
815      * <p>getImportTranscribingItemTypeLbIncludes.</p>
816      *
817      * @return a {@link java.lang.String} object.
818      */
819     public String getImportTranscribingItemTypeLbIncludes() {
820         return applicationConfig.getOption(Quadrige2ConfigurationOption.IMPORT_TRANSCRIBING_ITEM_TYPE_LB_INCLUDES.getKey());
821     }
822 
823     /**
824      * Get programs list, to limit synchronization (in/out) to this programs
825      *
826      * @return a {@link java.util.Set} object.
827      */
828     public Set<String> getSynchroProgramCodeIncludes() {
829         String programCodesStr = applicationConfig.getOption(Quadrige2ConfigurationOption.SYNCHRO_PROGRAM_CODES_INCLUDES.getKey());
830         if (StringUtils.isBlank(programCodesStr)) {
831             return null;
832         }
833 
834         return Sets.newHashSet(
835                 Splitter.on(',').trimResults().omitEmptyStrings().split(programCodesStr)
836         );
837     }
838 
839     /**
840      * <p>getConnectionProperties.</p>
841      *
842      * @return a {@link java.util.Properties} object.
843      */
844     public Properties getConnectionProperties() {
845         return Daos.getConnectionProperties(
846                 getJdbcURL(),
847                 getJdbcUsername(),
848                 getJdbcPassword(),
849                 null,
850                 getHibernateDialect(),
851                 getJdbcDriver());
852     }
853 
854     /**
855      * <p>getLiquibaseDiffTypes.</p>
856      *
857      * @return a {@link java.lang.String} object.
858      */
859     public String getLiquibaseDiffTypes() {
860         return applicationConfig.getOption(Quadrige2ConfigurationOption.LIQUIBASE_DIFF_TYPES.getKey());
861     }
862 
863     /**
864      * <p>getLiquibaseOutputFile.</p>
865      *
866      * @return a {@link java.io.File} object.
867      */
868     public File getLiquibaseOutputFile() {
869         return applicationConfig.getOptionAsFile(Quadrige2ConfigurationOption.LIQUIBASE_OUTPUT_FILE.getKey());
870     }
871     
872     /**
873      * <p>isForceLiquibaseOutputFile.</p>
874      *
875      * @return a boolean.
876      */
877     public boolean isForceLiquibaseOutputFile() {
878         return applicationConfig.getOptionAsBoolean(Quadrige2ConfigurationOption.LIQUIBASE_FORCE_OUTPUT_FILE.getKey());
879     }
880 
881     /**
882      * <p>getServerPort.</p>
883      *
884      * @return a {@link java.lang.Integer} object.
885      */
886     public Integer getServerPort() {
887         return applicationConfig.getOptionAsInt(Quadrige2ConfigurationOption.SERVER_PORT.getKey());
888     }
889     
890     /**
891      * <p>getEnumerationFilesPath.</p>
892      *
893      * @return an array of {@link java.lang.String} objects.
894      */
895     public String[] getEnumerationFilesPath() {
896         String enumerationFilesPath = applicationConfig.getOption(Quadrige2ConfigurationOption.DB_ENUMERATION_RESOURCE.getKey());
897         return enumerationFilesPath.split(",");
898     }
899 
900     //------------------------------------------------------------------------//
901     //--- Synchronization-related ---------------------------------------------------------//
902     //------------------------------------------------------------------------//
903 
904     /**
905      * <p>getSynchronizationSiteUrl.</p>
906      *
907      * @return a {@link java.net.URL} object.
908      */
909     public URL getSynchronizationSiteUrl() {
910         return getOptionAsURL(Quadrige2ConfigurationOption.SYNCHRONIZATION_SITE_URL.getKey());
911     }
912 
913     /**
914      * <p>getSynchronizationSiteTimeout.</p>
915      *
916      * @return a {@link java.lang.Integer} object.
917      */
918     public Integer getSynchronizationSiteTimeout() {
919         return applicationConfig.getOptionAsInt(Quadrige2ConfigurationOption.SYNCHRONIZATION_SITE_TIMEOUT.getKey());
920     }
921 
922     /**
923      * <p>getSynchronizationRefreshTimeout.</p>
924      *
925      * @return a {@link java.lang.Integer} object.
926      */
927     public Integer getSynchronizationRefreshTimeout() {
928         return applicationConfig.getOptionAsInt(Quadrige2ConfigurationOption.SYNCHRONIZATION_REFRESH_TIMEOUT.getKey());
929     }
930 
931     /**
932      * <p>getSynchronizationRefreshTimeout.</p>
933      *
934      * @return a {@link java.lang.Integer} object.
935      */
936     public Integer getSynchronizationMaxRetryCount() {
937         return applicationConfig.getOptionAsInt(Quadrige2ConfigurationOption.SYNCHRONIZATION_RETRY_COUNT.getKey());
938     }
939 
940     /**
941      * <p>getSynchronizationRetryTimeout.</p>
942      *
943      * @return a {@link java.lang.Integer} object.
944      */
945     public Integer getSynchronizationRetryTimeout() {
946         return applicationConfig.getOptionAsInt(Quadrige2ConfigurationOption.SYNCHRONIZATION_RETRY_TIMEOUT.getKey());
947     }
948 
949     /**
950      * <p>getSynchronizationDirectory.</p>
951      *
952      * @return a {@link java.io.File} object.
953      */
954     public File getSynchronizationDirectory() {
955         return applicationConfig.getOptionAsFile(Quadrige2ConfigurationOption.SYNCHRONIZATION_DIRECTORY.getKey());
956     }
957     /**
958      * <p>getSynchroDirectory.</p>
959      *
960      * @return a {@link java.io.File} object.
961      */
962     public File getSynchroDirectory() {
963         return applicationConfig.getOptionAsFile(Quadrige2ConfigurationOption.SYNCHRONIZATION_DIRECTORY.getKey());
964     }
965 
966     /**
967      * <p>isSynchronizationUsingServer.</p>
968      *
969      * @return a boolean.
970      */
971     public boolean isSynchronizationUsingServer() {
972         return applicationConfig.getOptionAsBoolean(Quadrige2ConfigurationOption.SYNCHRONIZATION_USE_SERVER.getKey());
973     }
974 
975     /**
976      * <p>getSynchroZipFilePrefix.</p>
977      *
978      * @return a {@link java.lang.String} object.
979      */
980     public String getSynchroZipFilePrefix() {
981         return applicationConfig.getOption(Quadrige2ConfigurationOption.SYNCHRONIZATION_ZIP_FILE_PREFIX.getKey());
982     }
983 
984     /**
985      * <p>getExtractionDirectory.</p>
986      *
987      * @param type a {@link java.lang.String} object.
988      * @return a {@link java.io.File} object.
989      */
990     public File getExtractionDirectory(String type) {
991         switch (type.toUpperCase()) {
992             case "SINP" :
993                 return applicationConfig.getOptionAsFile(Quadrige2ConfigurationOption.EXTRACTION_SINP_DIRECTORY.getKey());
994             case "PAMPA":
995                 return applicationConfig.getOptionAsFile(Quadrige2ConfigurationOption.EXTRACTION_PAMPA_DIRECTORY.getKey());
996         }
997         return null;
998     }
999 
1000     /**
1001      * <p>getImportDataMaxRootRowCount.</p>
1002      *
1003      * @return a int.
1004      */
1005     public int getImportDataMaxRootRowCount() {
1006         return applicationConfig.getOptionAsInt(Quadrige2ConfigurationOption.IMPORT_DATA_MAX_ROOT_ROW_COUNT.getKey());
1007     }
1008 
1009     public String getMailSmtpHost() {
1010         return applicationConfig.getOption(Quadrige2ConfigurationOption.MAIL_SMTP_HOST.getKey());
1011     }
1012 
1013     public int getMailSmtpPort() {
1014         return applicationConfig.getOptionAsInt(Quadrige2ConfigurationOption.MAIL_SMTP_PORT.getKey());
1015     }
1016 
1017     public String getMailSmtpUsername() {
1018         return applicationConfig.getOption(Quadrige2ConfigurationOption.MAIL_SMTP_USERNAME.getKey());
1019     }
1020 
1021     public String getMailSmtpPassword() {
1022         return applicationConfig.getOption(Quadrige2ConfigurationOption.MAIL_SMTP_PASSWORD.getKey());
1023     }
1024 
1025     public String getMailSmtpSender() {
1026         return applicationConfig.getOption(Quadrige2ConfigurationOption.MAIL_SMTP_SENDER.getKey());
1027     }
1028 
1029     public boolean getMailSmtpStartTLS() {
1030         return applicationConfig.getOptionAsBoolean(Quadrige2ConfigurationOption.MAIL_SMTP_STARTTLS.getKey());
1031     }
1032 
1033     public boolean getMailSmtpUseSSL() {
1034         return applicationConfig.getOptionAsBoolean(Quadrige2ConfigurationOption.MAIL_SMTP_SSL.getKey());
1035     }
1036 
1037 
1038     /* -- protected methods -- */
1039 
1040     /**
1041      * <p>getOptionAsURL.</p>
1042      *
1043      * @param key a {@link java.lang.String} object.
1044      * @return a {@link java.net.URL} object.
1045      */
1046     protected URL getOptionAsURL(String key) {
1047         String urlString = applicationConfig.getOption(key);
1048 
1049         // Could be empty (e.g. demo deployment)
1050         if (StringUtils.isBlank(urlString)) {
1051             return null;
1052         }
1053 
1054         // correct end of the url string
1055         if (!urlString.endsWith("/")) {
1056             int schemeIndex = urlString.indexOf("://");
1057             int firstSlashIndex = urlString.indexOf('/', schemeIndex + 3);
1058             boolean addSlash = false;
1059             if (firstSlashIndex == -1) {
1060                 addSlash = true;
1061             }
1062             else {
1063                 int lastSlashIndex = urlString.lastIndexOf('/');
1064                 if (lastSlashIndex > firstSlashIndex) {
1065                     addSlash = urlString.indexOf('.', lastSlashIndex) == -1;
1066                 }
1067             }
1068 
1069             if (addSlash) {
1070                 urlString += '/';
1071             }
1072         }
1073 
1074         URL url = null;
1075         try {
1076             url = new URL(urlString);
1077         } catch (MalformedURLException ex) {
1078             log.error(ex.getLocalizedMessage(), ex);
1079         }
1080 
1081         return url;
1082     }
1083 }