View Javadoc

1   /*
2    * $Id: Configuration.java,v 1.19 2006/01/12 17:10:29 tymoteusz Exp $
3    *
4    */ 
5   
6   package net.sourceforge.jdbdump.connect;
7   import java.io.FileInputStream;
8   import java.io.IOException;
9   import java.io.Serializable;
10  import java.util.Hashtable;
11  import java.util.Properties;
12  
13  import org.apache.log4j.Logger;
14  
15  /***
16   * This class is a Singleton, which purpose is to manage system's configuration data such as:
17   * <ul>
18   * <li> authorization data of users allowed to use the system,
19   * <li> configured connections to databases
20   * </ul>
21   * Data is passed to/from a subclass of ConfigurationIO class, which gives great flexibility in choose of 
22   * configuration data storage place and access methods.
23   * 
24   * @author tymoteusz
25   *
26   */
27  public class Configuration {
28  
29  	private static Hashtable<String, DatabaseConnectionData> connections = new Hashtable<String, DatabaseConnectionData>(); 
30  	private static Hashtable<String, DatabaseBackupData> backups = new Hashtable<String, DatabaseBackupData>(); 
31  	private static Hashtable<String, User> users = new Hashtable<String, User>();
32  	private static String email = new String();
33  	private static Configuration ref;
34  	private static Logger logger = Logger.getLogger(Configuration.class);
35  	private static ConfigurationIO confIO;
36  	private static Properties props = new Properties();
37  	private static String backupDir = new String();
38  	private static Hashtable<String, Serializable> confData = new Hashtable<String, Serializable>();
39  	/***
40  	 * Value of his variable determines if data should be implicitly saved after every use of put*() method.
41  	 * The default value set to true assumes that access to storage place is not expencieve (in time, or other units),
42  	 * and therefore data is saved automatically to free developer from remembering about commiting changes.
43  	 * Change this setting with setAutosave() method if connection to storage place is expencieve for you,
44  	 * and remember then to save() your changes!
45  	 * @see #setAutosave(boolean)
46  	 */
47  	private boolean autosave = true;
48  
49  	/***
50  	 * Value of his variable determines if data should be implicitly loaded for every use of get*() method.
51  	 * The default value set to false assumes that data at storage place is not versatile, and we don't expect 
52  	 * changes of data during execution of the application. Change this setting with setAutoload() method if you 
53  	 * need to be sure that configuration data you retrieve is most current.  
54  	 * @see #setAutoload(boolean)
55  	 */
56  	private boolean autoload = false;	
57  
58  	/***
59  	 * Creates configuration with one default user. Make sure class defined in system property 
60  	 * "Configuration.configurationIOsubclass", or the default FilesystemConfigurationIO exist in classpath,
61  	 * or constructor will throw an Exception and fail
62  	 * 
63  	 * @throws ClassNotFoundException if the initialization of ConfigurationIOprovoked by this method fails.
64  	 * @throws IllegalAccessException if the class or its nullary constructor is not accessible
65  	 * @throws InstantiationException if this class set in system properties as Configuration.configurationIOsubclass represents an abstract class, an interface, an array class, a primitive type, or void; or if the class has no nullary constructor; or if the instantiation fails for some other reason.
66  	 * @throws IOException if an I/O error occered when tried to fetch configuration
67  	 *
68  	 */
69  	private Configuration() throws InstantiationException, IllegalAccessException, ClassNotFoundException, IOException{
70  		props.load(new FileInputStream("app.properties"));// if it doesn't work, use: src/resources/app.properties
71  		confIO = (ConfigurationIO) Class.forName(
72  				props.getProperty("Configuration.configurationIOsubclass", "net.sourceforge.jdbdump.connect.FilesystemConfigurationIO")
73  				).newInstance();
74  		confData = confIO.load();
75  		setVariables();
76  		autoload = confIO.getDefaultAutoload();
77  		autosave = confIO.getDefaultAutosave();
78  		backupDir = props.getProperty("Configuration.backupDir");
79  	}
80  
81  	/***
82  	 * This method is the only possibility to get an instance of class Configuration. Aim for this limitation is to
83  	 * keep control on object creation. 
84  	 * @return the Singleton Configuration object;
85  	 * @throws ClassNotFoundException 
86  	 * @throws IllegalAccessException 
87  	 * @throws InstantiationException 
88  	 * @throws IOException 
89  	 */
90  	public static synchronized Configuration getInstance() throws InstantiationException, IllegalAccessException, ClassNotFoundException, IOException{
91  		if (ref == null)
92  			ref = new Configuration();		
93  		return ref;
94  	}
95  
96  	/***
97  	 * Prevents cloning the Configuration object, and therefore reduces the possibility of creating 
98  	 * more than one object - we are avoiding such situations, becouse Configuration is implementing 
99  	 * Singleton design pattern 
100 	 * 
101 	 * @throws CloneNotSupportedException if one tries to clone a Configuration object 
102 	 */
103 	public Object clone() throws CloneNotSupportedException{
104 		throw new CloneNotSupportedException(); 
105 	}
106 	
107 	@SuppressWarnings("unchecked")
108 	private void setVariables(){
109 		if(confData.containsKey("connections")){
110 			connections = (Hashtable<String, DatabaseConnectionData>) confData.get("connections");
111 		}
112 		if(confData.containsKey("backups")){
113 			backups = (Hashtable<String, DatabaseBackupData>) confData.get("backups");
114 		}
115 		if(confData.containsKey("email")){
116 			email = (String) confData.get("email");
117 		}
118 	}
119 	
120 	@SuppressWarnings("unchecked")
121 	private void putVariables(){
122 		confData.put("connections", connections);
123 		confData.put("backups", backups);
124 		confData.put("users", users);
125 		confData.put("email", email);
126 	}
127 	
128 	/***
129 	 * Changes value of autosave setting.
130 	 * @param value new setting of the autosave flag. 
131 	 * @return old value
132 	 * @see #autosave
133 	 * @see #save()
134 	 */
135 	public boolean setAutosave(boolean value){
136 		boolean old = autosave;
137 		autosave = value;
138 		return old;
139 	}
140 	
141 	/***
142 	 * Changes value of autoload setting.
143 	 * @param value new setting of the autoload flag.
144 	 * @return old value
145 	 * @see #autoload
146 	 * @see #reload()
147 	 */
148 	public boolean setAutoload(boolean value){
149 		boolean old = autoload;
150 		autoload = value;
151 		return old;
152 	}
153 
154 	private void smartReload(){
155 		if(autoload){// || users == null || connections == null){	// modify when users are thrown away
156 			try {
157 				confData = confIO.load();
158 			} catch (IOException e) {
159 				//  has to be handled!
160 			}
161 			setVariables();
162 		}
163 	}
164 
165 	private void smartSave(){
166 		if(autosave){
167 			putVariables();
168 			try {
169 				confIO.save(confData);
170 			} catch (IOException e) {
171 				//  has to be handled!
172 			}
173 		}
174 	}
175 	
176 	/***
177 	 * Adds data about database connection to current configuration.
178 	 *  
179 	 * @param dcd database connection to be added
180 	 */
181 	public void addDatabase(DatabaseConnectionData dcd){
182 		connections.put(dcd.getTitle(), dcd);
183 		smartSave();
184 	}
185 	
186 	/***
187 	 * Removes data about database connection from current configuration.
188 	 * 
189 	 * @param title name of database connection to be removed
190 	 */
191 	public void removeDatabase(String title){
192 		DatabaseConnectionData dbc = connections.get(title);
193 		if(dbc!=null){
194 			connections.remove(title);
195 		}
196 		smartSave();
197 	}
198 
199 	/*** Removes data about database connection from current configuration.
200 	 * 
201 	 * @param dcd database connection to be removed
202 	 */
203 	public void removeDatabase(DatabaseConnectionData dbc){
204 		String dbTitle = dbc.getTitle();
205 		DatabaseConnectionData database = connections.get(dbTitle);
206 		if(database!=null)
207 			connections.remove(dbTitle);
208 		smartSave();
209 	}
210 
211 	/***
212 	 * Adds data about database backup to current configuration.
213 	 * 
214 	 * @param dcd database backup info to be added
215 	 */
216 	public void addBackup(DatabaseBackupData dbd){
217 		backups.put(dbd.getDate()+"|"+dbd.getTitle(), dbd);
218 		smartSave();
219 	}	
220 	/***
221 	 * Removes data about database backup from current configuration.
222 	 * 
223 	 * @param title name of database backup info to be removed
224 	 * @param date date of database backup info to be removed
225 	 */
226 	public void removeBackup(String title, String date){
227 		DatabaseBackupData dbc = backups.get(title);
228 		if(dbc!=null)
229 			backups.remove(dbc);
230 		smartSave();
231 	}
232 
233 	/*** Removes data about database backup from current configuration.
234 	 * 
235 	 * @param dbd database backup info to be removed
236 	 */
237 	public void removeBackup(DatabaseBackupData dbd){
238 		DatabaseConnectionData backup = backups.get(dbd.getDate()+"|"+dbd.getTitle());
239 		if(dbd!=null)
240 			backups.remove(backup);
241 		smartSave();
242 	}
243 
244 	/***
245 	 * Returns list of configured database connections
246 	 *  
247 	 * @return list of configured database connections
248 	 */
249 	public Hashtable<String, DatabaseConnectionData> getConnections(){
250 		smartReload();
251 		return connections;
252 	}
253 	
254 	/***
255 	 * Returns list of backuped databases
256 	 *  
257 	 * @return list of backuped databases
258 	 */
259 	public Hashtable<String, DatabaseBackupData> getBackups(){
260 		smartReload();
261 		return backups;
262 	}
263 	
264 	public String getEmail(){
265 		smartReload();
266 		return email;
267 	}
268 	
269 	public void setEmail(String e){
270 		email = e;
271 		smartSave();
272 	}
273 	
274 	/***
275 	 * Saves configuration storred in the Configuration object. 
276 	 * 
277 	 */
278 	public void saveData() throws IOException{
279 		putVariables();
280 		confIO.save(confData);
281 	}
282 	
283 	/***
284 	 * Loads configuration data to the Configuration object
285 	 * 
286 	 */
287 	public void loadData() throws IOException, ClassNotFoundException{
288 		confData = confIO.load();
289 		setVariables();
290 	}
291 	
292 	
293 	public String getBackupDir(){
294 		return backupDir; 
295 	}
296 }
297