protected boolean findSourceFiles( IResourceDelta sourceDelta, ClasspathMultiDirectory md, int segmentCount) throws CoreException { // When a package becomes a type or vice versa, expect 2 deltas, // one on the folder & one on the source file IResource resource = sourceDelta.getResource(); // remember that if inclusion & exclusion patterns change then a full build is done boolean isExcluded = (md.exclusionPatterns != null || md.inclusionPatterns != null) && Util.isExcluded(resource, md.inclusionPatterns, md.exclusionPatterns); switch (resource.getType()) { case IResource.FOLDER: if (isExcluded && md.inclusionPatterns == null) return true; // no need to go further with this delta since its children cannot be // included switch (sourceDelta.getKind()) { case IResourceDelta.ADDED: if (!isExcluded) { IPath addedPackagePath = resource.getFullPath().removeFirstSegments(segmentCount); createFolder( addedPackagePath, md.binaryFolder); // ensure package exists in the output folder // see if any known source file is from the same package... classpath already includes // new package if (this.sourceLocations.length > 1 && this.newState.isKnownPackage(addedPackagePath.toString())) { if (JavaBuilder.DEBUG) System.out.println( "Skipped dependents of added package " + addedPackagePath); // $NON-NLS-1$ } else { if (JavaBuilder.DEBUG) System.out.println("Found added package " + addedPackagePath); // $NON-NLS-1$ addDependentsOf(addedPackagePath, true); } } // $FALL-THROUGH$ collect all the source files case IResourceDelta.CHANGED: IResourceDelta[] children = sourceDelta.getAffectedChildren(); for (int i = 0, l = children.length; i < l; i++) if (!findSourceFiles(children[i], md, segmentCount)) return false; return true; case IResourceDelta.REMOVED: if (isExcluded) { // since this folder is excluded then there is nothing to delete (from this md), but // must walk any included subfolders children = sourceDelta.getAffectedChildren(); for (int i = 0, l = children.length; i < l; i++) if (!findSourceFiles(children[i], md, segmentCount)) return false; return true; } IPath removedPackagePath = resource.getFullPath().removeFirstSegments(segmentCount); if (this.sourceLocations.length > 1) { for (int i = 0, l = this.sourceLocations.length; i < l; i++) { if (this.sourceLocations[i].sourceFolder.getFolder(removedPackagePath).exists()) { // only a package fragment was removed, same as removing multiple source files createFolder( removedPackagePath, md.binaryFolder); // ensure package exists in the output folder IResourceDelta[] removedChildren = sourceDelta.getAffectedChildren(); for (int j = 0, m = removedChildren.length; j < m; j++) if (!findSourceFiles(removedChildren[j], md, segmentCount)) return false; return true; } } } if ((sourceDelta.getFlags() & IResourceDelta.MOVED_TO) != 0) { // same idea as moving a source file // see bug 163200 IResource movedFolder = this.javaBuilder.workspaceRoot.getFolder(sourceDelta.getMovedToPath()); JavaBuilder.removeProblemsAndTasksFor(movedFolder); } IFolder removedPackageFolder = md.binaryFolder.getFolder(removedPackagePath); if (removedPackageFolder.exists()) removedPackageFolder.delete(IResource.FORCE, null); // add dependents even when the package thinks it does not exist to be on the safe side if (JavaBuilder.DEBUG) System.out.println("Found removed package " + removedPackagePath); // $NON-NLS-1$ addDependentsOf(removedPackagePath, true); this.newState.removePackage(sourceDelta); } return true; case IResource.FILE: if (isExcluded) return true; String resourceName = resource.getName(); // GROOVY start // determine if this is a Groovy project final boolean isInterestingProject = LanguageSupportFactory.isInterestingProject(this.javaBuilder.getProject()); // GROOVY end // GROOVY start /* old { if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(resourceName)) { } new */ // GRECLIPSE-404 must call 'isJavaLikeFile' directly in order to make the Scala-Eclipse // plugin's weaving happy if ((!isInterestingProject && org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(resourceName) && !LanguageSupportFactory.isInterestingSourceFile(resourceName)) || (isInterestingProject && LanguageSupportFactory.isSourceFile(resourceName, isInterestingProject))) { // GROOVY end IPath typePath = resource.getFullPath().removeFirstSegments(segmentCount).removeFileExtension(); String typeLocator = resource.getProjectRelativePath().toString(); switch (sourceDelta.getKind()) { case IResourceDelta.ADDED: if (JavaBuilder.DEBUG) System.out.println("Compile this added source file " + typeLocator); // $NON-NLS-1$ this.sourceFiles.add(new SourceFile((IFile) resource, md, true)); String typeName = typePath.toString(); if (!this.newState.isDuplicateLocator( typeName, typeLocator)) { // adding dependents results in 2 duplicate errors if (JavaBuilder.DEBUG) System.out.println("Found added source file " + typeName); // $NON-NLS-1$ addDependentsOf(typePath, true); } return true; case IResourceDelta.REMOVED: char[][] definedTypeNames = this.newState.getDefinedTypeNamesFor(typeLocator); if (definedTypeNames == null) { // defined a single type matching typePath removeClassFile(typePath, md.binaryFolder); if ((sourceDelta.getFlags() & IResourceDelta.MOVED_TO) != 0) { // remove problems and tasks for a compilation unit that is being moved (to // another package or renamed) // if the target file is a compilation unit, the new cu will be recompiled // if the target file is a non-java resource, then markers are removed // see bug 2857 IResource movedFile = this.javaBuilder.workspaceRoot.getFile(sourceDelta.getMovedToPath()); JavaBuilder.removeProblemsAndTasksFor(movedFile); } } else { if (JavaBuilder.DEBUG) System.out.println( "Found removed source file " + typePath.toString()); // $NON-NLS-1$ addDependentsOf( typePath, true); // add dependents of the source file since it may be involved in a name // collision if (definedTypeNames.length > 0) { // skip it if it failed to successfully define a type IPath packagePath = typePath.removeLastSegments(1); for (int i = 0, l = definedTypeNames.length; i < l; i++) removeClassFile( packagePath.append(new String(definedTypeNames[i])), md.binaryFolder); } } this.newState.removeLocator(typeLocator); return true; case IResourceDelta.CHANGED: if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0 && (sourceDelta.getFlags() & IResourceDelta.ENCODING) == 0) return true; // skip it since it really isn't changed if (JavaBuilder.DEBUG) System.out.println( "Compile this changed source file " + typeLocator); // $NON-NLS-1$ this.sourceFiles.add(new SourceFile((IFile) resource, md, true)); } return true; } else if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(resourceName)) { // perform full build if a managed class file has been changed if (this.makeOutputFolderConsistent) { IPath typePath = resource.getFullPath().removeFirstSegments(segmentCount).removeFileExtension(); if (this.newState.isKnownType(typePath.toString())) { if (JavaBuilder.DEBUG) System.out.println( "MUST DO FULL BUILD. Found change to class file " + typePath); // $NON-NLS-1$ return false; } } return true; } else if (md.hasIndependentOutputFolder) { if (this.javaBuilder.filterExtraResource(resource)) return true; // copy all other resource deltas to the output folder IPath resourcePath = resource.getFullPath().removeFirstSegments(segmentCount); IResource outputFile = md.binaryFolder.getFile(resourcePath); switch (sourceDelta.getKind()) { case IResourceDelta.ADDED: if (outputFile.exists()) { if (JavaBuilder.DEBUG) System.out.println("Deleting existing file " + resourcePath); // $NON-NLS-1$ outputFile.delete(IResource.FORCE, null); } if (JavaBuilder.DEBUG) System.out.println("Copying added file " + resourcePath); // $NON-NLS-1$ createFolder( resourcePath.removeLastSegments(1), md.binaryFolder); // ensure package exists in the output folder copyResource(resource, outputFile); return true; case IResourceDelta.REMOVED: if (outputFile.exists()) { if (JavaBuilder.DEBUG) System.out.println("Deleting removed file " + resourcePath); // $NON-NLS-1$ outputFile.delete(IResource.FORCE, null); } return true; case IResourceDelta.CHANGED: if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0 && (sourceDelta.getFlags() & IResourceDelta.ENCODING) == 0) return true; // skip it since it really isn't changed if (outputFile.exists()) { if (JavaBuilder.DEBUG) System.out.println("Deleting existing file " + resourcePath); // $NON-NLS-1$ outputFile.delete(IResource.FORCE, null); } if (JavaBuilder.DEBUG) System.out.println("Copying changed file " + resourcePath); // $NON-NLS-1$ createFolder( resourcePath.removeLastSegments(1), md.binaryFolder); // ensure package exists in the output folder copyResource(resource, outputFile); } return true; } } return true; }
protected void copyExtraResourcesBack( ClasspathMultiDirectory sourceLocation, final boolean deletedAll) throws CoreException { // When, if ever, does a builder need to copy resources files (not .java or .class) into the // output folder? // If we wipe the output folder at the beginning of the build then all 'extra' resources must be // copied to the output folder. this.notifier.subTask(Messages.build_copyingResources); final int segmentCount = sourceLocation.sourceFolder.getFullPath().segmentCount(); final char[][] exclusionPatterns = sourceLocation.exclusionPatterns; final char[][] inclusionPatterns = sourceLocation.inclusionPatterns; final IContainer outputFolder = sourceLocation.binaryFolder; final boolean isAlsoProject = sourceLocation.sourceFolder.equals(this.javaBuilder.currentProject); // GROOVY start final boolean isInterestingProject = LanguageSupportFactory.isInterestingProject(javaBuilder.getProject()); // GROOVY end sourceLocation.sourceFolder.accept( new IResourceProxyVisitor() { public boolean visit(IResourceProxy proxy) throws CoreException { IResource resource = null; switch (proxy.getType()) { case IResource.FILE: /* GROOVY start // original if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(proxy.getName()) || org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(proxy.getName())) return false; // new */ // copy groovy files if not in a groovy project // Also, must keep the call to 'isJavaLikeFileName' to keep Scala plugin happy: // GRECLIPSE-404 // here it is the same test as above, except if ((LanguageSupportFactory.isSourceFile(proxy.getName(), isInterestingProject) && org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName( proxy.getName())) || org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(proxy.getName())) return false; // GROOVY end resource = proxy.requestResource(); if (BatchImageBuilder.this.javaBuilder.filterExtraResource(resource)) return false; if (exclusionPatterns != null || inclusionPatterns != null) if (Util.isExcluded( resource.getFullPath(), inclusionPatterns, exclusionPatterns, false)) return false; IPath partialPath = resource.getFullPath().removeFirstSegments(segmentCount); IResource copiedResource = outputFolder.getFile(partialPath); if (copiedResource.exists()) { if (deletedAll) { IResource originalResource = findOriginalResource(partialPath); String id = originalResource.getFullPath().removeFirstSegments(1).toString(); createProblemFor( resource, null, Messages.bind(Messages.build_duplicateResource, id), BatchImageBuilder.this.javaBuilder.javaProject.getOption( JavaCore.CORE_JAVA_BUILD_DUPLICATE_RESOURCE, true)); return false; } copiedResource.delete(IResource.FORCE, null); // last one wins } createFolder( partialPath.removeLastSegments(1), outputFolder); // ensure package folder exists copyResource(resource, copiedResource); return false; case IResource.FOLDER: resource = proxy.requestResource(); if (BatchImageBuilder.this.javaBuilder.filterExtraResource(resource)) return false; if (isAlsoProject && isExcludedFromProject(resource.getFullPath())) return false; // the sourceFolder == project if (exclusionPatterns != null && inclusionPatterns == null) // must walk children if inclusionPatterns != null if (Util.isExcluded(resource.getFullPath(), null, exclusionPatterns, true)) return false; } return true; } }, IResource.NONE); }