/*******************************************************************************
 * 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.internal.project;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jem.java.JavaClass;
import org.eclipse.jem.java.JavaRefFactory;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jem.util.emf.workbench.WorkbenchByteArrayOutputStream;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jem.util.plugin.JEMUtilPlugin;
import org.eclipse.jem.workbench.utility.JemProjectUtilities;
import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive;
import org.eclipse.jst.j2ee.commonarchivecore.internal.EARFile;
import org.eclipse.jst.j2ee.commonarchivecore.internal.EJBJarFile;
import org.eclipse.jst.j2ee.commonarchivecore.internal.File;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.DeploymentDescriptorLoadException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.OpenFailureException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifest;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifestImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.impl.CommonarchiveFactoryImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.util.ArchiveUtil;
import org.eclipse.jst.j2ee.ejb.EJBJar;
import org.eclipse.jst.j2ee.ejb.EnterpriseBean;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
import org.eclipse.jst.j2ee.internal.archive.operations.JavaComponentLoadStrategyImpl;
import org.eclipse.jst.j2ee.internal.common.J2EEVersionUtil;
import org.eclipse.jst.j2ee.internal.common.classpath.J2EEComponentClasspathUpdater;
import org.eclipse.jst.j2ee.internal.componentcore.JavaEEBinaryComponentHelper;
import org.eclipse.jst.j2ee.internal.moduleextension.EarModuleManager;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.project.EarUtilities;
import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
import org.eclipse.jst.j2ee.project.facet.IJavaProjectMigrationDataModelProperties;
import org.eclipse.jst.j2ee.project.facet.JavaProjectMigrationDataModelProvider;
import org.eclipse.jst.j2ee.project.facet.JavaProjectMigrationOperation;
import org.eclipse.jst.jee.archive.IArchive;
import org.eclipse.jst.jee.archive.IArchiveResource;
import org.eclipse.jst.server.core.FacetUtil;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.impl.ModuleURIUtil;
import org.eclipse.wst.common.componentcore.internal.util.ComponentUtilities;
import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.common.componentcore.resources.IVirtualResource;
import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.frameworks.internal.SimpleValidateEdit;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IProjectFacet;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.server.core.IRuntime;

public class J2EEProjectUtilities extends ProjectUtilities implements IJ2EEFacetConstants {

	/**
	 * Return the absolute path of a loose archive in a J2EE application or WAR file
	 */
	public static IPath getRuntimeLocation(IProject aProject) {
		if (JemProjectUtilities.isBinaryProject(aProject))
			return getBinaryProjectJARLocation(aProject);
		return JemProjectUtilities.getJavaProjectOutputAbsoluteLocation(aProject);
	}

	public static IPath getBinaryProjectJARLocation(IProject aProject) {
		List sources = JemProjectUtilities.getLocalJARPathsFromClasspath(aProject);
		if (!sources.isEmpty()) {
			IPath path = (IPath) sources.get(0);
			return aProject.getFile(path).getLocation();
		}
		return null;
	}

	public static Archive getClientJAR(EJBJarFile file, EARFile earFile) {
		EJBJar jar = null;
		try {
			jar = file.getDeploymentDescriptor();
		} catch (DeploymentDescriptorLoadException exc) {
			return null;
		}
		if (jar == null)
			return null;
		String clientJAR = jar.getEjbClientJar();
		if (clientJAR == null || clientJAR.length() == 0)
			return null;
		String normalized = ArchiveUtil.deriveEARRelativeURI(clientJAR, file.getURI());
		if (normalized != null) {
			try {
				File aFile = earFile.getFile(normalized);
				if (aFile.isArchive() && !aFile.isModuleFile())
					return (Archive) aFile;
			} catch (FileNotFoundException nothingThere) {
			}
		}
		return null;
		// TODO - release the DD here to free up space
	}

	/**
	 * Append one IClasspathEntry to the build path of the passed project. If a classpath entry
	 * having the same path as the parameter already exists, then does nothing.
	 */
	public static void appendJavaClassPath(IProject p, IClasspathEntry newEntry) throws JavaModelException {
		IJavaProject javaProject = JemProjectUtilities.getJavaProject(p);
		if (javaProject == null)
			return;
		IClasspathEntry[] classpath = javaProject.getRawClasspath();
		List newPathList = new ArrayList(classpath.length);
		for (int i = 0; i < classpath.length; i++) {
			IClasspathEntry entry = classpath[i];
			// fix dup class path entry for .JETEmitter project
			// Skip the entry to be added if it already exists
			if (Platform.getOS().equals(Platform.OS_WIN32)) {
				if (!entry.getPath().toString().equalsIgnoreCase(newEntry.getPath().toString()))
					newPathList.add(entry);
				else
					return;
			} else {
				if (!entry.getPath().equals(newEntry.getPath()))
					newPathList.add(entry);
				else
					return;
			}
		}
		newPathList.add(newEntry);
		IClasspathEntry[] newClasspath = (IClasspathEntry[]) newPathList.toArray(new IClasspathEntry[newPathList.size()]);
		javaProject.setRawClasspath(newClasspath, new NullProgressMonitor());
	}

	public static Archive asArchiveFromBinary(String jarUri, IProject aProject) throws OpenFailureException {
		IPath path = getBinaryProjectJARLocation(aProject);
		if (path != null) {
			String location = path.toOSString();
			Archive anArchive = CommonarchiveFactoryImpl.getActiveFactory().primOpenArchive(location);
			anArchive.setURI(jarUri);
			return anArchive;
		}
		return null;
	}

	public static ArchiveManifest readManifest(IFile aFile) {
		InputStream in = null;
		try {
			if (aFile == null || !aFile.exists())
				return null;
			in = aFile.getContents();
			return new ArchiveManifestImpl(in);
		} catch (Exception ex) {
			org.eclipse.jem.util.logger.proxy.Logger.getLogger().logError(ex);
			return null;
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException weTried) {
				}
			}
		}
	}

	public static ArchiveManifest readManifest(IProject p) {
		InputStream in = null;
		try {
			IFile aFile = getManifestFile(p);
			if (aFile == null || !aFile.exists())
				return null;
			in = aFile.getContents();
			return new ArchiveManifestImpl(in);
		} catch (Exception ex) {
			org.eclipse.jem.util.logger.proxy.Logger.getLogger().logError(ex);
			return null;
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException weTried) {
				}
			}
		}
	}

	/**
	 * Equavalent to calling getManifestFile(project, true)
	 * 
	 * @param p
	 * @return
	 */
	public static IFile getManifestFile(IProject project) {
		return getManifestFile(project, true);
	}

	/**
	 * Returns the IFile handle to the J2EE manifest file for the specified
	 * project. If createIfNecessary is true, the MANIFEST.MF file will be
	 * created if it does not already exist.
	 * 
	 * @param p
	 * @param createIfNecessary
	 * @return
	 */
	public static IFile getManifestFile(IProject p, boolean createIfNecessary) {
		IVirtualComponent component = ComponentCore.createComponent(p);
		try {
			IFile file = ComponentUtilities.findFile(component, new Path(J2EEConstants.MANIFEST_URI));
			if (createIfNecessary && file == null) {
				IVirtualFolder virtualFolder = component.getRootFolder();
				file = virtualFolder.getUnderlyingFolder().getFile(new Path(J2EEConstants.MANIFEST_URI));

				try {
					ManifestFileCreationAction.createManifestFile(file, p);
				} catch (CoreException e) {
					Logger.getLogger().log(e);
				} catch (IOException e) {
					Logger.getLogger().log(e);
				}
			}
			return file;
		} catch (CoreException ce) {
			Logger.getLogger().log(ce);
		}
		return null;
	}

	public static void writeManifest(IProject aProject, ArchiveManifest manifest) throws java.io.IOException {
		writeManifest(aProject, getManifestFile(aProject), manifest);
	}

	public static void writeManifest(IFile aFile, ArchiveManifest manifest) throws java.io.IOException {
		writeManifest(aFile.getProject(), aFile, manifest);
	}

	private static void writeManifest(IProject aProject, IFile aFile, ArchiveManifest manifest) throws java.io.IOException {
		if (aFile != null) {
			if(SimpleValidateEdit.validateEdit(new IFile[] { aFile })){
				OutputStream out = new WorkbenchByteArrayOutputStream(aFile);
				manifest.writeSplittingClasspath(out);
				out.close();
				J2EEComponentClasspathUpdater.getInstance().queueUpdateModule(aProject);
			}
		}
	}
	
	public static ArchiveManifest readManifest(IVirtualComponent component) {
		if (!component.isBinary()) {
			IVirtualFile vManifest = component.getRootFolder().getFile(J2EEConstants.MANIFEST_URI);
			if (vManifest.exists()) {
				IFile manifestFile = vManifest.getUnderlyingFile();
				InputStream in = null;
				try {
					in = manifestFile.getContents();
					return new ArchiveManifestImpl(in);
				} catch (IOException e) {
					J2EEPlugin.logError(e);
				} catch (CoreException e) {
					J2EEPlugin.logError(e);
				} finally {
					if (in != null) {
						try {
							in.close();
							in = null;
						} catch (IOException e) {
							J2EEPlugin.logError(e);
						}
					}
				}
			}
		} else {
			JavaEEBinaryComponentHelper helper = null;
			try{
				helper = new JavaEEBinaryComponentHelper(component);
				if(helper != null){
					IArchive archive = null;
					InputStream in = null;
					try{
						archive = helper.accessArchive();
						if(null != archive){
							IPath manifestPath = new Path(J2EEConstants.MANIFEST_URI);
							if(archive.containsArchiveResource(manifestPath)){
								IArchiveResource manifestResource = archive.getArchiveResource(manifestPath);
								if(manifestResource != null){
									in = manifestResource.getInputStream();
									ArchiveManifest manifest = new ArchiveManifestImpl(in);
									return manifest;
								}
							}
						}
					} catch (FileNotFoundException e) {
						J2EEPlugin.logError(e);
					} catch (IOException e) {
						J2EEPlugin.logError(e);
					} finally{
						if (in != null) {
							try {
								in.close();
								in = null;
							} catch (IOException e) {
								J2EEPlugin.logError(e);
							}
						}
						if(archive != null){
							helper.releaseArchive(archive);
						}
					}
				}
			} finally{
				if(helper != null){
					helper.dispose();
				}
			}
		}
		return null;
	}
	/**
	 * Keys are the EJB JAR files and the values are the respective client JARs; includes only key
	 * value pairs for which EJB Client JARs are defined and exist.
	 * 
	 * @author schacher
	 */
	public static Map collectEJBClientJARs(EARFile earFile) {
		if (earFile == null)
			return Collections.EMPTY_MAP;
		Map ejbClientJARs = null;
		List ejbJARFiles = earFile.getEJBJarFiles();
		Archive clientJAR = null;
		for (int i = 0; i < ejbJARFiles.size(); i++) {
			EJBJarFile ejbJarFile = (EJBJarFile) ejbJARFiles.get(i);
			clientJAR = getClientJAR(ejbJarFile, earFile);
			if (clientJAR != null) {
				if (ejbClientJARs == null)
					ejbClientJARs = new HashMap();
				ejbClientJARs.put(ejbJarFile, clientJAR);
			}
		}
		return ejbClientJARs == null ? Collections.EMPTY_MAP : ejbClientJARs;
	}

	public static String computeRelativeText(String referencingURI, String referencedURI, EnterpriseBean bean) {
		if (bean == null)
			return null;

		String beanName = bean.getName();
		if (beanName == null)
			return null;

		String relativeUri = computeRelativeText(referencingURI, referencedURI);
		if (relativeUri == null)
			return beanName;
		return relativeUri + "#" + beanName; //$NON-NLS-1$
	}

	public static String computeRelativeText(String referencingURI, String referencedURI) {
		if (referencingURI == null || referencedURI == null)
			return null;
		IPath pPre = new Path(referencingURI);
		IPath pDep = new Path(referencedURI);
		if (pPre.getDevice() != null || pDep.getDevice() != null)
			return null;
		pPre = pPre.makeRelative();
		pDep = pDep.makeRelative(); // referenced Archive path URI

		while (pPre.segmentCount() > 1 && pDep.segmentCount() > 1 && pPre.segment(0).equals(pDep.segment(0))) {
			pPre = pPre.removeFirstSegments(1);
			pDep = pDep.removeFirstSegments(1);
		}

		IPath result = null;
		StringBuffer buf = new StringBuffer();
		String segment = null;
		do {
			segment = pDep.lastSegment();
			pPre = pPre.removeLastSegments(1);
			pDep = pDep.removeLastSegments(1);
			if (segment != null) {
				if (result == null)
					result = new Path(segment);
				else
					result = new Path(segment).append(result);
			}
			if (!pPre.equals(pDep) && !pPre.isEmpty())
				buf.append("../"); //$NON-NLS-1$
		} while (!pPre.equals(pDep));

		if (result != null)
			buf.append(result.makeRelative().toString());

		return buf.toString();
	}

	public static IProject getEJBProjectFromEJBClientProject(IProject ejbClientProject) {
		try {
			if (null != ejbClientProject && ejbClientProject.hasNature(JavaCore.NATURE_ID)) {
				IProject[] allProjects = getAllProjects();
				for (int i = 0; i < allProjects.length; i++) {
					if (null != EarModuleManager.getEJBModuleExtension().getEJBJar(allProjects[i])) {
						if (ejbClientProject == EarModuleManager.getEJBModuleExtension().getDefinedEJBClientJARProject(allProjects[i])) {
							return allProjects[i];
						}
					}
				}
			}
		} catch (CoreException e) {
		}
		return null;
	}

	public static EnterpriseBean getEnterpriseBean(ICompilationUnit cu) {
		IProject proj = cu.getJavaProject().getProject();
		EJBJar jar = EarModuleManager.getEJBModuleExtension().getEJBJar(proj);
		if (null == jar) {
			jar = EarModuleManager.getEJBModuleExtension().getEJBJar(getEJBProjectFromEJBClientProject(proj));
		}
		if (jar != null) {
			int index = cu.getElementName().indexOf('.');
			String className = cu.getElementName();
			if (index > 0)
				className = className.substring(0, index);
			JavaClass javaClass = (JavaClass) JavaRefFactory.eINSTANCE.reflectType(cu.getParent().getElementName(), className, jar.eResource().getResourceSet());
			return jar.getEnterpriseBeanWithReference(javaClass);
		}
		return null;
	}

	public static IContainer getSourceFolderOrFirst(IProject p, String defaultSourceName) {
		try {
			IPath sourcePath = getSourcePathOrFirst(p, defaultSourceName);
			if (sourcePath == null)
				return null;
			else if (sourcePath.isEmpty())
				return p;
			else
				return p.getFolder(sourcePath);
		} catch (IllegalArgumentException ex) {
			return null;
		}
	}

	public static void removeBuilders(IProject project, List builderids) throws CoreException {
		IProjectDescription desc = project.getDescription();
		ICommand[] oldSpec = desc.getBuildSpec();
		int oldLength = oldSpec.length;
		if (oldLength == 0)
			return;
		int remaining = 0;
		// null out all commands that match the builder to remove
		for (int i = 0; i < oldSpec.length; i++) {
			if (builderids.contains(oldSpec[i].getBuilderName()))
				oldSpec[i] = null;
			else
				remaining++;
		}
		// check if any were actually removed
		if (remaining == oldSpec.length)
			return;
		ICommand[] newSpec = new ICommand[remaining];
		for (int i = 0, newIndex = 0; i < oldLength; i++) {
			if (oldSpec[i] != null)
				newSpec[newIndex++] = oldSpec[i];
		}
		desc.setBuildSpec(newSpec);
		project.setDescription(desc, IResource.NONE, null);
	}

	public static IPath getSourcePathOrFirst(IProject p, String defaultSourceName) {
		IJavaProject javaProj = JemProjectUtilities.getJavaProject(p);
		if (javaProj == null)
			return null;
		IClasspathEntry[] cp = null;
		try {
			cp = javaProj.getRawClasspath();
		} catch (JavaModelException ex) {
			JEMUtilPlugin.getLogger().logError(ex);
			return null;
		}
		IClasspathEntry firstSource = null;
		IPath defaultSourcePath = null;
		if (defaultSourceName != null)
			defaultSourcePath = createPath(p, defaultSourceName);
		boolean found = false;
		for (int i = 0; i < cp.length; i++) {
			if (cp[i].getEntryKind() == IClasspathEntry.CPE_SOURCE) {
				// check if it contains /META-INF/MANIFEST.MF
				IPath sourceFolderPath = cp[i].getPath().removeFirstSegments(1);
				IFolder sourceFolder = p.getFolder(sourceFolderPath);
				if (isSourceFolderAnInputContainer(sourceFolder)) {
					found = true;
					if (firstSource == null) {
						firstSource = cp[i];
						if (defaultSourcePath == null)
							break;
					}
					if (cp[i].getPath().equals(defaultSourcePath))
						return defaultSourcePath.removeFirstSegments(1);
				}
			}
		}
		if (!found) {
			for (int i = 0; i < cp.length; i++) {
				if (cp[i].getEntryKind() == IClasspathEntry.CPE_SOURCE) {
					if (firstSource == null) {
						firstSource = cp[i];
						if (defaultSourcePath == null)
							break;
					}
					if (cp[i].getPath().equals(defaultSourcePath))
						return defaultSourcePath.removeFirstSegments(1);
				}
			}
		}
		if (firstSource == null)
			return null;
		if (firstSource.getPath().segment(0).equals(p.getName()))
			return firstSource.getPath().removeFirstSegments(1);
		return null;
	}

	public static boolean isSourceFolderAnInputContainer(IFolder sourceFolder) {
		IContainer parent = sourceFolder;
		while (true) {
			parent = parent.getParent();
			if (parent == null)
				return false;
			if (parent instanceof IProject)
				break;
		}
		IProject project = (IProject) parent;
		try {
			if (!project.isAccessible())
				return false;
			if (isEJBProject(project)) {
				return sourceFolder.findMember(J2EEConstants.EJBJAR_DD_URI) != null;
			} else if (isApplicationClientProject(project)) {
				return sourceFolder.findMember(J2EEConstants.APP_CLIENT_DD_URI) != null;
			} else if (isDynamicWebProject(project)) {
				return sourceFolder.findMember(J2EEConstants.WEBAPP_DD_URI) != null;
			} else if (isJCAProject(project)) {
				return sourceFolder.findMember(J2EEConstants.RAR_DD_URI) != null;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	public static Archive asArchive(String jarUri, IProject project, boolean exportSource) throws OpenFailureException {
		return asArchive(jarUri, project, exportSource, true);		
	}
	
	public static Archive asArchive(String jarUri, IProject project, boolean exportSource, boolean includeClasspathComponents) throws OpenFailureException {
		JavaComponentLoadStrategyImpl strat = new JavaComponentLoadStrategyImpl(ComponentCore.createComponent(project), includeClasspathComponents);
		strat.setExportSource(exportSource);
		return CommonarchiveFactoryImpl.getActiveFactory().primOpenArchive(strat, jarUri);
	}

	/**
	 * @deprecated - see {@link JavaEEProjectUtilities.isProjectOfType(IProject project, String typeID)}
	 */
	public static boolean isProjectOfType(IProject project, String typeID) {
		return JavaEEProjectUtilities.isProjectOfType(project,typeID);
	}

	private static boolean isProjectOfType(IFacetedProject facetedProject, String typeID) {

		if (facetedProject != null && ProjectFacetsManager.isProjectFacetDefined(typeID)) {
			IProjectFacet projectFacet = ProjectFacetsManager.getProjectFacet(typeID);
			return projectFacet != null && facetedProject.hasProjectFacet(projectFacet);
		}
		return false;
	}

	private static boolean isEARProject(IFacetedProject project) {
		return isProjectOfType(project, ENTERPRISE_APPLICATION);
	}

	private static boolean isDynamicWebProject(IFacetedProject project) {
		return isProjectOfType(project, DYNAMIC_WEB);
	}

	private static boolean isEJBProject(IFacetedProject project) {
		return isProjectOfType(project, EJB);
	}

	private static boolean isJCAProject(IFacetedProject project) {
		return isProjectOfType(project, JCA);
	}

	private static boolean isApplicationClientProject(IFacetedProject project) {
		return isProjectOfType(project, APPLICATION_CLIENT);
	}

	private static boolean isUtilityProject(IFacetedProject project) {
		return isProjectOfType(project, UTILITY);
	}

	/**
	 * @deprecated - see {@link JavaEEProjectUtilities.isEARProject(IProject project)}
	 */
	public static boolean isEARProject(IProject project) {
		return JavaEEProjectUtilities.isEARProject(project);
	}

	/**
	 * @deprecated - see {@link JavaEEProjectUtilities.isDynamicWebComponent(IVirtualComponent component)}
	 */
	public static boolean isDynamicWebComponent(IVirtualComponent component) {
		return JavaEEProjectUtilities.isDynamicWebComponent(component);
	}

	/**
	 * @deprecated - see {@link JavaEEProjectUtilities.isDynamicWebProject(IProject project)}
	 */
	public static boolean isDynamicWebProject(IProject project) {
		return JavaEEProjectUtilities.isDynamicWebProject(project);
	}

	/**
	 * @deprecated - see {@link JavaEEProjectUtilities.isStaticWebProject(IProject project)}
	 */
	public static boolean isStaticWebProject(IProject project) {
		return JavaEEProjectUtilities.isStaticWebProject(project);
	}

	/**
	 * @deprecated - see {@link JavaEEProjectUtilities.isEJBComponent(IVirtualComponent component)}
	 */
	public static boolean isEJBComponent(IVirtualComponent component) {
		return JavaEEProjectUtilities.isEJBComponent(component);
	}

	/**
	 * @deprecated - see {@link JavaEEProjectUtilities.isEJBProject(IProject project)}
	 */
	public static boolean isEJBProject(IProject project) {
		return JavaEEProjectUtilities.isEJBProject(project);
	}

	/**
	 * @deprecated - see {@link JavaEEProjectUtilities.isJCAComponent(IVirtualComponent component)}
	 */
	public static boolean isJCAComponent(IVirtualComponent component) {
		return JavaEEProjectUtilities.isJCAComponent(component);
	}

	/**
	 * @deprecated - see {@link JavaEEProjectUtilities.isJCAProject(IProject project)}
	 */
	public static boolean isJCAProject(IProject project) {
		return JavaEEProjectUtilities.isJCAProject(project);
	}

	/**
	 * @deprecated - see {@link JavaEEProjectUtilities.isApplicationClientComponent(IVirtualComponent component)}
	 */
	public static boolean isApplicationClientComponent(IVirtualComponent component) {
		return JavaEEProjectUtilities.isApplicationClientComponent(component);
	}

	/**
	 * @deprecated - see {@link JavaEEProjectUtilities.isApplicationClientProject(IProject project)}
	 */
	public static boolean isApplicationClientProject(IProject project) {
		return JavaEEProjectUtilities.isApplicationClientProject(project);
	}

	/**
	 * @deprecated - see {@link JavaEEProjectUtilities.isUtilityProject(IProject project)}
	 */
	public static boolean isUtilityProject(IProject project) {
		return JavaEEProjectUtilities.isUtilityProject(project);
	}

	/**
	 * @deprecated - see {@link EarUtilities.isStandaloneProject(IProject project)}
	 */
	public static boolean isStandaloneProject(IProject project) {
		return EarUtilities.isStandaloneProject(project);
	}
	
	/**
	 * Returns all referencing EAR projects.
	 * @param project Project to check. If null or an EAR, returns a zero length array.
	 * @return Array of referencing EAR projects.
	 */
	public static IProject[] getReferencingEARProjects(final IProject project) {
		if(project != null && isEARProject(project)){
			return new IProject[] {project};
		}
		
		List result = new ArrayList();
		IVirtualComponent component = ComponentCore.createComponent(project);
		if (component != null) {
			IVirtualComponent[] refComponents = component.getReferencingComponents();
			for (int i = 0; i < refComponents.length; i++) {
				if (isEARProject(refComponents[i].getProject()))
					result.add(refComponents[i].getProject());
			}
		}
		return (IProject[]) result.toArray(new IProject[result.size()]);
	}
	
	/**
	 * Returns all referencing dynamic web projects.
	 * @param project Project to check. If null or a dynamic web project, returns a zero length array.
	 * @return Array of referencing dynamic web projects.
	 */
	public static IProject[] getReferencingWebProjects(final IProject project) {
		if(project != null && isDynamicWebProject(project)){
			return new IProject[] {project};
		}
		
		List result = new ArrayList();
		IVirtualComponent component = ComponentCore.createComponent(project);
		if (component != null) {
			IVirtualComponent[] refComponents = component.getReferencingComponents();
			for (int i = 0; i < refComponents.length; i++) {
				if (isDynamicWebProject(refComponents[i].getProject()))
					result.add(refComponents[i].getProject());
			}
		}
		return (IProject[]) result.toArray(new IProject[result.size()]);	
	}

	/**
	 * Return all projects in workspace of the specified type
	 * 
	 * @param type -
	 *            use one of the static strings on this class as a type
	 * @return IProject[]
	 * @deprecated - see {@link JavaEEProjectUtilities.getAllProjectsInWorkspaceOfType(String type)}
	 */
	public static IProject[] getAllProjectsInWorkspaceOfType(String type) {
		return JavaEEProjectUtilities.getAllProjectsInWorkspaceOfType(type);
	}

	/**
	 * @deprecated - see {@link JavaEEProjectUtilities.getJ2EEComponentType(IVirtualComponent component)}
	 */
	public static String getJ2EEComponentType(IVirtualComponent component) {
		return JavaEEProjectUtilities.getJ2EEComponentType(component);
	}

	/**
	 * @deprecated - see {@link JavaEEProjectUtilities.getJ2EEProjectType(IProject project)}
	 */
	public static String getJ2EEProjectType(IProject project) {
		return JavaEEProjectUtilities.getJ2EEProjectType(project);
	}
	/**
	 * Returns the J2EE Module version based on the DD XML file
	 * @param project
	 * @return version String
	 * @deprecated - see {@link JavaEEProjectUtilities.getJ2EEDDProjectVersion(IProject project)}
	 */
	public static String getJ2EEDDProjectVersion(IProject project) {
		return JavaEEProjectUtilities.getJ2EEDDProjectVersion(project);
	}

	public static IRuntime getServerRuntime(IProject project) throws CoreException {
		if (project == null)
			return null;
		IFacetedProject facetedProject = ProjectFacetsManager.create(project);
		if (facetedProject == null)
			return null;
		org.eclipse.wst.common.project.facet.core.runtime.IRuntime runtime = facetedProject.getRuntime();
		if (runtime == null)
			return null;
		return FacetUtil.getRuntime(runtime);
	}

	/**
	 * Returns the J2EE Module version based on the project Facet installed
	 * @param project
	 * @return version String
	 */
	public static String getJ2EEProjectVersion(IProject project) {
		String type = getJ2EEProjectType(project);
		IFacetedProject facetedProject = null;
		IProjectFacet facet = null;
		try {
			facetedProject = ProjectFacetsManager.create(project);
			facet = ProjectFacetsManager.getProjectFacet(type);
		} catch (Exception e) {
			// Not Faceted project or not J2EE Project
		}
		if (facet != null && facetedProject.hasProjectFacet(facet))
			return facetedProject.getInstalledVersion(facet).getVersionString();
		return null;
	}

	public static JavaProjectMigrationOperation createFlexJavaProjectForProjectOperation(IProject project) {
		IDataModel model = DataModelFactory.createDataModel(new JavaProjectMigrationDataModelProvider());
		model.setProperty(IJavaProjectMigrationDataModelProperties.PROJECT_NAME, project.getName());
		return new JavaProjectMigrationOperation(model);
	}
	
	public static JavaProjectMigrationOperation createFlexJavaProjectForProjectOperation(IProject project, boolean addToEAR) {
		IDataModel model = DataModelFactory.createDataModel(new JavaProjectMigrationDataModelProvider());
		model.setProperty(IJavaProjectMigrationDataModelProperties.PROJECT_NAME, project.getName());
		model.setBooleanProperty(IJavaProjectMigrationDataModelProperties.ADD_TO_EAR, addToEAR);
		return new JavaProjectMigrationOperation(model);
	}

	/**
	 * Retrieve all the source containers for a given virtual workbench component
	 * 
	 * @param vc
	 * @return the array of IPackageFragmentRoots
	 */
	public static IPackageFragmentRoot[] getSourceContainers(IProject project) {
		IJavaProject jProject = JemProjectUtilities.getJavaProject(project);
		if (jProject == null)
			return new IPackageFragmentRoot[0];
		List list = new ArrayList();
		IVirtualComponent vc = ComponentCore.createComponent(project);
		IPackageFragmentRoot[] roots;
		try {
			roots = jProject.getPackageFragmentRoots();
			for (int i = 0; i < roots.length; i++) {
				if (roots[i].getKind() != IPackageFragmentRoot.K_SOURCE)
					continue;
				IResource resource = roots[i].getResource();
				if (null != resource) {
					IVirtualResource[] vResources = ComponentCore.createResources(resource);
					boolean found = false;
					for (int j = 0; !found && j < vResources.length; j++) {
						if (vResources[j].getComponent().equals(vc)) {
							if (!list.contains(roots[i]))
								list.add(roots[i]);
							found = true;
						}
					}
				}
			}
		} catch (JavaModelException e) {
			Logger.getLogger().logError(e);
		}
		return (IPackageFragmentRoot[]) list.toArray(new IPackageFragmentRoot[list.size()]);
	}
	
	/**
	 * Retrieves the IContainers for all Java output folders that correspond to src folders that are mapped to the
	 * virtual component tree via the component file.
	 * 
	 * @param vc
	 * @return array of IContainers for the output folders
	 */
	public static IContainer[] getOutputContainers(IProject project) {
		List result = new ArrayList();
		try {
			if (!project.hasNature(JavaCore.NATURE_ID))
				return new IContainer[] {};
		} catch (Exception e) {
		}
		IPackageFragmentRoot[] sourceContainers = getSourceContainers(project);
		for (int i = 0; i < sourceContainers.length; i++) {
			IContainer outputFolder = getOutputContainer(project, sourceContainers[i]);
			if (outputFolder != null && !result.contains(outputFolder))
				result.add(outputFolder);
		}
		return (IContainer[]) result.toArray(new IContainer[result.size()]);
	}

	public static IContainer getOutputContainer(IProject project, IPackageFragmentRoot sourceContainer) {
		try {
			IJavaProject jProject = JavaCore.create(project);
			IPath outputPath = sourceContainer.getRawClasspathEntry().getOutputLocation();
			if (outputPath == null) {
				if (jProject.getOutputLocation().segmentCount() == 1)
					return project;
				return project.getFolder(jProject.getOutputLocation().removeFirstSegments(1));
			}
			return project.getFolder(outputPath.removeFirstSegments(1));
		} catch (Exception e) {
		}
		return null;
	}

	/**
	 * Retrieve all Java output containers mapped into the virtual resource tree via the component file. Includes both directly
	 * mapped class folders and the class folders associated with mapped source folders.
	 * 
	 * @param vc
	 * @return the array of IPackageFragmentRoots
	 */
	public static IContainer[] getAllOutputContainers(IProject project) {
		IJavaProject jProject = JemProjectUtilities.getJavaProject(project);
		if (jProject == null)
			return new IContainer[0];
		List list = new ArrayList();
		IContainer[] srcOutputContainers = getOutputContainers(project);
		for (int i = 0; i < srcOutputContainers.length; i++) {
			list.add(srcOutputContainers[i]);
		}
		IVirtualComponent vc = ComponentCore.createComponent(project);
		IPackageFragmentRoot[] roots;
		try {
			roots = jProject.getPackageFragmentRoots();
			for (int i = 0; i < roots.length; i++) {
				if (roots[i].getKind() != IPackageFragmentRoot.K_BINARY)
					continue;
				IResource resource = roots[i].getResource();
				if (null != resource) {
					IVirtualResource[] vResources = ComponentCore.createResources(resource);
					boolean found = false;
					for (int j = 0; !found && j < vResources.length; j++) {
						if (vResources[j].getComponent().equals(vc)) {
							if (resource instanceof IContainer) {
								IContainer outputContainer = (IContainer) resource;
								if (!list.contains(outputContainer)) {
									list.add(outputContainer);
									found = true;
								}
							}
						}
					}
				}
			}
		} catch (JavaModelException e) {
			Logger.getLogger().logError(e);
		}
		return (IContainer[]) list.toArray(new IContainer[list.size()]);
	}

	
	/**
	 * 
	 * @param name
	 * @return
	 * @description the passed name should have either lib or var as its first segment e.g.
	 *              lib/D:/foo/foo.jar or var/<CLASSPATHVAR>/foo.jar
	 */
	public static IPath getResolvedPathForArchiveComponent(String name) {

		URI uri = URI.createURI(name);

		String resourceType = uri.segment(0);
		URI contenturi = ModuleURIUtil.trimToRelativePath(uri, 1);
		String contentName = contenturi.toString();

		if (resourceType.equals("lib")) { //$NON-NLS-1$
			// module:/classpath/lib/D:/foo/foo.jar
			return Path.fromOSString(contentName);

		} else if (resourceType.equals("var")) { //$NON-NLS-1$

			// module:/classpath/var/<CLASSPATHVAR>/foo.jar
			String classpathVar = contenturi.segment(0);
			URI remainingPathuri = ModuleURIUtil.trimToRelativePath(contenturi, 1);
			String remainingPath = remainingPathuri.toString();

			String[] classpathvars = JavaCore.getClasspathVariableNames();
			boolean found = false;
			for (int i = 0; i < classpathvars.length; i++) {
				if (classpathVar.equals(classpathvars[i])) {
					found = true;
					break;
				}
			}
			if (found) {
				IPath path = JavaCore.getClasspathVariable(classpathVar);
				if (path != null ){
					URI finaluri = URI.createURI(path.toOSString() + IPath.SEPARATOR + remainingPath);
					return Path.fromOSString(finaluri.toString());
				}
			}
		}
		return null;
	}

	public static List getAllJavaNonFlexProjects() throws CoreException {
		List nonFlexJavaProjects = new ArrayList();
		IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
		for (int i = 0; i < projects.length; i++) {
			if (projects[i].isAccessible() && projects[i].hasNature(JavaCore.NATURE_ID) && !projects[i].hasNature(IModuleConstants.MODULE_NATURE_ID)) {
				nonFlexJavaProjects.add(projects[i]);
			}
		}
		return nonFlexJavaProjects;
	}

	/**
	 * This method will retrieve the context root for the associated workbench module which is used
	 * by the server at runtime. This method is not yet completed as the context root has to be
	 * abstracted and added to the workbenchModule model. This API will not change though. Returns
	 * null for now.
	 * 
	 * @return String value of the context root for runtime of the associated module
	 */
	public static String getServerContextRoot(IProject project) {
		return ComponentUtilities.getServerContextRoot(project);
	}

	/**
	 * This method will set the context root on the associated workbench module with the given
	 * string value passed in. This context root is used by the server at runtime. This method is
	 * not yet completed as the context root still needs to be abstracted and added to the workbench
	 * module model. This API will not change though. Does nothing as of now.
	 * 
	 * @param contextRoot
	 *            string
	 */
	public static void setServerContextRoot(IProject project, String contextRoot) {
		ComponentUtilities.setServerContextRoot(project, contextRoot);
	}
	
	/**
	 * @param project
	 * @return true, if jee version 5.0 (or their respective ejb, web, app versions)
	 * , it must be noted that this method only looks at the facet & their versions to determine 
	 * the jee level. It does not read deployment descriptors for performance reasons.
	 */
	public static boolean isJEEProject(IProject project){
		boolean ret = false;
		
		IFacetedProject facetedProject;
		try {
			facetedProject = ProjectFacetsManager.create(project);
			if (facetedProject == null)
				return false;
			if(isEARProject(facetedProject)){
				IProjectFacet earFacet = ProjectFacetsManager.getProjectFacet(IModuleConstants.JST_EAR_MODULE);
				ret = facetedProject.hasProjectFacet(earFacet.getVersion(J2EEVersionUtil.convertVersionIntToString(J2EEVersionConstants.JEE_5_0_ID)));
			} else if(isDynamicWebProject(facetedProject)){
				IProjectFacet webFacet = ProjectFacetsManager.getProjectFacet(IModuleConstants.JST_WEB_MODULE);
				ret = facetedProject.hasProjectFacet(webFacet.getVersion(J2EEVersionUtil.convertVersionIntToString(J2EEVersionUtil.convertJ2EEVersionIDToWebVersionID(J2EEVersionConstants.JEE_5_0_ID))));
			} else if(isEJBProject(facetedProject)){
				IProjectFacet ejbFacet = ProjectFacetsManager.getProjectFacet(IModuleConstants.JST_EJB_MODULE);
				ret = facetedProject.hasProjectFacet(ejbFacet.getVersion(J2EEVersionUtil.convertVersionIntToString(J2EEVersionUtil.convertJ2EEVersionIDToEJBVersionID(J2EEVersionConstants.JEE_5_0_ID))));
			} else if(isApplicationClientProject(facetedProject)){
				IProjectFacet appFacet = ProjectFacetsManager.getProjectFacet(IModuleConstants.JST_APPCLIENT_MODULE);
				ret = facetedProject.hasProjectFacet(appFacet.getVersion(J2EEVersionUtil.convertVersionIntToString(J2EEVersionConstants.JEE_5_0_ID)));
			}
		} catch (CoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return ret;
	}
	
	/**
	 * @param project
	 * @return true, if j2ee version 1.2, 1.3, 1.4 (or their respective ejb, web, app versions)
	 * , it must be noted that this method only looks at the facet & their versions to determine 
	 * the j2ee level. It does not read deployment descriptors for performance reasons.
	 */
	public static boolean isLegacyJ2EEProject(IProject project){
		boolean ret = false;
		
		IFacetedProject facetedProject;
		try {
			facetedProject = ProjectFacetsManager.create(project);
			if (facetedProject == null)
				return false;
			
			if(isEARProject(facetedProject)){
				IProjectFacet earFacet = ProjectFacetsManager.getProjectFacet(IModuleConstants.JST_EAR_MODULE);
				ret = (facetedProject.hasProjectFacet(earFacet.getVersion(J2EEVersionUtil.convertVersionIntToString(J2EEVersionConstants.J2EE_1_4_ID)))
						|| facetedProject.hasProjectFacet(earFacet.getVersion(J2EEVersionUtil.convertVersionIntToString(J2EEVersionConstants.J2EE_1_3_ID)))
						|| facetedProject.hasProjectFacet(earFacet.getVersion(J2EEVersionUtil.convertVersionIntToString(J2EEVersionConstants.J2EE_1_2_ID)))
					);
			} else if(isDynamicWebProject(facetedProject)){
				IProjectFacet webFacet = ProjectFacetsManager.getProjectFacet(IModuleConstants.JST_WEB_MODULE);
				ret = (facetedProject.hasProjectFacet(webFacet.getVersion(J2EEVersionUtil.convertVersionIntToString(J2EEVersionUtil.convertJ2EEVersionIDToWebVersionID(J2EEVersionConstants.J2EE_1_4_ID))))
						|| facetedProject.hasProjectFacet(webFacet.getVersion(J2EEVersionUtil.convertVersionIntToString(J2EEVersionUtil.convertJ2EEVersionIDToWebVersionID(J2EEVersionConstants.J2EE_1_3_ID))))
						|| facetedProject.hasProjectFacet(webFacet.getVersion(J2EEVersionUtil.convertVersionIntToString(J2EEVersionUtil.convertJ2EEVersionIDToWebVersionID(J2EEVersionConstants.J2EE_1_2_ID))))
						);
			} else if(isEJBProject(facetedProject)){
				IProjectFacet ejbFacet = ProjectFacetsManager.getProjectFacet(IModuleConstants.JST_EJB_MODULE);
				ret = (facetedProject.hasProjectFacet(ejbFacet.getVersion(J2EEVersionUtil.convertVersionIntToString(J2EEVersionUtil.convertJ2EEVersionIDToEJBVersionID(J2EEVersionConstants.J2EE_1_4_ID))))
						|| facetedProject.hasProjectFacet(ejbFacet.getVersion(J2EEVersionUtil.convertVersionIntToString(J2EEVersionUtil.convertJ2EEVersionIDToEJBVersionID(J2EEVersionConstants.J2EE_1_3_ID))))
						|| facetedProject.hasProjectFacet(ejbFacet.getVersion(J2EEVersionUtil.convertVersionIntToString(J2EEVersionUtil.convertJ2EEVersionIDToEJBVersionID(J2EEVersionConstants.J2EE_1_2_ID))))
						);
			} else if(isApplicationClientProject(facetedProject)){
				IProjectFacet appFacet = ProjectFacetsManager.getProjectFacet(IModuleConstants.JST_APPCLIENT_MODULE);
				ret = (facetedProject.hasProjectFacet(appFacet.getVersion(J2EEVersionUtil.convertVersionIntToString(J2EEVersionConstants.J2EE_1_4_ID)))
						|| facetedProject.hasProjectFacet(appFacet.getVersion(J2EEVersionUtil.convertVersionIntToString(J2EEVersionConstants.J2EE_1_3_ID)))
						|| facetedProject.hasProjectFacet(appFacet.getVersion(J2EEVersionUtil.convertVersionIntToString(J2EEVersionConstants.J2EE_1_2_ID)))
						);
			} else if(isJCAProject(facetedProject)){
				IProjectFacet jcaFacet = ProjectFacetsManager.getProjectFacet(IModuleConstants.JST_CONNECTOR_MODULE);
				ret = (facetedProject.hasProjectFacet(jcaFacet.getVersion(J2EEVersionUtil.convertVersionIntToString(J2EEVersionUtil.convertJ2EEVersionIDToConnectorVersionID(J2EEVersionConstants.J2EE_1_4_ID))))
						|| facetedProject.hasProjectFacet(jcaFacet.getVersion(J2EEVersionUtil.convertVersionIntToString(J2EEVersionUtil.convertJ2EEVersionIDToConnectorVersionID(J2EEVersionConstants.J2EE_1_3_ID))))
						);
			} else if(isUtilityProject(facetedProject)){
				// not sure if there is a better way
				ret = true;
			} 
		} catch (CoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return ret;
	}

	/**
	 * This method will return the an IVirtualComponent for the given module name. The method take
	 * either moduleName or moduleName + ".module_extension" (module_extension = ".jar" || ".war" ||
	 * ".rar") which allows users to get a IVirtualComponent for a given entry in an application.xml
	 * 
	 * @return - a IVirtualComponent for module name
	 * @deprecated - see {@link EarUtilities.getModule(IVirtualComponent earComponent, String moduleName)}
	 */
	public static IVirtualComponent getModule(IVirtualComponent earComponent, String moduleName) {
		return EarUtilities.getModule(earComponent, moduleName);
	}

	/**
	 * This method will return the list of IVirtualReferences for the J2EE module components
	 * contained in this EAR application.
	 * 
	 * @return - an array of IVirtualReferences for J2EE modules in the EAR
	 * @deprecated - see {@link EarUtilities.getJ2EEModuleReferences(IVirtualComponent earComponent)}
	 */
	public static IVirtualReference[] getJ2EEModuleReferences(IVirtualComponent earComponent) {
		return EarUtilities.getJ2EEModuleReferences(earComponent);
	}

	/**
	 * This method will return the list of IVirtualReferences for all of the components contained in
	 * an EAR application.
	 * 
	 * @return - an array of IVirtualReferences for components in the EAR
	 * @deprecated - see {@link EarUtilities.getComponentReferences(IVirtualComponent earComponent)}
	 */
	public static IVirtualReference[] getComponentReferences(IVirtualComponent earComponent) {
		return EarUtilities.getComponentReferences(earComponent);
	}

	/**
	 * This method will return the IVirtualReference to the component of the given name
	 * 
	 * @return - IVirtualReference or null if not found
	 * @deprecated - see {@link EarUtilities.getComponentReference(IVirtualComponent earComponent, String componentName)}
	 */
	public static IVirtualReference getComponentReference(IVirtualComponent earComponent, String componentName) {
		return EarUtilities.getComponentReference(earComponent, componentName);
	}
}
