KickJava   Java API By Example, From Geeks To Geeks.

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


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.io.DataInputStream JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.lang.ref.Reference JavaDoc;
25 import java.lang.ref.SoftReference JavaDoc;
26 import java.lang.ref.WeakReference JavaDoc;
27 import java.net.URL JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.List JavaDoc;
30 import java.util.Map JavaDoc;
31 import java.util.WeakHashMap JavaDoc;
32
33 import org.netbeans.api.java.classpath.ClassPath;
34 import org.netbeans.api.project.libraries.Library;
35 import org.netbeans.api.project.libraries.LibraryManager;
36 import org.netbeans.spi.java.classpath.support.ClassPathSupport;
37 import org.netbeans.spi.java.queries.SourceLevelQueryImplementation;
38 import org.openide.filesystems.FileObject;
39 import org.openide.filesystems.FileUtil;
40 import org.openide.filesystems.URLMapper;
41
42 /**
43  *
44  * @author tom
45  */

46 public class J2SELibrarySourceLevelQueryImpl implements SourceLevelQueryImplementation {
47     
48     private static final String JavaDoc JDK_12 = "1.2"; //NOI18N
49
private static final String JavaDoc JDK_13 = "1.3"; //NOI18N
50
private static final String JavaDoc JDK_14 = "1.4"; //NOI18N
51
private static final String JavaDoc JDK_15 = "1.5"; //NOI18N
52
private static final String JavaDoc JDK_UNKNOWN = ""; //NOI18N
53
private static final String JavaDoc CLASS = "class"; //NOI18N
54
private static final int CF_MAGIC = 0xCAFEBABE;
55     private static final int CF_INVALID = -1;
56     private static final int CF_11 = 0x2d;
57     private static final int CF_12 = 0x2e;
58     private static final int CF_13 = 0x2f;
59     private static final int CF_14 = 0x30;
60     private static final int CF_15 = 0x31;
61     
62     //Cache for source level
63
private Map JavaDoc/*<Library, sourceLevel>*/ sourceLevelCache = new WeakHashMap JavaDoc ();
64     
65     //Cache for last used library, helps since queries are sequential
66
private /*Soft*/Reference JavaDoc lastUsedRoot;
67     private /*Weak*/Reference JavaDoc lastUsedLibrary;
68     
69     /** Creates a new instance of J2SELibrarySourceLevelQueryImpl */
70     public J2SELibrarySourceLevelQueryImpl() {
71     }
72     
73     public String JavaDoc getSourceLevel(org.openide.filesystems.FileObject javaFile) {
74         Library ll = this.isLastUsed (javaFile);
75         if (ll != null) {
76             return getSourceLevel (ll);
77         }
78         Library[] libraries = LibraryManager.getDefault().getLibraries();
79         for (int i=0; i< libraries.length; i++) {
80             if (!J2SELibraryTypeProvider.LIBRARY_TYPE.equalsIgnoreCase(libraries[i].getType())) {
81                 continue;
82             }
83             List JavaDoc sourceRoots = libraries[i].getContent(J2SELibraryTypeProvider.VOLUME_TYPE_SRC); //NOI18N
84
if (sourceRoots.size() == 0) {
85                 continue;
86             }
87             ClassPath cp = ClassPathSupport.createClassPath((URL JavaDoc[])sourceRoots.toArray(new URL JavaDoc[sourceRoots.size()]));
88             FileObject root;
89             if ((root = cp.findOwnerRoot(javaFile)) != null) {
90                 setLastUsedRoot (root, libraries[i]);
91                 return getSourceLevel(libraries[i]);
92             }
93         }
94         return null;
95     }
96     
97     private String JavaDoc getSourceLevel (Library lib) {
98         String JavaDoc slevel = (String JavaDoc)this.sourceLevelCache.get (lib);
99         if (slevel == null) {
100             slevel = getSourceLevel (lib.getContent(J2SELibraryTypeProvider.VOLUME_TYPE_CLASSPATH));
101             this.sourceLevelCache.put (lib,slevel);
102         }
103         return slevel == JDK_UNKNOWN ? null : slevel;
104     }
105     
106     private String JavaDoc getSourceLevel (List JavaDoc cpRoots) {
107         FileObject classFile = getClassFile (cpRoots);
108         if (classFile == null) {
109             return JDK_UNKNOWN;
110         }
111         int version = getClassFileMajorVersion (classFile);
112         if (version == CF_11 || version == CF_12) {
113             return JDK_12;
114         }
115         else if (version == CF_13) {
116             return JDK_13;
117         }
118         else if (version == CF_14) {
119             return JDK_14;
120         }
121         else if (version >= CF_15) {
122             return JDK_15;
123         }
124         return JDK_UNKNOWN;
125     }
126     
127     private FileObject getClassFile (List JavaDoc cpRoots) {
128         for (Iterator JavaDoc it = cpRoots.iterator(); it.hasNext();) {
129             FileObject root = URLMapper.findFileObject((URL JavaDoc)it.next());
130             if (root == null) {
131                 continue;
132             }
133             FileObject cf = findClassFile (root);
134             if (cf != null) {
135                 return cf;
136             }
137         }
138         return null;
139     }
140     
141     private FileObject findClassFile (FileObject root) {
142         if (root.isData()) {
143             if (CLASS.equals(root.getExt())) {
144                 return root;
145             }
146             else {
147                 return null;
148             }
149         }
150         else {
151             FileObject[] children = root.getChildren();
152             for (int i=0; i<children.length; i++) {
153                 FileObject result = findClassFile(children[i]);
154                 if (result != null) {
155                     return result;
156                 }
157             }
158             return null;
159         }
160     }
161     
162     private int getClassFileMajorVersion (FileObject classFile) {
163         DataInputStream JavaDoc in = null;
164         try {
165             in = new DataInputStream JavaDoc (classFile.getInputStream());
166             int magic = in.readInt();
167             if (CF_MAGIC != magic) {
168                 return CF_INVALID;
169             }
170             short minor = in.readShort(); //Ignore it
171
short major = in.readShort();
172             return major;
173         } catch (IOException JavaDoc e) {
174             return CF_INVALID;
175         } finally {
176             if (in != null) {
177                 try {
178                     in.close ();
179                 } catch (IOException JavaDoc e) {
180                     //Ignore it, can not recover
181
}
182             }
183         }
184     }
185     
186     private synchronized void setLastUsedRoot (FileObject root, Library lib) {
187         this.lastUsedRoot = new SoftReference JavaDoc (root);
188         this.lastUsedLibrary = new WeakReference JavaDoc (lib);
189     }
190     
191     private synchronized Library isLastUsed (FileObject javaFile) {
192         if (lastUsedRoot == null) {
193             return null;
194         }
195         
196         FileObject root = (FileObject) lastUsedRoot.get ();
197         if (root == null) {
198             return null;
199         }
200         
201         if (root.equals(javaFile) || FileUtil.isParentOf(root,javaFile)) {
202             return (Library) lastUsedLibrary.get ();
203         }
204         return null;
205     }
206     
207 }
208
Popular Tags