001package fr.ifremer.adagio.core.config; 002 003/* 004 * #%L 005 * SIH-Adagio :: Core for Allegro 006 * $Id:$ 007 * $HeadURL:$ 008 * %% 009 * Copyright (C) 2012 - 2013 Ifremer 010 * %% 011 * This program is free software: you can redistribute it and/or modify 012 * it under the terms of the GNU Affero General Public License as published by 013 * the Free Software Foundation, either version 3 of the License, or 014 * (at your option) any later version. 015 * 016 * This program is distributed in the hope that it will be useful, 017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 019 * GNU General Public License for more details. 020 * 021 * You should have received a copy of the GNU Affero General Public License 022 * along with this program. If not, see <http://www.gnu.org/licenses/>. 023 * #L% 024 */ 025 026import static org.nuiton.i18n.I18n.t; 027 028import java.io.File; 029import java.util.Arrays; 030import java.util.List; 031import java.util.Locale; 032import java.util.Properties; 033import java.util.Set; 034 035import org.apache.commons.collections4.CollectionUtils; 036import org.apache.commons.lang3.ArrayUtils; 037import org.apache.commons.logging.Log; 038import org.apache.commons.logging.LogFactory; 039import org.nuiton.config.ApplicationConfig; 040import org.nuiton.config.ApplicationConfigHelper; 041import org.nuiton.config.ApplicationConfigProvider; 042import org.nuiton.config.ArgumentsParserException; 043import org.nuiton.util.Version; 044import org.springframework.beans.BeansException; 045import org.springframework.beans.factory.BeanInitializationException; 046import org.springframework.beans.factory.InitializingBean; 047import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; 048import org.springframework.context.ApplicationContext; 049import org.springframework.context.ApplicationContextAware; 050import org.springframework.core.io.Resource; 051 052import com.google.common.base.Charsets; 053 054import fr.ifremer.adagio.core.AdagioTechnicalException; 055import fr.ifremer.adagio.core.dao.technical.DaoUtils; 056import fr.ifremer.adagio.core.service.technical.SpringUtils; 057 058public class AdagioConfiguration extends PropertyPlaceholderConfigurer implements ApplicationContextAware, InitializingBean { 059 /** Logger. */ 060 private static final Log log = LogFactory.getLog(AdagioConfiguration.class); 061 062 /** 063 * Delegate application config. 064 */ 065 protected final ApplicationConfig applicationConfig; 066 067 private static AdagioConfiguration instance; 068 069 public static AdagioConfiguration getInstance() { 070 return instance; 071 } 072 073 public static void setInstance(AdagioConfiguration instance) { 074 AdagioConfiguration.instance = instance; 075 } 076 077 protected final String[] optionKeyToNotSave; 078 079 protected File configFile; 080 081 private ApplicationContext appContext = null; 082 083 private boolean isInitialize = false; 084 085 public AdagioConfiguration(ApplicationConfig applicationConfig) { 086 super(); 087 this.applicationConfig = applicationConfig; 088 this.optionKeyToNotSave = null; 089 } 090 091 public AdagioConfiguration(String file, String... args) { 092 super(); 093 this.applicationConfig = new ApplicationConfig(); 094 this.applicationConfig.setEncoding(Charsets.UTF_8.name()); 095 this.applicationConfig.setConfigFileName(file); 096 097 // get all config providers 098 Set<ApplicationConfigProvider> providers = 099 ApplicationConfigHelper.getProviders(null, 100 null, 101 null, 102 true); 103 104 // load all default options 105 ApplicationConfigHelper.loadAllDefaultOption(applicationConfig, 106 providers); 107 108 // Load actions 109 for (ApplicationConfigProvider provider : providers) { 110 applicationConfig.loadActions(provider.getActions()); 111 } 112 113 // Define Alias 114 addAlias(applicationConfig); 115 116 // get all transient and final option keys 117 Set<String> optionToSkip = 118 ApplicationConfigHelper.getTransientOptionKeys(providers); 119 120 if (log.isDebugEnabled()) { 121 log.debug("Option that won't be saved: " + optionToSkip); 122 } 123 optionKeyToNotSave = optionToSkip.toArray(new String[optionToSkip.size()]); 124 125 try { 126 applicationConfig.parse(args); 127 128 } catch (ArgumentsParserException e) { 129 throw new AdagioTechnicalException(t("adagio.config.parse.error"), e); 130 } 131 132 // TODO Review this, this is very dirty to do this... 133 File allegroBasedir = applicationConfig.getOptionAsFile( 134 AdagioConfigurationOption.BASEDIR.getKey()); 135 136 if (allegroBasedir == null) { 137 allegroBasedir = new File(""); 138 } 139 if (!allegroBasedir.isAbsolute()) { 140 allegroBasedir = new File(allegroBasedir.getAbsolutePath()); 141 } 142 if (allegroBasedir.getName().equals("..")) { 143 allegroBasedir = allegroBasedir.getParentFile().getParentFile(); 144 } 145 if (allegroBasedir.getName().equals(".")) { 146 allegroBasedir = allegroBasedir.getParentFile(); 147 } 148 if (log.isInfoEnabled()) { 149 log.info("Application basedir: " + allegroBasedir); 150 } 151 applicationConfig.setOption( 152 AdagioConfigurationOption.BASEDIR.getKey(), 153 allegroBasedir.getAbsolutePath()); 154 } 155 156 /** 157 * Add alias to the given ApplicationConfig. <p/> 158 * This method could be override to add specific alias 159 * 160 * @param applicationConfig 161 */ 162 protected void addAlias(ApplicationConfig applicationConfig) { 163 applicationConfig.addAlias("-u", "--option", AdagioConfigurationOption.JDBC_USERNAME.getKey()); 164 applicationConfig.addAlias("--user", "--option", AdagioConfigurationOption.JDBC_USERNAME.getKey()); 165 applicationConfig.addAlias("-p", "--option", AdagioConfigurationOption.JDBC_PASSWORD.getKey()); 166 applicationConfig.addAlias("--password", "--option", AdagioConfigurationOption.JDBC_PASSWORD.getKey()); 167 applicationConfig.addAlias("-db", "--option", AdagioConfigurationOption.JDBC_URL.getKey()); 168 applicationConfig.addAlias("--database", "--option", AdagioConfigurationOption.JDBC_URL.getKey()); 169 applicationConfig.addAlias("--output", "--option", AdagioConfigurationOption.LIQUIBASE_OUTPUT_FILE.getKey()); 170 applicationConfig.addAlias("--port", "--option", AdagioConfigurationOption.SERVER_PORT.getKey()); 171 172 } 173 174 @Override 175 public void setApplicationContext(ApplicationContext appContext) throws BeansException { 176 this.appContext = appContext; 177 } 178 179 @Override 180 public void afterPropertiesSet() throws Exception { 181 182 if (isInitialize) { 183 return; 184 } 185 isInitialize = true; 186 187 // Retrieve paths from configuration 188 String[] enumerationFilePaths = getEnumerationFilesPath(); 189 if (ArrayUtils.isEmpty(enumerationFilePaths)) { 190 throw new BeanInitializationException( 191 String.format( 192 "No enumeration files path has been set in the configuration. This is need to initialize enumeration values. Please set the option [%s] in configuration file.", 193 AdagioConfigurationOption.DB_ENUMERATION_RESOURCE)); 194 } 195 if (log.isDebugEnabled()) { 196 log.debug(String.format("Getting enumeration files from path: %s", Arrays.toString(enumerationFilePaths))); 197 } 198 199 // For each path, retrieve corresponding resources 200 List<Resource> resources = SpringUtils.getResourcesFromPaths(enumerationFilePaths, appContext, true); 201 202 // Check if some files has been found 203 if (CollectionUtils.isEmpty(resources)) { 204 throw new BeanInitializationException(String.format("No enumeration files could be found from path %s", 205 Arrays.toString(enumerationFilePaths))); 206 } 207 if (log.isDebugEnabled()) { 208 log.debug(String.format("%s enumeration files found from path: %s", resources.size(), Arrays.toString(enumerationFilePaths))); 209 } 210 211 // Set enumeration default values (from enumeration file) 212 AdagioEnumerationHelper.reload(applicationConfig, resources); 213 } 214 215 public File getConfigFile() { 216 if (configFile == null) { 217 File dir = getBasedir(); 218 if (dir == null || !dir.exists()) { 219 dir = new File(applicationConfig.getUserConfigDirectory()); 220 } 221 configFile = new File(dir, applicationConfig.getConfigFileName()); 222 } 223 return configFile; 224 } 225 226 /** @return {@link AdagioConfigurationOption#BASEDIR} value */ 227 public File getBasedir() { 228 File result = applicationConfig.getOptionAsFile(AdagioConfigurationOption.BASEDIR.getKey()); 229 return result; 230 } 231 232 /** @return {@link AdagioConfigurationOption#DATA_DIRECTORY} value */ 233 public File getDataDirectory() { 234 File result = applicationConfig.getOptionAsFile(AdagioConfigurationOption.DATA_DIRECTORY.getKey()); 235 return result; 236 } 237 238 public ApplicationConfig getApplicationConfig() { 239 return applicationConfig; 240 } 241 242 @Override 243 protected String resolvePlaceholder(String placeholder, Properties props) { 244 if (applicationConfig == null) { 245 throw new AdagioTechnicalException( 246 "AdagioConfiguration.applicationConfig must not be null. Please initialize AdagioConfiguration instance with a not null applicationConfig BEFORE starting Spring."); 247 } 248 249 // Try to resolve placeholder from application configuration 250 String optionValue = applicationConfig.getOption(placeholder); 251 if (optionValue != null) { 252 return optionValue; 253 } 254 255 // If not found in configuration, delegate to the default Spring mecanism 256 return super.resolvePlaceholder(placeholder, props); 257 } 258 259 public File getDbDirectory() { 260 return applicationConfig.getOptionAsFile(AdagioConfigurationOption.DB_DIRECTORY.getKey()); 261 } 262 263 public void setDbDirectory(File dbDirectory) { 264 applicationConfig.setOption(AdagioConfigurationOption.DB_DIRECTORY.getKey(), dbDirectory.getPath()); 265 } 266 267 public File getDbAttachmentDirectory() { 268 return applicationConfig.getOptionAsFile(AdagioConfigurationOption.DB_ATTACHMENT_DIRECTORY.getKey()); 269 } 270 271 public File getCacheDirectory() { 272 return applicationConfig.getOptionAsFile(AdagioConfigurationOption.DB_CACHE_DIRECTORY.getKey()); 273 } 274 275 public File getDbBackupDirectory() { 276 return applicationConfig.getOptionAsFile(AdagioConfigurationOption.DB_BACKUP_DIRECTORY.getKey()); 277 } 278 279 public boolean useBacthTreeCache() { 280 return applicationConfig.getOptionAsBoolean(AdagioConfigurationOption.CACHE_BACTH_TREE.getKey()); 281 } 282 283 public boolean useLiquibaseAutoRun() { 284 return applicationConfig.getOptionAsBoolean(AdagioConfigurationOption.LIQUIBASE_RUN_AUTO.getKey()); 285 } 286 287 public String getLiquibaseChangeLogPath() { 288 return applicationConfig.getOption(AdagioConfigurationOption.LIQUIBASE_CHANGE_LOG_PATH.getKey()); 289 } 290 291 public String getHibernateDialect() { 292 return applicationConfig.getOption(AdagioConfigurationOption.HIBERNATE_DIALECT.getKey()); 293 } 294 295 public String getHibernateClientQueriesFile() { 296 return applicationConfig.getOption(AdagioConfigurationOption.HIBERNATE_CLIENT_QUERIES_FILE.getKey()); 297 } 298 299 public String getJdbcDriver() { 300 return applicationConfig.getOption(AdagioConfigurationOption.JDBC_DRIVER.getKey()); 301 } 302 303 public String getJdbcURL() { 304 return applicationConfig.getOption(AdagioConfigurationOption.JDBC_URL.getKey()); 305 } 306 307 public String getJdbcCatalog() { 308 return applicationConfig.getOption(AdagioConfigurationOption.JDBC_SCHEMA.getKey()); 309 } 310 311 public String getJdbcSchema() { 312 return applicationConfig.getOption(AdagioConfigurationOption.JDBC_SCHEMA.getKey()); 313 } 314 315 public boolean debugEntityLoad() { 316 return applicationConfig.getOptionAsBoolean(AdagioConfigurationOption.DEBUG_ENTITY_LOAD.getKey()); 317 } 318 319 public String[] getEnumerationFilesPath() { 320 String enumerationFilesPath = applicationConfig.getOption(AdagioConfigurationOption.DB_ENUMERATION_RESOURCE.getKey()); 321 String[] enumerationFilesPathArray = enumerationFilesPath.split(","); 322 return enumerationFilesPathArray; 323 } 324 325 public String getDbName() { 326 return applicationConfig.getOption(AdagioConfigurationOption.DB_NAME.getKey()); 327 } 328 329 public String getDbValidationQuery() { 330 return applicationConfig.getOption(AdagioConfigurationOption.DB_VALIDATION_QUERY.getKey()); 331 } 332 333 public String getJdbcUsername() { 334 return applicationConfig.getOption(AdagioConfigurationOption.JDBC_USERNAME.getKey()); 335 } 336 337 public String getJdbcPassword() { 338 return applicationConfig.getOption(AdagioConfigurationOption.JDBC_PASSWORD.getKey()); 339 } 340 341 public int getJdbcBatchSize() { 342 return applicationConfig.getOptionAsInt(AdagioConfigurationOption.JDBC_BATCH_SIZE.getKey()); 343 } 344 345 public String getStatusCodeTemporary() { 346 return applicationConfig.getOption(AdagioConfigurationOption.STATUS_CODE_TEMPORARY.getKey()); 347 } 348 349 public String getStatusCodeValid() { 350 return applicationConfig.getOption(AdagioConfigurationOption.STATUS_CODE_ENABLE.getKey()); 351 } 352 353 public Version getVersion() { 354 return applicationConfig.getOptionAsVersion(AdagioConfigurationOption.VERSION.getKey()); 355 } 356 357 public String getVesselRegistryProgramCode() { 358 return applicationConfig.getOption(AdagioConfigurationOption.PROGRAM_CODE_VESSEL_REGISTRY.getKey()); 359 } 360 361 public File getI18nDirectory() { 362 return applicationConfig.getOptionAsFile( 363 AdagioConfigurationOption.I18N_DIRECTORY.getKey()); 364 } 365 366 public Locale getI18nLocale() { 367 return applicationConfig.getOptionAsLocale( 368 AdagioConfigurationOption.I18N_LOCALE.getKey()); 369 } 370 371 public void setI18nLocale(Locale locale) { 372 applicationConfig.setOption(AdagioConfigurationOption.I18N_LOCALE.getKey(), locale.toString()); 373 } 374 375 public Properties getConnectionProperties() { 376 return DaoUtils.getConnectionProperties( 377 getJdbcURL(), 378 getJdbcUsername(), 379 getJdbcPassword(), 380 null, 381 getHibernateDialect(), 382 getJdbcDriver()); 383 } 384 385 public String getLiquibaseDiffTypes() { 386 return applicationConfig.getOption(AdagioConfigurationOption.LIQUIBASE_DIFF_TYPES.getKey()); 387 } 388 389 public File getLiquibaseOutputFile() { 390 return applicationConfig.getOptionAsFile(AdagioConfigurationOption.LIQUIBASE_OUTPUT_FILE.getKey()); 391 } 392 393 public Integer getServerPort() { 394 return applicationConfig.getOptionAsInt(AdagioConfigurationOption.SERVER_PORT.getKey()); 395 } 396}