KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sape > carbon > core > config > node > AbstractFolder


1 /*
2  * The contents of this file are subject to the Sapient Public License
3  * Version 1.0 (the "License"); you may not use this file except in compliance
4  * with the License. You may obtain a copy of the License at
5  * http://carbon.sf.net/License.html.
6  *
7  * Software distributed under the License is distributed on an "AS IS" basis,
8  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
9  * the specific language governing rights and limitations under the License.
10  *
11  * The Original Code is The Carbon Component Framework.
12  *
13  * The Initial Developer of the Original Code is Sapient Corporation
14  *
15  * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.
16  */

17
18 package org.sape.carbon.core.config.node;
19
20 import org.sape.carbon.core.config.Configuration;
21 import org.sape.carbon.core.config.InvalidConfigurationException;
22 import org.sape.carbon.core.config.format.ConfigurationFormatException;
23 import org.sape.carbon.core.config.node.link.LinkNode;
24 import org.sape.carbon.core.config.node.link.LinkNodeConfiguration;
25 import org.sape.carbon.core.config.node.link.LinkNodeFactory;
26 import org.sape.carbon.core.exception.InvalidParameterException;
27
28 /**
29  * This implementation of the <code>Folder</code> interface caches its
30  * children as they are requested. This implementation interfaces with the
31  * backing data store through sub-classes implementing the methods
32  * <code>loadChild</code> and <code>getAllChildNames</code>.
33  *
34  * Copyright 2002 Sapient
35  * @since carbon 1.0
36  * @author Douglas Voet, February 2002
37  * @version $Revision: 1.32 $($Author: dvoet $ / $Date: 2003/10/16 20:57:29 $)
38  */

39 public abstract class AbstractFolder extends AbstractNode implements Folder {
40
41     /**
42      * Factory used to construct all Folders within this folder. Final
43      * because the reference to the factory should never change.
44      */

45     private final NodeFactory subFolderFactory;
46
47     /**
48      * factory used to construct all ConfigurationDocuments within this
49      * folder. Final because the reference to the factory should never change.
50      */

51     private final NodeFactory configurationDocumentFactory;
52
53     /**
54      * factory used to construct all LinkNodes within this
55      * folder. Final because the reference to the factory should never change.
56      */

57     private final NodeFactory linkNodeFactory;
58
59     /**
60      * Constructor for AbstractFolder.
61      *
62      * @param parent the node's parent
63      * @param name the node's name
64      * @param subFolderFactory factory to use for sub folders
65      * @param configurationDocumentFactory factory to use for
66      * creating configuration documents
67      * @param linkNodeFactory factory to use for creating link nodes.
68      *
69      * @throws InvalidParameterException if name, subFolderFactory, or
70      * configurationDocumentFactory is null
71      */

72     public AbstractFolder(
73         Node parent,
74         String JavaDoc name,
75         Object JavaDoc readOrAlterNodeLock,
76         Object JavaDoc addOrLoadChildLock,
77         NodeFactory subFolderFactory,
78         NodeFactory configurationDocumentFactory,
79         NodeFactory linkNodeFactory) {
80
81         super(parent, name, readOrAlterNodeLock, addOrLoadChildLock);
82
83         // parameter check
84
if (subFolderFactory == null) {
85             throw new InvalidParameterException(
86                 this.getClass(),
87                     "subFolderFactory parameter cannot be null");
88         }
89         if (configurationDocumentFactory == null) {
90             throw new InvalidParameterException(
91                 this.getClass(),
92                     "configurationDocumentFactory parameter cannot be null");
93         }
94         if (linkNodeFactory == null) {
95             throw new InvalidParameterException(
96                 this.getClass(),
97                     "linkNodeFactory parameter cannot be null");
98         }
99
100         this.subFolderFactory = subFolderFactory;
101         this.configurationDocumentFactory = configurationDocumentFactory;
102         this.linkNodeFactory = linkNodeFactory;
103     }
104
105     /**
106      * Constructor for AbstractFolder.
107      *
108      * @param parent the node's parent
109      * @param name the node's name
110      * @param subFolderFactory factory to use for sub folders
111      * @param configurationDocumentFactory factory to use for
112      * creating configuration documents
113      * @param linkNodeFactory factory to use for creating link nodes.
114      *
115      * @throws InvalidParameterException if name, subFolderFactory, or
116      * configurationDocumentFactory is null
117      */

118     public AbstractFolder(
119         Node parent,
120         String JavaDoc name,
121         NodeFactory subFolderFactory,
122         NodeFactory configurationDocumentFactory,
123         NodeFactory linkNodeFactory) {
124
125         super(parent, name);
126
127         // parameter check
128
if (subFolderFactory == null) {
129             throw new InvalidParameterException(
130                 this.getClass(),
131                     "subFolderFactory parameter cannot be null");
132         }
133         if (configurationDocumentFactory == null) {
134             throw new InvalidParameterException(
135                 this.getClass(),
136                     "configurationDocumentFactory parameter cannot be null");
137         }
138         if (linkNodeFactory == null) {
139             throw new InvalidParameterException(
140                 this.getClass(),
141                     "linkNodeFactory parameter cannot be null");
142         }
143
144         this.subFolderFactory = subFolderFactory;
145         this.configurationDocumentFactory = configurationDocumentFactory;
146         this.linkNodeFactory = linkNodeFactory;
147     }
148
149     /**
150      * @see Folder#addConfigurationDocument
151      *
152      * synchronized to ensure no one is fetching or removing children while
153      * this method is removing them
154      */

155     public ConfigurationDocument addConfigurationDocument(
156         String JavaDoc name,
157         Configuration config)
158         throws NodeCreationException {
159
160         if (isRemoved()) {
161             throw new NodeRemovedException(
162                 this.getClass(),
163                 this);
164         }
165
166         ConfigurationDocument newDocument =
167             createNewConfigurationDocument(name, config);
168
169         return newDocument;
170     }
171
172     /**
173      * @see Folder#addSubFolder(String)
174      *
175      * synchronized to ensure no one is fetching or removing children while
176      * this method is removing them
177      */

178     public Folder addSubFolder(String JavaDoc name)
179         throws NodeCreationException {
180
181         if (isRemoved()) {
182             throw new NodeRemovedException(
183                 this.getClass(),
184                 this);
185         }
186
187         Folder newFolder = createNewFolder(name);
188
189         return newFolder;
190     }
191
192     /**
193      * @see Folder#addLink
194      */

195     public LinkNode addLink(
196         String JavaDoc name,
197         LinkNodeConfiguration linkConfiguration)
198         throws NodeCreationException {
199
200         if (isRemoved()) {
201             throw new NodeRemovedException(
202                 this.getClass(),
203                 this);
204         }
205
206         try {
207             synchronized (getAddOrLoadChildLock()) {
208                 
209                 // note that the call to the linkNodeFactory is not within
210
// the sync on this. this is because getInstance could possibly
211
// require other locks and maintaining a lock on this object while
212
// requiring a lock on another object opens us up to deadlock
213
ConfigurationDocument linkConfigurationDoc =
214                     (ConfigurationDocument) this.linkNodeFactory.getInstance(
215                         this,
216                         name);
217     
218                 synchronized (getReadOrAlterNodeLock()) {
219                     if (containsChild(name)) {
220                         throw new NodeCreationException(
221                             this.getClass(),
222                             this,
223                             name,
224                             "Node already exists");
225                     }
226                     
227                     linkConfigurationDoc.writeConfiguration(linkConfiguration);
228                 }
229     
230                 LinkNodeFactory linkFactory =
231                     (LinkNodeFactory) linkConfiguration
232                         .getLinkNodeFactoryClass()
233                         .newInstance();
234     
235                 LinkNode newLink =
236                     linkFactory.getInstance(
237                         this,
238                         name,
239                         linkConfigurationDoc);
240     
241                 synchronized (getReadOrAlterNodeLock()) {
242                     this.childNodes.put(name, newLink);
243                 }
244     
245                 return newLink;
246             }
247
248         } catch (NodeIOException nioe) {
249             throw new NodeCreationException(
250                 this.getClass(),
251                 this,
252                 name,
253                 "Could not write link configuration",
254                 nioe);
255
256         } catch (ConfigurationFormatException cfe) {
257             throw new NodeCreationException(
258                 this.getClass(),
259                 this,
260                 name,
261                 "Could not write link configuration",
262                 cfe);
263
264         } catch (ClassCastException JavaDoc cce) {
265             throw new InvalidConfigurationException(
266                 this.getClass(),
267                 this.getAbsoluteName() + Node.DELIMITER + name,
268                 "LinkNodeFactoryClass",
269                 "Class is not an instance of LinkNodeFactory",
270                 cce);
271
272         } catch (InstantiationException JavaDoc ie) {
273             throw new InvalidConfigurationException(
274                 this.getClass(),
275                 this.getAbsoluteName() + Node.DELIMITER + name,
276                 "LinkNodeFactoryClass",
277                 "Could instantiate class",
278                 ie);
279
280         } catch (IllegalAccessException JavaDoc iae) {
281             throw new InvalidConfigurationException(
282                 this.getClass(),
283                 this.getAbsoluteName() + Node.DELIMITER + name,
284                 "LinkNodeFactoryClass",
285                 "Could instantiate class",
286                 iae);
287         }
288     }
289
290     /**
291      * @see Folder#getConfigurationDocumentFactory()
292      */

293     public NodeFactory getConfigurationDocumentFactory() {
294         return this.configurationDocumentFactory;
295     }
296
297     /**
298      * @see Folder#getSubFolderFactory()
299      */

300     public NodeFactory getSubFolderFactory() {
301         return this.subFolderFactory;
302     }
303
304     /**
305      * Uses the subFolderFactory to create a child <code>Folder</code> and
306      * adds it to childNodes
307      *
308      * @param name name of the <code>Folder</code>
309      * @return Folder the new child
310      *
311      * @throws NodeCreationException if the child could not be created for
312      * any reason
313      */

314     protected Folder createNewFolder(String JavaDoc name)
315         throws NodeCreationException {
316
317         synchronized (getAddOrLoadChildLock()) {
318             if (containsChild(name)) {
319                 throw new NodeCreationException(
320                     this.getClass(),
321                     this,
322                     name,
323                     "Node already exists");
324             }
325     
326             // note that the call to the subFolderFactory is not within
327
// the sync on this. this is because getInstance could possibly
328
// require other locks and maintaining a lock on this object while
329
// requiring a lock on another object opens us up to deadlock
330
Folder newFolder =
331                 (Folder) this.subFolderFactory.getInstance(this, name);
332         
333             synchronized (getReadOrAlterNodeLock()) {
334                 this.childNodes.put(name, newFolder);
335             }
336
337             return newFolder;
338         }
339     
340     }
341
342     /**
343      * Uses the configurationDocumentFactory to create a child
344      * <code>ConfigurationDocument</code> and adds it to childNodes.
345      *
346      * @param name name of the <code>ConfigurationDocument</code>
347      * @param config the new config to write
348      * @return ConfigurationDocument the new child
349      *
350      * @throws NodeCreationException if the child could not be created for
351      * any reason
352      */

353     protected ConfigurationDocument createNewConfigurationDocument(
354         String JavaDoc name,
355         Configuration config)
356         throws NodeCreationException {
357             
358         synchronized (getReadOrAlterNodeLock()) {
359             // note that the call to the configurationDocumentFactory is not
360
// within the sync on this. this is because getInstance could possibly
361
// require other locks and maintaining a lock on this object while
362
// requiring a lock on another object opens us up to deadlock
363
ConfigurationDocument newDoc = (ConfigurationDocument)
364                 this.configurationDocumentFactory.getInstance(this, name);
365             
366             synchronized (getReadOrAlterNodeLock()) {
367                 if (containsChild(name)) {
368                     throw new NodeCreationException(
369                         this.getClass(),
370                         this,
371                         name,
372                         "Node already exists");
373                 }
374     
375                 try {
376                     // write to the new docuemnt
377
// note that this synchronizes on newDoc but that is OK
378
// because no one else has access to newDoc yet.
379
newDoc.writeConfiguration(config);
380                 } catch (NodeIOException nioe) {
381                     throw new NodeCreationException(
382                         this.getClass(),
383                         this,
384                         name,
385                         "Could not write to new ConfigurationDocument",
386                         nioe);
387         
388                 } catch (ConfigurationFormatException cfe) {
389                     throw new NodeCreationException(
390                         this.getClass(),
391                         this,
392                         name,
393                         "Could not write to new ConfigurationDocument",
394                         cfe);
395                 }
396                 
397                 this.childNodes.put(name, newDoc);
398         
399                 return newDoc;
400             }
401         }
402     }
403
404     /**
405      * @see Folder#getSubFolderFactory()
406      */

407     public NodeFactory getLinkNodeFactory() {
408         return this.linkNodeFactory;
409     }
410 }
Popular Tags