/*******************************************************************************
 * Copyright (c) 2009 by SAP AG, Walldorf. 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     SAP AG - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.ws.jaxws.dom.runtime.tests.dom.persistence.sync;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jst.ws.jaxws.dom.runtime.api.IServiceEndpointInterface;
import org.eclipse.jst.ws.jaxws.dom.runtime.api.IWebService;
import org.eclipse.jst.ws.jaxws.dom.runtime.api.IWebServiceProject;
import org.eclipse.jst.ws.jaxws.dom.runtime.persistence.JaxWsWorkspaceResource;
import org.eclipse.jst.ws.jaxws.testutils.jobs.JobUtils;
import org.eclipse.jst.ws.jaxws.testutils.project.TestEjb3Project;
import org.eclipse.jst.ws.jaxws.testutils.project.TestProject;

public class ModelSynchronizationTests extends SynchronizationTestFixture
{
	private void assertBeforeAfterAreTheSame()
	{	final IWebServiceProject newRefWsPrj1 = domUtil.findProjectByName(target.getDOM(), testPrj1.getJavaProject().getElementName());
		assertEquals(wsPrj1, newRefWsPrj1);
		assertEquals(ws1, domUtil.findWsByImplName(newRefWsPrj1, ws1ImplName));
		assertEquals(sei1, domUtil.findSeiByImplName(newRefWsPrj1, sei1ImplName));
		
		final IWebServiceProject newRefWsPrj2 = domUtil.findProjectByName(target.getDOM(), testPrj2.getJavaProject().getElementName());
		assertEquals(wsPrj2, newRefWsPrj2);
		assertEquals(ws2, domUtil.findWsByImplName(newRefWsPrj2, ws2ImplName));
		assertEquals(sei2, domUtil.findSeiByImplName(newRefWsPrj2, sei2ImplName));
	}
	
	public void test_openedWsProjectSynched() throws Exception
	{
		final TestProject testPrj3 = new TestProject(new TestEjb3Project("TestEJBProject3").getProject());
		try {
			allowedProjects.add(testPrj3.getJavaProject().getElementName());
			final IPackageFragment modelSync3 = testPrj3.createPackage("com.sap.test.modelsync3");
			testPrj3.createType(modelSync3, "Sei3.java", "@javax.jws.WebService(name=\"Sei3Name\") public interface Sei3 {}");
			testPrj3.createType(modelSync3, "WS3.java", "@javax.jws.WebService(serviceName=\"WS3Name\", endpointInterface=\"com.sap.test.modelsync1.Sei3Name\") public class WS3 {}");
			testPrj3.getProject().close(null);
			JobUtils.waitForJobs();
			
			target.startSynchronizing();
			testPrj3.getProject().open(null);
			JobUtils.waitForJobs();
			
			assertBeforeAfterAreTheSame();
			final IWebServiceProject wsPrj3 = domUtil.findProjectByName(target.getDOM(), testPrj3.getJavaProject().getElementName());
			assertNotNull("Web Service Project not synchronized after opened",wsPrj3);
			final IWebService ws3 = domUtil.findWsByImplName(wsPrj3, "com.sap.test.modelsync3.WS3");
			assertNotNull("Web Service not synchronized after containing project was oppened", ws3);
			final IServiceEndpointInterface sei3 = domUtil.findSeiByImplName(wsPrj3, "com.sap.test.modelsync3.Sei3");
			assertNotNull("Service Endpoint interface not synchronized after containing project was oppened", sei3);
		} finally
		{
			testPrj3.dispose();
		}
	}
		
	public void test_openedProjectWithEnumsInitialySynched() throws CoreException, Exception
	{
		final TestProject testPrj3 = new TestProject(new TestEjb3Project("TestEJBProject3").getProject());
		try {
			allowedProjects.add(testPrj3.getJavaProject().getElementName());
			final IPackageFragment modelSync3 = testPrj3.createPackage("com.sap.test.modelsync3");
			testPrj3.createType(modelSync3, "TestEnum.java", "public enum TestEnum {A, B, C}");
			target = createTarget();
			JobUtils.waitForJobs();
			
			target.load(null);
			final IWebServiceProject wsPrj3 = domUtil.findProjectByName(target.getDOM(), testPrj3.getJavaProject().getElementName());
			assertNotNull("Web Service Project not synchronized after created",wsPrj3);
		} finally 
		{
			testPrj3.dispose();
		}
	}

	public void test_newSeiCompilationUnitsSynched() throws JavaModelException, CoreException, InterruptedException
	{
		verifySetUpModelEntitesNotChanged();
		final IPackageFragment pf = testPrj1.createPackage("com.sap.test.newsei");
		JobUtils.waitForJobs();
		
		target.startSynchronizing();
		testPrj1.createType(pf, "Sei3.java", "@javax.jws.WebService(name=\"Sei3Name\", targetNamespace=\"http://com.sap.test/\") public interface Sei3 {}");
		JobUtils.waitForJobs();
		
		assertBeforeAfterAreTheSame();
		final IWebServiceProject wsPrj1 = domUtil.findProjectByName(target.getDOM(), testPrj1.getJavaProject().getElementName());
		final IServiceEndpointInterface sei3 = domUtil.findSeiByImplName(wsPrj1, "com.sap.test.newsei.Sei3");
		assertNotNull("Newly added SEI not synched into the model",sei3);
		assertEquals("Java Intf for newly added SEI does not match the expected", "com.sap.test.newsei.Sei3", sei3.getImplementation());
		assertEquals("Target NS for newly added SEI does not match the expected", "http://com.sap.test/", sei3.getTargetNamespace());
		assertEquals("The name of the newly added sei doesn't match", "Sei3Name", sei3.getName());
	}

	public void test_unreSolvedSeiRefGetsResolvedAfterSeiAdded() throws JavaModelException, CoreException, InterruptedException
	{
		verifySetUpModelEntitesNotChanged();
		final IPackageFragment pf = testPrj1.createPackage("com.sap.test.newws");
		JobUtils.waitForJobs();
		//Make the WS be created with a reference to "com.sap.test.newsei.Sei3" which doesn't exist yet. 
		target.startSynchronizing();
		testPrj1.createType(pf, "WS3.java", "@javax.jws.WebService(serviceName=\"WS3Name\", endpointInterface=\"com.sap.test.newsei.Sei3\") public class WS3 {}");
		JobUtils.waitForJobs();
		
		assertBeforeAfterAreTheSame();
		
		final IWebServiceProject wsPrj1 = domUtil.findProjectByName(target.getDOM(), testPrj1.getJavaProject().getElementName());
		final IWebService ws3 = domUtil.findWsByImplName(wsPrj1, "com.sap.test.newws.WS3");
		assertNotNull("Web Service not synchronized after new compilation unit with ws was added", ws3);
		//add a new sei and test that it has been synched.
		test_newSeiCompilationUnitsSynched();
		//now check taht the Sei ref in ws3 has been properly resolved
		final IServiceEndpointInterface newlyAddedSei = domUtil.findSeiByImplName(wsPrj1, "com.sap.test.newsei.Sei3");
		assertNotNull("Newly added sei not found in the model. Probably the test_newSeiCompilationUnitsSynched() test method has changed the name of the interface it works with", newlyAddedSei);
		assertSame("Web Service Reference not resolved properly", newlyAddedSei, ws3.getServiceEndpoint());
	}
	
	public void test_newSourceFolderWithJavaContentSynchedWhenAdded() throws JavaModelException, CoreException, InterruptedException
	{
	//	verifySetUpModelEntitesNotChanged();
		//create new folder, which will later on be made a soure folder
		IFolder folder = testPrj1.getProject().getFolder("src1");
		folder.create(true, true, null);
		//make the folder a source folder now in order to create the type in there.
		final IClasspathEntry[] oldEntries = testPrj1.getJavaProject().getRawClasspath();
		final IClasspathEntry[] newEntries = new IClasspathEntry[oldEntries.length + 1];
		//create a new package fragment folder. Note htat it cannot be used to create type, as the folder is not source folder yet
		System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length);
		final IPackageFragmentRoot newSourceFolder = testPrj1.getJavaProject().getPackageFragmentRoot(folder);
		newEntries[oldEntries.length] = JavaCore.newSourceEntry(newSourceFolder.getPath());
		testPrj1.getJavaProject().setRawClasspath(newEntries, null);
		final IPackageFragment pf = newSourceFolder.createPackageFragment("com.sap.test.newws", true, null);
		//now create the types
		testPrj1.createType(pf, "WS3.java", "@javax.jws.WebService(serviceName=\"WS3Name\", endpointInterface=\"com.sap.test.newsei.Sei3\") public class WS3 {}");
		testPrj1.createType(pf, "Sei3.java", "@javax.jws.WebService(name=\"Sei3Name\") public interface Sei3 {}");
		//after the type is created make the source folder an ordinary source again. 
		testPrj1.getJavaProject().setRawClasspath(oldEntries, null);
		JobUtils.waitForJobs();
		//then start synchronizing
		target.startSynchronizing();
		//finally the resource is sychnronizing and in the same time we have a folder with source content. So just make it a source folder again.
		testPrj1.getJavaProject().setRawClasspath(newEntries, null);
		JobUtils.waitForJobs();
		
		final IWebServiceProject wsPrj1 = domUtil.findProjectByName(target.getDOM(), testPrj1.getJavaProject().getElementName());
		final IWebService ws3 = domUtil.findWsByImplName(wsPrj1, "com.sap.test.newws.WS3");
		assertNotNull("Web Service not synchronized after a source folder in which it was contained was added", ws3);
		final IServiceEndpointInterface sei3 = domUtil.findSeiByImplName(wsPrj1, "com.sap.test.newws.Sei3");
		assertNotNull("Sei not synched after a source folder in which it was contained was added", sei3);
		
	}
	
	public void test_removedSourceFolderSyched() throws CoreException, InterruptedException
	{
		test_newSourceFolderWithJavaContentSynchedWhenAdded();
		final IClasspathEntry[] oldEntries = testPrj1.getJavaProject().getRawClasspath();
		final IClasspathEntry[]  newEntries = new IClasspathEntry[oldEntries.length - 1];
		System.arraycopy(oldEntries, 0, newEntries, 0, newEntries.length);
		testPrj1.getJavaProject().setRawClasspath(newEntries, null);
		JobUtils.waitForJobs();
		
		assertNull(domUtil.findWsByImplName(wsPrj1, "com.sap.test.newws.WS3"));
		assertNull(domUtil.findSeiByImplName(wsPrj1, "com.sap.test.newws.Sei3"));
	}
	
	public void test_removedOrClosedProjectSynched() throws JavaModelException, CoreException
	{
		target.startSynchronizing();
		final IPackageFragment modelSync1 = testPrj1.createPackage("com.sap.test.modelsync1_1");
		testPrj1.createType(modelSync1, "WS3.java", "@javax.jws.WebService(serviceName=\"WS3Name\", endpointInterface=\"com.sap.test.modelsync2_1.Sei3\") public class WS3 {}");
	
		final IPackageFragment modelSync2 = testPrj2.createPackage("com.sap.test.modelsync2_1");
		testPrj2.createType(modelSync2, "Sei3.java", "@javax.jws.WebService(name=\"Sei3Name\") public interface Sei3 {}");
		JobUtils.waitForJobs();
		
		
		final IWebService ws3 = domUtil.findWsByImplName(wsPrj1, "com.sap.test.modelsync1_1.WS3");
		assertNotNull(ws3);
		
		final IServiceEndpointInterface sei3 = domUtil.findSeiByImplName(wsPrj2, "com.sap.test.modelsync2_1.Sei3");
		assertNotNull(sei3);
		assertEquals(sei3, ws3.getServiceEndpoint());
		final String testPrj2Name = testPrj2.getJavaProject().getElementName();
		testPrj2.getProject().close(null);
		JobUtils.waitForJobs();
		assertNull(domUtil.findProjectByName(target.getDOM(), testPrj2Name));
		assertNull("The web service returns a sei instance which is contained in a closed project", ws3.getServiceEndpoint());
	}
	
	public void test_deletedCUWithSeiSynched() throws JavaModelException, CoreException
	{
		target.startSynchronizing();
		final ICompilationUnit sei1CU = testPrj1.getJavaProject().findType(sei1ImplName).getCompilationUnit();
		sei1CU.delete(true, null);
		JobUtils.waitForJobs();
		
		assertFalse(wsPrj1.getServiceEndpointInterfaces().contains(sei1));
		assertNull(ws1.getServiceEndpoint());
	}
	
	public void test_deletedCUWithWSSynched() throws JavaModelException, CoreException
	{
		target.startSynchronizing();
		final ICompilationUnit ws1CU = testPrj1.getJavaProject().findType(ws1ImplName).getCompilationUnit();
		ws1CU.delete(true, null);
		JobUtils.waitForJobs();
		
		assertFalse(wsPrj1.getWebServices().contains(ws1));
		assertFalse(sei1.getImplementingWebServices().contains(ws1));
	}

	public void test_deletedCuContentWithSeiSynched() throws JavaModelException
	{
		target.startSynchronizing();
		final ICompilationUnit sei1Cu = testPrj1.getJavaProject().findType(sei1ImplName).getCompilationUnit();
		testUtil.setContents(sei1Cu, "");
		JobUtils.waitForJobs();
		
		assertFalse(wsPrj1.getWebServices().contains(sei1));
		assertNull(ws1.getServiceEndpoint());
	}
	
	public void test_deletedCuContentWithWsSynched() throws JavaModelException
	{
		target.startSynchronizing();
		final ICompilationUnit ws1CU = testPrj1.getJavaProject().findType(ws1ImplName).getCompilationUnit();
		testUtil.setContents(ws1CU, "");
		JobUtils.waitForJobs();
		
		assertFalse(wsPrj1.getWebServices().contains(ws1));
		assertFalse(sei1.getImplementingWebServices().contains(ws1));
	}	
	
	public void test_movedCUWithWSInOtherProjectWithSameJavaNameSynched() throws JavaModelException, CoreException
	{
		target.startSynchronizing();
		final ICompilationUnit ws1CU = testPrj1.getJavaProject().findType(ws1ImplName).getCompilationUnit();
		final IPackageFragment moveIn = testPrj2.getSourceFolder().createPackageFragment(ws1CU.getParent().getElementName(), true, null);
		ws1CU.move(moveIn, null, null, false, null);
		JobUtils.waitForJobs();
		
		assertFalse(wsPrj1.getWebServices().contains(ws1));
		assertTrue(wsPrj2.getWebServices().contains(ws1));
		assertTrue(sei1.getImplementingWebServices().contains(ws1));
	}
	
	public void test_movedCUWithSeiInOtherProjectWithSameJavaNameSynched() throws JavaModelException, CoreException
	{
		target.startSynchronizing();
		final ICompilationUnit se1CU = testPrj1.getJavaProject().findType(sei1ImplName).getCompilationUnit();
		final IPackageFragment moveIn = testPrj2.getSourceFolder().createPackageFragment(se1CU.getParent().getElementName(), true, null);
		se1CU.move(moveIn, null, null, false, null);
		JobUtils.waitForJobs();
		
		assertFalse(wsPrj1.getServiceEndpointInterfaces().contains(sei1));
		assertTrue(wsPrj2.getServiceEndpointInterfaces().contains(sei1));
		assertSame(ws1.getServiceEndpoint(), sei1);
	}
	
	public void test_renamedCUWithSeiSynched() throws JavaModelException, CoreException
	{
		target.startSynchronizing();
		final ICompilationUnit se1CU = testPrj1.getJavaProject().findType(sei1ImplName).getCompilationUnit();
		se1CU.findPrimaryType().rename("Sei1NewName", false, null);
		JobUtils.waitForJobs();
		final ICompilationUnit se1CURenamed = testPrj1.getJavaProject().findType("com.sap.test.modelsync1.Sei1NewName").getCompilationUnit();
		
		assertEquals("Sei1NewName.java", se1CURenamed.getElementName());
		IServiceEndpointInterface renamedSei1 = domUtil.findSeiByImplName(wsPrj1, se1CURenamed.findPrimaryType().getFullyQualifiedName());
		assertNotNull(renamedSei1);
		assertNull(ws1.getServiceEndpoint());
	}

	public void test_renamedCUWithWSSynched() throws JavaModelException, CoreException
	{
		target.startSynchronizing();
		final ICompilationUnit ws1CU = testPrj1.getJavaProject().findType(ws1ImplName).getCompilationUnit();
		ws1CU.findPrimaryType().rename("WS1NewName", false, null);
		JobUtils.waitForJobs();
		final ICompilationUnit ws1CURenamed = testPrj1.getJavaProject().findType("com.sap.test.modelsync1.WS1NewName").getCompilationUnit();
		
		assertEquals("WS1NewName.java", ws1CURenamed.getElementName());
		IWebService renamedWS1 = domUtil.findWsByImplName(wsPrj1, ws1CURenamed.findPrimaryType().getFullyQualifiedName());
		assertNotNull(renamedWS1);
		assertFalse(sei1.getImplementingWebServices().contains(ws1));
		assertTrue(sei1.getImplementingWebServices().contains(renamedWS1));
		assertSame(sei1, renamedWS1.getServiceEndpoint());
	}
	
	public void test_removedWSAnnotationFromSeiSynched() throws JavaModelException, CoreException
	{
		target.startSynchronizing();
		final ICompilationUnit se1CU = testPrj1.getJavaProject().findType(sei1ImplName).getCompilationUnit();
		testUtil.setContents(se1CU, "public interface Sei1 {}");
		JobUtils.waitForJobs();
		assertNull(domUtil.findSeiByImplName(wsPrj1, sei1ImplName));
		assertNull(ws1.getServiceEndpoint());
	}
	
	public void test_removedWSAnnotationFromWSSynched() throws JavaModelException, CoreException
	{
		target.startSynchronizing();
		final ICompilationUnit se1CU = testPrj1.getJavaProject().findType(ws1ImplName).getCompilationUnit();
		testUtil.setContents(se1CU, "public class WS1 {}");
		JobUtils.waitForJobs();
		assertNull(domUtil.findSeiByImplName(wsPrj1, ws1ImplName));
		assertTrue(sei1.getImplementingWebServices().size() == 0);
	}
	
	public void test_addedWSAnnotaionToClassSynched() throws JavaModelException, CoreException
	{
		target.startSynchronizing();
		final IPackageFragment modelSync4 = testPrj1.createPackage("com.sap.test.modelsync4");
		final ICompilationUnit ws4CU = testPrj1.createType(modelSync4, "WS4.java", "public class WS4 {}").getCompilationUnit();
		testUtil.setContents(ws4CU, "@javax.jws.WebService(serviceName=\"WS4Name\", endpointInterface=\"com.sap.test.modelsync1.Sei1\", portName=\"TestPortName\", targetNamespace=\"http://com.sap/test\", wsdlLocation=\"C:/test/wsdl/location\") public class WS4 {}");
		JobUtils.waitForJobs();
		
		final IWebService addedWS4 = domUtil.findWsByImplName(wsPrj1, ws4CU.findPrimaryType().getFullyQualifiedName());
		assertNotNull(addedWS4);
		assertTrue(addedWS4.getServiceEndpoint() == sei1);
		assertEquals("portName not same", "TestPortName", addedWS4.getPortName());
		assertEquals("targetNamespace not same", "http://com.sap/test", addedWS4.getTargetNamespace());
		assertEquals("wsdlLocation not same", "C:/test/wsdl/location", addedWS4.getWsdlLocation());
	}
	
	public void test_addedWSAnnotationToSeiSynched() throws JavaModelException, CoreException
	{
		target.startSynchronizing();
		final IPackageFragment modelSync4 = testPrj1.createPackage("com.sap.test.modelsync4");
		
		final IType ws4Type = testPrj1.createType(modelSync4, "WS4.java", "@javax.jws.WebService(serviceName=\"WS4Name\", endpointInterface=\"com.sap.test.modelsync4.Sei4\") public class WS4 {}");
		JobUtils.waitForJobs();
		
		final IWebService ws4 = domUtil.findWsByImplName(wsPrj1, ws4Type.getFullyQualifiedName());
		assertNotNull(ws4);
		assertNull(ws4.getServiceEndpoint());
		
		final ICompilationUnit sei4CU = testPrj1.createType(modelSync4, "Sei4.java", "public interface Sei4 {}").getCompilationUnit();
		testUtil.setContents(sei4CU, "@javax.jws.WebService(name=\"Sei4Name\") public interface Sei4 {}");
		JobUtils.waitForJobs();
		
		final IServiceEndpointInterface addedWS4 = domUtil.findSeiByImplName(wsPrj1, sei4CU.findPrimaryType().getFullyQualifiedName());
		assertNotNull(addedWS4);
		assertSame(ws4.getServiceEndpoint(), addedWS4);
	}
	
	public void test_changedSeiRefSynched() throws JavaModelException, CoreException
	{
		target.startSynchronizing();
		final ICompilationUnit ws1CU = testPrj1.getJavaProject().findType(ws1.getImplementation()).getCompilationUnit();
		testUtil.setContents(ws1CU, "@javax.jws.WebService(serviceName=\"WS1Name\", endpointInterface=\"com.sap.test.modelsync2.Sei2\") public class WS1 {}");
		JobUtils.waitForJobs();
		
		assertSame(sei2, ws1.getServiceEndpoint());
		assertSame(ws1, domUtil.findWsByImplName(wsPrj1, ws1.getImplementation()));
	}
	
	public void test_changedSeiRefWithUnxesistingSynched() throws JavaModelException, CoreException
	{
		target.startSynchronizing();
		final ICompilationUnit ws1CU = testPrj1.getJavaProject().findType(ws1.getImplementation()).getCompilationUnit();
		testUtil.setContents(ws1CU, "@javax.jws.WebService(serviceName=\"WS1Name\", endpointInterface=\"com.sap.test.modelsync2.SeiUnexisting\") public class WS1 {}");
		JobUtils.waitForJobs();
		
		assertNull(ws1.getServiceEndpoint());
		assertSame(ws1, domUtil.findWsByImplName(wsPrj1, ws1.getImplementation()));
	}	
	
	public void test_changedFromExplicitToImplicit() throws JavaModelException, CoreException
	{
		target.startSynchronizing();
		final ICompilationUnit ws1CU = testPrj1.getJavaProject().findType(ws1.getImplementation()).getCompilationUnit();
		testUtil.setContents(ws1CU, "@javax.jws.WebService(serviceName=\"WS1Name\", name=\"ImplicitInterfaceName\") public class WS1 {}");
		JobUtils.waitForJobs();
		
		assertNotSame(sei2, ws1.getServiceEndpoint());
		assertTrue(ws1.getServiceEndpoint().isImplicit());
		assertEquals("ImplicitInterfaceName", ws1.getServiceEndpoint().getName());
	}
	
	public void test_deletedPackageSynched() throws CoreException
	{
		target.startSynchronizing();
		final IPackageFragment modelSync3 = testPrj1.createPackage("com.sap.test.modelsync3");
		testPrj1.createType(modelSync3, "WS4.java", "@javax.jws.WebService(serviceName=\"WS1Name\", endpointInterface=\"com.sap.test.modelsync1.Sei1\") public class WS4 {}");
		JobUtils.waitForJobs();
		
		final IWebService ws4 = domUtil.findWsByImplName(wsPrj1, "com.sap.test.modelsync3.WS4");
		assertNotNull(ws4);
		assertSame(sei1, ws4.getServiceEndpoint());
		final IPackageFragment pf = testPrj1.getSourceFolder().getPackageFragment("com.sap.test.modelsync1");
		pf.delete(true, null);
		JobUtils.waitForJobs();
		
		assertNull(domUtil.findSeiByImplName(wsPrj1, sei1ImplName));
		assertNull(domUtil.findWsByImplName(wsPrj1, ws1ImplName));
		assertNull(ws4.getServiceEndpoint());
	}
	
	public void test_addedPackageWithCompilationUnitsSynched() throws CoreException, IOException
	{
		target.startSynchronizing();
		final File ioPackage = new File(testPrj1.getSourceFolder().getResource().getRawLocation().toOSString(), "com/sap/test/modelsync4");
		ioPackage.mkdirs();
		final FileWriter writer = new FileWriter(new File(ioPackage, "WS4.java"));
		try {
			writer.write("package com.sap.test.modelsync4;\n @javax.jws.WebService(serviceName=\"WS1Name\", endpointInterface=\"com.sap.test.modelsync1.Sei1\") public class WS4 {}");
			writer.flush();
		} finally 
		{
			writer.close();
		}
		testPrj1.getSourceFolder().getResource().refreshLocal(IResource.DEPTH_INFINITE,null);
		JobUtils.waitForJobs();
		
		assertNotNull(domUtil.findWsByImplName(wsPrj1, "com.sap.test.modelsync4.WS4"));
	}

	public void test_changedClassToInterface() throws CoreException
	{
		target.startSynchronizing();
		final IPackageFragment modelSync = testPrj1.createPackage("com.sap.test.modelsync4");		
		final ICompilationUnit wsCU = testPrj1.createType(modelSync, "WS4.java", "@javax.jws.WebService() public class WS4 {}").getCompilationUnit();
		JobUtils.waitForJobs();
		IWebService ws4 = domUtil.findWsByImplName(wsPrj1, wsCU.findPrimaryType().getFullyQualifiedName());
		assertNotNull(ws4);
		testUtil.setContents(wsCU, "@javax.jws.WebService() public interface WS4 {}");
		JobUtils.waitForJobs();
		ws4 = domUtil.findWsByImplName(wsPrj1, wsCU.findPrimaryType().getFullyQualifiedName());
		assertNull(ws4);
		IServiceEndpointInterface sei = domUtil.findSeiByImplName(wsPrj1, wsCU.findPrimaryType().getFullyQualifiedName());
		assertNotNull(sei);
		assertFalse(sei.isImplicit());
	}

	public void test_changedInterfaceToClass() throws CoreException
	{
		target.startSynchronizing();
		final IPackageFragment modelSync = testPrj1.createPackage("com.sap.test.modelsync4");		
		final ICompilationUnit wsCU = testPrj1.createType(modelSync, "WS4.java", "@javax.jws.WebService() public interface WS4 {}").getCompilationUnit();
		JobUtils.waitForJobs();
		
		IServiceEndpointInterface sei = domUtil.findSeiByImplName(wsPrj1, wsCU.findPrimaryType().getFullyQualifiedName());
		assertNotNull(sei);
		assertFalse(sei.isImplicit());		
		testUtil.setContents(wsCU, "@javax.jws.WebService() public class WS4 {}");
		JobUtils.waitForJobs();
		
		sei = domUtil.findSeiByImplName(wsPrj1, wsCU.findPrimaryType().getFullyQualifiedName());
		assertNotNull(sei);
		assertTrue(sei.isImplicit());
		IWebService ws4 = domUtil.findWsByImplName(wsPrj1, wsCU.findPrimaryType().getFullyQualifiedName());
		assertNotNull(ws4);
	}
	
	public void test_changedInterfaceAndClassWithSimilarNamesNotRemovedFromDom() throws CoreException
	{
		target.startSynchronizing();
		final IPackageFragment modelSync = testPrj1.createPackage("com.sap.test.modelsync5");		
		final ICompilationUnit wsCU = testPrj1.createType(modelSync, "Test.java", "@javax.jws.WebService() public class Test {}").getCompilationUnit();
		JobUtils.waitForJobs();
		
		assertNotNull(domUtil.findWsByImplName(wsPrj1, wsCU.findPrimaryType().getFullyQualifiedName()));		
		final ICompilationUnit seiCU = testPrj1.createType(modelSync, "TestSei.java", "@javax.jws.WebService() public interface TestSei {}").getCompilationUnit();
		JobUtils.waitForJobs();
		assertNotNull(domUtil.findSeiByImplName(wsPrj1, seiCU.findPrimaryType().getFullyQualifiedName()));
		
		testUtil.setContents(wsCU, "@javax.jws.WebService(serviceName=\"TestService\") public class Test {}");
		JobUtils.waitForJobs();
		assertNotNull(domUtil.findSeiByImplName(wsPrj1, seiCU.findPrimaryType().getFullyQualifiedName()));
		assertNotNull(domUtil.findWsByImplName(wsPrj1, wsCU.findPrimaryType().getFullyQualifiedName()));		
	}	

	public void test_WsChangedToUseExplicitSEI() throws CoreException
	{
		target.startSynchronizing();
		final IPackageFragment modelSync = testPrj1.createPackage("com.sap.test.modelsync4");		
		final ICompilationUnit wsCU = testPrj1.createType(modelSync, "WS4.java", "@javax.jws.WebService() public class WS4 {}").getCompilationUnit();
		JobUtils.waitForJobs();
		IServiceEndpointInterface sei = domUtil.findSeiByImplName(wsPrj1, wsCU.findPrimaryType().getFullyQualifiedName());
		assertNotNull(sei);
		assertTrue(sei.isImplicit());		
		
		testUtil.setContents(wsCU, "@javax.jws.WebService(endpointInterface=\"com.sap.test.modelsync1.Sei1\") public class WS4 {}");
		JobUtils.waitForJobs();
		sei = domUtil.findSeiByImplName(wsPrj1, wsCU.findPrimaryType().getFullyQualifiedName());
		assertNull(sei);		
	}
	
	public void test_WsOpenedInWorkingCopyContentChangedReconcileCalled() throws CoreException
	{	
		target.startSynchronizing();
		final IPackageFragment modelSync = testPrj1.createPackage("com.sap.test.modelsync4");		
		final ICompilationUnit wsCu = testPrj1.createType(modelSync, "WS3.java", "@javax.jws.WebService() public class WS3 {}").getCompilationUnit();
		JobUtils.waitForJobs();
		IWebService ws3 = domUtil.findWsByImplName(wsPrj1, wsCu.findPrimaryType().getFullyQualifiedName());
		
		assertEquals(0, ws3.getServiceEndpoint().getWebMethods().size());
		// update compilation unit without updating the underlying resource
		wsCu.becomeWorkingCopy(null);
		wsCu.getBuffer().setContents("@javax.jws.WebService public class WS3 {" +
				"public void test() {}" +
				"}");
		wsCu.reconcile(ICompilationUnit.NO_AST, false, null, null);
		JobUtils.waitForJobs();
		
		assertEquals(1, ws3.getServiceEndpoint().getWebMethods().size());
	}
	
	public void test_WsOpenedInWorkingCopyContentChangedReconcileCalledOnNonJavaCU() throws CoreException
	{	
		target.startSynchronizing();
		
		IPackageFragmentRoot root = testPrj1.getJavaProject().getPackageFragmentRoot(testPrj1.getProject());
		IPackageFragment pf = root.getPackageFragment("");
		ICompilationUnit cu = pf.createCompilationUnit("NotWS.java", "@javax.jws.WebService public class NotWS {}", true, null);
		cu.becomeWorkingCopy(null);
		cu.getBuffer().setContents("@javax.jws.WebService(serviceName=\"NewNotWs\") public class NotWS {}");
		cu.reconcile(ICompilationUnit.NO_AST, false, null, null);
		JobUtils.waitForJobs();
		
		for (IWebService ws : wsPrj1.getWebServices()) {
			if (ws.getName().equals("NewNotWs")) {
				fail("reconcile on java file which is not on project's build path processed incorrectly");
			}
		}
	}
	
	private JaxWsWorkspaceResource createTarget()
	{
		return new JaxWsWorkspaceResource(javaModel) 
		{

			@Override
			public boolean approveProject(IJavaProject prj) {
				for (String allowedPrj : allowedProjects)
				{
					if (prj.getElementName().equals(allowedPrj))
					{
						return true;
					}
				}
				return false;
			}
		};
	}

	private void verifySetUpModelEntitesNotChanged()
	{
		final Adapter adapter = new AdapterImpl()
		{

			@Override
			public void notifyChanged(Notification msg)
			{
				fail("should not be called, because the objects created in the setup should not have been changed during this test");
				super.notifyChanged(msg);
			}
			
		};
		this.ws1.eAdapters().add(adapter);
		this.sei1.eAdapters().add(adapter);
		this.ws2.eAdapters().add(adapter);
		this.sei2.eAdapters().add(adapter);
	}
}
