/***********************************************************************
 * Copyright (c) 2008 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.jee.ui.internal.navigator.dnd;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jdt.internal.core.JarPackageFragmentRoot;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jst.j2ee.application.internal.operations.AddComponentToEnterpriseApplicationDataModelProvider;
import org.eclipse.jst.j2ee.application.internal.operations.IAddComponentToEnterpriseApplicationDataModelProperties;
import org.eclipse.jst.j2ee.application.internal.operations.RemoveComponentFromEnterpriseApplicationDataModelProvider;
import org.eclipse.jst.j2ee.application.internal.operations.UpdateManifestDataModelProperties;
import org.eclipse.jst.j2ee.application.internal.operations.UpdateManifestDataModelProvider;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifest;
import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualArchiveComponent;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.common.J2EEVersionUtil;
import org.eclipse.jst.j2ee.internal.dialogs.DependencyConflictResolveDialog;
import org.eclipse.jst.j2ee.internal.plugin.IJ2EEModuleConstants;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.j2ee.internal.provider.J2EEItemProvider;
import org.eclipse.jst.j2ee.model.IModelProvider;
import org.eclipse.jst.j2ee.model.ModelProviderManager;
import org.eclipse.jst.j2ee.navigator.internal.plugin.J2EENavigatorPlugin;
import org.eclipse.jst.j2ee.project.facet.EARFacetUtils;
import org.eclipse.jst.javaee.application.Application;
import org.eclipse.jst.jee.ui.internal.Messages;
import org.eclipse.jst.jee.ui.internal.navigator.ear.AbstractEarNode;
import org.eclipse.jst.jee.ui.internal.navigator.ear.BundledNode;
import org.eclipse.jst.jee.ui.internal.navigator.ear.GroupEARProvider;
import org.eclipse.jst.jee.ui.plugin.JEEUIPlugin;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.navigator.CommonDropAdapter;
import org.eclipse.ui.navigator.CommonDropAdapterAssistant;
import org.eclipse.ui.part.PluginTransfer;
import org.eclipse.ui.progress.IProgressService;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.datamodel.properties.ICreateReferenceComponentsDataModelProperties;
import org.eclipse.wst.common.componentcore.internal.operation.RemoveReferenceComponentsDataModelProvider;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent;
import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;

/**
 * Handles drop of JEE resources on EAR project thus adding them as modules.
 * 
 * @author Dimitar Giormov
 * 
 */
public class AddProjectToEARDropAssistant extends CommonDropAdapterAssistant {

	private static final Class IPROJECT_CLASS = IProject.class;
	private IVirtualComponent earComponent = null;
	private IProject earProject = null;
	private String libDir = null;
	private boolean resolveConflicts = false;

	public AddProjectToEARDropAssistant() {
		super();
	}

	public boolean isSupportedType(TransferData aTransferType) {
		return LocalSelectionTransfer.getTransfer().isSupportedType(aTransferType);
	}

	public IStatus handleDrop(CommonDropAdapter aDropAdapter, DropTargetEvent aDropTargetEvent, final Object aTarget) {
		if (LocalSelectionTransfer.getTransfer().isSupportedType(aDropAdapter.getCurrentTransfer())) {
			final IStructuredSelection selection = (IStructuredSelection) LocalSelectionTransfer.getTransfer().getSelection();
			IProgressService service = PlatformUI.getWorkbench().getProgressService();
			resolveConflicts = false;
			for (Iterator selectionIterator = selection.iterator(); selectionIterator.hasNext();) {
				Object sourceObject = selectionIterator.next();
				if (sourceObject instanceof IVirtualReference) {
					IVirtualReference reference = (IVirtualReference) sourceObject;
					/*
					 * If a reference is moved from the root to the lib
					 * directory check for conflicts with projects referenced by
					 * the ear referencing the same lib
					 */
					if (libDir.length() > 0 && !libDir.equals(reference.getRuntimePath().toString())) {
						if (hasConflictingProjectInMetaInf(reference)) {
							DependencyConflictResolveDialog dlg = new DependencyConflictResolveDialog(getShell(), DependencyConflictResolveDialog.DLG_TYPE_2);
							if (dlg.open() == DependencyConflictResolveDialog.BTN_ID_CANCEL) {
								return Status.CANCEL_STATUS;
							} else {
								resolveConflicts = true;
							}
						}
					}
				} else {
					if (libDir.length() > 0){
						IProject projectToAdd = getProject(sourceObject);
						if (hasConflictingProjectInMetaInf(projectToAdd)) {
							DependencyConflictResolveDialog dlg = new DependencyConflictResolveDialog(getShell(), DependencyConflictResolveDialog.DLG_TYPE_2);
							if (dlg.open() == DependencyConflictResolveDialog.BTN_ID_CANCEL) {
								return Status.CANCEL_STATUS;
							} else {
								resolveConflicts = true;
							}
						}
					}
				}
			}
			Job addProjectToEarJob = new Job(getJobTitle(earComponent)) {
				protected IStatus run(IProgressMonitor monitor) {

					IStatus status = null;

					List<IVirtualComponent> componentsToAdd = new ArrayList<IVirtualComponent>();
					List<IVirtualComponent> componentsToRemove = new ArrayList<IVirtualComponent>();

					for (Iterator selectionIterator = selection.iterator(); selectionIterator.hasNext();) {
						Object sourceObject = selectionIterator.next();

						if (sourceObject instanceof JarPackageFragmentRoot) {
							JarPackageFragmentRoot jarPackageFragment = (JarPackageFragmentRoot) sourceObject;

							String type = VirtualArchiveComponent.LIBARCHIVETYPE + IPath.SEPARATOR;
							IVirtualComponent archive = ComponentCore.createArchiveComponent(earComponent.getProject(), type + jarPackageFragment.getPath().toString());
							componentsToAdd.add(archive);
						} else if (sourceObject instanceof IVirtualReference) {
							IVirtualReference reference = (IVirtualReference) sourceObject;
							if (resolveConflicts) {
								status = resolveConflicts(reference.getReferencedComponent());
								if (!status.isOK()) {
									return status;
								}
							}
							IVirtualComponent archive = reference.getReferencedComponent();
							componentsToRemove.add(archive);
							status = removeComponentsFromEar(componentsToRemove, reference.getRuntimePath().toString());
							if (!status.isOK())
								return status;
							componentsToAdd.add(archive);
						} else {
							IProject projectToAdd = getProject(sourceObject);
							if (resolveConflicts) {
								status = resolveConflicts(ComponentCore.createComponent(projectToAdd));
								if (!status.isOK()) {
									return status;
								}
							}
							componentsToAdd.add(ComponentCore.createComponent(projectToAdd));
						}
					}

					if (!componentsToAdd.isEmpty()) {
						status = addComponentsToEar(componentsToAdd, libDir);
						if (!status.isOK())
							return status;
					}

					return status;
				}

			};
			service.showInDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), addProjectToEarJob);
			addProjectToEarJob.setRule(ResourcesPlugin.getWorkspace().getRoot());
			addProjectToEarJob.schedule();
		}
		return Status.OK_STATUS;
	}

	public IStatus validateDrop(Object target, int operation, TransferData transferType) {
		libDir = ""; //$NON-NLS-1$
		if (LocalSelectionTransfer.getTransfer().isSupportedType(transferType) || PluginTransfer.getInstance().isSupportedType(transferType)) {
			ISelection selection = LocalSelectionTransfer.getTransfer().getSelection();
			if (selection != null && !selection.isEmpty() && (selection instanceof IStructuredSelection)) {
				IStructuredSelection structuredSelection = (IStructuredSelection) selection;
				earProject = getProject(target);
				if (earProject == null) {
					return Status.CANCEL_STATUS;
				}
				earComponent = ComponentCore.createComponent(earProject);
				int earVersion = getEarVersion(earProject);
				if (target instanceof BundledNode && ((BundledNode) target).getBundledLibsDirectoryNode() == null) {
					libDir = ((Application) ModelProviderManager.getModelProvider(earProject).getModelObject()).getLibraryDirectory();
					if (libDir == null) {
						libDir = J2EEConstants.EAR_DEFAULT_LIB_DIR;
					}
				}

				IStatus status = null;
				for (Iterator iterator = structuredSelection.iterator(); iterator.hasNext();) {
					Object next = iterator.next();
					
					//check if library is physically present in the Ear path
					if (IVirtualReference.class.isInstance(next)){
						IVirtualComponent referencedComponent = ((IVirtualReference)next).getReferencedComponent();
						if (referencedComponent.isBinary() && VirtualArchiveComponent.class.isInstance(referencedComponent)){
							if (isPhysicallyAdded((VirtualArchiveComponent) referencedComponent)){
								return Status.CANCEL_STATUS;
							}
						}
					}

					if (next instanceof IVirtualReference) {
						return Status.OK_STATUS;
					}

					/*
					 * Check if we try to add a JarPackageFragment that is
					 * already referenced
					 */
					if (next instanceof JarPackageFragmentRoot) {
						JarPackageFragmentRoot jar = (JarPackageFragmentRoot) next;
						for (IVirtualReference reference : earComponent.getReferences()) {
							if (reference.getArchiveName().equals(jar.getElementName())) {
								return Status.CANCEL_STATUS;
							}
						}
						return Status.OK_STATUS;
					}

					/*
					 * Check if we try to add a module that is already
					 * referenced by the ear but at the same time allow to
					 * change its location from the root to the lib directory
					 * and the opposite.
					 */
					IProject projectToAdd = getProject(next);
					hasConflictingProjectInMetaInf(ComponentCore.createComponent(projectToAdd));
					try {
						for (IProject referencedProject : earProject.getReferencedProjects()) {
							if (referencedProject == projectToAdd) {
								return Status.CANCEL_STATUS;
							}
						}
					} catch (CoreException e) {
						String msg = e.getMessage() != null ? e.getMessage() : e.toString();
						status = J2EENavigatorPlugin.createErrorStatus(0, msg, e);
					}

					if ((status = validateProjectMayBeAdded(earProject, projectToAdd, earVersion)).isOK())
						return status;
				}
			}

		}
		return Status.CANCEL_STATUS;
	}
	
	private boolean isPhysicallyAdded(VirtualArchiveComponent component) {
		try {
			component.getProjectRelativePath();
			return true;
		} catch (IllegalArgumentException e) {
			return false;
		}
	}	

	/**
	 * @param target
	 */
	private IStatus validateProjectMayBeAdded(IProject earProject, IProject projectToAdd, int earVersion) {
		if (earProject == null || projectToAdd == null || earVersion < 0)
			return J2EENavigatorPlugin.createErrorStatus(0, Messages.AddProjectToEARDropAssistant_Could_not_add_module_to_Enterprise_, null);
		else if (!earProject.isAccessible()) {
			return J2EENavigatorPlugin.createErrorStatus(0, NLS.bind(Messages.AddProjectToEARDropAssistant_The_project_0_cannot_be_accesse_, earProject.getName()), null);
		} else if (!projectToAdd.isAccessible()) {
			return J2EENavigatorPlugin.createErrorStatus(0, Messages.AddProjectToEARDropAssistant_The_dragged_project_cannot_be_added_, null);
		}

		IStatus isValid = validateProjectToAdd(projectToAdd, earVersion);
		if (!isValid.isOK()) {
			return isValid;
		}
		
		return Status.OK_STATUS;
	}

	/**
	 * 
	 * @return -1 on error
	 */
	protected final int getEarVersion(IProject earProject) {
		int earVersion = -1;
		IModelProvider modelProvider = ModelProviderManager.getModelProvider(earProject);
		IFacetedProject facetedProject = null;
		try {
			facetedProject = ProjectFacetsManager.create(earProject);

			if (facetedProject != null) {
				double double1 = Double.parseDouble(facetedProject.getProjectFacetVersion(EARFacetUtils.EAR_FACET).getVersionString());
				earVersion = (int) (double1 * 10);
			} else {
				JEEUIPlugin.getDefault().logError("Could not acquire model elements for project \"" + earProject.getName() + "\".", null); //$NON-NLS-1$ //$NON-NLS-2$
			}
		} catch (CoreException e1) {
			String msg = e1.getMessage() != null ? e1.getMessage() : e1.toString();
			JEEUIPlugin.getDefault().logError(msg, e1);
		}

		return earVersion;
	}

	/**
	 * @param facetedProject
	 * @return
	 */
	protected final boolean hasEarFacet(IProject project) {
		IFacetedProject facetedProject = null;
		try {
			facetedProject = ProjectFacetsManager.create(project);
		} catch (CoreException e1) {
			String msg = e1.getMessage() != null ? e1.getMessage() : e1.toString();
			JEEUIPlugin.getDefault().logError(msg, e1);
		}
		return facetedProject != null && facetedProject.hasProjectFacet(EARFacetUtils.EAR_FACET);
	}

	protected final String calculateValidProjectName(final String originalName) {
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		String validName = originalName;
		int count = 1;
		while (root.getProject(validName).exists()) {
			validName = originalName + count++;
		}
		return validName;
	}

	protected String getJobTitle(IVirtualComponent earComponent) {
		return NLS.bind(Messages.AddModuleToEarDropAssistant_Adding_module_to_ea_, earComponent.getName());
	}

	protected IStatus validateProjectToAdd(IProject projectToAdd, int earVersion) {
		IStatus status = null;
		try {
			// check if the project to add is not an EAR itself
			IFacetedProject facetedProject = ProjectFacetsManager.create(projectToAdd);
			if (facetedProject == null) {
				facetedProject = ProjectFacetsManager.create(projectToAdd, true, new NullProgressMonitor());
				IProjectFacetVersion javafacetversion = ProjectFacetsManager.getProjectFacet(IModuleConstants.JST_JAVA).getDefaultVersion();
				facetedProject.installProjectFacet(javafacetversion, null, null);
				IProjectFacetVersion utilityfacetversion = ProjectFacetsManager.getProjectFacet(IModuleConstants.JST_UTILITY_MODULE).getDefaultVersion();
				facetedProject.installProjectFacet(utilityfacetversion, null, null);
			}
			if (facetedProject.hasProjectFacet(EARFacetUtils.EAR_FACET))
				status = Status.CANCEL_STATUS;
			else
				status = Status.OK_STATUS;

			// check if the project to add is with Java EE version equal or
			// lesser than that of the EAR
			String verStr = J2EEProjectUtilities.getJ2EEProjectVersion(projectToAdd);
			if (verStr != null) {
				int version;
				if (J2EEProjectUtilities.isApplicationClientProject(projectToAdd))
					version = J2EEVersionUtil.convertAppClientVersionStringToJ2EEVersionID(verStr);
				else if (J2EEProjectUtilities.isEJBProject(projectToAdd))
					version = J2EEVersionUtil.convertEJBVersionStringToJ2EEVersionID(verStr);
				else if (J2EEProjectUtilities.isDynamicWebProject(projectToAdd))
					version = J2EEVersionUtil.convertWebVersionStringToJ2EEVersionID(verStr);
				else if (J2EEProjectUtilities.isJCAProject(projectToAdd))
					version = J2EEVersionUtil.convertConnectorVersionStringToJ2EEVersionID(verStr);
				else
					version = J2EEVersionUtil.convertVersionStringToInt(verStr);

				if (version > earVersion)
					status = Status.CANCEL_STATUS;
				else
					status = Status.OK_STATUS;
			}
		} catch (CoreException e) {
			String msg = e.getMessage() != null ? e.getMessage() : e.toString();
			status = J2EENavigatorPlugin.createErrorStatus(0, msg, e);
		}
		return status;

	}

	protected static IProject getProject(Object element) {
		if (element == null)
			return null;
		IProject project = null;
		if (element instanceof IAdaptable)
			project = (IProject) ((IAdaptable) element).getAdapter(IPROJECT_CLASS);
		else
			project = (IProject) Platform.getAdapterManager().getAdapter(element, IPROJECT_CLASS);

		if (element instanceof AbstractEarNode) {
			project = ((AbstractEarNode) element).getEarProject();
		}

		if (element instanceof GroupEARProvider) {
			project = ((GroupEARProvider) element).getProject();
		}

		if (element instanceof IVirtualReference) {
			project = ((IVirtualReference) element).getReferencedComponent().getProject();
		}

		if (project == null) {
			if (element instanceof EObject) {
				project = ProjectUtilities.getProject((EObject) element);
			} else if (element instanceof J2EEItemProvider) {
				IFile associatedFile = ((J2EEItemProvider) element).getAssociatedFile();
				if (associatedFile != null)
					project = associatedFile.getProject();
			}
		}
		return project;
	}

	protected static String getDefaultURI(IVirtualComponent component) {
		IProject project = component.getProject();
		String name = component.getName();

		if (J2EEProjectUtilities.isDynamicWebProject(project)) {
			name += IModuleExtensions.DOT_WAR;
		} else if (J2EEProjectUtilities.isEARProject(project)) {
			name += IModuleExtensions.DOT_EAR;
		} else if (J2EEProjectUtilities.isJCAProject(project)) {
			name += IModuleExtensions.DOT_RAR;
		} else {
			name += IModuleExtensions.DOT_JAR;
		}
		return name;
	}

	private boolean hasConflictingProjectInMetaInf(Object lib) {
		IProject libProj = null; 
			if (lib instanceof IProject) {
				libProj = (IProject) lib; 
			} else if (lib instanceof IVirtualComponent) {
				libProj = ((IVirtualComponent) lib).getProject(); 
			} else if (lib instanceof IVirtualReference){
				libProj = ((IVirtualReference) lib).getReferencedComponent().getProject();
			}
		if(libProj == null){
			return false;
		}
		IProject earProject = earComponent.getProject();
		try {
			IProject[] earRefProjects = earProject.getReferencedProjects();
			for (int i = 0; i < earRefProjects.length; i++) {
				if (!J2EEProjectUtilities.isEARProject(earRefProjects[i]) && !earRefProjects[i].equals(libProj)) {
					IVirtualComponent cmp1 = ComponentCore.createComponent(earRefProjects[i]);
					if (cmp1 == null){
						continue;
					}
					IVirtualReference[] refs = cmp1.getReferences();
					for (int j = 0; j < refs.length; j++) {
						if (refs[j].getReferencedComponent().getProject().equals(libProj))
							return true;
					}
				}
			}
			return false;
		} catch (CoreException ce) {
			int k = 0;
		}
		return false;
	}

	protected IStatus addComponentsToEar(List<IVirtualComponent> components, String libDir) {
		IStatus status = null;
		IDataModel datamodel = DataModelFactory.createDataModel(new AddComponentToEnterpriseApplicationDataModelProvider());

		Map componentToURIMap = new HashMap();
		IVirtualComponent moduleComponent = null;
		for (Iterator itr = components.iterator(); itr.hasNext();) {
			moduleComponent = (IVirtualComponent) itr.next();
			componentToURIMap.put(moduleComponent, getDefaultURI(moduleComponent));
		}
		datamodel.setProperty(ICreateReferenceComponentsDataModelProperties.SOURCE_COMPONENT, earComponent);
		datamodel.setProperty(ICreateReferenceComponentsDataModelProperties.TARGET_COMPONENT_LIST, components);
		datamodel.setProperty(IAddComponentToEnterpriseApplicationDataModelProperties.TARGET_COMPONENTS_TO_URI_MAP, componentToURIMap);
		datamodel.setProperty(IAddComponentToEnterpriseApplicationDataModelProperties.TARGET_COMPONENTS_DEPLOY_PATH, libDir);
		try {
			return datamodel.getDefaultOperation().execute(new NullProgressMonitor(), null);
		} catch (ExecutionException e) {
			String msg = e.getMessage() != null ? e.getMessage() : e.toString();
			JEEUIPlugin.getDefault().logError(msg, e);
		}
		return status;
	}

	protected IStatus removeComponentsFromEar(List<IVirtualComponent> components, String libDir) {
		IStatus status = null;
		IDataModel datamodel = DataModelFactory.createDataModel(new RemoveComponentFromEnterpriseApplicationDataModelProvider());
		datamodel.setProperty(ICreateReferenceComponentsDataModelProperties.SOURCE_COMPONENT, earComponent);
		datamodel.setProperty(ICreateReferenceComponentsDataModelProperties.TARGET_COMPONENT_LIST, components);
		try {
			status = datamodel.getDefaultOperation().execute(new NullProgressMonitor(), null);
			if (!status.isOK()) {
				return status;
			}
		} catch (ExecutionException e) {
			String msg = e.getMessage() != null ? e.getMessage() : e.toString();
			JEEUIPlugin.getDefault().logError(msg, e);
		}
		return removeReferences(components, libDir, earComponent);
	}

	protected IStatus removeReferences(List<IVirtualComponent> components, String libDir, IVirtualComponent sourceComponent) {
		IVirtualReference[] refs = sourceComponent.getReferences();
		for (IVirtualReference ref : refs) {
			ref.getRuntimePath();
		}
		Map componentToURIMap = new HashMap();
		for (Iterator itr = components.iterator(); itr.hasNext();) {
			IVirtualComponent moduleComponent = (IVirtualComponent) itr.next();
			componentToURIMap.put(moduleComponent, getDefaultURI(moduleComponent));
		}
		final IDataModel model = DataModelFactory.createDataModel(new RemoveReferenceComponentsDataModelProvider());
		model.setProperty(IAddComponentToEnterpriseApplicationDataModelProperties.TARGET_COMPONENTS_TO_URI_MAP, componentToURIMap);
		model.setProperty(ICreateReferenceComponentsDataModelProperties.SOURCE_COMPONENT, sourceComponent);
		model.setProperty(ICreateReferenceComponentsDataModelProperties.TARGET_COMPONENT_LIST, components);
		if (libDir.length() > 0) {
			model.setProperty(ICreateReferenceComponentsDataModelProperties.TARGET_COMPONENTS_DEPLOY_PATH, libDir);
		}
		try {
			return model.getDefaultOperation().execute(null, null);
		} catch (ExecutionException e) {
			String msg = e.getMessage() != null ? e.getMessage() : e.toString();
			JEEUIPlugin.getDefault().logError(msg, e);
		}
		return Status.CANCEL_STATUS;
	}

	protected IStatus resolveConflicts(IVirtualComponent component) {
		IProject earProject = earComponent.getProject();
		try {
			IProject[] earRefProjects = earProject.getReferencedProjects();
			for (int i = 0; i < earRefProjects.length; i++) {
				if (!J2EEProjectUtilities.isEARProject(earRefProjects[i])) {
					IVirtualComponent cmp1 = ComponentCore.createComponent(earRefProjects[i]);
					if(cmp1 == null){
						continue;
					}
					IVirtualReference[] refs = cmp1.getReferences();
					for (int j = 0; j < refs.length; j++) {
						if (refs[j].getReferencedComponent().equals(component)) {
							List<IVirtualComponent> components = new ArrayList<IVirtualComponent>();
							components.add(refs[j].getReferencedComponent());
							IStatus status = removeReferences(components, refs[j].getRuntimePath().toString(), refs[j].getEnclosingComponent());
							if (!status.isOK()) {
								return status;
							}
							try {
								removeManifestDependency(refs[j].getEnclosingComponent(), refs[j].getReferencedComponent());
							} catch (ExecutionException e) {
								String msg = e.getMessage() != null ? e.getMessage() : e.toString();
								JEEUIPlugin.getDefault().logError(msg, e);
							}
						}
					}
				}
			}
		} catch (CoreException ce) {
			int k = 0;
		}
		// return false;
		return Status.OK_STATUS;
	}

	private void removeManifestDependency(final IVirtualComponent source, final IVirtualComponent target) throws ExecutionException {
		final String sourceProjName = source.getProject().getName();
		String targetProjName;
		if (target instanceof J2EEModuleVirtualArchiveComponent) {
			targetProjName = ((J2EEModuleVirtualArchiveComponent) target).getName();
			String[] pathSegments = targetProjName.split("" + IPath.SEPARATOR); //$NON-NLS-1$
			targetProjName = pathSegments[pathSegments.length - 1];
		} else {
			targetProjName = target.getProject().getName();
		}
		final IProgressMonitor monitor = new NullProgressMonitor();
		final IFile manifestmf = J2EEProjectUtilities.getManifestFile(source.getProject());
		final ArchiveManifest mf = J2EEProjectUtilities.readManifest(source.getProject());
		if (mf == null)
			return;
		final IDataModel updateManifestDataModel = DataModelFactory.createDataModel(new UpdateManifestDataModelProvider());
		updateManifestDataModel.setProperty(UpdateManifestDataModelProperties.PROJECT_NAME, sourceProjName);
		updateManifestDataModel.setBooleanProperty(UpdateManifestDataModelProperties.MERGE, false);
		updateManifestDataModel.setProperty(UpdateManifestDataModelProperties.MANIFEST_FILE, manifestmf);
		String[] cp = mf.getClassPathTokenized();
		List cpList = new ArrayList();
		String cpToRemove = (targetProjName.endsWith(IJ2EEModuleConstants.JAR_EXT)) ? 
				targetProjName : targetProjName + IJ2EEModuleConstants.JAR_EXT;
		for (int i = 0; i < cp.length; i++) {
			if (!cp[i].equals(cpToRemove)) {
				cpList.add(cp[i]);
			}
		}
		updateManifestDataModel.setProperty(UpdateManifestDataModelProperties.JAR_LIST, cpList);
		updateManifestDataModel.getDefaultOperation().execute(monitor, null);
	}
}
