1 /**
2 * Copyright 2005-2006 the original author or authors.
3 *
4 * Licensed under the Gnu General Pubic License, Version 2.0 (the
5 * "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.opensource.org/licenses/gpl-license.php
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the Gnu General Public License for more details.
14 */
15 package org.figure8.join.core.setup;
16
17 import org.figure8.join.util.LogUtil;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.digester.Digester;
21
22 import java.io.File;
23 import java.io.FileWriter;
24 import java.io.PrintWriter;
25 import java.io.IOException;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.Properties;
29 /**
30 * This ia an object that manages Join application configuration and associated
31 * operations (such as loading or savind configuration). It uses backed
32 * <code>ConfigProperty</code> Java Beans for storing config informations.
33 * @author <a href="mailto:laurent.broudoux@free.fr">Laurent Broudoux</a>
34 * @version $Revision: 1.3 $
35 */
36 public class ApplicationConfig{
37
38
39
40 /** Get a commons logger. */
41 protected static Log log = LogUtil.getLog(ApplicationConfig.class);
42
43 /** Configuration file into Join Home directory. */
44 public static final String CONFIG_FILE = "join.cfg.xml";
45
46 /** Application properties determining setup type */
47 public static final String SETUP_TYPE = "setup.type";
48 /** Custom setup type property value */
49 public static final String CUSTOM_TYPE = "Custom";
50 /** Standard setup type property value */
51 public static final String STANDARD_TYPE = "Standard";
52
53 /** Property used for telling if this side of app is the synch side */
54 public static final String SYNCH_SIDE = "setup.synch";
55 /** Property used for telling that synch/asynch services are dissociated */
56 public static final String DISSOCIATED = "setup.dissociated";
57 /** Property used for representing the url of this other side of application (if app is dissociated) */
58 public static final String OTHER_SIDE_URL = "setup.otherside.url";
59 /** Property used for identifying the setup process has completed */
60 public static final String SETUP_COMPLETE = "setup.complete";
61
62
63
64
65 /** Flag telling if setup has been completed */
66 private boolean setupComplete = false;
67 /** Path to the Join Home application directory. */
68 private String applicationHome = null;
69 /** A Map of <code>ConfigProperty</code>. */
70 private HashMap configProps = new HashMap();
71 /** The set of configured application properties. */
72 private Properties applicationProps = new Properties();
73
74
75
76
77 /** Creates a new instance of ApplicationConfig */
78 public ApplicationConfig(){
79 }
80
81
82
83
84 /** @param home Set the application home directory */
85 public void setApplicationHome(String home){
86 this.applicationHome = home;
87 }
88 /** @return Get the application home directory */
89 public String getApplicationHome(){
90 return applicationHome;
91 }
92
93 /**
94 * Set some application config properties.
95 * @param props Properties to add to application props.
96 */
97 public void setProperties(Properties props){
98 configProps.putAll(props);
99 applicationProps.putAll(props);
100
101 String setup = getProperty(SETUP_COMPLETE);
102 if (setup != null && setup.length() > 0){
103 try {setupComplete = Boolean.valueOf(setup).booleanValue();}
104 catch (Exception e) {setupComplete = false;}
105 }
106 }
107 /** @return The set of configured application properties */
108 public Properties getProperties(){
109 return applicationProps;
110 }
111
112 /**
113 * Set an application config property. If <b>value</b> is not
114 * null, its string representation (toString() result) will be inserted.
115 * @param key Unique id of the application property
116 * @param value Value associated to key
117 */
118 public void setProperty(String key, Object value){
119 if (value == null){
120
121 configProps.remove(key);
122 applicationProps.remove(key);
123 }
124 else{
125
126 ConfigProperty property = new ConfigProperty(key, value.toString());
127 configProps.put(property.getKey(), property);
128 applicationProps.setProperty(key, value.toString());
129 }
130 }
131 /**
132 * Get a specific application config property
133 * @param key Unique id of the property to retrieve
134 * @return The string property corresponding to key or null if it doesn't exist
135 */
136 public String getProperty(String key){
137 return applicationProps.getProperty(key);
138 }
139
140 /** @return true if setup has been completed, false otherwise */
141 public boolean isSetupComplete(){
142 return setupComplete;
143 }
144 /**
145 * Set the flag telling if setup has been completed
146 * @param complete Setup completion status
147 */
148 public void setSetupComplete(boolean complete){
149 this.setupComplete = complete;
150 setProperty(SETUP_COMPLETE, String.valueOf(setupComplete));
151 }
152
153 /** @return true if setup is a custom setup whether it is completed or not, false otherwise */
154 public boolean isCustomSetup(){
155
156 if (CUSTOM_TYPE.equals(getProperty(SETUP_TYPE)))
157 return true;
158 return false;
159 }
160 /** @return true if setup is not a custom setup whether it is completed or not, false otherwise */
161 public boolean isStandardSetup(){
162
163 if (STANDARD_TYPE.equals(getProperty(SETUP_TYPE)))
164 return true;
165 return false;
166 }
167
168 /** @return true if this side of application is synchronous */
169 public boolean isSynchronousSide(){
170 if (isCustomSetup()){
171
172 String synch = getProperty(SYNCH_SIDE);
173 if (synch != null && synch.length() > 0){
174 try {return Boolean.valueOf(synch).booleanValue();}
175 catch (Exception e) {return true;}
176 }
177 }
178 return true;
179 }
180 /** @return true if this side of application is asynchronous */
181 public boolean isAsynchronousSide(){
182 if (isCustomSetup()){
183
184 String synch = getProperty(SYNCH_SIDE);
185 if (synch != null && synch.length() > 0){
186 try {return !Boolean.valueOf(synch).booleanValue();}
187 catch (Exception e) {return true;}
188 }
189 }
190 return true;
191 }
192 /** @return true if setup is custom with dissociation of synch/.asynch services */
193 public boolean isDissociatedSetup(){
194 if (isCustomSetup()){
195
196 String dissociated = getProperty(DISSOCIATED);
197 if (dissociated != null && dissociated.length() > 0){
198 try {return Boolean.valueOf(dissociated).booleanValue();}
199 catch (Exception e) {return true;}
200 }
201 }
202 return false;
203 }
204
205 /**
206 * Tells if configuration file is an existing file
207 * @return true if config file exists, false otherwise
208 */
209 public boolean configurationFileExists(){
210 File file = new File(applicationHome, CONFIG_FILE);
211 return file.isFile();
212 }
213
214 /**
215 * Add a <code>ConfigProperty</code> obtained from configuration file
216 * @param property Property wrapper to add
217 */
218 public void addConfigProperty(ConfigProperty property){
219 log.debug("Adding a property to application config: " + property);
220
221 configProps.put(property.getKey(), property);
222 applicationProps.setProperty(property.getKey(), property.getValue());
223 }
224
225 /**
226 * Load the application configuration from config file
227 * @throws BootstrapException if something wrong happens during file loading
228 */
229 public void load() throws BootstrapException{
230 if (configurationFileExists()){
231
232 Digester digester = new Digester();
233 digester.setValidating(false);
234 digester.setNamespaceAware(true);
235 digester.setUseContextClassLoader(true);
236 digester.addRuleSet(new ApplicationConfigRuleSet());
237 digester.push(this);
238
239 try{
240
241 File configFile = new File(applicationHome, CONFIG_FILE);
242 log.debug("Loading application configuration from " + configFile.getAbsolutePath());
243 digester.parse(configFile);
244 }
245 catch (Exception e){
246 log.error("Exception while loading the application configuration file: " + e.getMessage());
247 throw new BootstrapException("Exception while loading the application config file: " + e.getMessage());
248 }
249
250
251 String setup = getProperty(SETUP_COMPLETE);
252 if (setup != null && setup.length() > 0){
253 try {setupComplete = Boolean.valueOf(setup).booleanValue();}
254 catch (Exception e) {setupComplete = false;}
255 }
256 }
257 }
258
259 /**
260 * Save the application configuration to config file
261 * @throws IOException if something wrong occurs during file writing
262 */
263 public void save() throws IOException{
264
265 File configFile = new File(applicationHome, CONFIG_FILE);
266 log.debug("Saving the application configuration to " + configFile.getAbsolutePath());
267
268 if (!configFile.isFile()){
269 log.info(CONFIG_FILE + " doesn't exists yet. Create it...");
270 configFile.createNewFile();
271 }
272
273 PrintWriter writer = null;
274 try{
275
276 writer = new PrintWriter(new FileWriter(configFile));
277 writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
278 writer.println("<join-configuration>");
279 writer.println(" <properties>");
280
281 Iterator properties = configProps.values().iterator();
282 while (properties.hasNext()){
283 ConfigProperty property = (ConfigProperty)properties.next();
284 writer.println(" " + property.toString());
285 }
286
287 writer.println(" </properties>");
288 writer.println("</join-configuration>");
289 }
290 catch (Exception e){
291 log.error("Exception while saving the application configuration: " + e.getMessage());
292 throw new IOException("Exception while saving to file: " + e.getMessage());
293 }
294 finally{
295 try {writer.close();}
296 catch (Exception ee) {log.warn("Exception while closing writer for configuration file: " + ee.getMessage());}
297 }
298 }
299
300 /**
301 * Get the configuration file name into application home directory
302 * @return The configuration file name
303 */
304 public static String getConfigurationFileName(){
305 return CONFIG_FILE;
306 }
307 }