KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > j2seplatform > libraries > JavadocForBinaryQueryLibraryImpl


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.j2seplatform.libraries;
21 import java.beans.PropertyChangeEvent JavaDoc;
22
23 import java.beans.PropertyChangeListener JavaDoc;
24
25
26
27 import java.net.URL JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Map JavaDoc;
32 import java.util.HashMap JavaDoc;
33 import javax.swing.event.ChangeEvent JavaDoc;
34
35 import javax.swing.event.ChangeListener JavaDoc;
36
37 import org.openide.ErrorManager;
38 import org.openide.util.WeakListeners;
39 import org.openide.filesystems.URLMapper;
40 import org.openide.filesystems.FileObject;
41 import org.openide.filesystems.FileStateInvalidException;
42 import org.openide.filesystems.FileUtil;
43 import org.netbeans.api.java.queries.JavadocForBinaryQuery;
44 import org.netbeans.api.project.libraries.Library;
45 import org.netbeans.api.project.libraries.LibraryManager;
46 import org.netbeans.spi.java.queries.JavadocForBinaryQueryImplementation;
47 import org.netbeans.modules.java.j2seplatform.platformdefinition.Util;
48
49
50
51 /**
52  * Implementation of Javadoc query for the library.
53  */

54 public class JavadocForBinaryQueryLibraryImpl implements JavadocForBinaryQueryImplementation {
55     
56     private static int MAX_DEPTH = 3;
57     private final Map JavaDoc/*<URL,URL>*/ normalizedURLCache = new HashMap JavaDoc();
58
59     /** Default constructor for lookup. */
60     public JavadocForBinaryQueryLibraryImpl() {
61     }
62
63     public JavadocForBinaryQuery.Result findJavadoc(final URL JavaDoc b) {
64         class R implements JavadocForBinaryQuery.Result, PropertyChangeListener JavaDoc {
65
66             private Library lib;
67             private ArrayList JavaDoc listeners;
68             private URL JavaDoc[] cachedRoots;
69             
70
71             public R (Library lib) {
72                 this.lib = lib;
73                 this.lib.addPropertyChangeListener (WeakListeners.propertyChange(this,this.lib));
74             }
75
76             public synchronized URL JavaDoc[] getRoots() {
77                 if (this.cachedRoots == null) {
78                     List JavaDoc l = lib.getContent(J2SELibraryTypeProvider.VOLUME_TYPE_JAVADOC);
79                     List JavaDoc result = new ArrayList JavaDoc ();
80                     for (Iterator JavaDoc it = l.iterator(); it.hasNext();) {
81                         URL JavaDoc u = (URL JavaDoc) it.next ();
82                         result.add (getIndexFolder(u));
83                     }
84                     this.cachedRoots = (URL JavaDoc[])result.toArray(new URL JavaDoc[result.size()]);
85                 }
86                 return this.cachedRoots;
87             }
88             
89             public synchronized void addChangeListener(ChangeListener JavaDoc l) {
90                 assert l != null : "Listener can not be null";
91                 if (this.listeners == null) {
92                     this.listeners = new ArrayList JavaDoc ();
93                 }
94                 this.listeners.add (l);
95             }
96             
97             public synchronized void removeChangeListener(ChangeListener JavaDoc l) {
98                 assert l != null : "Listener can not be null";
99                 if (this.listeners == null) {
100                     return;
101                 }
102                 this.listeners.remove (l);
103             }
104             
105             public void propertyChange (PropertyChangeEvent JavaDoc event) {
106                 if (Library.PROP_CONTENT.equals(event.getPropertyName())) {
107                     synchronized (this) {
108                         this.cachedRoots = null;
109                     }
110                     this.fireChange ();
111                 }
112             }
113             
114             private void fireChange () {
115                 Iterator JavaDoc it = null;
116                 synchronized (this) {
117                     if (this.listeners == null) {
118                         return;
119                     }
120                     it = ((ArrayList JavaDoc)this.listeners.clone()).iterator ();
121                 }
122                 ChangeEvent JavaDoc event = new ChangeEvent JavaDoc (this);
123                 while (it.hasNext()) {
124                     ((ChangeListener JavaDoc)it.next()).stateChanged(event);
125                 }
126             }
127         }
128
129         boolean isNormalizedURL = isNormalizedURL(b);
130         LibraryManager lm = LibraryManager.getDefault();
131         Library[] libs = lm.getLibraries();
132         for (int i=0; i<libs.length; i++) {
133             String JavaDoc type = libs[i].getType();
134             if (!J2SELibraryTypeProvider.LIBRARY_TYPE.equalsIgnoreCase(type)) {
135                 continue;
136             }
137             List JavaDoc jars = libs[i].getContent(J2SELibraryTypeProvider.VOLUME_TYPE_CLASSPATH); //NOI18N
138
Iterator JavaDoc it = jars.iterator();
139             while (it.hasNext()) {
140                 URL JavaDoc entry = (URL JavaDoc)it.next();
141                 URL JavaDoc normalizedEntry;
142                 if (isNormalizedURL) {
143                     normalizedEntry = getNormalizedURL(entry);
144                 }
145                 else {
146                     normalizedEntry = entry;
147                 }
148                 if (normalizedEntry != null && normalizedEntry.equals(b)) {
149                     return new R(libs[i]);
150                 }
151             }
152         }
153         return null;
154     }
155
156     private URL JavaDoc getNormalizedURL (URL JavaDoc url) {
157         //URL is already nornalized, return it
158
if (isNormalizedURL(url)) {
159             return url;
160         }
161         //Todo: Should listen on the LibrariesManager and cleanup cache
162
// in this case the search can use the cache onle and can be faster
163
// from O(n) to O(ln(n))
164
URL JavaDoc normalizedURL = (URL JavaDoc) this.normalizedURLCache.get (url);
165         if (normalizedURL == null) {
166             FileObject fo = URLMapper.findFileObject(url);
167             if (fo != null) {
168                 try {
169                     normalizedURL = fo.getURL();
170                     this.normalizedURLCache.put (url, normalizedURL);
171                 } catch (FileStateInvalidException e) {
172                     ErrorManager.getDefault().notify(e);
173                 }
174             }
175         }
176         return normalizedURL;
177     }
178
179     /**
180      * Returns true if the given URL is file based, it is already
181      * resolved either into file URL or jar URL with file path.
182      * @param URL url
183      * @return true if the URL is normal
184      */

185     private static boolean isNormalizedURL (URL JavaDoc url) {
186         if ("jar".equals(url.getProtocol())) { //NOI18N
187
url = FileUtil.getArchiveFile(url);
188         }
189         return "file".equals(url.getProtocol()); //NOI18N
190
}
191     
192     
193     
194     /**
195      * Tests if the query accepts the root as valid JavadocRoot,
196      * the query accepts the JavaDoc root, if it can find the index-files
197      * or index-all.html in the root.
198      * @param rootURL the javadoc root
199      * @return true if the root is a valid Javadoc root
200      */

201     static boolean isValidLibraryJavadocRoot (final URL JavaDoc rootURL) {
202         assert rootURL != null && rootURL.toExternalForm().endsWith("/");
203         final FileObject root = URLMapper.findFileObject(rootURL);
204         if (root == null) {
205             return false;
206         }
207         return findIndexFolder (root,1) != null;
208     }
209
210     /**
211      * Search for the actual root of the Javadoc containing the index-all.html or
212      * index-files. In case when it is not able to find it, it returns the given Javadoc folder/file.
213      * @param URL Javadoc folder/file
214      * @return URL either the URL of folder containg the index or the given parameter if the index was not found.
215      */

216     private static URL JavaDoc getIndexFolder (URL JavaDoc rootURL) {
217         if (rootURL == null) {
218             return null;
219         }
220         FileObject root = URLMapper.findFileObject(rootURL);
221         if (root == null) {
222             return rootURL;
223         }
224         FileObject result = findIndexFolder (root,1);
225         try {
226             return result == null ? rootURL : result.getURL();
227         } catch (FileStateInvalidException e) {
228             ErrorManager.getDefault().notify(e);
229             return rootURL;
230         }
231     }
232     
233     private static FileObject findIndexFolder (FileObject fo, int depth) {
234         if (depth > MAX_DEPTH) {
235             return null;
236         }
237         if (fo.getFileObject("index-files",null)!=null || fo.getFileObject("index-all.html",null)!=null) { //NOI18N
238
return fo;
239         }
240         FileObject[] children = fo.getChildren();
241         for (int i=0; i< children.length; i++) {
242             if (children[i].isFolder()) {
243                 FileObject result = findIndexFolder(children[i], depth+1);
244                 if (result != null) {
245                     return result;
246                 }
247             }
248         }
249         return null;
250     }
251
252 }
253
Popular Tags