1 package fr.ifremer.quadrige3.core.config;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import com.google.common.base.Joiner;
26 import com.google.common.base.Splitter;
27 import com.google.common.collect.Sets;
28 import fr.ifremer.common.synchro.config.SynchroConfiguration;
29 import fr.ifremer.common.synchro.config.SynchroConfigurationOption;
30 import fr.ifremer.quadrige3.core.dao.technical.Beans;
31 import fr.ifremer.quadrige3.core.dao.technical.Daos;
32 import fr.ifremer.quadrige3.core.dao.technical.Files;
33 import fr.ifremer.quadrige3.core.security.SecurityContextHelper;
34 import fr.ifremer.quadrige3.synchro.meta.DatabaseColumns;
35 import org.apache.commons.lang3.StringUtils;
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38 import org.nuiton.config.ApplicationConfig;
39 import org.nuiton.config.ApplicationConfigHelper;
40 import org.nuiton.config.ApplicationConfigProvider;
41 import org.nuiton.config.ArgumentsParserException;
42 import org.nuiton.jaxx.application.ApplicationConfiguration;
43 import org.nuiton.jaxx.application.ApplicationIOUtil;
44 import org.nuiton.jaxx.application.ApplicationTechnicalException;
45 import org.springframework.beans.factory.InitializingBean;
46 import org.springframework.util.CollectionUtils;
47
48 import javax.swing.KeyStroke;
49 import java.awt.Color;
50 import java.io.File;
51 import java.io.IOException;
52 import java.net.MalformedURLException;
53 import java.net.URL;
54 import java.nio.charset.StandardCharsets;
55 import java.util.*;
56 import java.util.stream.Collectors;
57
58 import static org.nuiton.i18n.I18n.t;
59
60
61
62
63 public abstract class QuadrigeCoreConfiguration extends ApplicationConfiguration implements InitializingBean {
64
65 private static final Log LOG = LogFactory.getLog(QuadrigeCoreConfiguration.class);
66
67 private static QuadrigeCoreConfiguration instance;
68 private final Set<String> optionKeyToNotSave = Sets.newHashSet();
69 private File configFile;
70
71 public QuadrigeCoreConfiguration(ApplicationConfig applicationConfig) {
72 super(applicationConfig);
73 prepareDirectories();
74 }
75
76 public QuadrigeCoreConfiguration(String file, String... args) {
77 super(new QuadrigeApplicationConfig());
78
79
80 applicationConfig.setEncoding(StandardCharsets.UTF_8.name());
81
82 applicationConfig.setConfigFileName(file);
83
84
85 loadProviders();
86
87
88 addAlias(applicationConfig);
89
90 try {
91 applicationConfig.parse(args);
92
93 } catch (ArgumentsParserException e) {
94 throw new ApplicationTechnicalException(t("quadrige3.config.parse.error"), e);
95 }
96
97
98 overrideExternalModulesDefaultOptions();
99
100
101 QuadrigeConfiguration quadrigeConfig = new QuadrigeConfiguration(applicationConfig);
102 QuadrigeConfiguration.setInstance(quadrigeConfig);
103
104
105 SynchroConfiguration synchroConfig = new SynchroConfiguration(applicationConfig);
106 SynchroConfiguration.setInstance(synchroConfig);
107
108 }
109
110 private void loadProviders() {
111
112
113 Set<ApplicationConfigProvider> providers = ApplicationConfigHelper.getProviders(null, null, null, true);
114
115
116 ApplicationConfigHelper.loadAllDefaultOption(applicationConfig, providers);
117
118
119 for (ApplicationConfigProvider provider : providers) {
120 applicationConfig.loadActions(provider.getActions());
121 }
122
123
124 Set<String> optionToSkip = ApplicationConfigHelper.getTransientOptionKeys(providers);
125
126 if (LOG.isDebugEnabled()) {
127 LOG.debug("Option that won't be saved: " + optionToSkip);
128 }
129 optionKeyToNotSave.addAll(optionToSkip);
130
131 }
132
133 public static QuadrigeCoreConfiguration getInstance() {
134 return instance;
135 }
136
137 public static void setInstance(QuadrigeCoreConfiguration instance) {
138 QuadrigeCoreConfiguration.instance = instance;
139 }
140
141 protected void overrideExternalModulesDefaultOptions() {
142
143
144 QuadrigeConfigurations.remapOptionsToPrefix(applicationConfig,
145 "synchro.persistence",
146 QuadrigeConfigurationOption.values(),
147 "quadrige3.persistence");
148
149
150 QuadrigeConfigurations.remapOptionsToPrefix(applicationConfig,
151 "synchro",
152 QuadrigeConfigurationOption.values(),
153 "quadrige3.synchro");
154
155 applicationConfig.setDefaultOption(SynchroConfigurationOption.TEMP_QUERY_PARAMETER_USER_ID.getKey(),
156 DatabaseColumns.QUSER_ID.name());
157 }
158
159
160
161
162
163
164
165 protected void addAlias(ApplicationConfig applicationConfig) {
166 applicationConfig.addAlias("-db", "--option", QuadrigeConfigurationOption.JDBC_URL.getKey());
167 applicationConfig.addAlias("--database", "--option", QuadrigeConfigurationOption.JDBC_URL.getKey());
168 applicationConfig.addAlias("--output", "--option", QuadrigeConfigurationOption.LIQUIBASE_OUTPUT_FILE.getKey());
169 }
170
171 @Override
172 public KeyStroke getShortcutClosePopup() {
173 return null;
174 }
175
176 @Override
177 public void afterPropertiesSet() {
178 prepareDirectories();
179 }
180
181 protected void prepareDirectories() {
182
183 File directory = getDataDirectory();
184 ApplicationIOUtil.forceMkdir(directory, t("quadrige3.error.create.directory", directory));
185
186 directory = getDbDirectory();
187 ApplicationIOUtil.forceMkdir(directory, t("quadrige3.error.create.directory", directory));
188
189 directory = getDbAttachmentDirectory();
190 ApplicationIOUtil.forceMkdir(directory, t("quadrige3.error.create.directory", directory));
191
192 directory = getDbPhotoDirectory();
193 ApplicationIOUtil.forceMkdir(directory, t("quadrige3.error.create.directory", directory));
194
195 directory = getDbBackupDirectory();
196 ApplicationIOUtil.forceMkdir(directory, t("quadrige3.error.create.directory", directory));
197
198
199
200
201 directory = getConfigDirectory();
202 ApplicationIOUtil.forceMkdir(directory, t("quadrige3.error.create.directory", directory));
203
204 directory = getTempDirectory();
205 if (directory.exists()) {
206 Files.cleanDirectory(directory, t("quadrige3.error.delete.directory", directory));
207 }
208 ApplicationIOUtil.forceMkdir(directory, t("quadrige3.error.create.directory", directory));
209
210 }
211
212
213
214
215 public File getBaseDirectory() {
216 return applicationConfig.getOptionAsFile(QuadrigeConfigurationOption.BASEDIR.getKey());
217 }
218
219 public File getLockFile() {
220 return new File(getBaseDirectory(), "application.lock");
221 }
222
223 public File getDataDirectory() {
224 return applicationConfig.getOptionAsFile(QuadrigeConfigurationOption.DATA_DIRECTORY.getKey());
225 }
226
227 public File getDbDirectory() {
228 return applicationConfig.getOptionAsFile(QuadrigeConfigurationOption.DB_DIRECTORY.getKey());
229 }
230
231 public String getDbName() {
232 return applicationConfig.getOption(QuadrigeConfigurationOption.DB_NAME.getKey());
233 }
234
235 public String getDbValidationQuery() {
236 return applicationConfig.getOption(QuadrigeConfigurationOption.DB_VALIDATION_QUERY.getKey());
237 }
238
239 public File getDbAttachmentDirectory() {
240 return applicationConfig.getOptionAsFile(QuadrigeConfigurationOption.DB_ATTACHMENT_DIRECTORY.getKey());
241 }
242
243 public File getDbPhotoDirectory() {
244 return applicationConfig.getOptionAsFile(QuadrigeConfigurationOption.DB_PHOTO_DIRECTORY.getKey());
245 }
246
247 public File getDbBackupDirectory() {
248 return applicationConfig.getOptionAsFile(QuadrigeConfigurationOption.DB_BACKUP_DIRECTORY.getKey());
249 }
250
251 public File getCacheDirectory() {
252 return applicationConfig.getOptionAsFile(QuadrigeConfigurationOption.DB_CACHE_DIRECTORY.getKey());
253 }
254
255 public File getI18nDirectory() {
256 return applicationConfig.getOptionAsFile(QuadrigeConfigurationOption.I18N_DIRECTORY.getKey());
257 }
258
259
260
261
262
263 public File getConfigDirectory() {
264 return applicationConfig.getOptionAsFile(QuadrigeCoreConfigurationOption.CONFIG_DIRECTORY.getKey());
265 }
266
267 public File getExtractionDirectory() {
268 return applicationConfig.getOptionAsFile(QuadrigeCoreConfigurationOption.EXTRACTION_DIRECTORY.getKey());
269 }
270
271 public File getExtractionConfigDirectory() {
272 return applicationConfig.getOptionAsFile(QuadrigeCoreConfigurationOption.EXTRACTION_CONFIG_DIRECTORY.getKey());
273 }
274
275 public File getContextDirectory() {
276 return applicationConfig.getOptionAsFile(QuadrigeCoreConfigurationOption.CONTEXT_DIRECTORY.getKey());
277 }
278
279 public File getMeasurementGridPresetsDirectory() {
280 return applicationConfig.getOptionAsFile(QuadrigeCoreConfigurationOption.MEASUREMENT_GRID_PRESETS_DIRECTORY.getKey());
281 }
282
283 public Set<File> getDbOtherDirectories() {
284 String configOption = applicationConfig.getOption(QuadrigeCoreConfigurationOption.DB_OTHER_DIRECTORIES.getKey());
285 return StringUtils.isNotBlank(configOption)
286 ? Beans.split(configOption, ";").stream().map(File::new).collect(Collectors.toSet())
287 : new HashSet<>();
288 }
289
290 public File getTempDirectory() {
291 return applicationConfig.getOptionAsFile(QuadrigeConfigurationOption.TMP_DIRECTORY.getKey());
292 }
293
294 public String getJdbcUrl() {
295 return applicationConfig.getOption(QuadrigeConfigurationOption.JDBC_URL.getKey());
296 }
297
298 public Class<?> getJdbcDriver() {
299 return applicationConfig.getOptionAsClass(QuadrigeConfigurationOption.JDBC_DRIVER.getKey());
300 }
301
302 public String getJdbcUsername() {
303 return applicationConfig.getOption(QuadrigeConfigurationOption.JDBC_USERNAME.getKey());
304 }
305
306 public String getJdbcPassword() {
307 return applicationConfig.getOption(QuadrigeConfigurationOption.JDBC_PASSWORD.getKey());
308 }
309
310 public Class<?> getHibernateDialect() {
311 return applicationConfig.getOptionAsClass(QuadrigeConfigurationOption.HIBERNATE_DIALECT.getKey());
312 }
313
314 public boolean isHibernateShowSql() {
315 return applicationConfig.getOptionAsBoolean(QuadrigeConfigurationOption.HIBERNATE_SHOW_SQL.getKey());
316 }
317
318 public boolean isHibernateUseSqlComment() {
319 return applicationConfig.getOptionAsBoolean(QuadrigeConfigurationOption.HIBERNATE_USE_SQL_COMMENT.getKey());
320 }
321
322 public boolean isHibernateFormatSql() {
323 return applicationConfig.getOptionAsBoolean(QuadrigeConfigurationOption.HIBERNATE_FORMAT_SQL.getKey());
324 }
325
326 public Properties getConnectionProperties() {
327 return Daos.getConnectionProperties(
328 getJdbcUrl(),
329 getJdbcUsername(),
330 getJdbcPassword(),
331 null,
332 getHibernateDialect().getName(),
333 getJdbcDriver().getName());
334 }
335
336 public boolean isDbExists() {
337 if (!Daos.isHsqlFileDatabase(getJdbcUrl())) {
338 return true;
339 }
340 File f = new File(getDbDirectory(), getDbName() + ".script");
341 return f.exists();
342 }
343
344
345
346
347
348
349 public String getUpdateApplicationUrl() {
350 return applicationConfig.getOption(QuadrigeCoreConfigurationOption.UPDATE_APPLICATION_URL.getKey());
351 }
352
353 public String getUpdateDataUrl() {
354 return applicationConfig.getOption(QuadrigeCoreConfigurationOption.UPDATE_DATA_URL.getKey());
355 }
356
357 public String getInstallDbUrl() {
358 return applicationConfig.getOption(QuadrigeCoreConfigurationOption.INSTALL_DB_URL.getKey());
359 }
360
361
362
363
364
365
366
367 public boolean isAuthenticationDisabled() {
368 return applicationConfig.getOptionAsBoolean(QuadrigeCoreConfigurationOption.AUTHENTICATION_DISABLED.getKey());
369 }
370
371 public boolean isAuthenticationForced() {
372 return applicationConfig.getOptionAsBoolean(QuadrigeCoreConfigurationOption.AUTHENTICATION_FORCED.getKey());
373 }
374
375 public URL getAuthenticationIntranetSiteUrl() {
376 return applicationConfig.getOptionAsURL(QuadrigeCoreConfigurationOption.AUTHENTICATION_INTRANET_SITE_URL.getKey());
377 }
378
379 public Integer getAuthenticationIntranetSiteTimeout() {
380 return applicationConfig.getOptionAsInt(QuadrigeCoreConfigurationOption.AUTHENTICATION_INTRANET_SITE_TIMEOUT.getKey());
381 }
382
383 public URL getAuthenticationExtranetSiteUrl() {
384 return applicationConfig.getOptionAsURL(QuadrigeCoreConfigurationOption.AUTHENTICATION_EXTRANET_SITE_URL.getKey());
385 }
386
387 public Integer getAuthenticationExtranetSiteTimeout() {
388 return applicationConfig.getOptionAsInt(QuadrigeCoreConfigurationOption.AUTHENTICATION_EXTRANET_SITE_TIMEOUT.getKey());
389 }
390
391 public String getAuthenticationDefaultUsername() {
392 return applicationConfig.getOption(QuadrigeCoreConfigurationOption.AUTHENTICATION_DEFAULT_USERNAME.getKey());
393 }
394
395 public void setAuthenticationDefaultUsername(String username) {
396 applicationConfig.setOption(QuadrigeCoreConfigurationOption.AUTHENTICATION_DEFAULT_USERNAME.getKey(), username);
397 }
398
399 public String getAuthenticationDefaultPassword() {
400 return applicationConfig.getOption(QuadrigeCoreConfigurationOption.AUTHENTICATION_DEFAULT_PASSWORD.getKey());
401 }
402
403 public String getAuthenticationMockUsername() {
404 return applicationConfig.getOption(QuadrigeCoreConfigurationOption.AUTHENTICATION_MOCK_USERNAME.getKey());
405 }
406
407 public String getAuthenticationMockPassword() {
408 return applicationConfig.getOption(QuadrigeCoreConfigurationOption.AUTHENTICATION_MOCK_PASSWORD.getKey());
409 }
410
411 public int getAuthenticationMockUserId() {
412 return applicationConfig.getOptionAsInt(QuadrigeCoreConfigurationOption.AUTHENTICATION_MOCK_USER_ID.getKey());
413 }
414
415
416
417
418
419 public boolean isSynchronizationUsingServer() {
420 return applicationConfig.getOptionAsBoolean(QuadrigeConfigurationOption.SYNCHRONIZATION_USE_SERVER.getKey());
421 }
422
423 public URL getSynchronizationSiteUrl() {
424 return getOptionAsURL(QuadrigeConfigurationOption.SYNCHRONIZATION_SITE_URL.getKey());
425 }
426
427 public Integer getSynchronizationSiteTimeout() {
428 return applicationConfig.getOptionAsInt(QuadrigeConfigurationOption.SYNCHRONIZATION_SITE_TIMEOUT.getKey());
429 }
430
431
432
433
434
435
436 public Integer getSynchronizationRefreshTimeout() {
437 return applicationConfig.getOptionAsInt(QuadrigeConfigurationOption.SYNCHRONIZATION_REFRESH_TIMEOUT.getKey());
438 }
439
440
441
442
443
444
445 public Integer getSynchronizationMaxRetryCount() {
446 return applicationConfig.getOptionAsInt(QuadrigeConfigurationOption.SYNCHRONIZATION_RETRY_COUNT.getKey());
447 }
448
449
450
451
452
453
454 public Integer getSynchronizationRetryTimeout() {
455 return applicationConfig.getOptionAsInt(QuadrigeConfigurationOption.SYNCHRONIZATION_RETRY_TIMEOUT.getKey());
456 }
457
458 public File getSynchronizationDirectory() {
459 return applicationConfig.getOptionAsFile(QuadrigeConfigurationOption.SYNCHRONIZATION_DIRECTORY.getKey());
460 }
461
462 public boolean isSynchronizationEnabled() {
463 return ( !isAuthenticationDisabled()) && getSynchronizationSiteUrl() != null;
464 }
465
466 public boolean isSynchronizationPeriodSelectionEnable() {
467 return applicationConfig.getOptionAsBoolean(QuadrigeCoreConfigurationOption.SYNCHRONIZATION_PERIOD_SELECTION_ENABLE.getKey());
468 }
469
470 public String getSynchroZipFilePrefix() {
471 return applicationConfig.getOption(QuadrigeCoreConfigurationOption.SYNCHRONIZATION_ZIP_FILE_PREFIX.getKey());
472 }
473
474 public File getSynchroUserDirectory() {
475 return new File(getSynchronizationDirectory(), Integer.toString(SecurityContextHelper.getQuadrigeUserId()));
476 }
477
478 public Set<String> getSynchroProgramCodeIncludes() {
479 String programCodesStr = applicationConfig.getOption(QuadrigeCoreConfigurationOption.SYNCHRO_PROGRAM_CODES_INCLUDES.getKey());
480 if (StringUtils.isBlank(programCodesStr)) {
481 return new HashSet<>();
482 }
483
484 return Sets.newLinkedHashSet(
485 Splitter.on(',').trimResults().omitEmptyStrings().split(programCodesStr)
486 );
487 }
488
489 public void setSynchroProgramCodeIncludes(Set<String> programCodes) {
490 String option = CollectionUtils.isEmpty(programCodes) ? null : Joiner.on(',').join(programCodes);
491 applicationConfig.setOption(QuadrigeCoreConfigurationOption.SYNCHRO_PROGRAM_CODES_INCLUDES.getKey(), option);
492 }
493
494 public boolean isSynchroPhotoEnabledByDefault() {
495 return applicationConfig.getOptionAsBoolean(QuadrigeCoreConfigurationOption.SYNCHRO_PHOTO_ENABLE_DEFAULT.getKey());
496 }
497
498 public long getSynchroPhotoMaxSize() {
499 return applicationConfig.getOptionAsLong(QuadrigeCoreConfigurationOption.SYNCHRO_PHOTO_MAX_SIZE.getKey());
500 }
501
502 public int getSynchroPhotoMaxNumberThreshold() {
503 return applicationConfig.getOptionAsInt(QuadrigeCoreConfigurationOption.SYNCHRO_PHOTO_MAX_NUMBER_THRESHOLD.getKey());
504 }
505
506
507
508
509
510
511
512
513
514
515 public boolean isFullLaunchMode() {
516 return "full".equals(getLaunchMode());
517 }
518
519
520
521
522
523
524
525 public boolean isSilentLaunchMode() {
526 return "silent".equals(getLaunchMode());
527 }
528
529
530
531
532
533
534 public String getLaunchMode() {
535 return applicationConfig.getOption(QuadrigeCoreConfigurationOption.LAUNCH_MODE.getKey());
536 }
537
538
539
540
541
542 public boolean isDebugMode() {
543 return applicationConfig.getOptionAsBoolean(QuadrigeCoreConfigurationOption.DEBUG_MODE.getKey());
544 }
545
546
547
548
549
550
551 public String getAdminEmail() {
552 return applicationConfig.getOption(QuadrigeConfigurationOption.ADMIN_EMAIL.getKey());
553 }
554
555
556
557
558
559
560 public boolean isShowFullConfigEnabled() {
561 return !isFullLaunchMode();
562 }
563
564 public Locale getI18nLocale() {
565 return applicationConfig.getOptionAsLocale(QuadrigeCoreConfigurationOption.I18N_LOCALE.getKey());
566 }
567
568 public void setI18nLocale(Locale locale) {
569 applicationConfig.setOption(QuadrigeCoreConfigurationOption.I18N_LOCALE.getKey(), locale.toString());
570 }
571
572 public List<String> getSplashScreenRightLogos() {
573 String option = applicationConfig.getOption(QuadrigeCoreConfigurationOption.UI_SPLASH_SCREEN_RIGHT_LOGOS.getKey());
574 return StringUtils.isBlank(option) ? null : Arrays.stream(option.split(",")).collect(Collectors.toList());
575 }
576
577 public List<String> getSplashScreenLeftLogos() {
578 String option = applicationConfig.getOption(QuadrigeCoreConfigurationOption.UI_SPLASH_SCREEN_LEFT_LOGOS.getKey());
579 return StringUtils.isBlank(option) ? null : Arrays.stream(option.split(",")).collect(Collectors.toList());
580 }
581
582
583
584
585
586 public String getCsvSeparator() {
587 return applicationConfig.getOption(QuadrigeConfigurationOption.CSV_SEPARATOR.getKey());
588 }
589
590 public String getValueSeparator() {
591 return applicationConfig.getOption(QuadrigeConfigurationOption.VALUE_SEPARATOR.getKey());
592 }
593
594 public String getAttributeSeparator() {
595 return applicationConfig.getOption(QuadrigeConfigurationOption.ATTRIBUTE_SEPARATOR.getKey());
596 }
597
598 public File newTempFile(String basename) {
599 return new File(getTempDirectory(), basename + "_" + System.nanoTime());
600 }
601
602 public File getConfigFile() {
603 if (configFile == null) {
604 File dir = getConfigDirectory();
605 if (dir == null || !dir.exists()) {
606 dir = new File(applicationConfig.getUserConfigDirectory());
607 }
608 File originalConfigFile = new File(applicationConfig.getConfigFileName());
609 configFile = new File(dir, originalConfigFile.getName());
610 }
611 return configFile;
612 }
613
614 public void overridesOptions(Properties options) {
615
616 for (String key : options.stringPropertyNames()) {
617 String value = options.getProperty(key);
618 applicationConfig.setOption(key, value);
619 }
620
621 }
622
623 protected void addOptionToNotSave(String optionKey) {
624 optionKeyToNotSave.add(optionKey);
625 }
626
627 public void save() {
628
629 File file = getConfigFile();
630 if (LOG.isDebugEnabled()) {
631 LOG.debug("Save configuration at: " + file);
632 }
633 try {
634
635 applicationConfig.save(file, false, optionKeyToNotSave.toArray(new String[0]));
636 } catch (IOException e) {
637 throw new ApplicationTechnicalException(t("quadrige3.config.save.error", file), e);
638 }
639 }
640
641
642
643
644
645 protected URL getOptionAsURL(String key) {
646 String urlString = applicationConfig.getOption(key);
647
648
649 if (StringUtils.isBlank(urlString)) {
650 return null;
651 }
652
653
654 if (!urlString.endsWith("/")) {
655 int schemeIndex = urlString.indexOf("://");
656 int firstSlashIndex = urlString.indexOf('/', schemeIndex + 3);
657 boolean addSlash = false;
658 if (firstSlashIndex == -1) {
659 addSlash = true;
660 } else {
661 int lastSlashIndex = urlString.lastIndexOf('/');
662 if (lastSlashIndex > firstSlashIndex) {
663 addSlash = urlString.indexOf('.', lastSlashIndex) == -1;
664 }
665 }
666
667 if (addSlash) {
668 urlString += '/';
669 }
670 }
671
672 URL url = null;
673 try {
674 url = new URL(urlString);
675 } catch (MalformedURLException ex) {
676 LOG.error(ex.getLocalizedMessage());
677 }
678
679 return url;
680 }
681
682
683 public Color getColorBlockingLayer() {
684 return null;
685 }
686
687 }