KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > NodeFactoryPool


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.java;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.Collection JavaDoc;
24 import java.util.Collections JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.LinkedList JavaDoc;
27 import java.util.List JavaDoc;
28 import org.netbeans.modules.java.ui.nodes.ExElementNodeFactory;
29 import org.netbeans.modules.java.ui.nodes.ExFilterFactory;
30 import org.netbeans.modules.java.ui.nodes.FilterSourceNodeFactory;
31 import org.netbeans.modules.java.ui.nodes.JavaSourceNodeFactory;
32 import org.netbeans.modules.java.ui.nodes.SourceNodeFactory;
33 import org.netbeans.modules.java.ui.nodes.SourceNodes;
34 import org.openide.ErrorManager;
35 import org.openide.cookies.InstanceCookie;
36 import org.openide.loaders.DataFolder;
37 import org.openide.loaders.FolderInstance;
38 import org.openide.src.nodes.ElementNodeFactory;
39 import org.openide.src.nodes.FilterFactory;
40
41 /**
42  * A pool for registering FilterSourceNodeFactories for the object browser and the
43  * explorer. The implementation is backward compatible for FilterFactories.
44  *
45  * @author Svatopluk Dedic
46  *
47  */

48 final class NodeFactoryPool extends FolderInstance {
49
50     /**
51      * Base factory, which serves as a default and the tail of the chain.
52      */

53     ElementNodeFactory base;
54     
55     /**
56      * Factories, which were explicitly added by calls to {@link #addFactory}
57      */

58     LinkedList JavaDoc explicit;
59     
60     /**
61      * State of the underlying folder. Contains list of factories registered
62      * through the SFS.
63      */

64     List JavaDoc factories = Collections.EMPTY_LIST;
65     
66     /**
67      * Computed head of the factory chain.
68      */

69     ElementNodeFactory head;
70     
71     /**
72      * True, if the folder scan was triggered at least once.
73      */

74     boolean initialized;
75     
76     NodeFactoryPool(DataFolder storage, ElementNodeFactory base) {
77         super(storage);
78         this.base = base;
79         head = base;
80     }
81     
82     final Object JavaDoc sync() {
83         return base;
84     }
85
86     /**
87      * Returns the head of the current factory list. Except for the initialization,
88      * the method does not block.
89      */

90     ElementNodeFactory getHead() {
91         // force folder scan the first time the Pool is queried
92
if (!initialized) {
93             recreate();
94             waitFinished();
95             initialized = true;
96         }
97         return head;
98     }
99
100     /**
101      * Creates an array of factories from the underlying folder. The "product" of
102      * the method is the head of the factory list.
103      */

104     protected Object JavaDoc createInstance(InstanceCookie[] cookies)
105     throws java.io.IOException JavaDoc, ClassNotFoundException JavaDoc {
106         List JavaDoc l = new ArrayList JavaDoc(cookies.length + 1);
107         JavaSourceNodeFactory jsnf = new JavaSourceNodeFactory();
108         jsnf.setGenerateForTree(((JavaElementNodeFactory) base).getGenerateForTree());
109         l.add(jsnf);
110         for (int i = 0; i < cookies.length; i++) {
111                 Object JavaDoc o = cookies[i].instanceCreate();
112                 if (o instanceof FilterSourceNodeFactory) {
113                     l.add(o);
114                 } else if (o instanceof FilterFactory) { // backward compatibility
115
ExFilterFactory eff = new ExFilterFactory((ElementNodeFactory) o);
116                     l.add(eff);
117                 }
118         }
119         synchronized (sync()) {
120             ElementNodeFactory f = relinkFactories(l);
121             this.factories = l;
122             return head = f;
123         }
124     }
125
126     /**
127      * Reattaches factories in the logicall factory chain to each other.
128      */

129     private ElementNodeFactory relinkFactories(Collection JavaDoc first) {
130         Object JavaDoc previousFactory = new ExFilterFactory(base);
131         Iterator JavaDoc it;
132         Collection JavaDoc next = explicit;
133         
134         if (first == null)
135             first = factories;
136         
137         for (it = first.iterator(); it.hasNext(); ) {
138             Object JavaDoc obj = it.next();
139             attachFactories(obj, previousFactory);
140             previousFactory = obj;
141         }
142         if (next != null) {
143             for (it = next.iterator(); it.hasNext(); ) {
144                 Object JavaDoc obj = it.next(); // FilterFactory
145
ExFilterFactory eff = new ExFilterFactory((ElementNodeFactory) obj);
146                 attachFactories(previousFactory, eff);
147                 previousFactory = obj;
148             }
149         }
150         return previousFactory instanceof ElementNodeFactory?
151                 (ElementNodeFactory) previousFactory:
152                 SourceNodes.createElementNodeFactory((FilterSourceNodeFactory) previousFactory);
153     }
154     
155     /**
156      * attaches factory f2 to f1
157      * @param f1 FilterSourceNodeFactory or ExFilterFactory instance
158      * @param f2 SourceNodeFactory or ExElementNodeFactory instance
159      */

160     private static void attachFactories(Object JavaDoc f1, Object JavaDoc f2) {
161         if (f1 instanceof FilterSourceNodeFactory) {
162             FilterSourceNodeFactory f1SNF = (FilterSourceNodeFactory) f1;
163             if (f2 instanceof SourceNodeFactory) {
164                 f1SNF.attach((SourceNodeFactory) f2);
165             } else if (f2 instanceof ExElementNodeFactory) {
166                 f1SNF.attach(SourceNodes.createSourceNodeFactory((ExElementNodeFactory) f2));
167             } else {
168                 ErrorManager.getDefault().notify(
169                         ErrorManager.INFORMATIONAL, new IllegalStateException JavaDoc("Unsupported factory: " + f2)); // NOI18N
170
}
171         } else if (f1 instanceof ExFilterFactory) {
172             ExFilterFactory f1EFF = (ExFilterFactory) f1;
173             if (f2 instanceof ExElementNodeFactory) {
174                 f1EFF.attach((ExElementNodeFactory) f2);
175             } else if (f2 instanceof SourceNodeFactory){
176                 f1EFF.attach(SourceNodes.createElementNodeFactory((SourceNodeFactory) f2));
177             } else {
178                 ErrorManager.getDefault().notify(
179                         ErrorManager.INFORMATIONAL, new IllegalStateException JavaDoc("Unsupported factory: " + f2)); // NOI18N
180
}
181         } else {
182             ErrorManager.getDefault().notify(
183                     ErrorManager.INFORMATIONAL, new IllegalStateException JavaDoc("Unsupported factory: " + f1)); // NOI18N
184
}
185     }
186
187     /**
188      * Adds an explicit factory and the head of the chain. Relinks the entire
189      * chain as well.
190      */

191     void addFactory(FilterFactory f) {
192         synchronized (sync()) {
193             if (explicit == null) {
194                 explicit = new LinkedList JavaDoc();
195             }
196             explicit.add(f);
197             head = relinkFactories(null);
198         }
199     }
200
201     /**
202      * Removes one factory from the explicit list. Relinks the chain, if the
203      * factory was, actually, on the list.
204      */

205     void removeFactory(FilterFactory f) {
206         synchronized (sync()) {
207             if (!explicit.remove(f))
208                 return;
209             relinkFactories(null);
210         }
211     }
212
213     
214 }
215
Popular Tags