1 19 20 package org.netbeans.modules.java.j2seplatform.libraries; 21 22 import java.io.DataInputStream ; 23 import java.io.IOException ; 24 import java.lang.ref.Reference ; 25 import java.lang.ref.SoftReference ; 26 import java.lang.ref.WeakReference ; 27 import java.net.URL ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 import java.util.Map ; 31 import java.util.WeakHashMap ; 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 46 public class J2SELibrarySourceLevelQueryImpl implements SourceLevelQueryImplementation { 47 48 private static final String JDK_12 = "1.2"; private static final String JDK_13 = "1.3"; private static final String JDK_14 = "1.4"; private static final String JDK_15 = "1.5"; private static final String JDK_UNKNOWN = ""; private static final String CLASS = "class"; 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 private Map sourceLevelCache = new WeakHashMap (); 64 65 private Reference lastUsedRoot; 67 private Reference lastUsedLibrary; 68 69 70 public J2SELibrarySourceLevelQueryImpl() { 71 } 72 73 public String 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 sourceRoots = libraries[i].getContent(J2SELibraryTypeProvider.VOLUME_TYPE_SRC); if (sourceRoots.size() == 0) { 85 continue; 86 } 87 ClassPath cp = ClassPathSupport.createClassPath((URL [])sourceRoots.toArray(new URL [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 getSourceLevel (Library lib) { 98 String slevel = (String )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 getSourceLevel (List 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 cpRoots) { 128 for (Iterator it = cpRoots.iterator(); it.hasNext();) { 129 FileObject root = URLMapper.findFileObject((URL )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 in = null; 164 try { 165 in = new DataInputStream (classFile.getInputStream()); 166 int magic = in.readInt(); 167 if (CF_MAGIC != magic) { 168 return CF_INVALID; 169 } 170 short minor = in.readShort(); short major = in.readShort(); 172 return major; 173 } catch (IOException e) { 174 return CF_INVALID; 175 } finally { 176 if (in != null) { 177 try { 178 in.close (); 179 } catch (IOException e) { 180 } 182 } 183 } 184 } 185 186 private synchronized void setLastUsedRoot (FileObject root, Library lib) { 187 this.lastUsedRoot = new SoftReference (root); 188 this.lastUsedLibrary = new WeakReference (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 |