📄 depend.java
字号:
* @exception IOException if either the dependencies cache or the class * files cannot be read or written */ private void determineDependencies() throws IOException { affectedClassMap = new Hashtable(); classFileInfoMap = new Hashtable(); boolean cacheDirty = false; Hashtable dependencyMap = new Hashtable(); File cacheFile = null; boolean cacheFileExists = true; long cacheLastModified = Long.MAX_VALUE; // read the dependency cache from the disk if (cache != null) { cacheFile = new File(cache, CACHE_FILE_NAME); cacheFileExists = cacheFile.exists(); cacheLastModified = cacheFile.lastModified(); if (cacheFileExists) { dependencyMap = readCachedDependencies(cacheFile); } } Enumeration classfileEnum = getClassFiles(destPath).elements(); while (classfileEnum.hasMoreElements()) { ClassFileInfo info = (ClassFileInfo) classfileEnum.nextElement(); log("Adding class info for " + info.className, Project.MSG_DEBUG); classFileInfoMap.put(info.className, info); Vector dependencyList = null; if (cache != null) { // try to read the dependency info from the map if it is // not out of date if (cacheFileExists && cacheLastModified > info.absoluteFile.lastModified()) { // depFile exists and is newer than the class file // need to get dependency list from the map. dependencyList = (Vector) dependencyMap.get(info.className); } } if (dependencyList == null) { // not cached - so need to read directly from the class file DependencyAnalyzer analyzer = new AntAnalyzer(); analyzer.addRootClass(info.className); analyzer.addClassPath(destPath); analyzer.setClosure(false); dependencyList = new Vector(); Enumeration depEnum = analyzer.getClassDependencies(); while (depEnum.hasMoreElements()) { dependencyList.addElement(depEnum.nextElement()); } cacheDirty = true; dependencyMap.put(info.className, dependencyList); } // This class depends on each class in the dependency list. For each // one of those, add this class into their affected classes list Enumeration depEnum = dependencyList.elements(); while (depEnum.hasMoreElements()) { String dependentClass = (String) depEnum.nextElement(); Hashtable affectedClasses = (Hashtable) affectedClassMap.get(dependentClass); if (affectedClasses == null) { affectedClasses = new Hashtable(); affectedClassMap.put(dependentClass, affectedClasses); } affectedClasses.put(info.className, info); } } classpathDependencies = null; Path checkPath = getCheckClassPath(); if (checkPath != null) { // now determine which jars each class depends upon classpathDependencies = new Hashtable(); AntClassLoader loader = getProject().createClassLoader(checkPath); Hashtable classpathFileCache = new Hashtable(); Object nullFileMarker = new Object(); for (Enumeration e = dependencyMap.keys(); e.hasMoreElements();) { String className = (String) e.nextElement(); Vector dependencyList = (Vector) dependencyMap.get(className); Hashtable dependencies = new Hashtable(); classpathDependencies.put(className, dependencies); Enumeration e2 = dependencyList.elements(); while (e2.hasMoreElements()) { String dependency = (String) e2.nextElement(); Object classpathFileObject = classpathFileCache.get(dependency); if (classpathFileObject == null) { classpathFileObject = nullFileMarker; if (!dependency.startsWith("java.") && !dependency.startsWith("javax.")) { URL classURL = loader.getResource(dependency.replace('.', '/') + ".class"); if (classURL != null) { if (classURL.getProtocol().equals("jar")) { String jarFilePath = classURL.getFile(); int classMarker = jarFilePath.indexOf('!'); jarFilePath = jarFilePath.substring(0, classMarker); if (jarFilePath.startsWith("file:")) { classpathFileObject = new File( FileUtils.getFileUtils().fromURI(jarFilePath)); } else { throw new IOException( "Bizarre nested path in jar: protocol: " + jarFilePath); } } else if (classURL.getProtocol().equals("file")) { classpathFileObject = new File( FileUtils.getFileUtils() .fromURI(classURL.toExternalForm())); } log("Class " + className + " depends on " + classpathFileObject + " due to " + dependency, Project.MSG_DEBUG); } } classpathFileCache.put(dependency, classpathFileObject); } if (classpathFileObject != nullFileMarker) { // we need to add this jar to the list for this class. File jarFile = (File) classpathFileObject; dependencies.put(jarFile, jarFile); } } } } // write the dependency cache to the disk if (cache != null && cacheDirty) { writeCachedDependencies(dependencyMap); } } /** * Delete all the class files which are out of date, by way of their * dependency on a class which is out of date * * @return the number of files deleted. */ private int deleteAllAffectedFiles() { int count = 0; for (Enumeration e = outOfDateClasses.elements(); e.hasMoreElements();) { String className = (String) e.nextElement(); count += deleteAffectedFiles(className); ClassFileInfo classInfo = (ClassFileInfo) classFileInfoMap.get(className); if (classInfo != null && classInfo.absoluteFile.exists()) { classInfo.absoluteFile.delete(); count++; } } return count; } /** * Delete all the class files of classes which depend on the given class * * @param className the name of the class whose dependent classes will be * deleted * @return the number of class files removed */ private int deleteAffectedFiles(String className) { int count = 0; Hashtable affectedClasses = (Hashtable) affectedClassMap.get(className); if (affectedClasses == null) { return count; } for (Enumeration e = affectedClasses.keys(); e.hasMoreElements();) { String affectedClass = (String) e.nextElement(); ClassFileInfo affectedClassInfo = (ClassFileInfo) affectedClasses.get(affectedClass); if (!affectedClassInfo.absoluteFile.exists()) { continue; } if (affectedClassInfo.sourceFile == null) { warnOutOfDateButNotDeleted(affectedClassInfo, affectedClass, className); continue; } log("Deleting file " + affectedClassInfo.absoluteFile.getPath() + " since " + className + " out of date", Project.MSG_VERBOSE); affectedClassInfo.absoluteFile.delete(); count++; if (closure) { count += deleteAffectedFiles(affectedClass); } else { // without closure we may delete an inner class but not the // top level class which would not trigger a recompile. if (affectedClass.indexOf("$") == -1) { continue; } // need to delete the main class String topLevelClassName = affectedClass.substring(0, affectedClass.indexOf("$")); log("Top level class = " + topLevelClassName, Project.MSG_VERBOSE); ClassFileInfo topLevelClassInfo = (ClassFileInfo) classFileInfoMap.get(topLevelClassName); if (topLevelClassInfo != null && topLevelClassInfo.absoluteFile.exists()) { log("Deleting file " + topLevelClassInfo.absoluteFile.getPath() + " since one of its inner classes was removed", Project.MSG_VERBOSE); topLevelClassInfo.absoluteFile.delete(); count++; if (closure) { count += deleteAffectedFiles(topLevelClassName); } } } } return count; } /** * warn when a class is out of date, but not deleted as its source is unknown. * MSG_WARN is the normal level, but we downgrade to MSG_VERBOSE for RMI files * if {@link #warnOnRmiStubs is false} * @param affectedClassInfo info about the affectd class * @param affectedClass the name of the affected .class file * @param className the file that is triggering the out of dateness */ private void warnOutOfDateButNotDeleted( ClassFileInfo affectedClassInfo, String affectedClass, String className) { if (affectedClassInfo.isUserWarned) { return; } int level = Project.MSG_WARN; if (!warnOnRmiStubs) { //downgrade warnings on RMI stublike classes, as they are generated //by rmic, so there is no need to tell the user that their source is //missing. if (isRmiStub(affectedClass, className)) { level = Project.MSG_VERBOSE; } } log("The class " + affectedClass + " in file " + affectedClassInfo.absoluteFile.getPath() + " is out of date due to " + className + " but has not been deleted because its source file" + " could not be determined", level); affectedClassInfo.isUserWarned = true; } /** * test for being an RMI stub * @param affectedClass class being tested * @param className possible origin of the RMI stub * @return whether the class affectedClass is a RMI stub */ private boolean isRmiStub(String affectedClass, String className) { return isStub(affectedClass, className, DefaultRmicAdapter.RMI_STUB_SUFFIX) || isStub(affectedClass, className, DefaultRmicAdapter.RMI_SKEL_SUFFIX) || isStub(affectedClass, className, WLRmic.RMI_STUB_SUFFIX) || isStub(affectedClass, className, WLRmic.RMI_SKEL_SUFFIX); } private boolean isStub(String affectedClass, String baseClass, String suffix) { return (baseClass + suffix).equals(affectedClass); } /** * Dump the dependency information loaded from the classes to the Ant log */ private void dumpDependencies() { log("Reverse Dependency Dump for " + affectedClassMap.size() + " classes:", Project.MSG_DEBUG); Enumeration classEnum = affectedClassMap.keys(); while (classEnum.hasMoreElements()) { String className = (String) classEnum.nextElement(); log(" Class " + className + " affects:", Project.MSG_DEBUG); Hashtable affectedClasses = (Hashtable) affectedClassMap.get(className); Enumeration affectedClassEnum = affectedClasses.keys(); while (affectedClassEnum.hasMoreElements()) { String affectedClass = (String) affectedClassEnum.nextElement(); ClassFileInfo info = (ClassFileInfo) affectedClasses.get(affectedClass); log(" " + affectedClass + " in " + info.absoluteFile.getPath(), Project.MSG_DEBUG); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -