View Javadoc

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     // Static -------------------------------------------------------------------
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     // Attributes ---------------------------------------------------------------
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     // Constructors -------------------------------------------------------------
76     
77     /** Creates a new instance of ApplicationConfig */
78     public ApplicationConfig(){
79     }
80     
81     
82     // Public -------------------------------------------------------------------
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       // Update setupComplete flag.
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          // Remove null value property.
121          configProps.remove(key);
122          applicationProps.remove(key);
123       }
124       else{
125          // Add new config and application property.
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       // Check setup type application property.
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       // Check setup type application property.
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          // Check setup synchronous flag for this side of app.
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          // Check setup synchronous flag for this side of app.
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          // Check dissoctad flag for application.
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       // Keep this property under its COnfigProperty form.
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          // Init digester with correct rules and push this.
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             // Prepare file to parse.
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          // Update setupComplete flag.
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       // Get configuration file in Join Home.
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          // Initialize writer.
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          // Browse and add configuration properties.
281          Iterator properties = configProps.values().iterator();
282          while (properties.hasNext()){
283             ConfigProperty property = (ConfigProperty)properties.next();
284             writer.println("    " + property.toString());
285          }
286          // Close Xml document.
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 }