/*******************************************************************************
 * Copyright (c) 2003, 2007 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.j2ee.application.internal.operations;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jst.j2ee.applicationclient.internal.creation.AppClientComponentImportDataModelProvider;
import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonarchiveFactory;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.OpenFailureException;
import org.eclipse.jst.j2ee.datamodel.properties.IAddWebComponentToEnterpriseApplicationDataModelProperties;
import org.eclipse.jst.j2ee.datamodel.properties.IEARComponentImportDataModelProperties;
import org.eclipse.jst.j2ee.datamodel.properties.IJ2EEComponentImportDataModelProperties;
import org.eclipse.jst.j2ee.datamodel.properties.IJ2EEModuleImportDataModelProperties;
import org.eclipse.jst.j2ee.datamodel.properties.IJavaUtilityJarImportDataModelProperties;
import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
import org.eclipse.jst.j2ee.internal.archive.ArchiveWrapper;
import org.eclipse.jst.j2ee.internal.archive.operations.EARComponentImportOperation;
import org.eclipse.jst.j2ee.internal.common.J2EEVersionUtil;
import org.eclipse.jst.j2ee.internal.common.XMLResource;
import org.eclipse.jst.j2ee.internal.earcreation.EARCreationResourceHandler;
import org.eclipse.jst.j2ee.internal.moduleextension.EarModuleManager;
import org.eclipse.jst.j2ee.internal.moduleextension.EjbModuleExtension;
import org.eclipse.jst.j2ee.internal.moduleextension.JcaModuleExtension;
import org.eclipse.jst.j2ee.internal.moduleextension.WebModuleExtension;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.j2ee.project.facet.EARFacetProjectCreationDataModelProvider;
import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetInstallDataModelProperties;
import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetProjectCreationDataModelProperties;
import org.eclipse.jst.jee.util.internal.JavaEEQuickPeek;
import org.eclipse.wst.common.componentcore.datamodel.properties.IFacetDataModelProperties;
import org.eclipse.wst.common.componentcore.datamodel.properties.IFacetProjectCreationDataModelProperties;
import org.eclipse.wst.common.componentcore.datamodel.properties.IFacetProjectCreationDataModelProperties.FacetDataModelMap;
import org.eclipse.wst.common.frameworks.datamodel.DataModelEvent;
import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.frameworks.datamodel.IDataModelListener;
import org.eclipse.wst.common.frameworks.datamodel.IDataModelOperation;
import org.eclipse.wst.common.frameworks.internal.WTPPlugin;
import org.eclipse.wst.common.frameworks.internal.operations.IProjectCreationPropertiesNew;
import org.eclipse.wst.common.frameworks.internal.operations.ProjectCreationDataModelProviderNew;
import org.eclipse.wst.common.frameworks.internal.plugin.WTPCommonPlugin;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.common.project.facet.core.runtime.IRuntime;

/**
 * This dataModel is used for to import Enterprise Applications(from EAR files) into the workspace.
 * 
 * This class (and all its fields and methods) is likely to change during the WTP 1.0 milestones as the new project
 * structures are adopted. Use at your own risk.
 * 
 * @plannedfor WTP 1.0
 */
public final class EARComponentImportDataModelProvider extends J2EEArtifactImportDataModelProvider implements IAnnotationsDataModel, IEARComponentImportDataModelProperties {

	/**
	 * This is only to force validation for the nested projects; do not set.
	 */
	public static final String NESTED_PROJECTS_VALIDATION = "EARImportDataModel.NESTED_PROJECTS_VALIDATION"; //$NON-NLS-1$

	/**
	 * This is only to force validation for the EAR name against the nested projects; do not set.
	 */
	public static final String EAR_NAME_VALIDATION = "EARImportDataModel.EAR_NAME_VALIDATION";//$NON-NLS-1$

	private IDataModelListener nestedListener = new IDataModelListener() {
		public void propertyChanged(DataModelEvent event) {
			if (event.getPropertyName().equals(PROJECT_NAME)) {
				model.notifyPropertyChange(NESTED_PROJECTS_VALIDATION, IDataModel.DEFAULT_CHG);
			}
		}
	};

	private Hashtable<IDataModel, IDataModel> ejbJarModelsToClientJarModels = new Hashtable<IDataModel, IDataModel>();

	private Hashtable<IDataModel, IDataModel> clientJarModelsToEjbJarModels = new Hashtable<IDataModel, IDataModel>();

	private ArchiveWrapper cachedLoadError = null;

	public Set getPropertyNames() {
		Set propertyNames = super.getPropertyNames();
		propertyNames.add(NESTED_MODULE_ROOT);
		propertyNames.add(UTILITY_LIST);
		propertyNames.add(MODULE_MODELS_LIST);
		propertyNames.add(EJB_CLIENT_LIST);
		propertyNames.add(UTILITY_MODELS_LIST);
		propertyNames.add(NESTED_PROJECTS_VALIDATION);
		propertyNames.add(EAR_NAME_VALIDATION);
		propertyNames.add(SELECTED_MODELS_LIST);
		propertyNames.add(USE_ANNOTATIONS);
		propertyNames.add(ALL_PROJECT_MODELS_LIST);
		propertyNames.add(UNHANDLED_PROJECT_MODELS_LIST);
		propertyNames.add(HANDLED_PROJECT_MODELS_LIST);
		return propertyNames;
	}

	public Object getDefaultProperty(String propertyName) {
		if (NESTED_MODULE_ROOT.equals(propertyName)) {
			return getLocation().toOSString();
		} else if (MODULE_MODELS_LIST.equals(propertyName) || UTILITY_LIST.equals(propertyName) || UTILITY_MODELS_LIST.equals(propertyName) || SELECTED_MODELS_LIST.equals(propertyName) || EJB_CLIENT_LIST.equals(propertyName)) {
			return Collections.EMPTY_LIST;
		} else if (USE_ANNOTATIONS.equals(propertyName)) {
			return Boolean.FALSE;
		} else if (ALL_PROJECT_MODELS_LIST.equals(propertyName)) {
			return getProjectModels();
		} else if (UNHANDLED_PROJECT_MODELS_LIST.equals(propertyName)) {
			return getUnhandledProjectModels();
		} else if (HANDLED_PROJECT_MODELS_LIST.equals(propertyName)) {
			return getHandledSelectedModels();
		}
		return super.getDefaultProperty(propertyName);
	}

	public void propertyChanged(DataModelEvent event) {
		super.propertyChanged(event);
		if (event.getPropertyName().equals(PROJECT_NAME)) {
			changeModuleCreationLocationForNameChange(getProjectModels());
		} else if (event.getPropertyName().equals(IFacetProjectCreationDataModelProperties.FACET_RUNTIME) && event.getDataModel() == model.getNestedModel(NESTED_MODEL_J2EE_COMPONENT_CREATION)) {
			Object propertyValue = event.getProperty();
			IDataModel nestedModel = null;
			List projectModels = (List) getProperty(ALL_PROJECT_MODELS_LIST);
			for (int i = 0; i < projectModels.size(); i++) {
				nestedModel = (IDataModel) projectModels.get(i);
				nestedModel.setProperty(IFacetProjectCreationDataModelProperties.FACET_RUNTIME, propertyValue);
			}
			fixupJavaFacets();
		}
	}

	public boolean propertySet(String propertyName, Object propertyValue) {
		if (ALL_PROJECT_MODELS_LIST.equals(propertyName) || UNHANDLED_PROJECT_MODELS_LIST.equals(propertyName) || HANDLED_PROJECT_MODELS_LIST.equals(propertyName) || EAR_NAME_VALIDATION.equals(propertyName)) {
			throw new RuntimeException(propertyName + " is an unsettable property"); //$NON-NLS-1$
		}
		boolean doSet = super.propertySet(propertyName, propertyValue);
		if (NESTED_MODULE_ROOT.equals(propertyName)) {
			updateModuleRoot();
		} else if (FILE_NAME.equals(propertyName)) {
			List nestedModels = getModuleModels();
			setProperty(MODULE_MODELS_LIST, nestedModels);
			updateModuleRoot();
			setProperty(UTILITY_LIST, null);

			IDataModel earProjectModel = model.getNestedModel(NESTED_MODEL_J2EE_COMPONENT_CREATION);
			if (getArchiveWrapper() != null) {
				FacetDataModelMap map = (FacetDataModelMap) earProjectModel.getProperty(IFacetProjectCreationDataModelProperties.FACET_DM_MAP);
				IDataModel earFacetDataModel = map.getFacetDataModel(J2EEProjectUtilities.ENTERPRISE_APPLICATION);

				JavaEEQuickPeek quickPeek = getArchiveWrapper().getJavaEEQuickPeek();
				int minimumVersion = quickPeek.getVersion();
				if(nestedModels != null){
					//increase the JavaEE facet version to accommodate the highest module version
					for(int i=0;i<nestedModels.size(); i++){
						IDataModel nestedModel = (IDataModel)nestedModels.get(i);
						ArchiveWrapper nestedWrapper = (ArchiveWrapper)nestedModel.getProperty(ARCHIVE_WRAPPER);
						int nestedEEVersion = nestedWrapper.getJavaEEQuickPeek().getJavaEEVersion();
						if(nestedEEVersion > minimumVersion){
							minimumVersion = nestedEEVersion;
						}
					}
				}
				
				String versionText = J2EEVersionUtil.getJ2EETextVersion(minimumVersion);
				earFacetDataModel.setStringProperty(IFacetDataModelProperties.FACET_VERSION_STR, versionText);
			}

			model.notifyPropertyChange(PROJECT_NAME, IDataModel.VALID_VALUES_CHG);
			if (getJ2EEVersion() < J2EEVersionConstants.VERSION_1_3)
				setBooleanProperty(USE_ANNOTATIONS, false);
			model.notifyPropertyChange(USE_ANNOTATIONS, IDataModel.ENABLE_CHG);
			fixupJavaFacets();
		} else if (UTILITY_LIST.equals(propertyName)) {
			updateUtilityModels((List) propertyValue);
		} else if (USE_ANNOTATIONS.equals(propertyName)) {
			List projectModels = (List) getProperty(MODULE_MODELS_LIST);
			IDataModel nestedModel = null;
			for (int i = 0; i < projectModels.size(); i++) {
				nestedModel = (IDataModel) projectModels.get(i);
				if (nestedModel.isProperty(USE_ANNOTATIONS)) {
					nestedModel.setProperty(USE_ANNOTATIONS, propertyValue);
				}
			}
		} else if (MODULE_MODELS_LIST.equals(propertyName)) {
			List newList = new ArrayList();
			newList.addAll(getProjectModels());
			setProperty(SELECTED_MODELS_LIST, newList);
		} else if (PROJECT_NAME.equals(propertyName)) {
			List nestedModels = (List) getProperty(MODULE_MODELS_LIST);
			IDataModel nestedModel = null;
			for (int i = 0; i < nestedModels.size(); i++) {
				nestedModel = (IDataModel) nestedModels.get(i);
				nestedModel.setProperty(IJ2EEFacetProjectCreationDataModelProperties.EAR_PROJECT_NAME, propertyValue);
			}
			nestedModels = (List) getProperty(UTILITY_MODELS_LIST);
			for (int i = 0; i < nestedModels.size(); i++) {
				nestedModel = (IDataModel) nestedModels.get(i);
				nestedModel.setProperty(IJavaUtilityJarImportDataModelProperties.EAR_PROJECT_NAME, propertyValue);
			}

			if (ProjectCreationDataModelProviderNew.validateProjectName(getStringProperty(PROJECT_NAME)).isOK()) {
				IProject project = ProjectUtilities.getProject(getStringProperty(PROJECT_NAME));
				if (null != project && project.exists()) {

					IFacetedProject facetedProject = null;
					boolean canContinue = true;
					try {
						facetedProject = ProjectFacetsManager.create(project);
					} catch (CoreException e) {
						Logger.getLogger().logError(e);
						canContinue = false;
					}

					if (canContinue) {
						IRuntime runtime = facetedProject.getRuntime();
						if (null != runtime) {
							setProperty(IFacetProjectCreationDataModelProperties.FACET_RUNTIME, runtime);
						}
					}
				}
			}
		}
		return doSet;
	}

	protected boolean forceResetOnPreserveMetaData() {
		return false;
	}

	protected void fixupJavaFacets() {
		List subProjects = getSelectedModels();
		IDataModel subDataModel = null;
		for (int i = 0; i < subProjects.size(); i++) {
			subDataModel = (IDataModel) subProjects.get(i);
			subDataModel.validateProperty(FACET_RUNTIME);
		}
	}

	public IStatus validate(String propertyName) {
		if (propertyName.equals(NESTED_PROJECTS_VALIDATION) || propertyName.equals(EAR_NAME_VALIDATION)) {
			boolean checkAgainstEARNameOnly = propertyName.equals(EAR_NAME_VALIDATION);

			String earProjectName = getStringProperty(IFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME);
			List subProjects = getSelectedModels();
			IDataModel subDataModel = null;
			String tempProjectName = null;
			ArchiveWrapper tempArchive = null;
			IStatus tempStatus = null;
			Hashtable<String, ArchiveWrapper> projects = new Hashtable<String, ArchiveWrapper>(4);
			for (int i = 0; i < subProjects.size(); i++) {
				subDataModel = (IDataModel) subProjects.get(i);
				tempProjectName = subDataModel.getStringProperty(IFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME);
				// TODO: add manual validation
				// IStatus status =
				// ProjectCreationDataModel.validateProjectName(tempProjectName);
				// if (!status.isOK()) {
				// return status;
				// }
				tempArchive = (ArchiveWrapper) subDataModel.getProperty(ARCHIVE_WRAPPER);

				if (checkAgainstEARNameOnly) {
					if (tempProjectName.equals(earProjectName)) {
						return WTPCommonPlugin.createWarningStatus(EARCreationResourceHandler.bind(EARCreationResourceHandler.EARImportDataModel_UI_1, new Object[] { tempProjectName,
								tempArchive.getPath() }));
					} else if (!WTPPlugin.isPlatformCaseSensitive()) {
						if (tempProjectName.toLowerCase().equals(earProjectName.toLowerCase())) {
							return WTPCommonPlugin.createWarningStatus(EARCreationResourceHandler.bind(EARCreationResourceHandler.EARImportDataModel_UI_1a, new Object[] { earProjectName,
									tempProjectName, tempArchive.getPath() }));
						}
					}
				} else {
					// if (!overwrite && subDataModel.getProject().exists()) {
					// return
					// WTPCommonPlugin.createErrorStatus(EARCreationResourceHandler.getString("EARImportDataModel_UI_0",
					// new Object[]{tempProjectName, tempArchive.getURI()})); //$NON-NLS-1$
					// }
					tempStatus = subDataModel.validateProperty(IFacetDataModelProperties.FACET_PROJECT_NAME);
					if (!tempStatus.isOK()) {
						return WTPCommonPlugin.createErrorStatus(EARCreationResourceHandler.bind(EARCreationResourceHandler.EARImportDataModel_UI_0, new Object[] { tempProjectName,
								tempArchive.getPath() }));
					}
					tempStatus = subDataModel.validate();
					if (!tempStatus.isOK()) {
						return tempStatus;
					}
					if (tempProjectName.equals(earProjectName)) {
						return WTPCommonPlugin.createErrorStatus(EARCreationResourceHandler.bind(EARCreationResourceHandler.EARImportDataModel_UI_1, new Object[] { tempProjectName,
								tempArchive.getPath() }));
					} else if (!WTPPlugin.isPlatformCaseSensitive()) {
						if (tempProjectName.toLowerCase().equals(earProjectName.toLowerCase())) {
							return WTPCommonPlugin.createErrorStatus(EARCreationResourceHandler.bind(EARCreationResourceHandler.EARImportDataModel_UI_1a, new Object[] { earProjectName,
									tempProjectName, tempArchive.getPath() }));
						}
					}
					if (projects.containsKey(tempProjectName)) {
						return WTPCommonPlugin.createErrorStatus(EARCreationResourceHandler.bind(EARCreationResourceHandler.EARImportDataModel_UI_2, new Object[] { tempProjectName,
								tempArchive.getPath(), ((Archive) projects.get(tempProjectName)).getURI() }));
					} else if (!WTPPlugin.isPlatformCaseSensitive()) {
						String lowerCaseProjectName = tempProjectName.toLowerCase();
						String currentKey = null;
						Enumeration keys = projects.keys();
						while (keys.hasMoreElements()) {
							currentKey = (String) keys.nextElement();
							if (currentKey.toLowerCase().equals(lowerCaseProjectName)) {
								return WTPCommonPlugin.createErrorStatus(EARCreationResourceHandler.bind(EARCreationResourceHandler.EARImportDataModel_UI_2a, new Object[] { tempProjectName,
										currentKey, tempArchive.getPath(), projects.get(currentKey).getPath() }));
							}
						}
					}
					projects.put(tempProjectName, tempArchive);
				}
			}
		} else if (propertyName.equals(FILE_NAME)) {
			IStatus status = super.validate(propertyName);
			if (!status.isOK()) {
				return status;
			} else if (cachedLoadError != null) {
				return WTPCommonPlugin
						.createWarningStatus(EARCreationResourceHandler.bind(EARCreationResourceHandler.EARImportDataModel_UI_4, new Object[] { cachedLoadError.getPath().toOSString() }));
			}
			return status;
		}
		// TODO: check context root is not inside current working
		// directory...this is invalid
		return super.validate(propertyName);
	}

	private void updateModuleRoot() {
		List projects = getProjectModels();
		String basePath = isPropertySet(NESTED_MODULE_ROOT) ? getStringProperty(NESTED_MODULE_ROOT) : null;
		boolean useDefault = basePath == null;
		IDataModel localModel = null;
		for (int i = 0; null != projects && i < projects.size(); i++) {
			localModel = (IDataModel) projects.get(i);
			localModel.setProperty(IProjectCreationPropertiesNew.USER_DEFINED_BASE_LOCATION, basePath);
			localModel.setBooleanProperty(IProjectCreationPropertiesNew.USE_DEFAULT_LOCATION, useDefault);
		}
	}

	private void changeModuleCreationLocationForNameChange(List projects) {
		IDataModel localModel = null;
		for (int i = 0; null != projects && i < projects.size(); i++) {
			localModel = (IDataModel) projects.get(i);
			if (isPropertySet(NESTED_MODULE_ROOT)) {
				IPath newPath = new Path((String) getProperty(NESTED_MODULE_ROOT));
				newPath = newPath.append((String) localModel.getProperty(IJ2EEComponentImportDataModelProperties.PROJECT_NAME));
				// model.setProperty(J2EEComponentCreationDataModel.PROJECT_LOCATION,
				// newPath.toOSString());
			} else {
				// model.setProperty(J2EEComponentCreationDataModel.PROJECT_LOCATION, null);
			}
		}
	}

	private IPath getLocation() {
		return ResourcesPlugin.getWorkspace().getRoot().getLocation();
	}

	private void trimSelection() {
		boolean modified = false;
		List selectedList = getSelectedModels();
		List allList = getProjectModels();
		for (int i = selectedList.size() - 1; i > -1; i--) {
			if (!allList.contains(selectedList.get(i))) {
				modified = true;
				selectedList.remove(i);
			}
		}
		if (modified) {
			List newList = new ArrayList();
			newList.addAll(selectedList);
			setProperty(SELECTED_MODELS_LIST, newList);
		}
	}

	private void updateUtilityModels(List<ArchiveWrapper> utilityJars) {
		updateUtilityModels(utilityJars, SELECTED_MODELS_LIST, UTILITY_MODELS_LIST);
	}

	private void updateUtilityModels(List<ArchiveWrapper> utilityJars, String selectedProperty, String listTypeProperty) {
		boolean allSelected = true;
		List<IDataModel> selectedList = (List<IDataModel>) getProperty(selectedProperty);
		List<IDataModel> allList = getProjectModels();
		if (selectedList.size() == allList.size()) {
			for (int i = 0; i < selectedList.size() && allSelected; i++) {
				if (!selectedList.contains(allList.get(i)) || !allList.contains(selectedList.get(i))) {
					allSelected = false;
				}
			}
		} else {
			allSelected = false;
		}
		List<IDataModel> utilityModels = (List<IDataModel>) getProperty(listTypeProperty);
		ArchiveWrapper currentArchive = null;
		IDataModel currentUtilityModel = null;
		boolean utilityJarsModified = false;
		// Add missing
		for (int i = 0; null != utilityJars && i < utilityJars.size(); i++) {
			currentArchive = utilityJars.get(i);
			boolean added = false;
			for (int j = 0; utilityModels != null && j < utilityModels.size() && !added; j++) {
				currentUtilityModel = (IDataModel) utilityModels.get(j);
				if (currentUtilityModel.getProperty(IJavaUtilityJarImportDataModelProperties.ARCHIVE_WRAPPER) == currentArchive) {
					added = true;
				}
			}
			if (!added) {
				if (!isPropertySet(listTypeProperty)) {
					utilityModels = new ArrayList<IDataModel>();
					setProperty(listTypeProperty, utilityModels);
				}
				IDataModel localModel = DataModelFactory.createDataModel(new J2EEUtilityJarImportDataModelProvider());
				localModel.setProperty(IJavaUtilityJarImportDataModelProperties.ARCHIVE_WRAPPER, currentArchive);
				localModel.setProperty(IJavaUtilityJarImportDataModelProperties.EAR_PROJECT_NAME, getStringProperty(PROJECT_NAME));
				localModel.setProperty(IFacetProjectCreationDataModelProperties.FACET_RUNTIME, getProperty(IFacetProjectCreationDataModelProperties.FACET_RUNTIME));
				utilityModels.add(localModel);
				localModel.addListener(nestedListener);
				utilityJarsModified = true;
			}
		} // Remove extras
		for (int i = utilityModels.size() - 1; i >= 0; i--) {
			currentUtilityModel = (IDataModel) utilityModels.get(i);
			currentArchive = (ArchiveWrapper) currentUtilityModel.getProperty(IJavaUtilityJarImportDataModelProperties.ARCHIVE_WRAPPER);
			if (null == utilityJars || !utilityJars.contains(currentArchive)) {
				currentUtilityModel.removeListener(nestedListener);
				currentUtilityModel.dispose();
				utilityModels.remove(currentUtilityModel);
				utilityJarsModified = true;
			}
		}
		allList = getProjectModels();
		if (allSelected) {
			List<IDataModel> newList = new ArrayList<IDataModel>();
			newList.addAll(allList);
			setProperty(SELECTED_MODELS_LIST, newList);
		} else {
			trimSelection();
		}
		if (utilityJarsModified) {
			model.notifyPropertyChange(NESTED_PROJECTS_VALIDATION, IDataModel.VALUE_CHG);
		}
	}

	private List getModuleModels() {
		ArchiveWrapper earWrapper = getArchiveWrapper();
		if (earWrapper == null)
			return Collections.EMPTY_LIST;
		cachedLoadError = null;
		List<ArchiveWrapper> modules = earWrapper.getEarModules();
		List moduleModels = new ArrayList();
		List<ArchiveWrapper> clientJarArchives = new ArrayList();
		IDataModel localModel;
		String earProjectName = getStringProperty(IFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME);

		List defaultModuleNames = new ArrayList();
		defaultModuleNames.add(earProjectName);
		List collidingModuleNames = null;
		Hashtable<IDataModel, ArchiveWrapper> ejbJarsWithClients = new Hashtable();
		for (int i = 0; i < modules.size(); i++) {
			localModel = null;
			ArchiveWrapper temp = modules.get(i);
			try {
				if (temp.isApplicationClientFile()) {
					localModel = DataModelFactory.createDataModel(new AppClientComponentImportDataModelProvider());
				} else if (temp.isWARFile()) {
					WebModuleExtension webExt = EarModuleManager.getWebModuleExtension();
					if (webExt != null) {
						localModel = webExt.createImportDataModel();
						String ctxRt = temp.getWebContextRoot();
						if (null != ctxRt) {
							localModel.setProperty(IAddWebComponentToEnterpriseApplicationDataModelProperties.CONTEXT_ROOT, ctxRt);
						}
					}
				} else if (temp.isEJBJarFile()) {
					EjbModuleExtension ejbExt = EarModuleManager.getEJBModuleExtension();
					if (ejbExt != null) {
						localModel = ejbExt.createImportDataModel();
					}
					try {
						ArchiveWrapper clientArch = earWrapper.getEJBClientArchiveWrapper(temp);
						if (null != clientArch) {
							clientJarArchives.add(clientArch);
							ejbJarsWithClients.put(localModel, clientArch);
						}
					} catch (Exception e) {
						Logger.getLogger().logError(e);
					}

				} else if (temp.isRARFile()) {
					JcaModuleExtension rarExt = EarModuleManager.getJCAModuleExtension();
					if (rarExt != null) {
						localModel = rarExt.createImportDataModel();
					}
				}
				if (localModel != null) {
					localModel.setProperty(ARCHIVE_WRAPPER, temp);
					localModel.setProperty(IJ2EEFacetProjectCreationDataModelProperties.EAR_PROJECT_NAME, earProjectName);
					localModel.setProperty(IFacetProjectCreationDataModelProperties.FACET_RUNTIME, getProperty(IFacetProjectCreationDataModelProperties.FACET_RUNTIME));
					localModel.addListener(this);
					localModel.addListener(nestedListener);
					moduleModels.add(localModel);
					String moduleName = localModel.getStringProperty(IJ2EEFacetProjectCreationDataModelProperties.FACET_PROJECT_NAME);
					if (defaultModuleNames.contains(moduleName)) {
						if (collidingModuleNames == null) {
							collidingModuleNames = new ArrayList();
						}
						collidingModuleNames.add(moduleName);
					} else {
						defaultModuleNames.add(moduleName);
					}
				}
			} catch (Exception e) {
				Logger.getLogger().logError("Error loading nested archive: " + temp.getPath().toOSString()); //$NON-NLS-1$
				Logger.getLogger().logError(e);
				cachedLoadError = temp;
			}
		}
		updateUtilityModels(clientJarArchives, EJB_CLIENT_LIST, EJB_CLIENT_LIST);
		List<IDataModel> clientModelList = (List<IDataModel>) getProperty(EJB_CLIENT_LIST);
		Enumeration<IDataModel> ejbModels = ejbJarsWithClients.keys();
		ejbJarModelsToClientJarModels.clear();
		clientJarModelsToEjbJarModels.clear();
		while (ejbModels.hasMoreElements()) {
			IDataModel ejbModel = ejbModels.nextElement();
			ArchiveWrapper ejbClientArchiveWrapper = ejbJarsWithClients.get(ejbModel);
			IDataModel clientModel = null;
			for (int i = 0; clientModel == null && i < clientModelList.size(); i++) {
				if (((ArchiveWrapper) clientModelList.get(i).getProperty(ARCHIVE_WRAPPER)).getUnderLyingArchive() == ejbClientArchiveWrapper.getUnderLyingArchive()) {
					clientModel = clientModelList.get(i);
				}
			}
			ejbJarModelsToClientJarModels.put(ejbModel, clientModel);
			clientJarModelsToEjbJarModels.put(clientModel, ejbModel);
		}

		for (int i = 0; collidingModuleNames != null && i < moduleModels.size(); i++) {
			localModel = (IDataModel) moduleModels.get(i);
			String moduleName = localModel.getStringProperty(IJ2EEModuleImportDataModelProperties.PROJECT_NAME);
			if (collidingModuleNames.contains(moduleName)) {
				ArchiveWrapper module = (ArchiveWrapper) localModel.getProperty(IJ2EEModuleImportDataModelProperties.ARCHIVE_WRAPPER);
				String suffix = null;
				if (module.isApplicationClientFile()) {
					suffix = "_AppClient"; //$NON-NLS-1$
				} else if (module.isWARFile()) {
					suffix = "_WEB"; //$NON-NLS-1$
				} else if (module.isEJBJarFile()) {
					suffix = "_EJB"; //$NON-NLS-1$
				} else if (module.isRARFile()) {
					suffix = "_JCA"; //$NON-NLS-1$
				}
				if (defaultModuleNames.contains(moduleName + suffix)) {
					int count = 1;
					for (; defaultModuleNames.contains(moduleName + suffix + count) && count < 10; count++)
						;
					suffix += count;
				}
				localModel.setProperty(IJ2EEModuleImportDataModelProperties.PROJECT_NAME, moduleName + suffix);
			}
		}
		return moduleModels;
	}

	protected int getType() {
		return XMLResource.APPLICATION_TYPE;
	}

	protected Archive openArchive(String uri) throws OpenFailureException {
		return CommonarchiveFactory.eINSTANCE.openEARFile(getArchiveOptions(), uri);
	}

	/*
	 * private EARFile getEARFile() { return (EARFile) getArchiveFile(); }
	 */
	/*
	 * public boolean handlesArchive(Archive anArchive) { List temp = new ArrayList(); List tempList = (List)
	 * getProperty(MODULE_MODELS_LIST); if (null != tempList) { temp.addAll(tempList); } tempList = (List)
	 * getProperty(EJB_CLIENT_LIST); if (null != tempList) { temp.addAll(tempList); } tempList = getSelectedModels();
	 * for (int i = 0; i < tempList.size(); i++) { if (!temp.contains(tempList.get(i))) { temp.add(tempList.get(i)); } }
	 * IDataModel importDM = null; for (int i = 0; i < temp.size(); i++) { importDM = (IDataModel) temp.get(i); if
	 * (importDM.getProperty(ARCHIVE_WRAPPER) == anArchive) { return true; } } return false; }
	 */
	private List<IDataModel> getProjectModels() {
		List<IDataModel> temp = new ArrayList<IDataModel>();
		List tempList = (List) getProperty(MODULE_MODELS_LIST);
		if (null != tempList) {
			temp.addAll(tempList);
		}
		tempList = (List) getProperty(UTILITY_MODELS_LIST);
		if (null != tempList) {
			temp.addAll(tempList);
		}
		tempList = (List) getProperty(EJB_CLIENT_LIST);
		if (null != tempList) {
			temp.addAll(tempList);
		}
		return temp;
	}

	private List getUnhandledProjectModels() {
		List handled = removeHandledModels(getProjectModels(), getProjectModels(), false);
		List all = getProjectModels();
		all.removeAll(handled);
		return all;
	}

	public List getSelectedModels() {
		return (List) getProperty(SELECTED_MODELS_LIST);
	}

	private List removeHandledModels(List listToPrune, List modelsToCheck, boolean addModels) {
		List newList = new ArrayList();
		newList.addAll(listToPrune);
		// IDataModel localModel = null;
		// for (int i = 0; i < modelsToCheck.size(); i++) {
		// localModel = (IDataModel) modelsToCheck.get(i);
		// model.extractHandled(newList, addModels);
		// }
		return newList;
	}

	private List getHandledSelectedModels() {
		List selectedModels = getSelectedModels();
		return removeHandledModels(selectedModels, selectedModels, true);
	}

	/*
	 * public int getJ2EEVersion() { EARFile ef = getEARFile(); return null == ef ? J2EEVersionConstants.J2EE_1_2_ID :
	 * ArchiveUtil.getFastSpecVersion(ef); }
	 */

	public boolean isPropertyEnabled(String propertyName) {
		if (!super.isPropertyEnabled(propertyName)) {
			return false;
		}
		if (propertyName.equals(USE_ANNOTATIONS)) {
			if (getJ2EEVersion() < J2EEVersionConstants.VERSION_1_3)
				return false;
			return true;
		}
		return true;
	}

	public void dispose() {
		super.dispose();
		List list = getProjectModels();
		for (int i = 0; i < list.size(); i++) {
			((IDataModel) list.get(i)).dispose();
		}
	}

	/**
	 * Do not use this it will be deleted post 2.0.  This method will be moved to a utility class.
	 * @deprecated 
	 * @param earFile
	 * @return
	 */
	public static List getAllUtilities(org.eclipse.jst.j2ee.commonarchivecore.internal.EARFile earFile) {
		List files = earFile.getFiles();
		List utilJars = new ArrayList();
		for (int i = 0; i < files.size(); i++) {
			org.eclipse.jst.j2ee.commonarchivecore.internal.impl.FileImpl file = (org.eclipse.jst.j2ee.commonarchivecore.internal.impl.FileImpl) files.get(i);
			if (file.isArchive() && !file.isModuleFile() && file.getURI().endsWith(".jar")) { //$NON-NLS-1$
				utilJars.add(file);
			}
			if (file.isWARFile()) {
				utilJars.addAll(getWebLibs((org.eclipse.jst.j2ee.commonarchivecore.internal.WARFile) file));
			}
		}
		return utilJars;
	}
	
	/**
	 * Do not use this it will be deleted post 2.0  This method will be moved to a utility class.
	 * @deprecated
	 * @param warFile
	 * @return
	 */
	public static List getWebLibs(org.eclipse.jst.j2ee.commonarchivecore.internal.WARFile warFile) {
		return ((org.eclipse.jst.j2ee.commonarchivecore.internal.impl.WARFileImpl) warFile).getLibArchives();
	}
	
	// TODO: Implement with J2EEArtifactImportDataModelProvider
	/*
	 * public J2EEArtifactImportDataModel getMatchingEJBJarOrClient(J2EEArtifactImportDataModel model) { if
	 * (clientJarToEjbJarModels.containsKey(model)) { return (J2EEArtifactImportDataModel)
	 * clientJarToEjbJarModels.get(model); } else if (ejbJarToClientJarModels.containsKey(model)) { return
	 * (J2EEArtifactImportDataModel) ejbJarToClientJarModels.get(model); } else { return null; } }
	 */

	protected IDataModel createJ2EEComponentCreationDataModel() {
		return DataModelFactory.createDataModel(new EARFacetProjectCreationDataModelProvider());
	}

	public IDataModelOperation getDefaultOperation() {
		return new EARComponentImportOperation(model);
	}

	public void init() {
		super.init();
		IDataModel componentCreationDM = model.getNestedModel(NESTED_MODEL_J2EE_COMPONENT_CREATION);
		FacetDataModelMap map = (FacetDataModelMap) componentCreationDM.getProperty(IFacetProjectCreationDataModelProperties.FACET_DM_MAP);
		IDataModel earFacet = map.getFacetDataModel( IJ2EEFacetConstants.ENTERPRISE_APPLICATION );	
		earFacet.setBooleanProperty(IJ2EEFacetInstallDataModelProperties.GENERATE_DD, false);
	}
}
