KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > javacore > classpath > FilterClassPathImplementation


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 package org.netbeans.modules.javacore.classpath;
20
21
22 import java.beans.PropertyChangeListener JavaDoc;
23 import java.beans.PropertyChangeSupport JavaDoc;
24 import java.beans.PropertyChangeEvent JavaDoc;
25 import java.net.URL JavaDoc;
26 import java.util.*;
27 import org.openide.filesystems.FileObject;
28 import org.openide.filesystems.FileStateInvalidException;
29 import org.netbeans.api.java.classpath.ClassPath;
30 import org.netbeans.api.java.queries.SourceForBinaryQuery;
31 import org.netbeans.modules.javacore.Cache;
32 import org.netbeans.modules.javacore.JMManager;
33 import org.netbeans.spi.java.classpath.ClassPathImplementation;
34 import org.netbeans.spi.java.classpath.ClassPathFactory;
35 import org.netbeans.spi.java.classpath.PathResourceImplementation;
36 import org.netbeans.spi.java.classpath.support.ClassPathSupport;
37 import org.openide.util.WeakListeners;
38
39
40 /**
41  * FilterClassPathImplementation
42  * @author Tomas Zezula, Martin Matula
43  */

44 public class FilterClassPathImplementation implements ClassPathImplementation, PropertyChangeListener JavaDoc, Cache.CachedElement {
45     
46     private static final boolean DEBUG = false;
47
48     private final PropertyChangeSupport JavaDoc support;
49     private final Object JavaDoc key;
50     private final List resources;
51     private boolean isUpToDate = true;
52     
53     private static HashMap resourceCache = new HashMap();
54     private static HashMap instanceMap = new HashMap(15);
55     private static HashMap implToCP = new HashMap(15);
56     private static Cache cache = new Cache(10);
57     private static ClassPath validator;
58
59     private FilterClassPathImplementation(List/*<ClassPath>*/ original, boolean preferSources) {
60         assert original != null && original.size() > 0 : "Array of original classpaths can not be null or empty or contain nulls: " + original; //NOI18N
61
this.support = new PropertyChangeSupport JavaDoc(this);
62         this.key = getKey(original, preferSources);
63         this.resources = Collections.unmodifiableList(createResources(original, preferSources));
64         instanceMap.put(key, this);
65     }
66
67     public void release() {
68         if (DEBUG) System.err.println("dropping unused classpath: " + key); // NOI18N
69
implToCP.remove(this);
70         instanceMap.remove(key);
71     }
72     
73     public boolean isValid() {
74         return isUpToDate;
75     }
76
77     public void propertyChange(PropertyChangeEvent JavaDoc evt) {
78         isUpToDate = false;
79     }
80
81     public List getResources() {
82         return resources;
83     }
84
85     public void addPropertyChangeListener(PropertyChangeListener JavaDoc listener) {
86         this.support.addPropertyChangeListener (listener);
87     }
88
89     public void removePropertyChangeListener(PropertyChangeListener JavaDoc listener) {
90         this.support.removePropertyChangeListener (listener);
91     }
92     
93     private List createResources(List/*<ClassPath>*/ original, boolean preferSources) {
94         List list = new ArrayList ();
95
96         JMManager manager = (JMManager) JMManager.getManager();
97         
98         if (validator == null) {
99             validator = manager.getMergedClassPath();
100         }
101         Set visited = new HashSet();
102         Set added = new HashSet();
103         validator.addPropertyChangeListener((PropertyChangeListener JavaDoc) WeakListeners.create(PropertyChangeListener JavaDoc.class, this, validator));
104         if (DEBUG) System.err.println("creating resources from paths: "); // NOI18N
105
for (int j = 0; j < original.size(); j++) {
106             if (DEBUG) System.err.println(" path[" + j + "]"); // NOI18N
107
ClassPath origCP = (ClassPath) original.get(j);
108             if (origCP == null) continue;
109             for (Iterator it = origCP.entries().iterator(); it.hasNext();) {
110                 ClassPath.Entry entry = (ClassPath.Entry) it.next();
111                 URL JavaDoc url = entry.getURL();
112                 if (DEBUG) System.err.println(" root: " + url); // NOI18N
113
// if the root is not in the classpath yet, let's try to add it
114
if (visited.add(url)) {
115                     FileObject root = entry.getRoot();
116                     boolean addBinary = false;
117                     // check if the root exists and whether the MDR already knows about it - set the force flag if not
118
boolean forceSource = !(root != null && manager.mergedCPContainsRoot(root));
119                     if (DEBUG) System.err.println(" forceSource=" + forceSource); // NOI18N
120
// try to take all source roots from this root
121
FileObject[] sroots = SourceForBinaryQuery.findSourceRoots (url).getRoots();
122                     // if yes, first check if the source roots are read-only - if not, then it is likely that the binary root will change too often
123
// (e.g. during clean, build, compile, etc.)
124
// i.e. in that case it is better to add the source root so that everything is resolved to source elements
125
if (DEBUG) System.err.println(" source roots: " + Arrays.asList((Object JavaDoc[]) sroots)); // NOI18N
126
if (sroots.length > 0) {
127                         boolean cont = forceSource;
128                         if (!forceSource) {
129                             int i = 0;
130                             for (; i < sroots.length; i++) {
131                                 if (!manager.mergedCPContainsRoot(sroots[i])) break;
132                             }
133                             cont = i >= sroots.length;
134                         }
135                         if (cont) {
136                             for (int i = 0; i < sroots.length; i++) {
137                                 if (!forceSource || manager.mergedCPContainsRoot(sroots[i])) {
138                                     try {
139                                         URL JavaDoc surl = sroots[i].getURL();
140                                         if (visited.add(surl)) {
141                                             if (preferSources || forceSource || sroots.length != 1 || !surl.getProtocol().equals("jar")) { // NOI18N
142
// if the source root is not a zip file or there are more than one source roots,
143
// or forceSource flag is set, sources need to be added to the classpath instead of binaries
144
PathResourceImplementation resource = (PathResourceImplementation) resourceCache.get(surl);
145                                                 if (resource == null) {
146                                                     resource = ClassPathSupport.createResource(surl);
147                                                 }
148                                                 resourceCache.put(surl, resource);
149                                                 list.add(resource);
150                                                 added.add(surl);
151                                                 if (DEBUG) System.err.println(" * adding source root: " + surl); // NOI18N
152
} else {
153                                                 addBinary = true;
154                                             }
155                                         } else {
156                                             if (!added.contains(surl)) {
157                                                 addBinary = true;
158                                             }
159                                         }
160                                     } catch (FileStateInvalidException fsie) {
161                                         //Skip it illegal source root
162
}
163                                 }
164                             }
165                         } else {
166                             addBinary = true;
167                         }
168                     } else {
169                         addBinary = true;
170                     }
171                     if (addBinary && !forceSource) {
172                         // the sources for this binary root were not added to the classpath yet -> we will add this root
173
PathResourceImplementation resource = (PathResourceImplementation) resourceCache.get(url);
174                         if (resource == null) {
175                             resource = ClassPathSupport.createResource(url);
176                         }
177                         resourceCache.put(url, resource);
178                         list.add(resource);
179                         if (DEBUG) System.err.println(" * adding root: " + url); // NOI18N
180
}
181                 }
182             }
183             origCP.addPropertyChangeListener((PropertyChangeListener JavaDoc) WeakListeners.create(PropertyChangeListener JavaDoc.class, this, origCP));
184         }
185         return list;
186     }
187     
188     private static Object JavaDoc getKey(List/*<ClassPath>*/ original, boolean preferSources) {
189         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(1024);
190         
191         ClassPath mergedPath = ((JMManager) JMManager.getManager()).getMergedClassPath();
192         for (Iterator it = original.iterator(); it.hasNext();) {
193             Object JavaDoc item = it.next();
194             if (item == mergedPath) {
195                 buf.append("Merged"); // NOI18N
196
} else {
197                 buf.append(item);
198             }
199         }
200         return buf.toString() + preferSources;
201     }
202
203     public static synchronized ClassPath createClassPath(List/*<ClassPath>*/ original, boolean preferSources) {
204         if (DEBUG) System.err.println("\n**************** request for classpath"); // NOI18N
205
FilterClassPathImplementation instance = (FilterClassPathImplementation) instanceMap.get(getKey(original, preferSources));
206         ClassPath result;
207         if (instance == null || !instance.isUpToDate) {
208             if (DEBUG) {
209                 System.err.println("classpath does not exist or is not up to date - creating..."); // NOI18N
210
Thread.dumpStack();
211             }
212             instance = new FilterClassPathImplementation(original, preferSources);
213             result = ClassPathFactory.createClassPath(instance);
214             implToCP.put(instance, result);
215         } else {
216             result = (ClassPath) implToCP.get(instance);
217         }
218         cache.put(instance);
219         return result;
220     }
221 }
222
Popular Tags