KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > sync4j > syncclient > spdm > NodeImpl


1 /**
2  * Copyright (C) 2003-2005 Funambol
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18
19
20
21 package sync4j.syncclient.spdm;
22
23 import java.util.Hashtable JavaDoc;
24 import java.util.Properties JavaDoc;
25 import java.util.Enumeration JavaDoc;
26 import java.util.StringTokenizer JavaDoc;
27
28 import java.io.*;
29 import java.lang.reflect.Method JavaDoc;
30
31 import sync4j.syncclient.common.logging.Logger;
32
33
34 /**
35  * This is an implementation of <i>ManagamentNode</i> that uses file system
36  * directories for contexts and properties file for leaf nodes.
37  *
38  *
39  * @author Fabio Maggi @ Funambol
40  * $Id: NodeImpl.java,v 1.5 2005/03/29 08:16:29 nichele Exp $
41  */

42
43 public class NodeImpl implements ManagementNode {
44     //----------------------------------------------------------------- Costants
45
private static final String JavaDoc PROPERTY_CLASS_NAME = "className";
46
47     // ------------------------------------------------------------ Private data
48

49     private String JavaDoc context = null;
50     private String JavaDoc fullContext = null;
51     private ManagementNode parent = null;
52
53     //
54
// save last file properties values
55
//
56
Hashtable JavaDoc propertiesValues = null;
57
58     //
59
// save lastModified about last read file properties
60
//
61
long lastModified = 0;
62
63     // ------------------------------------------------------------ Constructors
64

65     /**
66      * Creates a <i>NodeImpl</i> object for the given management context
67      * and parent node.
68      *
69      * @param parent the parent context; if null, create a root node
70      * @param context the context
71      *
72      */

73     public NodeImpl (ManagementNode parent, String JavaDoc context) {
74         this.parent = parent;
75         this.context = context;
76
77         if (parent != null) {
78             String JavaDoc fc = parent.getFullContext();
79             this.fullContext = fc
80                              + ((fc.endsWith("/")) ? "" : "/")
81                              + context;
82         } else {
83             this.fullContext = context;
84         }
85     }
86
87     //----------------------------------------------------------- Public methods
88

89     /** Returns the node's context
90      *
91      * @return the node's context
92      *
93      */

94     public String JavaDoc getContext() {
95         return this.context;
96     }
97
98     /** Returns the entire node's context path (concatenation of all parent
99      * context paths).
100      *
101      * @return the entire node's context path
102      *
103      */

104     public String JavaDoc getFullContext() {
105         return this.fullContext;
106     }
107
108
109     /**
110      *
111      * @return value
112      *
113      */

114     public Object JavaDoc getValue(String JavaDoc name) throws DMException {
115         Hashtable JavaDoc values = this.getValues();
116         return values.get((Object JavaDoc) name);
117     }
118
119     /**
120      *
121      * @return values
122      *
123      */

124     public Hashtable JavaDoc getValues()
125     throws DMException{
126         try {
127
128             File f = (parent != null)
129                    ? new File(parent.getFullContext(), context + ".properties")
130                    : new File(context + ".properties")
131                    ;
132
133             long filePropertiesLastModified = f.lastModified();
134
135             //
136
// load file properties only filePropertiesLastModified is changed
137
//
138
if (lastModified != filePropertiesLastModified) {
139
140                 propertiesValues = this.loadProperties(f);
141
142                 lastModified = filePropertiesLastModified;
143
144             }
145
146             return propertiesValues;
147
148         } catch (IOException e){
149             throw new DMException("Error loading values for the context "
150                                  + fullContext
151                                  + ": "
152                                  + e.getMessage()
153                                  , e);
154         }
155     }
156
157     /**
158      * Provides direct access to a management subtree relative to the node's
159      * fullContext.
160      *
161      * @param node the name of the subnode (it may contain directories)
162      *
163      * @return the node values
164      *
165      */

166     public Hashtable JavaDoc getNodeValues(String JavaDoc node)
167     throws DMException {
168         try {
169             return loadProperties(new File(fullContext, node + ".properties"));
170         } catch (IOException e) {
171             throw new DMException( "Error reading the management node values in " +
172                                    fullContext +
173                                    '/' +
174                                    node, e);
175         }
176     }
177
178    /**
179      * Retrieves a value from the given management subnode name.
180      *
181      * @param node the subnode containing the config value specified by name
182      * @param name the name of the configuration value to return
183      *
184      * @return the node value
185      *
186      * @throws DMException in case of errors.
187      */

188     public Object JavaDoc getNodeValue(String JavaDoc node, String JavaDoc name)
189     throws DMException {
190         Hashtable JavaDoc values = getNodeValues(node);
191
192         return values.get(name);
193     }
194
195     /**
196      * Reads the properties of the given node and creates an object with the
197      * values read.
198      * @param node the subnode containing the required config values
199      * @return the object
200      * @throws DMException in case of errors.
201      */

202      public Object JavaDoc getManagementObject(String JavaDoc node) throws DMException {
203          Object JavaDoc objectToReturn = null;
204
205          Hashtable JavaDoc properties = getNodeValues(node);
206          String JavaDoc className = (String JavaDoc)properties.get(PROPERTY_CLASS_NAME);
207
208          try {
209              objectToReturn = (Class.forName(className)).newInstance();
210          } catch (Exception JavaDoc e) {
211
212              String JavaDoc msg = "Error loading class " +
213                           className +
214                           ": " +
215                           e.getMessage();
216
217              throw new DMException(msg);
218          }
219
220          // setting all properties
221
Enumeration JavaDoc e = properties.keys();
222
223          String JavaDoc key = null;
224          while (e.hasMoreElements()) {
225              key = (String JavaDoc)e.nextElement();
226              if (!PROPERTY_CLASS_NAME.equals(key)) {
227                  setProperty(objectToReturn, key, (String JavaDoc)properties.get(key));
228              }
229          }
230
231          return objectToReturn;
232      }
233
234     /**
235      * Retrieves the children subnodes of the current node. Subnodes may be
236      * directories or property files. In the latter case, the node context is
237      * the name of the file without the extension.
238      *
239      * @return an array of <i>ManagementNode</i> containing this node's children
240      *
241      * @throws DMException in case of errors.
242      */

243     public ManagementNode[] getChildren() throws DMException{
244         File f = new File(fullContext);
245
246         String JavaDoc[] children = f.list();
247
248         if ((children == null) || (children.length==0)) {
249             return new ManagementNode[0];
250         }
251
252         ManagementNode[] nodes = new ManagementNode[children.length];
253         for (int i=0; i<children.length; ++i){
254             nodes[i] = new NodeImpl(this, removeExtension(children[i]));
255         }
256
257         return nodes;
258     }
259
260     /**
261      * Retrieves the subnode with the given name
262      *
263      * @return subcontext the subnode context (name)
264      *
265      * @throws DMException in case of errors.
266      */

267     public ManagementNode getChildNode(String JavaDoc subcontext)
268     throws DMException {
269         if ((!new File(fullContext, subcontext).exists() && !new File(fullContext, subcontext+".properties").exists())) {
270             throw new DMException("The sub context "
271                                   + subcontext
272                                   + " does not exist in context "
273                                   + fullContext
274                                   );
275         }
276
277         return new NodeImpl(this, subcontext);
278     }
279
280     /**
281      * Retrieves this node's parent.
282      *
283      * @return the node's parent
284      *
285      * @throws DMException in case of errors.
286      */

287     public ManagementNode getParent(){
288         return this.parent;
289     }
290
291     /**
292      * Sets a node value as a whole object.
293      *
294      * @param name
295      * @param value the value
296      *
297      * @throws DMException in case of errors.
298      */

299     public void setValue(String JavaDoc name, Object JavaDoc value) throws DMException {
300
301         File file = new File(fullContext + ".properties");
302         setValue(file, "", name, value);
303     }
304
305     /**
306      * Sets a subnode specific value.
307      *
308      * @param node subnode to set
309      * @param name configuration parameter to set
310      * @param value
311      *
312      * @throws DMException in case of errors.
313      */

314     public void setValue(String JavaDoc node, String JavaDoc name, Object JavaDoc value)
315     throws DMException {
316
317        File file = new File(fullContext, node + ".properties");
318        setValue(file, node, name, value);
319     }
320
321
322     /**
323      * Remove subnode from configuration three.
324      *
325      * @param node subnode to reomove
326      *
327      * @throws DMException in case of errors.
328      */

329     public void removeNode(String JavaDoc node)
330     throws DMException {
331
332         Properties JavaDoc values = null;
333
334         File context = new File(fullContext, node);
335         File file = new File(fullContext, node + ".properties");
336
337         if (file.exists()) {
338             file.delete();
339         }
340
341         emptyTree(context);
342     }
343
344     // ------------------------------------------------------------ Private methods
345

346    /**
347     * Sets a subnode specific value
348     *
349     * @param file file to set
350     * @param name configuration parameter to set
351     * @param value
352     *
353     * @throws DMException in case of errors.
354     */

355    private void setValue(File file, String JavaDoc node, String JavaDoc name, Object JavaDoc value)
356         throws DMException {
357
358        Properties JavaDoc values = null;
359
360        //creates a new, empty file named by this abstract pathname
361
//if and only if a file with this name does not yet exist
362
if(!file.exists()) {
363            String JavaDoc dir = file.getParent();
364
365            try {
366                if (dir != null) {
367                    new File(dir).mkdirs();
368                }
369            } catch (Exception JavaDoc e) {
370                throw new DMException( "Error creating the management node "
371                                     +
372                                     + '/'
373                                     + node + " " + e
374                                     , e);
375            }
376            values = new Properties JavaDoc();
377        } else {
378            try {
379                values = loadProperties(file);
380            } catch (IOException e) {
381                throw new DMException("Error reading the management node values in " +
382                                      fullContext +
383                                      '/' +
384                                      node, e );
385            }
386        }
387
388        values.put(name, value);
389
390        try {
391            saveProperties(file, values);
392        } catch (IOException e) {
393            throw new DMException("Error writing the management node values in " +
394                                  fullContext +
395                                  '/' +
396                                  node, e);
397        }
398     }
399
400     private Properties JavaDoc loadProperties(File file)
401     throws IOException {
402         FileInputStream fis = null;
403         Properties JavaDoc prop = new Properties JavaDoc();
404
405         try {
406             fis = new FileInputStream(file);
407             prop.load(fis);
408             return prop;
409         } finally {
410             if (fis != null) try {
411                 fis.close();
412             } catch (IOException e) {}
413         }
414
415     }
416
417     private void saveProperties(File file, Properties JavaDoc values)
418     throws IOException {
419         FileOutputStream fos = null;
420
421         try {
422             fos = new FileOutputStream(file);
423             values.save(fos, "");
424         } finally {
425             if (fos != null) try {
426                 fos.close();
427             } catch (IOException e) {}
428         }
429     }
430
431     private String JavaDoc removeExtension(String JavaDoc context) {
432         int p = context.lastIndexOf('.');
433         if (p < 0) {
434             return context;
435         }
436
437         if (p == 0) {
438             return "";
439         }
440
441         return context.substring(0, p);
442     }
443
444
445     /**
446      * Remove files and directories in a folder
447      *
448      * @param dir folder to empty
449      *
450      */

451     private void emptyTree(File dir) {
452         String JavaDoc[] files = dir.list();
453
454         if (files == null) {
455             return;
456         }
457
458         File f;
459         for (int i=0; i < files.length;i++) {
460             f = new File(dir, files[i]);
461             if (f.isDirectory()) {
462                 emptyTree(f);
463             }
464             f.delete();
465         }
466
467         dir.delete();
468     }
469
470     private void setProperty(Object JavaDoc obj, String JavaDoc key, String JavaDoc value) {
471         String JavaDoc methodName = "";
472
473         char firstLetter = key.toUpperCase().charAt(0);
474         if (key.length() > 1) {
475             methodName = key.substring(1);
476         }
477
478         methodName = "set" + firstLetter + methodName;
479
480         Class JavaDoc objClass = obj.getClass();
481
482         try {
483             Method JavaDoc m = objClass.getMethod(methodName, new Class JavaDoc[] { String JavaDoc.class });
484             m.invoke(obj, new String JavaDoc[] {value});
485         } catch (Exception JavaDoc e) {
486             String JavaDoc msg = "Property " +
487                           key +
488                           " not set to " +
489                           value +
490                           ". Method " +
491                           methodName +
492                           "(String s) not found in " +
493                           objClass.getName() ;
494
495             if (Logger.isLoggable(Logger.DEBUG)) {
496                 Logger.debug(msg);
497             }
498         }
499     }
500
501 }
502
Popular Tags