1 19 20 package org.netbeans.modules.form.project; 21 22 import java.io.*; 23 import java.net.*; 24 import java.util.*; 25 import java.text.MessageFormat ; 26 27 import org.openide.ErrorManager; 28 import org.openide.filesystems.*; 29 import org.openide.util.Lookup; 30 import org.openide.util.NbBundle; 31 32 import org.netbeans.api.project.*; 33 import org.netbeans.api.project.ant.*; 34 import org.netbeans.api.project.libraries.Library; 35 import org.netbeans.api.project.libraries.LibraryManager; 36 import org.netbeans.api.java.classpath.ClassPath; 37 import org.netbeans.spi.java.classpath.support.ClassPathSupport; 38 import org.netbeans.api.java.queries.SourceForBinaryQuery; 39 import org.netbeans.spi.java.project.classpath.ProjectClassPathExtender; 40 41 46 47 public class ClassPathUtils { 48 49 private static Map loaders = new WeakHashMap(); 50 51 static final int UNSPECIFIED_CLASS = 0; static final int SYSTEM_CLASS = 1; static final int SYSTEM_CLASS_WITH_PROJECT = 2; 56 62 public static Class loadClass(String name, FileObject fileInProject) 63 throws ClassNotFoundException 64 { 65 return Class.forName(name, true, getFormClassLoader(fileInProject)); 66 } 68 69 public static boolean checkUserClass(String name, FileObject fileInProject) { 70 ClassPath classPath = ClassPath.getClassPath(fileInProject, ClassPath.EXECUTE); 71 if (classPath == null) 72 return false; 73 74 String fileName = name.replace('.', '/').concat(".class"); return classPath.findResource(fileName) != null; 76 } 77 78 private static FormClassLoader getFormClassLoader(FileObject fileInProject) { 79 Project p = FileOwnerQuery.getOwner(fileInProject); 80 FormClassLoader fcl = (FormClassLoader) loaders.get(p); 81 ClassLoader existingProjectCL = fcl != null ? fcl.getProjectClassLoader() : null; 82 ClassLoader newProjectCL = ProjectClassLoader.getUpToDateClassLoader( 83 fileInProject, existingProjectCL); 84 if (fcl == null || newProjectCL != existingProjectCL) { 85 fcl = new FormClassLoader(newProjectCL); 86 loaders.put(p, fcl); 87 } 88 return fcl; 89 } 90 91 static int getClassLoadingType(String className) { 92 int i = className.lastIndexOf("[L"); if (i != -1) 94 className = className.substring(i+2, className.length()-1); 95 if (isClassLoaderType(className, SYSTEM_CLASS)) 96 return SYSTEM_CLASS; 97 if (isClassLoaderType(className, SYSTEM_CLASS_WITH_PROJECT)) 98 return SYSTEM_CLASS_WITH_PROJECT; 99 return UNSPECIFIED_CLASS; 100 } 101 102 105 public static Class loadClass(ClassSource classSource) 106 throws ClassNotFoundException 107 { 108 String className = classSource.getClassName(); 109 if (className == null) 110 return null; 111 112 ClassLoader loader = null; 113 int cpRootCount = classSource.getCPRootCount(); 114 115 if (cpRootCount == 0) { 116 loader = (ClassLoader ) Lookup.getDefault().lookup(ClassLoader .class); 118 } 119 else try { 120 List urlList = new ArrayList(); 121 for (int i=0; i < cpRootCount; i++) { 122 String type = classSource.getCPRootType(i); 123 String name = classSource.getCPRootName(i); 124 125 if (ClassSource.JAR_SOURCE.equals(type)) { 126 File jarFile = new File(name); 127 urlList.add(FileUtil.getArchiveRoot(jarFile.toURI().toURL())); 128 } 129 else if (ClassSource.LIBRARY_SOURCE.equals(type)) { 130 Library lib = LibraryManager.getDefault().getLibrary(name); 131 if (lib != null) { 132 List content = lib.getContent("classpath"); for (Iterator it=content.iterator(); it.hasNext(); ) { 134 URL rootURL = (URL) it.next(); 135 if (FileUtil.isArchiveFile(rootURL)) 136 rootURL = FileUtil.getArchiveRoot(rootURL); 137 urlList.add(rootURL); 138 } 139 } 140 } 141 else if (ClassSource.PROJECT_SOURCE.equals(type)) { 142 File outputFile = new File(name); 143 URL rootURL = FileUtil.getArchiveRoot(outputFile.toURI().toURL()); 144 if (FileUtil.isArchiveFile(rootURL)) 145 rootURL = FileUtil.getArchiveRoot(rootURL); 146 urlList.add(rootURL); 147 } 148 } 149 150 if (urlList.size() > 0) { 151 URL[] roots = new URL[urlList.size()]; 152 urlList.toArray(roots); 153 loader = ClassPathSupport.createClassPath(roots).getClassLoader(true); 154 } 155 else return null; 156 } 157 catch (Exception ex) { IllegalArgumentException iae = new IllegalArgumentException (); 159 ErrorManager.getDefault().annotate(iae, ex); 160 throw iae; 161 } 163 164 return loader.loadClass(classSource.getClassName()); 165 } 166 167 173 public static ClassSource getProjectClassSource(FileObject fileInProject, 174 String classname) 175 { 176 Project project = FileOwnerQuery.getOwner(fileInProject); 177 if (project == null) 178 return null; 180 AntArtifact[] artifacts = 183 AntArtifactQuery.findArtifactsByType(project, "jar"); if (artifacts.length == 0) 185 return null; 187 String [] outputs = null; 188 189 for (int i=0; i < artifacts.length; i++) { 190 URI scriptLocation = artifacts[i].getScriptLocation().toURI(); 191 URI[] artifactLocations = artifacts[i].getArtifactLocations(); 192 for (int k=0; k < artifactLocations.length; k++) { 193 File outputFile = new File(scriptLocation.resolve(artifactLocations[k]).normalize()); 194 195 URL outputURL; 196 try { 197 outputURL = outputFile.toURI().toURL(); 198 } 199 catch (MalformedURLException ex) { continue; 201 } 202 203 if (FileUtil.isArchiveFile(outputURL)) 204 outputURL = FileUtil.getArchiveRoot(outputURL); 205 FileObject sourceRoots[] = 206 SourceForBinaryQuery.findSourceRoots(outputURL).getRoots(); 207 for (int j=0; j < sourceRoots.length; j++) 208 if (FileUtil.isParentOf(sourceRoots[j], fileInProject)) { 209 outputs = new String [] { outputFile.getAbsolutePath() }; 210 break; 211 } 212 if (outputs != null) 213 break; 214 } 215 } 216 217 if (outputs == null) { 218 223 if (!fileInProject.getExt().equals("class")) return null; 226 ArrayList outputList = new ArrayList(artifacts.length); 227 for (int i=0; i < artifacts.length; i++) { 228 URI[] artifactLocations = artifacts[i].getArtifactLocations(); 229 for (int j=0; j < artifactLocations.length; j++) { 230 File outputFile = new File( 231 artifacts[i].getScriptLocation().getParent() 232 + File.separator 233 + artifactLocations[j].getPath()); 234 outputList.add(outputFile.getAbsolutePath()); 235 } 236 } 237 outputs = (String [])outputList.toArray(new String [outputList.size()]); 238 } 239 240 String [] types = new String [outputs.length]; 241 for (int i=0; i < types.length; i++) 242 types[i] = ClassSource.PROJECT_SOURCE; 243 244 return new ClassSource(classname, types, outputs); 245 } 246 247 public static boolean isJava6ProjectPlatform(FileObject fileInProject) { 248 ClassPath classPath = ClassPath.getClassPath(fileInProject, ClassPath.BOOT); 249 if (classPath == null) 250 return false; 251 252 return classPath.findResource("javax/swing/GroupLayout.class") != null; } 254 255 257 public static boolean updateProject(FileObject fileInProject, 258 ClassSource classSource) 259 throws IOException 260 { 261 if (classSource.getCPRootCount() == 0) 262 return false; 264 Project project = FileOwnerQuery.getOwner(fileInProject); 265 if(project==null) 266 return false; 267 268 ProjectClassPathExtender projectClassPath = (ProjectClassPathExtender) 269 project.getLookup().lookup(ProjectClassPathExtender.class); 270 if (projectClassPath == null) 271 return false; 273 for (int i=0, n=classSource.getCPRootCount(); i < n; i++) { 274 String type = classSource.getCPRootType(i); 275 String name = classSource.getCPRootName(i); 276 277 if (ClassSource.JAR_SOURCE.equals(type)) { 278 FileObject jarFile = FileUtil.toFileObject(new File(name)); 279 projectClassPath.addArchiveFile(jarFile); 280 } 281 else if (ClassSource.LIBRARY_SOURCE.equals(type)) { 282 Library lib = LibraryManager.getDefault().getLibrary(name); 283 projectClassPath.addLibrary(lib); 284 } 285 else if (ClassSource.PROJECT_SOURCE.equals(type)) { 286 File jarFile = new File(name); 287 AntArtifact artifact = 288 AntArtifactQuery.findArtifactFromFile(jarFile); 289 if (artifact.getProject() != project) { 290 URI[] locs = artifact.getArtifactLocations(); 291 for (int y=0; y<locs.length; y++ ) { 292 projectClassPath.addAntArtifact(artifact, locs[y]); 293 } 294 } 295 } 296 } 297 298 return true; 299 } 300 301 304 public static String getClassSourceDescription(ClassSource classSource) { 305 if (classSource == null || classSource.getCPRootCount() == 0) { 306 String className = classSource.getClassName(); 307 if (className != null) { 308 if (className.startsWith("javax.") || className.startsWith("java.")) return getBundleString("MSG_StandardJDKSource"); if (className.startsWith("org.netbeans.")) return getBundleString("MSG_NetBeansSource"); } 314 } 315 else { 316 String type = classSource.getCPRootType(0); 317 String name = classSource.getCPRootName(0); 318 319 if (ClassSource.JAR_SOURCE.equals(type)) { 320 return MessageFormat.format( 321 getBundleString("FMT_JarSource"), new Object [] { name }); 323 } 324 else if (ClassSource.LIBRARY_SOURCE.equals(type)) { 325 Library lib = LibraryManager.getDefault().getLibrary(name); 326 return MessageFormat.format( 327 getBundleString("FMT_LibrarySource"), new Object [] { lib != null ? lib.getDisplayName() : name }); 329 } 330 else if (ClassSource.PROJECT_SOURCE.equals(type)) { 331 try { 332 Project project = FileOwnerQuery.getOwner(new File(name).toURI()); 333 return MessageFormat.format( 334 getBundleString("FMT_ProjectSource"), new Object [] { project == null ? name : 336 project.getProjectDirectory().getPath() 337 .replace('/', File.separatorChar) }); 338 } 339 catch (Exception ex) {} } 341 } 342 343 return getBundleString("MSG_UnspecifiedSource"); } 345 346 static String getBundleString(String key) { 347 return NbBundle.getBundle(ClassPathUtils.class).getString(key); 348 } 349 350 353 private static FileObject patternSystemFolder; 354 private static FileObject patternSystemWithProjectFolder; 355 356 private static List patternsSystem; 357 private static List patternsSystemWithProject; 358 359 private static final String CL_LAYER_BASE = "org-netbeans-modules-form/classloader/"; private static final String CL_SYSTEM_CLASS = "system"; private static final String CL_SYSTEM_CLASS_WITH_PROJECT = "system_with_project"; 363 private static boolean isClassLoaderType(String className, int clType) { 364 List list = getClassPatterns(clType); 365 if (list == null) 366 return false; 367 368 Iterator it = list.iterator(); 369 while (it.hasNext()) { 370 ClassPattern cp = (ClassPattern) it.next(); 371 switch (cp.type) { 372 case (ClassPattern.CLASS): 373 if (className.equals(cp.name)) 374 return true; 375 break; 376 case (ClassPattern.PACKAGE): 377 if (className.startsWith(cp.name) && (className.lastIndexOf('.') <= cp.name.length())) 378 return true; 379 break; 380 case (ClassPattern.PACKAGE_AND_SUBPACKAGES): 381 if (className.startsWith(cp.name)) 382 return true; 383 break; 384 } 385 } 386 return false; 387 } 388 389 private static List getClassPatterns(int clType) { 390 List list = null; 391 switch (clType) { 392 case SYSTEM_CLASS: 393 list = patternsSystem; 394 if (list == null) { 395 list = loadClassPatterns(getClassPatternsFolder(clType)); 396 patternsSystem = list; 397 } 398 break; 399 case SYSTEM_CLASS_WITH_PROJECT: 400 list = patternsSystemWithProject; 401 if (list == null) { 402 list = loadClassPatterns(getClassPatternsFolder(clType)); 403 patternsSystemWithProject = list; 404 } 405 break; 406 } 407 return list; 408 } 409 410 private static FileObject getClassPatternsFolder(int clType) { 411 FileObject folder = null; 412 switch (clType) { 413 case SYSTEM_CLASS: 414 folder = patternSystemFolder; 415 if (folder == null) { 416 folder = getClassPatternsFolder(CL_SYSTEM_CLASS); 417 if (folder == null) 418 return null; 419 folder.addFileChangeListener(new FileChangeAdapter() { 421 public void fileDataCreated(FileEvent ev) { 422 patternsSystem = null; 423 loaders.clear(); 424 } 425 public void fileDeleted(FileEvent ev) { 426 patternsSystem = null; 427 if (ev.getFile() == patternSystemFolder) { 428 patternSystemFolder.removeFileChangeListener(this); 429 patternSystemFolder = null; 430 } 431 loaders.clear(); 432 } 433 }); 434 patternSystemFolder = folder; 435 } 436 break; 437 case SYSTEM_CLASS_WITH_PROJECT: 438 folder = patternSystemWithProjectFolder; 439 if (folder == null) { 440 folder = getClassPatternsFolder(CL_SYSTEM_CLASS_WITH_PROJECT); 441 if (folder == null) 442 return null; 443 folder.addFileChangeListener(new FileChangeAdapter() { 445 public void fileDataCreated(FileEvent ev) { 446 patternsSystemWithProject = null; 447 loaders.clear(); 448 } 449 public void fileDeleted(FileEvent ev) { 450 patternsSystemWithProject = null; 451 if (ev.getFile() == patternSystemFolder) { 452 patternSystemWithProjectFolder.removeFileChangeListener(this); 453 patternSystemWithProjectFolder = null; 454 } 455 loaders.clear(); 456 } 457 }); 458 patternSystemWithProjectFolder = folder; 459 } 460 break; 461 } 462 return folder; 463 } 464 465 private static FileObject getClassPatternsFolder(String folderName) { 466 FileObject folder = null; 467 if (folderName != null) { 468 try { 469 folder = Repository.getDefault().getDefaultFileSystem() 470 .findResource(CL_LAYER_BASE + folderName); } 472 catch (Exception ex) { 473 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); 474 } 475 } 476 return folder; 477 } 478 479 private static List loadClassPatterns(FileObject folder) { 480 List list = new ArrayList(); 481 if (folder == null) 482 return list; 483 484 FileObject[] files = folder.getChildren(); 485 for (int i=0; i < files.length; i++) { 486 try { 487 BufferedReader r = new BufferedReader(new InputStreamReader(files[i].getInputStream())); 488 String line = r.readLine(); 489 while (line != null) { 490 if (!line.equals("")) { ClassPattern cp; 492 if (line.endsWith("**")) { cp = new ClassPattern(line.substring(0, line.length()-2), 494 ClassPattern.PACKAGE_AND_SUBPACKAGES); 495 } 496 else if (line.endsWith("*")) { cp = new ClassPattern(line.substring(0, line.length()-1), 498 ClassPattern.PACKAGE); 499 } 500 else { 501 cp = new ClassPattern(line, ClassPattern.CLASS); 502 } 503 list.add(cp); 504 } 505 line = r.readLine(); 506 } 507 } 508 catch (IOException ex) { 509 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); 510 } 511 } 512 return list; 513 } 514 515 private static class ClassPattern { 516 static final int CLASS = 0; 517 static final int PACKAGE = 1; 518 static final int PACKAGE_AND_SUBPACKAGES = 2; 519 String name; 520 int type; 521 522 ClassPattern(String name, int type) { 523 this.name = name; 524 this.type = type; 525 } 526 } 527 } 528 | Popular Tags |