2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Nokia. Portions Copyright 2003 Nokia.
28
* All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
42
package org.netbeans.modules.enode;
44
import java.util.ArrayList;
45
import java.util.HashSet;
46
import java.util.List;
48
import java.util.StringTokenizer;
49
import java.util.logging.Level;
50
import java.util.logging.Logger;
52
import org.openide.filesystems.FileObject;
53
import org.openide.nodes.Node;
54
import org.openide.util.Lookup;
55
import org.openide.util.Lookup.Template;
57
import org.netbeans.spi.enode.LookupContentFactory;
59
/** Wrapper object for delaying of loading classes of the attached
60
* objects. Reads the file attributes needed for this optimalization.
61
* @author David Strupl
63
public class FactoryWrapper implements LookupContentFactory {
65
private static final Logger log = Logger.getLogger(FactoryWrapper.class.getName());
66
private static boolean LOGGABLE = log.isLoggable(Level.FINE);
69
* File object on the system filesystem. The attributes of this
70
* file object are used to determine the class of the result.
75
* The result of call to the <code> instantiate </code> method.
80
* Stores the classes that we were asked for and returned that
81
* the resulting object does not implement them. The collection
82
* is used in method @see #checkImplementsClause(Object).
84
private Set<Class> implementsQueries = new HashSet<Class>();
86
/** Just remembers the parameter.*/
87
public FactoryWrapper(FileObject f) {
92
* Method from the LookupContentFactory interface. This method
93
* passes the <code>target</code> argument to the delegated
94
* LookupContentFactory.
96
public Object create(Node target) {
100
if (obj instanceof LookupContentFactory) {
101
LookupContentFactory lcf = (LookupContentFactory)obj;
102
Object result = lcf.create(target);
103
checkImplementsClause(result);
106
checkImplementsClause(obj);
113
private void checkImplementsClause(Object toBeReturned) {
114
for (Class clazz : implementsQueries) {
115
if (clazz.isInstance(toBeReturned)) {
116
throw new IllegalStateException("Registration under " + f.getPath() + // NOI18N
117
" \n is missing implements entries for " + toBeReturned + // NOI18N
118
" \n namelly " + clazz.getName() + // NOI18N
119
" \n the implements attribute is " + // NOI18N
120
f.getAttribute("implements")); // NOI18N
126
* Method from the LookupContentFactory interface. This method
127
* passes the <code>target</code> argument to the delegated
128
* LookupContentFactory.
130
public Lookup createLookup(Node target) {
134
if (obj instanceof LookupContentFactory) {
135
LookupContentFactory lcf = (LookupContentFactory)obj;
136
return lcf.createLookup(target);
142
* Checks whether we can match the template. If the resulting object
143
* has been computed we just use its class or if it has not the file
144
* object is examined for the "implements" attribute.
146
boolean matches(Template template) {
147
if (template.getType() != null) {
149
// after the factory object was created we cannot determine
150
// which interfaces it implements and do not want to go
151
// through the expensive check bellow we simply return
152
// true here and the lookup implementation will handle
153
// correct return value from the lookup
156
if (! resultImplements().contains(template.getType().getName())) {
158
log.fine("implementsQueries adding " +
159
template.getType().getName() +
160
" while the attribute is " +
161
f.getAttribute("implements"));
163
implementsQueries.add(template.getType());
171
* Parses the value of attribute "implements"
172
* @return List of String with names of classes/interfaces
173
* implemented by the resulting object
175
private List resultImplements() {
176
String classAttr = (String)f.getAttribute("implements"); // NOI18N
178
log.fine("resultImplements the attribute is " +
179
f.getAttribute("implements"));
181
ArrayList res = new ArrayList();
182
if (classAttr == null) {
185
StringTokenizer t = new StringTokenizer(classAttr, ",");
186
while (t.hasMoreElements()) {
187
res.add(t.nextElement());
193
* We use the system classloader for resolving the class specified
194
* in the file attribute.
195
* @return Class of the resulting object. If the object has not
196
* been created yet the attribute "factoryClass" is consulted
197
* @throws IllegalStateException if something went wrong
199
private Class clazz() {
201
return obj.getClass();
204
String classAttr = (String)f.getAttribute("factoryClass"); // NOI18N
205
ClassLoader cl = (ClassLoader)Lookup.getDefault().lookup(ClassLoader.class);
206
if (classAttr != null) {
207
Class c = Class.forName(classAttr, true, cl);
210
throw new IllegalStateException("Attribute factoryClass not specified for " + f); // NOI18N
212
} catch (ClassNotFoundException cnfe) {
213
IllegalStateException ise = new IllegalStateException(cnfe);
219
* After calling the clazz method newInstance of the resulting
221
* @throws IllegalStateException if something went wrong
223
private Object instantiate() {
225
return clazz().newInstance();
226
} catch (InstantiationException is) {
227
IllegalStateException ise = new IllegalStateException(is);
229
} catch (IllegalAccessException iae) {
230
IllegalStateException ise = new IllegalStateException(iae);
236
* @return Human readable description of the wrapper object.
238
public String toString() {
240
return "FactoryWrapper[" + clazz().getName() + "]"; // NOI18N
242
return "FactoryWrapper[" + f.getAttribute("factoryClass") + "]"; // NOI18N