/** * Add the list of class files from the given directory to the class file vector, including any * subdirectories. * * @param classFileList a list of ClassFileInfo objects for all the files in the diretcort tree * @param dir tyhe directory tree to be searched, recursivley, for class files * @param root the root of the source tree. This is used to determine the absoluate class name * from the relative position in the source tree */ private void addClassFiles(Vector classFileList, File dir, File root) { String[] filesInDir = dir.list(); if (filesInDir == null) { return; } int length = filesInDir.length; int rootLength = root.getPath().length(); for (int i = 0; i < length; ++i) { File file = new File(dir, filesInDir[i]); if (file.isDirectory()) { addClassFiles(classFileList, file, root); } else if (file.getName().endsWith(".class")) { ClassFileInfo info = new ClassFileInfo(); info.absoluteFile = file; String relativeName = file.getPath().substring(rootLength + 1, file.getPath().length() - 6); info.className = ClassFileUtils.convertSlashName(relativeName); info.sourceFile = findSourceFile(relativeName); classFileList.addElement(info); } } }
/** * Creates the children elements for this class file adding the resulting new handles and info * objects to the newElements table. Returns true if successful, or false if an error is * encountered parsing the class file. * * @see Openable * @see Signature */ protected boolean buildStructure( OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException { IBinaryType typeInfo = getBinaryTypeInfo((IFile) underlyingResource); if (typeInfo == null) { // The structure of a class file is unknown if a class file format errors occurred // during the creation of the diet class file representative of this ClassFile. info.setChildren(new IJavaElement[] {}); return false; } // Make the type IType type = getType(); info.setChildren(new IJavaElement[] {type}); newElements.put(type, typeInfo); // Read children ((ClassFileInfo) info).readBinaryChildren(this, (HashMap) newElements, typeInfo); return true; }
/** * Delete all the class files of classes which depend on the given class * * @param className the name of the class whose dependent classes willbe 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) { if (!affectedClassInfo.isUserWarned) { 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", Project.MSG_WARN); affectedClassInfo.isUserWarned = true; } 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; }