/** @see ICodeAssist#codeSelect(int, int, WorkingCopyOwner) */
  public IJavaElement[] codeSelect(int offset, int length, WorkingCopyOwner owner)
      throws JavaModelException {
    IBuffer buffer = getBuffer();
    char[] contents;
    if (buffer != null && (contents = buffer.getCharacters()) != null) {
      BinaryType type = (BinaryType) getType();
      // GROOVY start
      /*old{
      BasicCompilationUnit cu = new BasicCompilationUnit(contents, null, type.sourceFileName((IBinaryType) type.getElementInfo()));
      }new*/

      // handle code select for Groovy files differently
      IBinaryType typeInfo = (IBinaryType) type.getElementInfo();
      if (LanguageSupportFactory.isInterestingBinary(type, typeInfo)) {
        return LanguageSupportFactory.binaryCodeSelect(this, offset, length, owner);
      }
      BasicCompilationUnit cu =
          new BasicCompilationUnit(contents, null, type.sourceFileName(typeInfo));
      // GROOVY end
      return super.codeSelect(cu, offset, length, owner);
    } else {
      // has no associated souce
      return new IJavaElement[] {};
    }
  }
  /**
   * Updates the content of <code>cu</code>, modifying the type name and/or package declaration as
   * necessary.
   *
   * @return an AST rewrite or null if no rewrite needed
   */
  private TextEdit updateContent(ICompilationUnit cu, PackageFragment dest, String newName)
      throws JavaModelException {
    String[] currPackageName = ((PackageFragment) cu.getParent()).names;
    String[] destPackageName = dest.names;
    if (Util.equalArraysOrNull(currPackageName, destPackageName) && newName == null) {
      return null; // nothing to change
    } else {
      // ensure cu is consistent (noop if already consistent)
      cu.makeConsistent(this.progressMonitor);

      // GROOVY start
      // don't use the ASTParser if not a Java compilation unit
      if (LanguageSupportFactory.isInterestingSourceFile(cu.getElementName())) {
        // ZALUUM
        // old return updateNonJavaContent(cu, destPackageName, currPackageName, newName);
        return LanguageSupportFactory.updateContent(cu, destPackageName, currPackageName, newName);
        // END ZALUUM
      }
      // GROOVY end

      this.parser.setSource(cu);
      CompilationUnit astCU = (CompilationUnit) this.parser.createAST(this.progressMonitor);
      AST ast = astCU.getAST();
      ASTRewrite rewrite = ASTRewrite.create(ast);
      updateTypeName(cu, astCU, cu.getElementName(), newName, rewrite);
      updatePackageStatement(astCU, destPackageName, rewrite, cu);
      return rewrite.rewriteAST();
    }
  }
  public static void checkSanity(int expectMinor) throws BundleException {
    Bundle bundle = CompilerUtils.getActiveGroovyBundle();
    assertNotNull("No active Groovy bundle found", bundle);
    assertEquals(
        "Wrong version for groovy bundle: " + bundle.getVersion(),
        expectMinor,
        bundle.getVersion().getMinor());
    if (bundle.getState() != Bundle.ACTIVE) {
      bundle.start();
    }

    bundle = Platform.getBundle("org.eclipse.jdt.core");
    final String qualifier = bundle.getVersion().getQualifier();
    // TODO: the conditions below should be activated... or test will break on non E_3_6 builds...
    // for now leave like this
    // to be 100% sure sanity checks are really executed!
    //		if (StsTestUtil.isOnBuildSite() && StsTestUtil.ECLIPSE_3_6_OR_LATER) {
    assertTrue(
        "JDT patch not properly installed (org.eclipse.jdt.core version = "
            + bundle.getVersion()
            + ")",
        qualifier.contains("xx") || qualifier.equals("qualifier"));
    //		}
    if (bundle.getState() != Bundle.ACTIVE) {
      bundle.start();
    }
    assertTrue(
        "Groovy language support is not active",
        LanguageSupportFactory.getEventHandler()
            .getClass()
            .getName()
            .endsWith("GroovyEventHandler"));
  }
Exemple #4
0
 public void initializeParser() {
   // GROOVY start
   /* old
   this.parser = new Parser(this.problemReporter, this.options.parseLiteralExpressionsAsConstants);
   // new */
   this.parser =
       LanguageSupportFactory.getParser(
           this,
           this.lookupEnvironment == null ? null : this.lookupEnvironment.globalOptions,
           this.problemReporter,
           this.options.parseLiteralExpressionsAsConstants,
           1);
   // GROOVY end
 }
  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;
  }
  /**
   * Copies/moves a package fragment with the name <code>newName</code> to the destination package.
   * <br>
   *
   * @exception JavaModelException if the operation is unable to complete
   */
  private void processPackageFragmentResource(
      PackageFragment source, PackageFragmentRoot root, String newName) throws JavaModelException {
    try {
      String[] newFragName = (newName == null) ? source.names : Util.getTrimmedSimpleNames(newName);
      PackageFragment newFrag = root.getPackageFragment(newFragName);
      IResource[] resources = collectResourcesOfInterest(source);

      // if isMove() can we move the folder itself ? (see
      // http://bugs.eclipse.org/bugs/show_bug.cgi?id=22458)
      boolean shouldMoveFolder =
          isMove() && !newFrag.resource().exists(); // if new pkg fragment exists, it is an override
      IFolder srcFolder = (IFolder) source.resource();
      IPath destPath = newFrag.getPath();
      if (shouldMoveFolder) {
        // check if destination is not included in source
        if (srcFolder.getFullPath().isPrefixOf(destPath)) {
          shouldMoveFolder = false;
        } else {
          // check if there are no sub-packages
          IResource[] members = srcFolder.members();
          for (int i = 0; i < members.length; i++) {
            if (members[i] instanceof IFolder) {
              shouldMoveFolder = false;
              break;
            }
          }
        }
      }
      boolean containsReadOnlySubPackageFragments =
          createNeededPackageFragments(
              (IContainer) source.parent.resource(), root, newFragName, shouldMoveFolder);
      boolean sourceIsReadOnly = Util.isReadOnly(srcFolder);

      // Process resources
      if (shouldMoveFolder) {
        // move underlying resource
        // TODO Revisit once bug 43044 is fixed
        if (sourceIsReadOnly) {
          Util.setReadOnly(srcFolder, false);
        }
        srcFolder.move(destPath, this.force, true /* keep history */, getSubProgressMonitor(1));
        if (sourceIsReadOnly) {
          Util.setReadOnly(srcFolder, true);
        }
        setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
      } else {
        // process the leaf resources
        if (resources.length > 0) {
          if (isRename()) {
            if (!destPath.equals(source.getPath())) {
              moveResources(resources, destPath);
            }
          } else if (isMove()) {
            // we need to delete this resource if this operation wants to override existing
            // resources
            for (int i = 0, max = resources.length; i < max; i++) {
              IResource destinationResource =
                  ResourcesPlugin.getWorkspace()
                      .getRoot()
                      .findMember(destPath.append(resources[i].getName()));
              if (destinationResource != null) {
                if (this.force) {
                  deleteResource(destinationResource, IResource.KEEP_HISTORY);
                } else {
                  throw new JavaModelException(
                      new JavaModelStatus(
                          IJavaModelStatusConstants.NAME_COLLISION,
                          Messages.bind(
                              Messages.status_nameCollision,
                              destinationResource.getFullPath().toString())));
                }
              }
            }
            moveResources(resources, destPath);
          } else {
            // we need to delete this resource if this operation wants to override existing
            // resources
            for (int i = 0, max = resources.length; i < max; i++) {
              IResource destinationResource =
                  ResourcesPlugin.getWorkspace()
                      .getRoot()
                      .findMember(destPath.append(resources[i].getName()));
              if (destinationResource != null) {
                if (this.force) {
                  // we need to delete this resource if this operation wants to override existing
                  // resources
                  deleteResource(destinationResource, IResource.KEEP_HISTORY);
                } else {
                  throw new JavaModelException(
                      new JavaModelStatus(
                          IJavaModelStatusConstants.NAME_COLLISION,
                          Messages.bind(
                              Messages.status_nameCollision,
                              destinationResource.getFullPath().toString())));
                }
              }
            }
            copyResources(resources, destPath);
          }
        }
      }

      // Update package statement in compilation unit if needed
      if (!Util.equalArraysOrNull(
          newFragName, source.names)) { // if package has been renamed, update the compilation units
        char[][] inclusionPatterns = root.fullInclusionPatternChars();
        char[][] exclusionPatterns = root.fullExclusionPatternChars();
        for (int i = 0; i < resources.length; i++) {
          String resourceName = resources[i].getName();
          if (Util.isJavaLikeFileName(resourceName)) {
            // we only consider potential compilation units
            ICompilationUnit cu = newFrag.getCompilationUnit(resourceName);
            // ZALUUM
            TextEdit edits;
            if (LanguageSupportFactory.isInterestingSourceFile(resourceName)) {
              edits = LanguageSupportFactory.updateContent(cu, newFragName, source.names, null);
            } else {
              if (Util.isExcluded(
                  cu.getPath(), inclusionPatterns, exclusionPatterns, false /* not a folder */))
                continue;
              this.parser.setSource(cu);
              CompilationUnit astCU = (CompilationUnit) this.parser.createAST(this.progressMonitor);
              AST ast = astCU.getAST();
              ASTRewrite rewrite = ASTRewrite.create(ast);
              updatePackageStatement(astCU, newFragName, rewrite, cu);
              edits = rewrite.rewriteAST();
            }
            // END ZALUUM
            applyTextEdit(cu, edits);
            cu.save(null, false);
          }
        }
      }

      // Discard empty old package (if still empty after the rename)
      boolean isEmpty = true;
      if (isMove()) {
        // delete remaining files in this package (.class file in the case where Proj=src=bin)
        // in case of a copy
        updateReadOnlyPackageFragmentsForMove(
            (IContainer) source.parent.resource(), root, newFragName, sourceIsReadOnly);
        if (srcFolder.exists()) {
          IResource[] remaining = srcFolder.members();
          for (int i = 0, length = remaining.length; i < length; i++) {
            IResource file = remaining[i];
            if (file instanceof IFile) {
              if (Util.isReadOnly(file)) {
                Util.setReadOnly(file, false);
              }
              deleteResource(file, IResource.FORCE | IResource.KEEP_HISTORY);
            } else {
              isEmpty = false;
            }
          }
        }
        if (isEmpty) {
          IResource rootResource;
          // check if source is included in destination
          if (destPath.isPrefixOf(srcFolder.getFullPath())) {
            rootResource = newFrag.resource();
          } else {
            rootResource = source.parent.resource();
          }

          // delete recursively empty folders
          deleteEmptyPackageFragment(source, false, rootResource);
        }
      } else if (containsReadOnlySubPackageFragments) {
        // in case of a copy
        updateReadOnlyPackageFragmentsForCopy(
            (IContainer) source.parent.resource(), root, newFragName);
      }
      // workaround for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=24505
      if (isEmpty && isMove() && !(Util.isExcluded(source) || Util.isExcluded(newFrag))) {
        IJavaProject sourceProject = source.getJavaProject();
        getDeltaFor(sourceProject).movedFrom(source, newFrag);
        IJavaProject destProject = newFrag.getJavaProject();
        getDeltaFor(destProject).movedTo(newFrag, source);
      }
    } catch (JavaModelException e) {
      throw e;
    } catch (CoreException ce) {
      throw new JavaModelException(ce);
    }
  }
  /**
   * Copies/moves a compilation unit with the name <code>newCUName</code> to the destination
   * package.<br>
   * The package statement in the compilation unit is updated if necessary. The main type of the
   * compilation unit is renamed if necessary.
   *
   * @exception JavaModelException if the operation is unable to complete
   */
  private void processCompilationUnitResource(ICompilationUnit source, PackageFragment dest)
      throws JavaModelException {
    String newCUName = getNewNameFor(source);
    String destName = (newCUName != null) ? newCUName : source.getElementName();
    TextEdit edit = updateContent(source, dest, newCUName); // null if unchanged

    // TODO (frederic) remove when bug 67606 will be fixed (bug 67823)
    // store encoding (fix bug 66898)
    IFile sourceResource = (IFile) source.getResource();
    String sourceEncoding = null;
    try {
      sourceEncoding = sourceResource.getCharset(false);
    } catch (CoreException ce) {
      // no problem, use default encoding
    }
    // end todo
    // copy resource
    IContainer destFolder = (IContainer) dest.getResource(); // can be an IFolder or an IProject
    IFile destFile = destFolder.getFile(new Path(destName));
    // GROOVY start
    /* old {
    org.eclipse.jdt.internal.core.CompilationUnit destCU = new org.eclipse.jdt.internal.core.CompilationUnit(dest, destName, DefaultWorkingCopyOwner.PRIMARY);
       } new */
    org.eclipse.jdt.internal.core.CompilationUnit destCU =
        LanguageSupportFactory.newCompilationUnit(dest, destName, DefaultWorkingCopyOwner.PRIMARY);
    // GROOVY end

    if (!destFile.equals(sourceResource)) {
      try {
        if (!destCU.isWorkingCopy()) {
          if (destFile.exists()) {
            if (this.force) {
              // we can remove it
              deleteResource(destFile, IResource.KEEP_HISTORY);
              destCU.close(); // ensure the in-memory buffer for the dest CU is closed
            } else {
              // abort
              throw new JavaModelException(
                  new JavaModelStatus(
                      IJavaModelStatusConstants.NAME_COLLISION,
                      Messages.bind(
                          Messages.status_nameCollision, destFile.getFullPath().toString())));
            }
          }
          int flags = this.force ? IResource.FORCE : IResource.NONE;
          if (isMove()) {
            flags |= IResource.KEEP_HISTORY;
            sourceResource.move(destFile.getFullPath(), flags, getSubProgressMonitor(1));
          } else {
            if (edit != null) flags |= IResource.KEEP_HISTORY;
            sourceResource.copy(destFile.getFullPath(), flags, getSubProgressMonitor(1));
          }
          setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
        } else {
          destCU.getBuffer().setContents(source.getBuffer().getContents());
        }
      } catch (JavaModelException e) {
        throw e;
      } catch (CoreException e) {
        throw new JavaModelException(e);
      }

      // update new resource content
      if (edit != null) {
        boolean wasReadOnly = destFile.isReadOnly();
        try {
          saveContent(dest, destName, edit, sourceEncoding, destFile);
        } catch (CoreException e) {
          if (e instanceof JavaModelException) throw (JavaModelException) e;
          throw new JavaModelException(e);
        } finally {
          Util.setReadOnly(destFile, wasReadOnly);
        }
      }

      // register the correct change deltas
      prepareDeltas(source, destCU, isMove());
      if (newCUName != null) {
        // the main type has been renamed
        String oldName = Util.getNameWithoutJavaLikeExtension(source.getElementName());
        String newName = Util.getNameWithoutJavaLikeExtension(newCUName);
        prepareDeltas(source.getType(oldName), destCU.getType(newName), isMove());
      }
    } else {
      if (!this.force) {
        throw new JavaModelException(
            new JavaModelStatus(
                IJavaModelStatusConstants.NAME_COLLISION,
                Messages.bind(Messages.status_nameCollision, destFile.getFullPath().toString())));
      }
      // update new resource content
      // in case we do a saveas on the same resource we have to simply update the contents
      // see http://dev.eclipse.org/bugs/show_bug.cgi?id=9351
      if (edit != null) {
        saveContent(dest, destName, edit, sourceEncoding, destFile);
      }
    }
  }
  protected void cleanOutputFolders(boolean copyBack) throws CoreException {
    boolean deleteAll =
        JavaCore.CLEAN.equals(
            this.javaBuilder.javaProject.getOption(
                JavaCore.CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER, true));
    if (deleteAll) {
      if (this.javaBuilder.participants != null)
        for (int i = 0, l = this.javaBuilder.participants.length; i < l; i++)
          this.javaBuilder.participants[i].cleanStarting(this.javaBuilder.javaProject);

      ArrayList visited = new ArrayList(this.sourceLocations.length);
      for (int i = 0, l = this.sourceLocations.length; i < l; i++) {
        this.notifier.subTask(
            Messages.bind(
                Messages.build_cleaningOutput, this.javaBuilder.currentProject.getName()));
        ClasspathMultiDirectory sourceLocation = this.sourceLocations[i];
        if (sourceLocation.hasIndependentOutputFolder) {
          IContainer outputFolder = sourceLocation.binaryFolder;
          if (!visited.contains(outputFolder)) {
            visited.add(outputFolder);
            IResource[] members = outputFolder.members();
            for (int j = 0, m = members.length; j < m; j++) {
              IResource member = members[j];
              if (!member.isDerived()) {
                member.accept(
                    new IResourceVisitor() {
                      public boolean visit(IResource resource) throws CoreException {
                        resource.setDerived(true, null);
                        return resource.getType() != IResource.FILE;
                      }
                    });
              }
              member.delete(IResource.FORCE, null);
            }
          }
          this.notifier.checkCancel();
          if (copyBack) copyExtraResourcesBack(sourceLocation, true);
        } else {
          boolean isOutputFolder = sourceLocation.sourceFolder.equals(sourceLocation.binaryFolder);
          final char[][] exclusionPatterns =
              isOutputFolder
                  ? sourceLocation.exclusionPatterns
                  : null; // ignore exclusionPatterns if output folder == another source folder...
                          // not this one
          final char[][] inclusionPatterns =
              isOutputFolder
                  ? sourceLocation.inclusionPatterns
                  : null; // ignore inclusionPatterns if output folder == another source folder...
                          // not this one
          sourceLocation.binaryFolder.accept(
              new IResourceProxyVisitor() {
                public boolean visit(IResourceProxy proxy) throws CoreException {
                  if (proxy.getType() == IResource.FILE) {
                    if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(
                        proxy.getName())) {
                      IResource resource = proxy.requestResource();
                      if (exclusionPatterns != null || inclusionPatterns != null)
                        if (Util.isExcluded(
                            resource.getFullPath(), inclusionPatterns, exclusionPatterns, false))
                          return false;
                      if (!resource.isDerived()) resource.setDerived(true, null);
                      resource.delete(IResource.FORCE, null);
                    }
                    return false;
                  }
                  if (exclusionPatterns != null
                      && inclusionPatterns
                          == null) // must walk children if inclusionPatterns != null
                  if (Util.isExcluded(proxy.requestFullPath(), null, exclusionPatterns, true))
                      return false;
                  BatchImageBuilder.this.notifier.checkCancel();
                  return true;
                }
              },
              IResource.NONE);
          this.notifier.checkCancel();
        }
        this.notifier.checkCancel();
      }
    } else if (copyBack) {
      for (int i = 0, l = this.sourceLocations.length; i < l; i++) {
        ClasspathMultiDirectory sourceLocation = this.sourceLocations[i];
        if (sourceLocation.hasIndependentOutputFolder)
          copyExtraResourcesBack(sourceLocation, false);
        this.notifier.checkCancel();
      }
    }
    // GROOVY start
    LanguageSupportFactory.getEventHandler()
        .handle(this.javaBuilder.javaProject, "cleanOutputFolders");
    // GROOVY end
  }
  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);
  }