KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > apisupport > project > queries > GlobalSourceForBinaryImpl


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.apisupport.project.queries;
21
22 import java.beans.PropertyChangeEvent JavaDoc;
23 import java.beans.PropertyChangeListener JavaDoc;
24 import java.io.File JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.net.MalformedURLException JavaDoc;
28 import java.net.URI JavaDoc;
29 import java.net.URL JavaDoc;
30 import java.util.ArrayList JavaDoc;
31 import java.util.Enumeration JavaDoc;
32 import java.util.HashMap JavaDoc;
33 import java.util.HashSet JavaDoc;
34 import java.util.Iterator JavaDoc;
35 import java.util.List JavaDoc;
36 import java.util.Map JavaDoc;
37 import java.util.StringTokenizer JavaDoc;
38 import java.util.zip.ZipEntry JavaDoc;
39 import java.util.zip.ZipException JavaDoc;
40 import java.util.zip.ZipFile JavaDoc;
41 import javax.swing.event.ChangeEvent JavaDoc;
42 import javax.swing.event.ChangeListener JavaDoc;
43 import org.netbeans.api.java.queries.SourceForBinaryQuery;
44 import org.netbeans.modules.apisupport.project.NbModuleProjectType;
45 import org.netbeans.modules.apisupport.project.Util;
46 import org.netbeans.modules.apisupport.project.universe.ModuleList;
47 import org.netbeans.modules.apisupport.project.universe.NbPlatform;
48 import org.netbeans.modules.apisupport.project.universe.TestEntry;
49 import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
50 import org.openide.ErrorManager;
51 import org.openide.filesystems.FileObject;
52 import org.openide.filesystems.FileUtil;
53 import org.openide.filesystems.URLMapper;
54 import org.openide.xml.XMLUtil;
55 import org.w3c.dom.Document JavaDoc;
56 import org.w3c.dom.Element JavaDoc;
57 import org.xml.sax.InputSource JavaDoc;
58 import org.xml.sax.SAXException JavaDoc;
59
60 /**
61  * Able to find sources in the NetBeans sources zip.
62  *
63  * @author Martin Krauskopf
64  */

65 public final class GlobalSourceForBinaryImpl implements SourceForBinaryQueryImplementation {
66     
67     /** for use from unit tests */
68     static boolean quiet = false;
69     
70     public SourceForBinaryQuery.Result findSourceRoots(URL JavaDoc binaryRoot) {
71         try {
72             { // #68685 hack - associate reasonable sources with XTest's versions of various test libs
73
String JavaDoc binaryRootS = binaryRoot.toExternalForm();
74                 URL JavaDoc result = null;
75                 if (binaryRootS.startsWith("jar:file:")) { // NOI18N
76
if (binaryRootS.endsWith("/xtest/lib/nbjunit.jar!/")) { // NOI18N
77
result = new URL JavaDoc(binaryRootS.substring("jar:".length(), binaryRootS.length() - "/xtest/lib/nbjunit.jar!/".length()) + "/xtest/nbjunit/src/"); // NOI18N
78
} else if (binaryRootS.endsWith("/xtest/lib/nbjunit-ide.jar!/")) { // NOI18N
79
result = new URL JavaDoc(binaryRootS.substring("jar:".length(), binaryRootS.length() - "/xtest/lib/nbjunit-ide.jar!/".length()) + "/xtest/nbjunit/ide/src/"); // NOI18N
80
} else if (binaryRootS.endsWith("/xtest/lib/insanelib.jar!/")) { // NOI18N
81
result = new URL JavaDoc(binaryRootS.substring("jar:".length(), binaryRootS.length() - "/xtest/lib/insanelib.jar!/".length()) + "/performance/insanelib/src/"); // NOI18N
82
} else {
83                         // tests.jar in test distribution
84
TestEntry testJar = TestEntry.get(archiveURLToFile(binaryRoot));
85                         if (testJar != null) {
86                            result = testJar.getSrcDir();
87                         }
88                     }
89                     final FileObject resultFO = result != null ? URLMapper.findFileObject(result) : null;
90                     if (resultFO != null) {
91                         return new SourceForBinaryQuery.Result() {
92                             public FileObject[] getRoots() {
93                                 return new FileObject[] {resultFO};
94                             }
95                             public void addChangeListener(ChangeListener JavaDoc l) {}
96                             public void removeChangeListener(ChangeListener JavaDoc l) {}
97                         };
98                     }
99                 }
100             }
101             NbPlatform supposedPlaf = null;
102             for (Iterator JavaDoc it = NbPlatform.getPlatforms().iterator(); it.hasNext(); ) {
103                 NbPlatform plaf = (NbPlatform) it.next();
104                 // XXX more robust condition?
105
if (binaryRoot.toExternalForm().indexOf(plaf.getDestDir().toURI().toURL().toExternalForm()) != -1) {
106                     supposedPlaf = plaf;
107                     break;
108                 }
109             }
110             if (supposedPlaf == null) {
111                 return null;
112             }
113             if (!binaryRoot.getProtocol().equals("jar")) { // NOI18N
114
Util.err.log(binaryRoot + " is not an archive file."); // NOI18N
115
return null;
116             }
117             File JavaDoc binaryRootF = archiveURLToFile(binaryRoot);
118             FileObject fo = FileUtil.toFileObject(binaryRootF);
119             if (fo == null) {
120                 Util.err.log("Cannot found FileObject for " + binaryRootF + "(" + binaryRoot + ")"); // NOI18N
121
return null;
122             }
123   // if (testCnb != null && supposedPlaf != null) {
124
// test
125
// supposedPlaf.
126
// }
127
return new NbPlatformResult(supposedPlaf, binaryRoot, fo.getName().replace('-', '.'));
128         } catch (IOException JavaDoc ex) {
129             throw new AssertionError JavaDoc(ex);
130         }
131     }
132     
133     private static final class NbPlatformResult implements
134             SourceForBinaryQuery.Result, PropertyChangeListener JavaDoc {
135         
136         private final List JavaDoc<ChangeListener JavaDoc> listeners = new ArrayList JavaDoc();
137         private final NbPlatform platform;
138         private final URL JavaDoc binaryRoot;
139         private final String JavaDoc cnb;
140         
141         private boolean alreadyListening;
142         
143         NbPlatformResult(final NbPlatform platform, final URL JavaDoc binaryRoot, final String JavaDoc cnb) {
144             this.platform = platform;
145             this.binaryRoot = binaryRoot;
146             this.cnb = cnb;
147 // this.testType = testType;
148
// this.testCluster = testCluster;
149
}
150         
151         public FileObject[] getRoots() {
152             final List JavaDoc<FileObject> candidates = new ArrayList JavaDoc();
153             URL JavaDoc[] roots = platform.getSourceRoots();
154             try {
155                 for (int i = 0; i < roots.length; i++) {
156                     if (roots[i].getProtocol().equals("jar")) { // NOI18N
157
// suppose zipped sources
158
File JavaDoc nbSrcF = archiveURLToFile(roots[i]);
159                         if (!nbSrcF.exists()) {
160                             continue;
161                         }
162                         NetBeansSourcesParser nbsp;
163                         try {
164                             nbsp = NetBeansSourcesParser.getInstance(nbSrcF);
165                         } catch (ZipException JavaDoc e) {
166                             if (!quiet) {
167                                 Util.err.annotate(e, ErrorManager.UNKNOWN, nbSrcF + " does not seem to be a valid ZIP file.", null, null, null); // NOI18N
168
Util.err.notify(ErrorManager.INFORMATIONAL, e);
169                             }
170                             continue;
171                         }
172                         if (nbsp == null) {
173                             continue;
174                         }
175                         String JavaDoc pathInZip = nbsp.findSourceRoot(cnb);
176                         if (pathInZip == null) {
177                             continue;
178                         }
179                         URL JavaDoc u = new URL JavaDoc(roots[i], pathInZip);
180                         FileObject entryFO = URLMapper.findFileObject(u);
181                         if (entryFO != null) {
182                             candidates.add(entryFO);
183                         }
184                     } else {
185                         // Does not resolve nbjunit and similar from ZIPped
186
// sources. Not a big issue since the default distributed
187
// sources do not contain them anyway.
188
String JavaDoc relPath = resolveSpecialNBSrcPath(binaryRoot);
189                         if (relPath == null) {
190                             continue;
191                         }
192                         URL JavaDoc url = new URL JavaDoc(roots[i], relPath);
193                         FileObject dir = URLMapper.findFileObject(url);
194                         if (dir != null) {
195                             candidates.add(dir);
196                         } // others dirs are currently resolved by o.n.m.apisupport.project.queries.SourceForBinaryImpl
197
}
198                 }
199             } catch (IOException JavaDoc ex) {
200                 throw new AssertionError JavaDoc(ex);
201             }
202             return (FileObject[]) candidates.toArray(new FileObject[candidates.size()]);
203         }
204         
205         public void addChangeListener(ChangeListener JavaDoc l) {
206             // start listening on NbPlatform
207
synchronized (listeners) {
208                 listeners.add(l);
209             }
210             if (!alreadyListening) {
211                 platform.addPropertyChangeListener(this);
212                 alreadyListening = true;
213             }
214         }
215
216         public void removeChangeListener(ChangeListener JavaDoc l) {
217             synchronized (listeners) {
218                 listeners.remove(l);
219             }
220             if (listeners.isEmpty()) {
221                 platform.removePropertyChangeListener(this);
222                 alreadyListening = false;
223             }
224         }
225         
226         public void propertyChange(PropertyChangeEvent JavaDoc evt) {
227             if (evt.getPropertyName() == NbPlatform.PROP_SOURCE_ROOTS) {
228                 Iterator JavaDoc it;
229                 synchronized (listeners) {
230                     if (listeners.isEmpty()) {
231                         return;
232                     }
233                     it = new HashSet JavaDoc(listeners).iterator();
234                 }
235                 ChangeEvent JavaDoc ev = new ChangeEvent JavaDoc(this);
236                 while (it.hasNext()) {
237                     ((ChangeListener JavaDoc) it.next()).stateChanged(ev);
238                 }
239             }
240         }
241         
242     }
243     
244     private static String JavaDoc resolveSpecialNBSrcPath(URL JavaDoc binaryRoot) throws MalformedURLException JavaDoc {
245         String JavaDoc binaryRootS = binaryRoot.toExternalForm();
246         String JavaDoc result = null;
247         if (binaryRootS.startsWith("jar:file:")) { // NOI18N
248
if (binaryRootS.endsWith("/modules/org-netbeans-modules-nbjunit.jar!/")) { // NOI18N
249
result = "xtest/nbjunit/src/"; // NOI18N
250
} else if (binaryRootS.endsWith("/modules/org-netbeans-modules-nbjunit-ide.jar!/")) { // NOI18N
251
result = "xtest/nbjunit/ide/src/"; // NOI18N
252
} else if (binaryRootS.endsWith("/modules/ext/insanelib.jar!/")) { // NOI18N
253
result = "performance/insanelib/src/"; // NOI18N
254
} else {
255                 result = null;
256             }
257         }
258         return result;
259     }
260
261     private static File JavaDoc archiveURLToFile(final URL JavaDoc archiveURL) {
262         return new File JavaDoc(URI.create(FileUtil.getArchiveFile(archiveURL).toExternalForm()));
263     }
264     
265     public static final class NetBeansSourcesParser {
266         
267         /** Zip file to instance map. */
268         private static final Map JavaDoc<File JavaDoc, NetBeansSourcesParser> instances = new HashMap JavaDoc();
269         
270         private static final String JavaDoc NBBUILD_ENTRY = "nbbuild/"; // NOI18N
271

272         private Map JavaDoc<String JavaDoc,String JavaDoc> cnbToPrjDir;
273         private final ZipFile JavaDoc nbSrcZip;
274         private final String JavaDoc zipNBCVSRoot;
275         
276         /**
277          * May return <code>null</code> if the given zip is not a valid
278          * NetBeans sources zip.
279          */

280         public static NetBeansSourcesParser getInstance(File JavaDoc nbSrcZip) throws ZipException JavaDoc, IOException JavaDoc {
281             NetBeansSourcesParser nbsp = (NetBeansSourcesParser) instances.get(nbSrcZip);
282             if (nbsp == null) {
283                 ZipFile JavaDoc nbSrcZipFile = new ZipFile JavaDoc(nbSrcZip);
284                 String JavaDoc zipNBCVSRoot = NetBeansSourcesParser.findNBCVSRoot(nbSrcZipFile);
285                 if (zipNBCVSRoot != null) {
286                     nbsp = new NetBeansSourcesParser(nbSrcZipFile, zipNBCVSRoot);
287                     instances.put(nbSrcZip, nbsp);
288                 }
289             }
290             return nbsp;
291         }
292         
293         NetBeansSourcesParser(ZipFile JavaDoc nbSrcZip, String JavaDoc zipNBCVSRoot) {
294             this.nbSrcZip = nbSrcZip;
295             this.zipNBCVSRoot = zipNBCVSRoot;
296         }
297         
298         String JavaDoc findSourceRoot(final String JavaDoc cnb) {
299             if (cnbToPrjDir == null) {
300                 try {
301                     doScanZippedNetBeansOrgSources();
302                 } catch (IOException JavaDoc ex) {
303                     Util.err.notify(ErrorManager.WARNING, ex);
304                 }
305             }
306             return (String JavaDoc) cnbToPrjDir.get(cnb);
307         }
308         
309         private static String JavaDoc findNBCVSRoot(final ZipFile JavaDoc nbSrcZip) {
310             String JavaDoc nbRoot = null;
311             for (Enumeration JavaDoc<? extends ZipEntry JavaDoc> en = nbSrcZip.entries(); en.hasMoreElements(); ) {
312                 ZipEntry JavaDoc entry = (ZipEntry JavaDoc) en.nextElement();
313                 if (!entry.isDirectory()) {
314                     continue;
315                 }
316                 String JavaDoc name = entry.getName();
317                 if (!name.equals(NBBUILD_ENTRY) &&
318                         !(name.endsWith(NBBUILD_ENTRY) && name.substring(name.indexOf('/') + 1).equals(NBBUILD_ENTRY))) {
319                     continue;
320                 }
321                 ZipEntry JavaDoc xmlEntry = nbSrcZip.getEntry(name + "nbproject/project.xml"); // NOI18N
322
if (xmlEntry != null) {
323                     nbRoot = name.substring(0, name.length() - NBBUILD_ENTRY.length());
324                     break;
325                 }
326             }
327             return nbRoot;
328         }
329         
330         private void doScanZippedNetBeansOrgSources() throws IOException JavaDoc {
331             cnbToPrjDir = new HashMap JavaDoc();
332             for (Enumeration JavaDoc<? extends ZipEntry JavaDoc> en = nbSrcZip.entries(); en.hasMoreElements(); ) {
333                 ZipEntry JavaDoc entry = (ZipEntry JavaDoc) en.nextElement();
334                 if (!entry.isDirectory()) {
335                     continue;
336                 }
337                 String JavaDoc path = entry.getName().substring(0, entry.getName().length() - 1); // remove last slash
338
if (this.zipNBCVSRoot != null && (!path.startsWith(this.zipNBCVSRoot) || path.equals(this.zipNBCVSRoot))) {
339                     continue;
340                 }
341                 StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(path, "/"); // NOI18N
342
if (st.countTokens() > ModuleList.DEPTH_NB_ALL) {
343                     continue;
344                 }
345                 String JavaDoc name = path.substring(path.lastIndexOf('/') + 1, path.length());
346                 if (ModuleList.EXCLUDED_DIR_NAMES.contains(name)) {
347                     // #61579: known to not be project dirs, so skip to save time.
348
continue;
349                 }
350                 // XXX should read src.dir from properties
351
ZipEntry JavaDoc src = nbSrcZip.getEntry(entry.getName() + "src/"); // NOI18N
352
if (src == null || !src.isDirectory()) {
353                     continue;
354                 }
355                 
356                 ZipEntry JavaDoc projectXML = nbSrcZip.getEntry(entry.getName() + "nbproject/project.xml"); // NOI18N
357
if (projectXML == null) {
358                     continue;
359                 }
360                 String JavaDoc cnb = parseCNB(projectXML);
361                 if (cnb != null) {
362                     cnbToPrjDir.put(cnb, entry.getName() + "src/"); // NOI18N
363
}
364             }
365         }
366         
367         private String JavaDoc parseCNB(final ZipEntry JavaDoc projectXML) throws IOException JavaDoc {
368             Document JavaDoc doc;
369             InputStream JavaDoc is = nbSrcZip.getInputStream(projectXML);
370             try {
371                 doc = XMLUtil.parse(new InputSource JavaDoc(is), false, true, null, null);
372             } catch (SAXException JavaDoc e) {
373                 throw (IOException JavaDoc) new IOException JavaDoc(projectXML + ": " + e.toString()).initCause(e); // NOI18N
374
} finally {
375                 is.close();
376             }
377             Element JavaDoc docel = doc.getDocumentElement();
378             Element JavaDoc type = Util.findElement(docel, "type", "http://www.netbeans.org/ns/project/1"); // NOI18N
379
String JavaDoc cnb = null;
380             if (Util.findText(type).equals("org.netbeans.modules.apisupport.project")) { // NOI18N
381
Element JavaDoc cfg = Util.findElement(docel, "configuration", "http://www.netbeans.org/ns/project/1"); // NOI18N
382
Element JavaDoc data = Util.findElement(cfg, "data", NbModuleProjectType.NAMESPACE_SHARED); // NOI18N
383
if (data != null) {
384                     cnb = Util.findText(Util.findElement(data, "code-name-base", NbModuleProjectType.NAMESPACE_SHARED)); // NOI18N
385
}
386             }
387             return cnb;
388         }
389         
390     }
391     
392 }
393
Popular Tags