001/* 002 * Copyright 2012 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.runtime.config; 017 018import java.io.File; 019import java.util.Date; 020import java.util.HashMap; 021import java.util.Map; 022 023import javax.xml.parsers.SAXParserFactory; 024 025import org.slf4j.Logger; 026import org.slf4j.LoggerFactory; 027 028import org.ametys.runtime.parameter.ParameterHelper; 029import org.ametys.runtime.parameter.ParameterHelper.ParameterType; 030import org.ametys.runtime.util.MapHandler; 031 032 033/** 034 * Config bean <br> 035 * Reads/Write config file. <br> 036 */ 037public final class Config 038{ 039 // Logger for traces 040 private static Logger _logger = LoggerFactory.getLogger(Config.class); 041 042 // config file 043 private static String __filename; 044 045 // true if the config file does exist 046 private static boolean __fileExists; 047 048 // shared instance for optimization 049 private static Config __config; 050 051 // Initialization status 052 private static boolean _initialized; 053 054 // The last modification date 055 private static long __lastModified = -1; 056 057 // Typed value (filled after read) 058 private Map<String, String> _values; 059 060 private Config() throws Exception 061 { 062 if (_logger.isInfoEnabled()) 063 { 064 _logger.info("Loading configuration values from file"); 065 } 066 067 _values = read(); 068 } 069 070 /** 071 * Get the instance of Config using the config file.<br> 072 * @return An instance of Config containing config file value, or null if config file cannot be read. 073 */ 074 public static Config getInstance() 075 { 076 if (!_initialized) 077 { 078 return null; 079 } 080 081 if (__config == null) 082 { 083 try 084 { 085 __config = new Config(); 086 } 087 catch (Exception e) 088 { 089 if (_logger.isWarnEnabled()) 090 { 091 _logger.warn("Exception creating Config, it won't be accessible.", e); 092 } 093 094 return null; 095 } 096 } 097 else if (__fileExists && new File(__filename).exists() && __lastModified < new File(__filename).lastModified()) 098 { 099 try 100 { 101 _logger.info("The config file has changed. Let's reload."); 102 __config._values = read(); 103 } 104 catch (Exception e) 105 { 106 // __lastModified was changed, so we will not fail several times 107 // _values was not modified 108 // __fileExists is still true 109 _logger.error("The config file '" + __filename + "' was modified but could not be reloaded due to an exception", e); 110 } 111 } 112 113 return __config; 114 } 115 116 /** 117 * Dispose this Config instance 118 */ 119 public static void dispose() 120 { 121 __config = null; 122 } 123 124 /** 125 * Set the config filename 126 * @param filename Name with path of the config file 127 */ 128 public static void setFilename(String filename) 129 { 130 __filename = filename; 131 __fileExists = new File(__filename).exists(); 132 } 133 134 /** 135 * Set the initialization status of the configuration 136 * @param initialized the initialization status of the configuration 137 */ 138 public static void setInitialized(boolean initialized) 139 { 140 _initialized = initialized; 141 } 142 143 /** 144 * Returns true if the config filename exists. 145 * @return true if the config filename exists. 146 */ 147 public static boolean getFileExists() 148 { 149 return __fileExists; 150 } 151 152 /** 153 * Return the typed value as String 154 * @param id Id of the parameter to get 155 * @return the typed value as String 156 */ 157 public String getValueAsString(String id) 158 { 159 return _values.get(id); 160 } 161 162 /** 163 * Return the typed value as Date 164 * @param id Id of the parameter to get 165 * @return the typed value as Date 166 */ 167 public Date getValueAsDate(String id) 168 { 169 String value = _values.get(id); 170 171 return (Date) ParameterHelper.castValue(value, ParameterType.DATE); 172 } 173 174 /** 175 * Return the typed value as long 176 * @param id Id of the parameter to get 177 * @return the typed value as long 178 */ 179 public Long getValueAsLong(String id) 180 { 181 String value = _values.get(id); 182 183 return (Long) ParameterHelper.castValue(value, ParameterType.LONG); 184 } 185 186 /** 187 * Return the typed value as boolean 188 * @param id Id of the parameter to get 189 * @return the typed value as boolean 190 */ 191 public Boolean getValueAsBoolean(String id) 192 { 193 String value = _values.get(id); 194 195 return (Boolean) ParameterHelper.castValue(value, ParameterType.BOOLEAN); 196 } 197 198 /** 199 * Return the typed value casted in double 200 * @param id Id of the parameter to get 201 * @return the typed value casted in double 202 */ 203 public Double getValueAsDouble(String id) 204 { 205 String value = _values.get(id); 206 207 return (Double) ParameterHelper.castValue(value, ParameterType.DOUBLE); 208 } 209 210 /** 211 * Read config file and get untyped values (String object) 212 * @return Map (key, untyped value) representing the config file 213 * @throws Exception if a problem occurs reading values 214 */ 215 public static Map<String, String> read() throws Exception 216 { 217 Map<String, String> configValues = new HashMap<>(); 218 219 // Lit le fichier de déploiement pour déterminer les valeurs non typées 220 File configFile = new File(__filename); 221 222 __fileExists = configFile.exists(); 223 if (__fileExists) 224 { 225 __lastModified = configFile.lastModified(); 226 SAXParserFactory.newInstance().newSAXParser().parse(configFile, new MapHandler(configValues)); 227 } 228 else 229 { 230 __lastModified = -1; 231 } 232 233 return configValues; 234 } 235}