/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Vladimir Piskarev <pisv@1c.ru> - F_CONTENT sometimes lost when merging deltas - https://bugs.eclipse.org/520336
 *******************************************************************************/
package org.eclipse.jdt.core.tests.model;

import junit.framework.Test;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.internal.core.util.Util;

public class CopyMoveResourcesTests extends CopyMoveTests {
/**
 */
public CopyMoveResourcesTests(String name) {
	super(name);
}
/**
 * Copies the element to the container with optional rename
 * and forcing. The operation should succeed, so any exceptions
 * encountered are thrown.
 */
@Override
public IJavaElement copyPositive(IJavaElement element, IJavaElement container, IJavaElement sibling, String rename, boolean force) throws JavaModelException {
	DeltaListener listener = new DeltaListener();
	try {
		startDeltas(listener);

		// if forcing, ensure that a name collision exists
		if (force) {
			IJavaElement collision = generateHandle(element, rename, container);
			assertTrue("Collision does not exist", collision.exists());
		}

		// copy
	 	((ISourceManipulation) element).copy(container, sibling, rename, force, null);

		// ensure the original element still exists
		assertTrue("The original element must still exist", element.exists());

		// generate the new element	handle
		IJavaElement copy = generateHandle(element, rename, container);
		assertTrue("Copy should exist", copy.exists());
		//ensure correct position
		if (element.getElementType() > IJavaElement.COMPILATION_UNIT) {
			ensureCorrectPositioning((IParent) container, sibling, copy);
		} else if (container.getElementType() != IJavaElement.PACKAGE_FRAGMENT_ROOT) {
			// ensure package name is correct
			if (container.getElementName().equals("")) {
				// default package - should be no package decl
				IJavaElement[] children = ((ICompilationUnit) copy).getChildren();
				boolean found = false;
				for (int i = 0; i < children.length; i++) {
					if (children[i] instanceof IPackageDeclaration) {
						found = true;
					}
				}
				assertTrue("Should not find package decl", !found);
			} else {
				IJavaElement[] children = ((ICompilationUnit) copy).getChildren();
				boolean found = false;
				for (int i = 0; i < children.length; i++) {
					if (children[i] instanceof IPackageDeclaration) {
						assertTrue("package declaration incorrect", ((IPackageDeclaration) children[i]).getElementName().equals(container.getElementName()));
						found = true;
					}
				}
				assertTrue("Did not find package decl", found);
			}
		}
		IJavaElementDelta destDelta = listener.getDeltaFor(container, true);
		assertTrue("Destination container not changed", destDelta != null && destDelta.getKind() == IJavaElementDelta.CHANGED);
		IJavaElementDelta[] deltas = null;
		if (force) {
			deltas = destDelta.getChangedChildren();
		}
		else {
			deltas = destDelta.getAddedChildren();
		}
		// FIXME: not strong enough
		boolean found = false;
		for (int i = 0; i < deltas.length; i++) {
			if (deltas[i].getElement().equals(copy))
				found = true;
		}
		assertTrue("Added children not correct for element copy", found);
		return copy;
	} finally {
		stopDeltas(listener);
	}
}

/**
 * Moves the elements to the containers with optional renaming
 * and forcing. The operation should succeed, so any exceptions
 * encountered are thrown.
 */
@Override
public void movePositive(IJavaElement[] elements, IJavaElement[] destinations, IJavaElement[] siblings, String[] names, boolean force, IProgressMonitor monitor) throws JavaModelException {
	DeltaListener listener = new DeltaListener();
	try {
		startDeltas(listener);

		// if forcing, ensure that a name collision exists
		int i;
		if (force) {
			for (i = 0; i < elements.length; i++) {
				IJavaElement e = elements[i];
				IJavaElement collision = null;
				if (names == null) {
					collision = generateHandle(e, null, destinations[i]);
				} else {
					collision = generateHandle(e, names[i], destinations[i]);
				}
				assertTrue("Collision does not exist", collision.exists());
			}
		}

		// move
		getJavaModel().move(elements, destinations, siblings, names, force, monitor);

		for (i = 0; i < elements.length; i++) {
			IJavaElement element = elements[i];
			IJavaElement moved = null;
			if (names == null) {
				moved = generateHandle(element, null, destinations[i]);
			} else {
				moved = generateHandle(element, names[i], destinations[i]);
			}
			// ensure the original element no longer exists, unless moving within the same container, or moving a primary working copy
			if (!destinations[i].equals(element.getParent())) {
				if (element.getElementType() != IJavaElement.COMPILATION_UNIT || !((ICompilationUnit) element).isWorkingCopy())
					assertTrue("The original element must not exist", !element.exists());
			}
			assertTrue("Moved element should exist", moved.exists());

			IJavaElement container = destinations[i];
			if (container.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
				if (container.getElementName().equals("")) {
					// default package
					if (moved.getElementType() == IJavaElement.COMPILATION_UNIT) {
						IJavaElement[] children = ((ICompilationUnit) moved).getChildren();
						for (int j = 0; j < children.length; j++) {
							if (children[j].getElementType() == IJavaElement.PACKAGE_DECLARATION) {
								assertTrue("Should not find package decl", false);
							}
						}
					}
				} else {
					IJavaElement[] children = ((ICompilationUnit) moved).getChildren();
					boolean found = false;
					for (int j = 0; j < children.length; j++) {
						if (children[j] instanceof IPackageDeclaration) {
							assertTrue("package declaration incorrect", ((IPackageDeclaration) children[j]).getElementName().equals(container.getElementName()));
							found = true;
							break;
						}
					}
					assertTrue("Did not find package decl", found);
				}
			}
			IJavaElementDelta destDelta = null;
			if (isMainType(element, destinations[i]) && names != null && names[i] != null) { //moved/renamed main type to same cu
				destDelta = listener.getDeltaFor(moved.getParent());
				assertTrue("Renamed compilation unit as result of main type not added", destDelta != null && destDelta.getKind() == IJavaElementDelta.ADDED);
				IJavaElementDelta[] deltas = destDelta.getAddedChildren();
				assertTrue("Added children not correct for element copy", deltas[0].getElement().equals(moved));
				assertTrue("flag should be F_MOVED_FROM", (deltas[0].getFlags() & IJavaElementDelta.F_MOVED_FROM) > 0);
				assertTrue("moved from handle should be original", deltas[0].getMovedFromElement().equals(element));
			} else {
				destDelta = listener.getDeltaFor(destinations[i], true);
				assertTrue("Destination container not changed", destDelta != null && destDelta.getKind() == IJavaElementDelta.CHANGED);
				IJavaElementDelta[] deltas = destDelta.getAddedChildren();
				for (int j = 0; j < deltas.length - 1; j++) {
					// side effect packages added
					IJavaElement pkg = deltas[j].getElement();
					assertTrue("Side effect child should be a package fragment", pkg.getElementType() == IJavaElement.PACKAGE_FRAGMENT);
					assertTrue("Side effect child should be an enclosing package", element.getElementName().startsWith(pkg.getElementName()));
				}
				IJavaElementDelta pkgDelta = deltas[deltas.length - 1];
				assertTrue("Added children not correct for element copy", pkgDelta.getElement().equals(moved));
				assertTrue("flag should be F_MOVED_FROM", (pkgDelta.getFlags() & IJavaElementDelta.F_MOVED_FROM) > 0);
				assertTrue("moved from handle shoud be original", pkgDelta.getMovedFromElement().equals(element));
				IJavaElementDelta sourceDelta = listener.getDeltaFor(element, true);
				assertTrue("moved to handle should be original", sourceDelta.getMovedToElement().equals(moved));
			}
		}
	} finally {
		stopDeltas(listener);
	}
}
/**
 * Setup for the next test.
 */
@Override
public void setUp() throws Exception {
	super.setUp();

	this.createJavaProject("P", new String[] {"src", "src2"}, new String[] { "JCL_LIB" }, "bin", "1.4");
}
static {
//	TESTS_NAMES = new String[] { "testCopyWorkingCopyDestination"};
}
public static Test suite() {
	return buildModelTestSuite(CopyMoveResourcesTests.class);
}
/**
 * Cleanup after the previous test.
 */
@Override
public void tearDown() throws Exception {
	this.deleteProject("P");

	super.tearDown();
}
/**
 * Ensures that a CU can be copied to a different package.
 */
public void testCopyCU01() throws CoreException {
	this.createFolder("/P/src/p1");
	this.createFile(
		"/P/src/p1/X.java",
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);
	ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");

	this.createFolder("/P/src/p2");
	IPackageFragment pkgDest = getPackage("/P/src/p2");

	copyPositive(cuSource, pkgDest, null, null, false);

	ICompilationUnit cu= pkgDest.getCompilationUnit("X.java");
	assertTrue("Package declaration not updated for copied cu", cu.getPackageDeclaration("p2").exists());
}
/**
 * This operation should fail as copying a CU and a CU member at the
 * same time is not supported.
 */
public void testCopyCU02() throws CoreException {
	this.createFolder("/P/src/p1");
	this.createFile(
		"/P/src/p1/X.java",
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);
	ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");

	copyNegative(
		new IJavaElement[]{cuSource, cuSource.getType("X")},
		new IJavaElement[]{cuSource.getParent(), cuSource},
		null,
		new String[]{"Y.java", "Y"},
		false,
		IJavaModelStatusConstants.INVALID_ELEMENT_TYPES);
}
/**
 * Ensures that a CU can be copied to a different package, replacing an existing CU.
 */
public void testCopyCU03() throws CoreException {
	this.createFolder("/P/src/p1");
	this.createFile(
		"/P/src/p1/X.java",
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);
	ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");

	this.createFolder("/P/src/p2");
	this.createFile(
		"/P/src/p2/X.java",
		"package p2;\n" +
		"public class X {\n" +
		"}"
	);
	IPackageFragment pkgDest = getPackage("/P/src/p2");

	copyPositive(cuSource, pkgDest, null, null, true);
}
/**
 * Ensures that a CU can be copied from a default package to a non-default package.
 */
public void testCopyCU04() throws CoreException {
	createFile(
		"/P/src/X.java",
		"public class X {\n" +
		"}"
	);
	ICompilationUnit cuSource = getCompilationUnit("/P/src/X.java");

	createFolder("/P/src/p");
	IPackageFragment pkgDest = getPackage("/P/src/p");

	copyPositive(cuSource, pkgDest, null, null, false);

	ICompilationUnit cu= pkgDest.getCompilationUnit("X.java");
	assertTrue("Package declaration not updated for copied cu", cu.getPackageDeclaration("p").exists());
}
/**
 * Ensures that a CU can be copied to a different package,
 * and be renamed.
 */
public void testCopyCU05() throws CoreException {
	this.createFolder("/P/src/p1");
	this.createFile(
		"/P/src/p1/X.java",
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);
	ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");

	this.createFolder("/P/src/p2");
	IPackageFragment pkgDest = getPackage("/P/src/p2");

	copyPositive(cuSource, pkgDest, null, "Y.java", false);
}
/**
 * Ensures that a read-only CU can be copied to a different package.
 */
public void testCopyCU06() throws CoreException {
	if (!Util.isReadOnlySupported()) {
		// Do not test if file system does not support read-only attribute
		return;
	}
	IFile file = null;
	IFile file2 = null;
	try {
		this.createFolder("/P/src/p1");
		file = this.createFile(
			"/P/src/p1/X.java",
			"package p1;\n" +
			"public class X {\n" +
			"}"
		);
		Util.setReadOnly(file, true);
		ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");

		this.createFolder("/P/src/p2");
		IPackageFragment pkgDest = getPackage("/P/src/p2");

		copyPositive(cuSource, pkgDest, null, null, false);

		file2 = getFile("/P/src/p2/X.java");
		assertTrue("Destination cu should be read-only", file2.isReadOnly());
	} finally {
		if (file != null) {
			Util.setReadOnly(file, false);
		}
		if (file2 != null) {
			Util.setReadOnly(file2, false);
		}
		deleteFolder("/P/src/p1");
		deleteFolder("/P/src/p2");
	}
}
/**
 * Ensures that a CU can be copied to a different package,
 * and be renamed, overwriting an existing CU
 */
public void testCopyCU07() throws CoreException {
	this.createFolder("/P/src/p1");
	this.createFile(
		"/P/src/p1/X.java",
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);
	ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");

	this.createFolder("/P/src/p2");
	this.createFile(
		"/P/src/p2/Y.java",
		"package p2;\n" +
		"public class Y {\n" +
		"}"
	);
	IPackageFragment pkgDest = getPackage("/P/src/p2");

	copyPositive(cuSource, pkgDest, null, "Y.java", true);
}
/**
 * Ensures that a CU cannot be copied to a different package,over an existing CU when no force.
 */
public void testCopyCU08() throws CoreException {
	this.createFolder("/P/src/p1");
	this.createFile(
		"/P/src/p1/X.java",
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);
	ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");

	this.createFolder("/P/src/p2");
	this.createFile(
		"/P/src/p2/X.java",
		"package p2;\n" +
		"public class X {\n" +
		"}"
	);
	IPackageFragment pkgDest = getPackage("/P/src/p2");

	copyNegative(cuSource, pkgDest, null, null, false, IJavaModelStatusConstants.NAME_COLLISION);
}
/**
 * Ensures that a CU cannot be copied to an invalid destination
 */
public void testCopyCU09() throws CoreException {
	this.createFolder("/P/src/p1");
	this.createFile(
		"/P/src/p1/X.java",
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);
	ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");

	copyNegative(cuSource, cuSource, null, null, false, IJavaModelStatusConstants.INVALID_DESTINATION);
}
/**
 * Ensures that a CU can be copied to a null container
 */
public void testCopyCU10() throws CoreException {
	this.createFolder("/P/src/p1");
	this.createFile(
		"/P/src/p1/X.java",
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);
	ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");

	try {
		cuSource.copy(null, null, null, false, null);
	} catch (IllegalArgumentException iae) {
		return;
	}
	assertTrue("Should not be able to move a cu to a null container", false);
}
/**
 * Ensures that a CU can be copied to along with its server properties.
 * (Regression test for PR #1G56QT9)
 */
public void testCopyCU11() throws CoreException {
	this.createFolder("/P/src/p1");
	this.createFile(
		"/P/src/p1/X.java",
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);
	ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");

	QualifiedName qualifiedName = new QualifiedName("x.y.z", "a property");
	cuSource.getUnderlyingResource().setPersistentProperty(
		qualifiedName,
		"some value");

	this.createFolder("/P/src/p2");
	IPackageFragment pkgDest = getPackage("/P/src/p2");

	copyPositive(cuSource, pkgDest, null, null, false);
	ICompilationUnit cu= pkgDest.getCompilationUnit("X.java");
	String propertyValue = cu.getUnderlyingResource().getPersistentProperty(qualifiedName);
	assertEquals(
		"Server property should be copied with cu",
		"some value",
		propertyValue
	);
}
/*
 * Ensures that the correct scheduling rule is used when copying a CU
 * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=142990 )
 */
public void testCopyCU12() throws Exception {
	createFolder("/P/src/p1");
	createFile("/P/src/p1/X.java", "package p1; public class X {}");
	this.createFolder("/P/src/p2");

	IWorkspaceRunnable runnable = new IWorkspaceRunnable(){
		public void run(IProgressMonitor monitor) throws CoreException {
			ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");
			IPackageFragment pkgDest = getPackage("/P/src/p2");
			cuSource.copy(pkgDest, null, null, false, null);
			assertTrue("/P/src/p2/X.java should exist", getCompilationUnit("/P/src/p2/X.java").exists());
		}
	};
	getWorkspace().run(runnable, getFolder("/P/src/p2"), IResource.NONE, null);
}
/**
 * Ensures that a package fragment can be copied to a different package fragment root.
 */
public void testCopyPackageFragment() throws CoreException {
	this.createFolder("/P/src/p1");
	this.createFile(
		"/P/src/p1/X.java",
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);
	IPackageFragment pkgSource = getPackage("/P/src/p1");

	IPackageFragmentRoot rootDest= getPackageFragmentRoot("P", "src2");

	copyPositive(pkgSource, rootDest, null, null, false);
}
/**
 * Ensures that a package fragment can be copied to a different package fragment root.
 */
public void testCopyReadOnlyPackageFragment() throws CoreException {
	if (!Util.isReadOnlySupported()) {
		// Do not test if file system does not support read-only attribute
		return;
	}
	IPackageFragment pkgSource = null;
	IPackageFragment pkg2 = null;
	try {
		this.createFolder("/P/src/p1/p2/p3");
		this.createFile(
			"/P/src/p1/p2/p3/X.java",
			"package p1.p2.p3;\n" +
			"public class X {\n" +
			"}"
		);
		Util.setReadOnly(getFile("/P/src/p1/p2/p3/X.java"), true);
		pkgSource = getPackage("/P/src/p1");
		Util.setReadOnly(pkgSource.getResource(), true);
		pkg2 = getPackage("/P/src/p1/p2/p3");
		Util.setReadOnly(pkg2.getResource(), true);

		IPackageFragmentRoot rootDest= getPackageFragmentRoot("P", "src2");

		copyPositive(pkg2, rootDest, null, null, false);

		assertTrue("Not readOnly", Util.isReadOnly(getPackage("/P/src2/p1").getResource()));
		assertTrue("Is readOnly", !Util.isReadOnly(getPackage("/P/src2/p1/p2").getResource()));
		assertTrue("Not readOnly", Util.isReadOnly(getPackage("/P/src2/p1/p2/p3").getResource()));
		assertTrue("Is readOnly", Util.isReadOnly(getFile("/P/src2/p1/p2/p3/X.java")));
	} finally {
		IFile xSrcFile = getFile("/P/src/p1/p2/p3/X.java");
		if (xSrcFile != null) {
			Util.setReadOnly(xSrcFile, false);
		}
		if (pkg2 != null) {
			Util.setReadOnly(pkg2.getResource(), false);
		}
		if (pkgSource != null) {
			Util.setReadOnly(pkgSource.getResource(), false);
		}
		IPackageFragment p1Fragment = getPackage("/P/src2/p1");
		if (p1Fragment != null) {
			Util.setReadOnly(p1Fragment.getResource(), false);
		}
		IPackageFragment p3Fragment = getPackage("/P/src2/p1/p2/p3");
		if (p3Fragment != null) {
			Util.setReadOnly(p3Fragment.getResource(), false);
		}
		IFile xFile = getFile("/P/src2/p1/p2/p3/X.java");
		if (xFile != null) {
			Util.setReadOnly(xFile, false);
		}
		deleteFolder("/P/src/p1");
	}
}
/**
 * Ensures that a WorkingCopy can be copied to a different package.
 */
public void testCopyWorkingCopy() throws CoreException {
	ICompilationUnit copy = null;
	try {
		this.createFolder("/P/src/p1");
		this.createFile(
			"/P/src/p1/X.java",
			"package p1;\n" +
			"public class X {\n" +
			"}"
		);
		ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");
		copy = cuSource.getWorkingCopy(null);

		this.createFolder("/P/src/p2");
		IPackageFragment pkgDest = getPackage("/P/src/p2");

		copyPositive(copy, pkgDest, null, null, false);
	} finally {
		if (copy != null) copy.discardWorkingCopy();
	}
}
/*
 * Ensures that a CU can be copied over an existing primary working copy in a different package.
 * (regression test for bug 117282 Package declaration inserted on wrong CU while copying class if names collide and editor opened)
 */
public void testCopyWorkingCopyDestination() throws CoreException {
	ICompilationUnit copy = null;
	try {
		createFolder("/P/src/p1");
		createFile(
			"/P/src/p1/X.java",
			"package p1;\n" +
			"public class X {\n" +
			"  void foo() {}\n" +
			"}"
		);
		ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");

		createFolder("/P/src/p2");
		IPackageFragment pkgDest = getPackage("/P/src/p2");
		createFile(
			"/P/src/p2/X.java",
			"\n" +
			"package p1;\n" +
			"public class X {\n" +
			"}"
		);
		copy = getCompilationUnit("/P/src/p2/X.java");
		copy.becomeWorkingCopy(null);

		copyPositive(cuSource, pkgDest, null, null, true/*force*/);
	} finally {
		if (copy != null) copy.discardWorkingCopy();
	}
}
/**
 * Ensures that a WorkingCopy can be copied to a different package, replacing an existing WorkingCopy.
 */
public void testCopyWorkingCopyForce() throws CoreException {
	ICompilationUnit copy = null;
	try {
		this.createFolder("/P/src/p1");
		this.createFile(
			"/P/src/p1/X.java",
			"package p1;\n" +
			"public class X {\n" +
			"}"
		);
		ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");
		copy = cuSource.getWorkingCopy(null);

		this.createFolder("/P/src/p2");
		this.createFile(
			"/P/src/p2/X.java",
			"package p2;\n" +
			"public class X {\n" +
			"}"
		);
		IPackageFragment pkgDest = getPackage("/P/src/p2");

		copyPositive(copy, pkgDest, null, null, true);
	} finally {
		if (copy != null) copy.discardWorkingCopy();
	}
}
/**
 * Ensures that a WorkingCopy can be copied to a different package,
 * and be renamed.
 */
public void testCopyWorkingCopyRename() throws CoreException {
	ICompilationUnit copy = null;
	try {
		this.createFolder("/P/src/p1");
		this.createFile(
			"/P/src/p1/X.java",
			"package p1;\n" +
			"public class X {\n" +
			"}"
		);
		ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");
		copy = cuSource.getWorkingCopy(null);

		this.createFolder("/P/src/p2");
		IPackageFragment pkgDest = getPackage("/P/src/p2");

		copyPositive(copy, pkgDest, null, "Y.java", false);
	} finally {
		if (copy != null) copy.discardWorkingCopy();
	}
}
/**
 * Ensures that a WorkingCopy can be copied to a different package,
 * and be renamed, overwriting an existing WorkingCopy
 */
public void testCopyWorkingCopyRenameForce() throws CoreException {
	ICompilationUnit copy = null;
	try {
		this.createFolder("/P/src/p1");
		this.createFile(
			"/P/src/p1/X.java",
			"package p1;\n" +
			"public class X {\n" +
			"}"
		);
		ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");
		copy = cuSource.getWorkingCopy(null);

		this.createFolder("/P/src/p2");
		this.createFile(
			"/P/src/p2/Y.java",
			"package p2;\n" +
			"public class Y {\n" +
			"}"
		);
		IPackageFragment pkgDest = getPackage("/P/src/p2");

		copyPositive(copy, pkgDest, null, "Y.java", true);
	} finally {
		if (copy != null) copy.discardWorkingCopy();
	}
}
/**
 * Ensures that a WorkingCopy cannot be copied to a different package,over an existing WorkingCopy when no force.
 */
public void testCopyWorkingCopyWithCollision() throws CoreException {
	ICompilationUnit copy = null;
	try {
		this.createFolder("/P/src/p1");
		this.createFile(
			"/P/src/p1/X.java",
			"package p1;\n" +
			"public class X {\n" +
			"}"
		);
		ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");
		copy = cuSource.getWorkingCopy(null);

		this.createFolder("/P/src/p2");
		this.createFile(
			"/P/src/p2/X.java",
			"package p2;\n" +
			"public class X {\n" +
			"}"
		);
		IPackageFragment pkgDest = getPackage("/P/src/p2");

		copyNegative(copy, pkgDest, null, null, false, IJavaModelStatusConstants.NAME_COLLISION);
	} finally {
		if (copy != null) copy.discardWorkingCopy();
	}
}
/**
 * Ensures that a WorkingCopy cannot be copied to an invalid destination
 */
public void testCopyWorkingCopyWithInvalidDestination() throws CoreException {
	ICompilationUnit copy = null;
	try {
		this.createFolder("/P/src/p1");
		this.createFile(
			"/P/src/p1/X.java",
			"package p1;\n" +
			"public class X {\n" +
			"}"
		);
		ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");
		copy = cuSource.getWorkingCopy(null);

		copyNegative(copy, cuSource, null, null, false, IJavaModelStatusConstants.INVALID_DESTINATION);
	} finally {
		if (copy != null) copy.discardWorkingCopy();
	}
}
/**
 * Ensures that a CU can be moved to a different package.
 */
public void testMoveCU01() throws CoreException {
	this.createFolder("/P/src/p1");
	this.createFile(
		"/P/src/p1/X.java",
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);
	ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");

	this.createFolder("/P/src/p2");
	IPackageFragment pkgDest = getPackage("/P/src/p2");

	movePositive(cuSource, pkgDest, null, null, false);

	ICompilationUnit cu= pkgDest.getCompilationUnit("X.java");
	assertTrue("Package declaration not updated for copied cu", cu.getPackageDeclaration("p2").exists());
}
/**
 * This operation should fail as moving a CU and a CU member at the
 * same time is not supported.
 */
public void testMoveCU02() throws CoreException {
	this.createFolder("/P/src/p1");
	this.createFile(
		"/P/src/p1/X.java",
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);
	ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");

	moveNegative(
		new IJavaElement[]{cuSource, cuSource.getType("X")},
		new IJavaElement[]{cuSource.getParent(), cuSource},
		null,
		new String[]{"Y.java", "Y"},
		false,
		IJavaModelStatusConstants.INVALID_ELEMENT_TYPES);
}
/**
 * Ensures that a CU can be moved to a different package, replacing an
 * existing CU.
 */
public void testMoveCU03() throws CoreException {
	DeltaListener listener = new DeltaListener();
	try {
		this.createFolder("/P/src/p1");
		this.createFile(
			"/P/src/p1/X.java",
			"package p1;\n" +
			"public class X {\n" +
			"}"
		);
		ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");

		this.createFolder("/P/src/p2");
		this.createFile(
			"/P/src/p2/X.java",
			"package p2;\n" +
			"public class X {\n" +
			"}"
		);
		IPackageFragment pkgDest = getPackage("/P/src/p2");
		startDeltas(listener);
		movePositive(new IJavaElement[] {cuSource}, new IJavaElement[] {pkgDest}, null, null, true, false, null);
			assertDeltas(
					"Incorrect delta",
					"P[*]: {CHILDREN}\n"
							+ "	src[*]: {CHILDREN}\n"
							+ "		p1[*]: {CHILDREN}\n"
							+ "			X.java[-]: {MOVED_TO(X.java [in p2 [in src [in P]]])}\n"
							+ "		p2[*]: {CHILDREN}\n"
							+ "			X.java[*]: {CONTENT | PRIMARY RESOURCE}", listener);
	}
	finally {
		stopDeltas(listener);
	}
}
/**
 * Ensures that a CU can be moved to a different package,
 * be renamed
 */
public void testMoveCU04() throws CoreException {
	this.createFolder("/P/src/p1");
	this.createFile(
		"/P/src/p1/X.java",
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);
	ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");

	this.createFolder("/P/src/p2");
	IPackageFragment pkgDest = getPackage("/P/src/p2");

	movePositive(cuSource, pkgDest, null, "Y.java", false);
}
/**
 * Ensures that a CU can be moved to a different package,
 * be renamed, overwriting an existing resource.
 */
public void testMoveCU05() throws CoreException {
	DeltaListener listener = new DeltaListener();
	try {
		this.createFolder("/P/src/p1");
		this.createFile(
			"/P/src/p1/X.java",
			"package p1;\n" +
			"public class X {\n" +
			"}"
		);
		ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");

		this.createFolder("/P/src/p2");
		this.createFile(
			"/P/src/p2/Y.java",
			"package p2;\n" +
			"public class Y {\n" +
			"}"
		);
		IPackageFragment pkgDest = getPackage("/P/src/p2");
		startDeltas(listener);
		movePositive(new IJavaElement[] {cuSource}, new IJavaElement[] {pkgDest}, null, new String[]{"Y.java"}, true, false, null);
		assertDeltas(
					"Incorrect delta",
					"P[*]: {CHILDREN}\n"
							+ "	src[*]: {CHILDREN}\n"
							+ "		p1[*]: {CHILDREN}\n"
							+ "			X.java[-]: {MOVED_TO(Y.java [in p2 [in src [in P]]])}\n"
							+ "		p2[*]: {CHILDREN}\n"
							+ "			Y.java[*]: {CHILDREN | CONTENT | FINE GRAINED | PRIMARY RESOURCE}\n"
							+ "				Y[+]: {MOVED_FROM(X [in X.java [in p1 [in src [in P]]]])}", listener);
	}
	finally {
		stopDeltas(listener);
	}
}
/**
 * Ensures that a CU cannot be moved to a different package, replacing an
 * existing CU when not forced.
 */
public void testMoveCU06() throws CoreException {
	this.createFolder("/P/src/p1");
	this.createFile(
		"/P/src/p1/X.java",
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);
	ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");

	this.createFolder("/P/src/p2");
	this.createFile(
		"/P/src/p2/X.java",
		"package p2;\n" +
		"public class X {\n" +
		"}"
	);
	IPackageFragment pkgDest = getPackage("/P/src/p2");

	moveNegative(cuSource, pkgDest, null, null, false, IJavaModelStatusConstants.NAME_COLLISION);
}
/**
 * Ensures that a CU cannot be moved to an invalid destination.
 */
public void testMoveCU07() throws CoreException {
	this.createFolder("/P/src/p1");
	this.createFile(
		"/P/src/p1/X.java",
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);
	ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");

	moveNegative(cuSource, cuSource, null, null, false, IJavaModelStatusConstants.INVALID_DESTINATION);
}
/**
 * Ensures that a CU cannot be moved to a null container
 */
public void testMoveCU08() throws CoreException {
	this.createFolder("/P/src/p1");
	this.createFile(
		"/P/src/p1/X.java",
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);
	ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");

	try {
		cuSource.move(null, null, null, false, null);
	} catch (IllegalArgumentException iae) {
		return;
	}
	assertTrue("Should not be able to move a cu to a null container", false);
}
/*
 * Ensures that the correct scheduling rule is used when moving a CU
 * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=142990 )
 */
public void testMoveCU09() throws Exception {
	createFolder("/P/src/p1");
	createFile("/P/src/p1/X.java", "package p1; public class X {}");
	this.createFolder("/P/src/p2");

	IWorkspaceRunnable runnable = new IWorkspaceRunnable(){
		public void run(IProgressMonitor monitor) throws CoreException {
			ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");
			IPackageFragment pkgDest = getPackage("/P/src/p2");
			cuSource.move(pkgDest, null, null, false, null);
			assertFalse("/P/src/p1/X.java should no longer exist", cuSource.exists());
		}
	};
	getWorkspace().run(runnable, getFolder("/P/src"), IResource.NONE, null);
}
/*
 * Ensures that the first block comment is not lost if moving a cu to the default package
 * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=247757 )
 */
public void testMoveCU10() throws CoreException {
	createFolder("/P/src/p1");
	createFile(
		"/P/src/p1/X.java",
		"/* some comment */\n" +
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);
	ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");
	IPackageFragment pkgDest = getPackage("/P/src");
	cuSource.move(pkgDest, null/*no sibling*/, null/*no rename*/, false/*don't replace*/, null/*no progress*/);

	ICompilationUnit cuDest = getCompilationUnit("/P/src/X.java");
	assertSourceEquals(
		"Unexpected source",
		"/* some comment */\n" +
		"\n" +
		"public class X {\n" +
		"}",
		cuDest.getSource());
}
/*
 * Ensures that the first block comments are not lost if moving a cu to the default package
 * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=247757 )
 */
public void testMoveCU11() throws CoreException {
	createFolder("/P/src/p1");
	createFile(
		"/P/src/p1/X.java",
		"/* some comment */\n" +
		"/* other comment */\n" +
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);
	ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");
	IPackageFragment pkgDest = getPackage("/P/src");
	cuSource.move(pkgDest, null/*no sibling*/, null/*no rename*/, false/*don't replace*/, null/*no progress*/);

	ICompilationUnit cuDest = getCompilationUnit("/P/src/X.java");
	assertSourceEquals(
		"Unexpected source",
		"/* some comment */\n" +
		"/* other comment */\n" +
		"\n" +
		"public class X {\n" +
		"}",
		cuDest.getSource());
}
/*
 * Ensures that the Javadoc comment is not lost if moving a cu to the default package
 * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=247757 )
 */
public void testMoveCU12() throws CoreException {
	createFolder("/P/src/p1");
	createFile(
		"/P/src/p1/X.java",
		"/** some Javadoc */\n" +
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);
	ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");
	IPackageFragment pkgDest = getPackage("/P/src");
	cuSource.move(pkgDest, null/*no sibling*/, null/*no rename*/, false/*don't replace*/, null/*no progress*/);

	ICompilationUnit cuDest = getCompilationUnit("/P/src/X.java");
	assertSourceEquals(
		"Unexpected source",
		"/** some Javadoc */\n" +
		"\n" +
		"public class X {\n" +
		"}",
		cuDest.getSource());
}
/*
 * Ensures that the Javadoc comment is not lost if moving a cu to the default package
 * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=247757 )
 */
public void testMoveCU13() throws CoreException {
	createFolder("/P/src/p1");
	createFile(
		"/P/src/p1/X.java",
		"/** some Javadoc */\n" +
		"// some line comment\n" +
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);
	ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");
	IPackageFragment pkgDest = getPackage("/P/src");
	cuSource.move(pkgDest, null/*no sibling*/, null/*no rename*/, false/*don't replace*/, null/*no progress*/);

	ICompilationUnit cuDest = getCompilationUnit("/P/src/X.java");
	assertSourceEquals(
		"Unexpected source",
		"/** some Javadoc */\n" +
		"// some line comment\n" +
		"\n" +
		"public class X {\n" +
		"}",
		cuDest.getSource());
}
/**
 * Ensures that a package fragment can be moved to a different package fragment root.
 */
public void testMovePackageFragment() throws CoreException {
	this.createFolder("/P/src/p1");
	this.createFile(
		"/P/src/p1/X.java",
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);
	IPackageFragment pkgSource = getPackage("/P/src/p1");

	IPackageFragmentRoot rootDest= getPackageFragmentRoot("P", "src2");

	movePositive(pkgSource, rootDest, null, null, false);
}
/**
 * Ensures that a package fragment can be copied to a different package fragment root.
 */
public void testMoveReadOnlyPackageFragment() throws CoreException {
	if (!Util.isReadOnlySupported()) {
		// Do not test if file system does not support read-only attribute
		return;
	}
	IPackageFragment pkgSource = null;
	IPackageFragment pkg2 = null;
	try {
		this.createFolder("/P/src/p1/p2/p3");
		this.createFile(
			"/P/src/p1/p2/p3/X.java",
			"package p1.p2.p3;\n" +
			"public class X {\n" +
			"}"
		);
		Util.setReadOnly(getFile("/P/src/p1/p2/p3/X.java"), true);
		pkgSource = getPackage("/P/src/p1");
		Util.setReadOnly(pkgSource.getResource(), true);
		pkg2 = getPackage("/P/src/p1/p2/p3");
		Util.setReadOnly(pkg2.getResource(), true);

		IPackageFragmentRoot rootDest= getPackageFragmentRoot("P", "src2");

		movePositive(pkg2, rootDest, null, null, false);

		assertTrue("Not readOnly", Util.isReadOnly(getPackage("/P/src2/p1").getResource()));
		assertTrue("Is readOnly", !Util.isReadOnly(getPackage("/P/src2/p1/p2").getResource()));
		assertTrue("Not readOnly", Util.isReadOnly(getPackage("/P/src2/p1/p2/p3").getResource()));
		assertTrue("Is readOnly", Util.isReadOnly(getFile("/P/src2/p1/p2/p3/X.java")));
	} finally {
		IFile xSrcFile = getFile("/P/src/p1/p2/p3/X.java");
		if (xSrcFile != null) {
			Util.setReadOnly(xSrcFile, false);
		}
		if (pkg2 != null) {
			Util.setReadOnly(pkg2.getResource(), false);
		}
		if (pkgSource != null) {
			Util.setReadOnly(pkgSource.getResource(), false);
		}
		IPackageFragment p1Fragment = getPackage("/P/src2/p1");
		if (p1Fragment != null) {
			Util.setReadOnly(p1Fragment.getResource(), false);
		}
		IPackageFragment p3Fragment = getPackage("/P/src2/p1/p2/p3");
		if (p3Fragment != null) {
			Util.setReadOnly(p3Fragment.getResource(), false);
		}
		IFile xFile = getFile("/P/src2/p1/p2/p3/X.java");
		if (xFile != null) {
			Util.setReadOnly(xFile, false);
		}
		deleteFolder("/P/src/p1");
	}
}
/**
 * Ensures that a WorkingCopy cannot be moved to a different package.
 */
public void testMoveWorkingCopy() throws CoreException {
	ICompilationUnit copy = null;
	try {
		this.createFolder("/P/src/p1");
		this.createFile(
			"/P/src/p1/X.java",
			"package p1;\n" +
			"public class X {\n" +
			"}"
		);
		ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");
		copy = cuSource.getWorkingCopy(null);

		this.createFolder("/P/src/p2");
		IPackageFragment pkgDest = getPackage("/P/src/p2");

		moveNegative(copy, pkgDest, null, null, false, IJavaModelStatusConstants.INVALID_ELEMENT_TYPES);
	} finally {
		if (copy != null) copy.discardWorkingCopy();
	}
}

/*
 * Ensures that a primary working copy can be moved to a different package
 * and that its buffer doesn't contain unsaved changed after the move.
 * (regression test for bug 83599 CU dirty after move refactoring)
 */
public void testMoveWorkingCopy2() throws CoreException {
	ICompilationUnit copy = null;
	try {
		this.createFolder("/P/src/p1");
		this.createFile(
			"/P/src/p1/X.java",
			"package p1;\n" +
			"public class X {\n" +
			"}"
		);
		copy = getCompilationUnit("/P/src/p1/X.java");
		copy.becomeWorkingCopy(null);

		this.createFolder("/P/src/p2");
		IPackageFragment pkgDest = getPackage("/P/src/p2");

		movePositive(copy, pkgDest, null, null, false);
		assertTrue("Should not have unsaved changes", !copy.getBuffer().hasUnsavedChanges());
	} finally {
		if (copy != null) copy.discardWorkingCopy();
	}
}
}
