X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CopyResourceElementsOperation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CopyResourceElementsOperation.java new file mode 100644 index 0000000..2e30065 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CopyResourceElementsOperation.java @@ -0,0 +1,648 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import net.sourceforge.phpdt.core.IBuffer; +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaElementDelta; +import net.sourceforge.phpdt.core.IJavaModelStatus; +import net.sourceforge.phpdt.core.IJavaModelStatusConstants; +import net.sourceforge.phpdt.core.IJavaProject; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.IPackageFragmentRoot; +import net.sourceforge.phpdt.core.IType; +import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.jdom.DOMException; +import net.sourceforge.phpdt.core.jdom.DOMFactory; +import net.sourceforge.phpdt.core.jdom.IDOMCompilationUnit; +import net.sourceforge.phpdt.core.jdom.IDOMNode; +import net.sourceforge.phpdt.core.jdom.IDOMPackage; +import net.sourceforge.phpeclipse.PHPCore; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +/** + * This operation copies/moves/renames a collection of resources from their current + * container to a new container, optionally renaming the + * elements. + *
Notes:
DOMFactory
used to manipulate the source code of
+ * ICompilationUnit
.
+ */
+ protected DOMFactory fFactory;
+ /**
+ * The list of new resources created during this operation.
+ */
+ protected ArrayList fCreatedElements;
+ /**
+ * When executed, this operation will copy the given resources to the
+ * given containers. The resources and destination containers must be in
+ * the correct order. If there is > 1 destination, the number of destinations
+ * must be the same as the number of resources being copied/moved.
+ */
+ public CopyResourceElementsOperation(IJavaElement[] resourcesToCopy, IJavaElement[] destContainers, boolean force) {
+ super(resourcesToCopy, destContainers, force);
+ fFactory = new DOMFactory();
+ }
+ /**
+ * When executed, this operation will copy the given resources to the
+ * given container.
+ */
+ public CopyResourceElementsOperation(IJavaElement[] resourcesToCopy, IJavaElement destContainer, boolean force) {
+ this(resourcesToCopy, new IJavaElement[]{destContainer}, force);
+ }
+ /**
+ * Returns the children of source
which are affected by this operation.
+ * If source
is a K_SOURCE
, these are the .java
+ * files, if it is a K_BINARY
, they are the .class
files.
+ */
+ private IResource[] collectResourcesOfInterest(IPackageFragment source) throws JavaModelException {
+ IJavaElement[] children = source.getChildren();
+ int childOfInterest = IJavaElement.COMPILATION_UNIT;
+// if (source.getKind() == IPackageFragmentRoot.K_BINARY) {
+// childOfInterest = IJavaElement.CLASS_FILE;
+// }
+ ArrayList correctKindChildren = new ArrayList(children.length);
+ for (int i = 0; i < children.length; i++) {
+ IJavaElement child = children[i];
+ if (child.getElementType() == childOfInterest) {
+ correctKindChildren.add(child.getResource());
+ }
+ }
+ // Gather non-java resources
+// Object[] nonJavaResources = source.getNonJavaResources();
+// int actualNonJavaResourceCount = 0;
+// for (int i = 0, max = nonJavaResources.length; i < max; i++){
+// if (nonJavaResources[i] instanceof IResource) actualNonJavaResourceCount++;
+// }
+// IResource[] actualNonJavaResources = new IResource[actualNonJavaResourceCount];
+// for (int i = 0, max = nonJavaResources.length, index = 0; i < max; i++){
+// if (nonJavaResources[i] instanceof IResource) actualNonJavaResources[index++] = (IResource)nonJavaResources[i];
+// }
+
+// if (actualNonJavaResourceCount != 0) {
+// int correctKindChildrenSize = correctKindChildren.size();
+// IResource[] result = new IResource[correctKindChildrenSize + actualNonJavaResourceCount];
+// correctKindChildren.toArray(result);
+// System.arraycopy(actualNonJavaResources, 0, result, correctKindChildrenSize, actualNonJavaResourceCount);
+// return result;
+// } else {
+ IResource[] result = new IResource[correctKindChildren.size()];
+ correctKindChildren.toArray(result);
+ return result;
+// }
+ }
+ /**
+ * Creates any destination package fragment(s) which do not exists yet.
+ */
+ private void createNeededPackageFragments(IContainer sourceFolder, IPackageFragmentRoot root, String newFragName, boolean moveFolder) throws JavaModelException {
+ IContainer parentFolder = (IContainer) root.getResource();
+ JavaElementDelta projectDelta = null;
+ String[] names = net.sourceforge.phpdt.internal.core.Util.getTrimmedSimpleNames(newFragName);
+ StringBuffer sideEffectPackageName = new StringBuffer();
+ char[][] exclusionsPatterns = ((PackageFragmentRoot)root).fullExclusionPatternChars();
+ for (int i = 0; i < names.length; i++) {
+ String subFolderName = names[i];
+ sideEffectPackageName.append(subFolderName);
+ IResource subFolder = parentFolder.findMember(subFolderName);
+ if (subFolder == null) {
+ // create deepest folder only if not a move (folder will be moved in processPackageFragmentResource)
+ if (!(moveFolder && i == names.length-1)) {
+ createFolder(parentFolder, subFolderName, fForce);
+ }
+ parentFolder = parentFolder.getFolder(new Path(subFolderName));
+ sourceFolder = sourceFolder.getFolder(new Path(subFolderName));
+ if (sourceFolder.isReadOnly()) {
+ parentFolder.setReadOnly(true);
+ }
+ IPackageFragment sideEffectPackage = root.getPackageFragment(sideEffectPackageName.toString());
+ if (i < names.length - 1 // all but the last one are side effect packages
+ && !net.sourceforge.phpdt.internal.core.Util.isExcluded(parentFolder, exclusionsPatterns)) {
+ if (projectDelta == null) {
+ projectDelta = getDeltaFor(root.getJavaProject());
+ }
+ projectDelta.added(sideEffectPackage);
+ }
+ fCreatedElements.add(sideEffectPackage);
+ } else {
+ parentFolder = (IContainer) subFolder;
+ }
+ sideEffectPackageName.append('.');
+ }
+ }
+ /**
+ * Returns the JavaElementDelta
for javaProject
,
+ * creating it and putting it in fDeltasPerProject
if
+ * it does not exist yet.
+ */
+ private JavaElementDelta getDeltaFor(IJavaProject javaProject) {
+ JavaElementDelta delta = (JavaElementDelta) fDeltasPerProject.get(javaProject);
+ if (delta == null) {
+ delta = new JavaElementDelta(javaProject);
+ fDeltasPerProject.put(javaProject, delta);
+ }
+ return delta;
+ }
+ /**
+ * @see MultiOperation
+ */
+ protected String getMainTaskName() {
+ return net.sourceforge.phpdt.internal.core.Util.bind("operation.copyResourceProgress"); //$NON-NLS-1$
+ }
+ /**
+ * Sets the deltas to register the changes resulting from this operation
+ * for this source element and its destination.
+ * If the operation is a cross project operationnewCUName
+ * to the destination package.processCompilationUnitResource
or
+ * processPackageFragmentResource
, depending on the type of
+ * element
.
+ */
+ protected void processElement(IJavaElement element) throws JavaModelException {
+ IJavaElement dest = getDestinationParent(element);
+ switch (element.getElementType()) {
+ case IJavaElement.COMPILATION_UNIT :
+ processCompilationUnitResource((ICompilationUnit) element, (IPackageFragment) dest);
+ fCreatedElements.add(((IPackageFragment) dest).getCompilationUnit(element.getElementName()));
+ break;
+ case IJavaElement.PACKAGE_FRAGMENT :
+ processPackageFragmentResource((IPackageFragment) element, (IPackageFragmentRoot) dest, getNewNameFor(element));
+ break;
+ default :
+ throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element));
+ }
+ }
+ /**
+ * @see MultiOperation
+ * Overridden to allow special processing of JavaElementDelta
s
+ * and fResultElements
.
+ */
+ protected void processElements() throws JavaModelException {
+ fCreatedElements = new ArrayList(fElementsToProcess.length);
+ try {
+ super.processElements();
+ } catch (JavaModelException jme) {
+ throw jme;
+ } finally {
+ fResultElements = new IJavaElement[fCreatedElements.size()];
+ fCreatedElements.toArray(fResultElements);
+ processDeltas();
+ }
+ }
+ /**
+ * Copies/moves a package fragment with the name newName
+ * to the destination package.cu
, modifying the type name and/or package
+ * declaration as necessary.
+ *
+ * @return the new source
+ */
+ private String updatedContent(ICompilationUnit cu, IPackageFragment dest, String newName) throws JavaModelException {
+ String currPackageName = cu.getParent().getElementName();
+ String destPackageName = dest.getElementName();
+ if (currPackageName.equals(destPackageName) && newName == null) {
+ return null; //nothing to change
+ } else {
+ String typeName = cu.getElementName();
+ typeName = typeName.substring(0, typeName.length() - 5);
+ IDOMCompilationUnit cuDOM = null;
+ IBuffer buffer = cu.getBuffer();
+ if (buffer == null) return null;
+ char[] contents = buffer.getCharacters();
+ if (contents == null) return null;
+ cuDOM = fFactory.createCompilationUnit(contents, typeName);
+ updateTypeName(cu, cuDOM, cu.getElementName(), newName);
+ updatePackageStatement(cuDOM, destPackageName);
+ return cuDOM.getContents();
+ }
+ }
+ /**
+ * Makes sure that cu
declares to be in the pkgName
package.
+ */
+ private void updatePackageStatement(IDOMCompilationUnit domCU, String pkgName) throws JavaModelException {
+ boolean defaultPackage = pkgName.equals(IPackageFragment.DEFAULT_PACKAGE_NAME);
+ boolean seenPackageNode = false;
+ Enumeration enum = domCU.getChildren();
+ while (enum.hasMoreElements()) {
+ IDOMNode node = (IDOMNode) enum.nextElement();
+ if (node.getNodeType() == IDOMNode.PACKAGE) {
+ if (! defaultPackage) {
+ node.setName(pkgName);
+ } else {
+ node.remove();
+ }
+ seenPackageNode = true;
+ break;
+ }
+ }
+ if (!seenPackageNode && !defaultPackage) {
+ //the cu was in a default package...no package declaration
+ //create the new package declaration as the first child of the cu
+// IDOMPackage pkg = fFactory.createPackage("package " + pkgName + ";" + net.sourceforge.phpdt.internal.compiler.util.Util.LINE_SEPARATOR); //$NON-NLS-1$ //$NON-NLS-2$
+// IDOMNode firstChild = domCU.getFirstChild();
+// if (firstChild != null) {
+// firstChild.insertSibling(pkg);
+// } // else the cu was empty: leave it empty
+ }
+ }
+ /**
+ * Renames the main type in cu
.
+ */
+ private void updateTypeName(ICompilationUnit cu, IDOMCompilationUnit domCU, String oldName, String newName) throws JavaModelException {
+ if (newName != null) {
+ if (fRenamedCompilationUnits == null) {
+ fRenamedCompilationUnits= new ArrayList(1);
+ }
+ fRenamedCompilationUnits.add(cu);
+ String oldTypeName= oldName.substring(0, oldName.length() - 5);
+ String newTypeName= newName.substring(0, newName.length() - 5);
+ // update main type name
+ IType[] types = cu.getTypes();
+ for (int i = 0, max = types.length; i < max; i++) {
+ IType currentType = types[i];
+ if (currentType.getElementName().equals(oldTypeName)) {
+ IDOMNode typeNode = ((JavaElement) currentType).findNode(domCU);
+ if (typeNode != null) {
+ typeNode.setName(newTypeName);
+ }
+ }
+ }
+ }
+ }
+ /**
+ * Possible failures:
+ *