001package fr.ifremer.adagio.core.config; 002 003/* 004 * #%L 005 * SIH-Adagio Core Shared 006 * $Id: EnumerationsInitializationHelper.java 11870 2013-12-03 10:10:32Z tc1fbb1 $ 007 * $HeadURL: https://forge.ifremer.fr/svn/sih-adagio/trunk/adagio/core-shared/src/main/java/fr/ifremer/adagio/core/dao/EnumerationsInitializationHelper.java $ 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 java.io.IOException; 027import java.io.InputStream; 028import java.util.Arrays; 029import java.util.List; 030import java.util.Properties; 031import java.util.Set; 032 033import org.apache.commons.collections4.CollectionUtils; 034import org.apache.commons.lang3.ArrayUtils; 035import org.apache.commons.logging.Log; 036import org.apache.commons.logging.LogFactory; 037import org.nuiton.config.ApplicationConfig; 038import org.nuiton.util.RecursiveProperties; 039import org.reflections.Reflections; 040import org.reflections.util.FilterBuilder; 041import org.springframework.beans.factory.BeanInitializationException; 042import org.springframework.context.ApplicationContext; 043import org.springframework.core.io.Resource; 044 045import com.google.common.base.Preconditions; 046import com.google.common.collect.Lists; 047 048import fr.ifremer.adagio.core.dao.technical.AdagioEnumerationDef; 049 050/** 051 * Classe utilitaire pour vérifier que les valeurs d'énumération sont correctement configurées. 052 * 053 * @author Benoit Lavenier <benoit.lavenier@e-is.pro> 054 */ 055public class AdagioEnumerationHelper { 056 /** Logger. */ 057 private static final Log log = LogFactory.getLog(AdagioEnumerationHelper.class); 058 059 private static final String MODEL_PACKAGE_NAME = "fr.ifremer.adagio.core.dao"; 060 061 private static List<AdagioEnumerationDef<?>> cachedModelEnumsAsConfigOptions = null; 062 063 public static List<AdagioEnumerationDef<?>> getAllModelEnumerations() { 064 if (cachedModelEnumsAsConfigOptions != null) { 065 return cachedModelEnumsAsConfigOptions; 066 } 067 068 // Retrieve enumerations classes used in adagio 069 Reflections reflections = Reflections.collect(); 070 if (reflections == null) { 071 reflections = new Reflections(MODEL_PACKAGE_NAME); 072 } 073 Set<Class<? extends AdagioEnumerationDef>> enumerationClasses = 074 reflections.getSubTypesOf(AdagioEnumerationDef.class); 075 if (log.isDebugEnabled()) { 076 log.debug(String.format("%s enumeration classes detected in package [%s]", enumerationClasses.size(), MODEL_PACKAGE_NAME)); 077 } 078 079 List<AdagioEnumerationDef<?>> options = Lists.newArrayList(); 080 for(Class<? extends AdagioEnumerationDef> enumClass : enumerationClasses) { 081 AdagioEnumerationDef<?>[] enums = enumClass.getEnumConstants(); 082 if (ArrayUtils.isEmpty(enums)) { 083 log.warn(String.format("Enumeration class [%s] has no value. Skipped.", enumClass.getName())); 084 } 085 else { 086 for (AdagioEnumerationDef<?> aEnum : enums) { 087 AdagioEnumerationDef<?> configOption = (AdagioEnumerationDef<?>) aEnum; 088 options.add(configOption); 089 } 090 } 091 } 092 093 cachedModelEnumsAsConfigOptions = options; 094 if (log.isDebugEnabled()) { 095 log.debug(String.format("%s enumeration values detected in package [%s]", options.size(), MODEL_PACKAGE_NAME)); 096 } 097 098 return cachedModelEnumsAsConfigOptions; 099 } 100 101 public static void reload(ApplicationConfig applicationConfig, List<org.springframework.core.io.Resource> resources) { 102 103 Properties enumerationProperties = new RecursiveProperties(); 104 if (log.isDebugEnabled()) { 105 log.debug(String.format("Starting to load enumeration values...")); 106 } 107 108 for (Resource resource : resources) { 109 InputStream is = null; 110 try { 111 if (log.isDebugEnabled()) { 112 log.debug("Load enumeration file: " + 113 resource.getURI().toString()); 114 } 115 is = resource.getInputStream(); 116 enumerationProperties.load(is); 117 } catch (IOException e) { 118 log.warn(String.format("Could not load enumeration file: %s. File skipped.", resource.getFilename())); 119 } finally { 120 try { 121 is.close(); 122 } 123 catch(IOException e) { } 124 } 125 } 126 127 // Set each property as a default option for enumeration 128 for (Object key: enumerationProperties.keySet()) { 129 String value = enumerationProperties.getProperty((String)key); 130 applicationConfig.setDefaultOption(AdagioEnumerationDef.CONFIG_OPTION_PREFIX + (String)key, value); 131 if (log.isTraceEnabled()) { 132 log.trace(String.format(" %s%s (%)", AdagioEnumerationDef.CONFIG_OPTION_PREFIX, (String)key, value)); 133 } 134 } 135 136 // Refresh enumeration values 137 List<AdagioEnumerationDef<?>> modelOptions = getAllModelEnumerations(); 138 for (AdagioEnumerationDef enumDef : modelOptions) { 139 Class clazz = enumDef.getType(); 140 String key = enumDef.getKey(); 141 String stringValue = applicationConfig.getOption(key); 142 143 Object value = applicationConfig.getOption(clazz, key); 144 if (value != null 145 && !enumDef.getValue().equals(value)) { 146 147 // Check for conversion error 148 if (stringValue.equals(value.toString()) == false) { 149 log.warn(String.format("Incompatible value '%s' for property '%s' (%s expected): Value skipped.", stringValue, key, enumDef.getType().getSimpleName())); 150 } 151 else { 152 Object oldValue = enumDef.getValue(); 153 try { 154 enumDef.setValue(value); 155 } 156 catch(ClassCastException cce) { 157 log.warn(String.format("Could not set %s with value %s", key, value)); 158 } 159 if (log.isTraceEnabled()) { 160 log.trace(String.format(" %s (%s -> %s)", key, oldValue, value)); 161 } 162 } 163 } 164 } 165 } 166 167}