KickJava   Java API By Example, From Geeks To Geeks.

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


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
22 import java.beans.PropertyChangeEvent JavaDoc;
23 import java.beans.PropertyChangeListener JavaDoc;
24 import java.net.URL JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.HashMap JavaDoc;
30 import javax.swing.event.ChangeEvent JavaDoc;
31 import javax.swing.event.ChangeListener JavaDoc;
32 import org.netbeans.api.java.queries.SourceForBinaryQuery;
33 import org.netbeans.api.project.libraries.Library;
34 import org.netbeans.api.project.libraries.LibraryManager;
35 import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
36 import org.openide.ErrorManager;
37 import org.openide.filesystems.FileObject;
38 import org.openide.filesystems.FileStateInvalidException;
39 import org.openide.filesystems.FileUtil;
40 import org.openide.filesystems.URLMapper;
41 import org.openide.util.WeakListeners;
42
43 /**
44  * Finds the locations of sources for various libraries.
45  * @author Tomas Zezula
46  */

47 public class J2SELibrarySourceForBinaryQuery implements SourceForBinaryQueryImplementation {
48
49     private final Map JavaDoc/*<URL,SourceForBinaryQuery.Result>*/ cache = new HashMap JavaDoc();
50     private final Map JavaDoc/*<URL,URL>*/ normalizedURLCache = new HashMap JavaDoc();
51
52     /** Default constructor for lookup. */
53     public J2SELibrarySourceForBinaryQuery() {}
54
55     public SourceForBinaryQuery.Result findSourceRoots(URL JavaDoc binaryRoot) {
56         SourceForBinaryQuery.Result res = (SourceForBinaryQuery.Result) this.cache.get (binaryRoot);
57         if (res != null) {
58             return res;
59         }
60         boolean isNormalizedURL = isNormalizedURL(binaryRoot);
61         LibraryManager lm = LibraryManager.getDefault ();
62         Library[] libs = lm.getLibraries();
63         for (int i=0; i< libs.length; i++) {
64             String JavaDoc type = libs[i].getType ();
65             if (J2SELibraryTypeProvider.LIBRARY_TYPE.equalsIgnoreCase(type)) {
66                 List JavaDoc classes = libs[i].getContent(J2SELibraryTypeProvider.VOLUME_TYPE_CLASSPATH);
67                 for (Iterator JavaDoc it = classes.iterator(); it.hasNext();) {
68                     URL JavaDoc entry = (URL JavaDoc) it.next();
69                     URL JavaDoc normalizedEntry;
70                     if (isNormalizedURL) {
71                         normalizedEntry = getNormalizedURL(entry);
72                     }
73                     else {
74                         normalizedEntry = entry;
75                     }
76                     if (normalizedEntry != null && normalizedEntry.equals(binaryRoot)) {
77                         res = new Result(entry, libs[i]);
78                         cache.put (binaryRoot, res);
79                         return res;
80                     }
81                 }
82             }
83         }
84         return null;
85     }
86     
87     
88     private URL JavaDoc getNormalizedURL (URL JavaDoc url) {
89         //URL is already nornalized, return it
90
if (isNormalizedURL(url)) {
91             return url;
92         }
93         //Todo: Should listen on the LibrariesManager and cleanup cache
94
// in this case the search can use the cache onle and can be faster
95
// from O(n) to O(ln(n))
96
URL JavaDoc normalizedURL = (URL JavaDoc) this.normalizedURLCache.get (url);
97         if (normalizedURL == null) {
98             FileObject fo = URLMapper.findFileObject(url);
99             if (fo != null) {
100                 try {
101                     normalizedURL = fo.getURL();
102                     this.normalizedURLCache.put (url, normalizedURL);
103                 } catch (FileStateInvalidException e) {
104                     ErrorManager.getDefault().notify(e);
105                 }
106             }
107         }
108         return normalizedURL;
109     }
110     
111     /**
112      * Returns true if the given URL is file based, it is already
113      * resolved either into file URL or jar URL with file path.
114      * @param URL url
115      * @return true if the URL is normal
116      */

117     private static boolean isNormalizedURL (URL JavaDoc url) {
118         if ("jar".equals(url.getProtocol())) { //NOI18N
119
url = FileUtil.getArchiveFile(url);
120         }
121         return "file".equals(url.getProtocol()); //NOI18N
122
}
123     
124     
125     private static class Result implements SourceForBinaryQuery.Result, PropertyChangeListener JavaDoc {
126         
127         private Library lib;
128         private URL JavaDoc entry;
129         private ArrayList JavaDoc listeners;
130         private FileObject[] cache;
131         
132         public Result (URL JavaDoc queryFor, Library lib) {
133             this.entry = queryFor;
134             this.lib = lib;
135             this.lib.addPropertyChangeListener ((PropertyChangeListener JavaDoc)WeakListeners.create(PropertyChangeListener JavaDoc.class,this,this.lib));
136         }
137         
138         public synchronized FileObject[] getRoots () {
139             if (this.cache == null) {
140                 if (this.lib.getContent(J2SELibraryTypeProvider.VOLUME_TYPE_CLASSPATH).contains(entry)) {
141                     List JavaDoc src = this.lib.getContent(J2SELibraryTypeProvider.VOLUME_TYPE_SRC);
142                     List JavaDoc result = new ArrayList JavaDoc ();
143                     for (Iterator JavaDoc sit = src.iterator(); sit.hasNext();) {
144                         FileObject sourceRootURL = URLMapper.findFileObject((URL JavaDoc) sit.next());
145                         if (sourceRootURL!=null) {
146                             result.add (sourceRootURL);
147                         }
148                     }
149                     this.cache = (FileObject[]) result.toArray(new FileObject[result.size()]);
150                 }
151                 else {
152                     this.cache = new FileObject[0];
153                 }
154             }
155             return this.cache;
156         }
157         
158         public synchronized void addChangeListener (ChangeListener JavaDoc l) {
159             assert l != null : "Listener cannot be null"; // NOI18N
160
if (this.listeners == null) {
161                 this.listeners = new ArrayList JavaDoc ();
162             }
163             this.listeners.add (l);
164         }
165         
166         public synchronized void removeChangeListener (ChangeListener JavaDoc l) {
167             assert l != null : "Listener cannot be null"; // NOI18N
168
if (this.listeners == null) {
169                 return;
170             }
171             this.listeners.remove (l);
172         }
173         
174         public void propertyChange (PropertyChangeEvent JavaDoc event) {
175             if (Library.PROP_CONTENT.equals(event.getPropertyName())) {
176                 synchronized (this) {
177                     this.cache = null;
178                 }
179                 this.fireChange ();
180             }
181         }
182         
183         private void fireChange () {
184             Iterator JavaDoc it = null;
185             synchronized (this) {
186                 if (this.listeners == null) {
187                     return;
188                 }
189                 it = ((ArrayList JavaDoc)this.listeners.clone()).iterator();
190             }
191             ChangeEvent JavaDoc event = new ChangeEvent JavaDoc (this);
192             while (it.hasNext ()) {
193                 ((ChangeListener JavaDoc)it.next()).stateChanged(event);
194             }
195         }
196         
197     }
198     
199 }
200
Popular Tags