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

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;

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.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jem.workbench.utility.JemProjectUtilities;
import org.eclipse.jst.j2ee.application.Application;
import org.eclipse.jst.j2ee.classpathdep.ClasspathDependencyUtil;
import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants;
import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualArchiveComponent;
import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent;
import org.eclipse.jst.j2ee.componentcore.util.EARArtifactEdit;
import org.eclipse.jst.j2ee.ejb.EJBJar;
import org.eclipse.jst.j2ee.internal.EjbModuleExtensionHelper;
import org.eclipse.jst.j2ee.internal.IEJBModelExtenderManager;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyManifestUtil;
import org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyVirtualComponent;
import org.eclipse.jst.j2ee.internal.componentcore.JavaEEBinaryComponentHelper;
import org.eclipse.jst.j2ee.internal.plugin.IJ2EEModuleConstants;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
import org.eclipse.jst.jee.util.internal.JavaEEQuickPeek;
import org.eclipse.jst.server.core.IApplicationClientModule;
import org.eclipse.jst.server.core.IConnectorModule;
import org.eclipse.jst.server.core.IEJBModule;
import org.eclipse.jst.server.core.IEnterpriseApplication;
import org.eclipse.jst.server.core.IJ2EEModule;
import org.eclipse.jst.server.core.IWebModule;
import org.eclipse.wst.common.componentcore.ArtifactEdit;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.ComponentResource;
import org.eclipse.wst.common.componentcore.internal.Property;
import org.eclipse.wst.common.componentcore.internal.StructureEdit;
import org.eclipse.wst.common.componentcore.internal.WorkbenchComponent;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent;
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.IVirtualFolder;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.ServerUtil;
import org.eclipse.wst.server.core.internal.ModuleFile;
import org.eclipse.wst.server.core.internal.ModuleFolder;
import org.eclipse.wst.server.core.model.IModuleFile;
import org.eclipse.wst.server.core.model.IModuleFolder;
import org.eclipse.wst.server.core.model.IModuleResource;
import org.eclipse.wst.web.internal.deployables.ComponentDeployable;
/**
 * J2EE module superclass.
 */
public class J2EEFlexProjDeployable extends ComponentDeployable implements IJ2EEModule, IEnterpriseApplication, IApplicationClientModule, IConnectorModule, IEJBModule, IWebModule {
	protected static final IPath WEB_CLASSES_PATH = new Path(J2EEConstants.WEB_INF_CLASSES);
	protected static final IPath MANIFEST_PATH = new Path(J2EEConstants.MANIFEST_URI);
	protected static IPath WEBLIB = new Path(J2EEConstants.WEB_INF_LIB).makeAbsolute();
	private static String USE_SINGLE_ROOT_PROPERTY = "useSingleRoot"; //$NON-NLS-1$
	protected IPackageFragmentRoot[] cachedSourceContainers;
	protected IContainer[] cachedOutputContainers;
	protected HashMap cachedOutputMappings;
	protected HashMap cachedSourceOutputPairs;
	protected List classpathComponentDependencyURIs = new ArrayList();
	private boolean isSingleJavaOutputNonSource = false;

	/**
	 * Constructor for J2EEFlexProjDeployable.
	 * 
	 * @param project
	 * @param aComponent
	 */
	public J2EEFlexProjDeployable(IProject project, IVirtualComponent aComponent) {
		super(project, aComponent);
	}
	

	/**
	 * Constructor for J2EEFlexProjDeployable.
	 * 
	 * @param project
	 */
	public J2EEFlexProjDeployable(IProject project) {
		super(project);
	}

	/**
	 * Returns the root folders for the resources in this module.
	 * 
	 * @return a possibly-empty array of resource folders
	 */
	public IContainer[] getResourceFolders() {
		List result = new ArrayList();
		IVirtualComponent vc = ComponentCore.createComponent(getProject());
		if (vc != null) {
			IVirtualFolder vFolder = vc.getRootFolder();
			if (vFolder != null) {
				IContainer[] underlyingFolders = vFolder.getUnderlyingFolders();
				result.addAll(Arrays.asList(underlyingFolders));
			}
		}
		return (IContainer[]) result.toArray(new IContainer[result.size()]);
	}

	/**
	 * Returns the root folders containing Java output in this module.
	 * 
	 * @return a possibly-empty array of Java output folders
	 */
	public IContainer[] getJavaOutputFolders() {
		if (cachedOutputContainers == null)
			cachedOutputContainers = getJavaOutputFolders(getProject());
		return cachedOutputContainers;
	}
	
	public IContainer[] getJavaOutputFolders(IProject project) {
		if (project == null)
			return new IContainer[0];
		return J2EEProjectUtilities.getOutputContainers(project);
	}

	protected boolean shouldIncludeUtilityComponent(IVirtualComponent virtualComp,IVirtualReference[] references, ArtifactEdit edit) {
		// If the component module is an EAR we know all archives are filtered out of virtual component members
		// and we will return only those archives which are not binary J2EE modules in the EAR DD.  These J2EE modules will
		// be returned by getChildModules()
		if (J2EEProjectUtilities.isEARProject(component.getProject())) {
			return virtualComp != null && virtualComp.isBinary() && !isNestedJ2EEModule(virtualComp, references, (EARArtifactEdit)edit);
		} else { 
			return super.shouldIncludeUtilityComponent(virtualComp, references, edit);
		}
	}
	
	protected void addUtilMember(IVirtualComponent parent, IVirtualReference reference, IPath runtimePath) {
		// do not add classpath dependencies whose runtime path (../) maps to the parent component or that represent
		// class folders
		if (!runtimePath.equals(IClasspathDependencyConstants.RUNTIME_MAPPING_INTO_CONTAINER_PATH) 
				&& !ClasspathDependencyUtil.isClassFolderReference(reference)) {
			super.addUtilMember(parent, reference, runtimePath);
		}
	}
	
	protected IModuleResource[] getBinaryModuleMembers() {
		IPath archivePath = ((J2EEModuleVirtualArchiveComponent)component).getWorkspaceRelativePath();
		ModuleFile mf = null;
		if (archivePath != null) { //In Workspace
			IFile utilFile = ResourcesPlugin.getWorkspace().getRoot().getFile(archivePath);
			mf = new ModuleFile(utilFile, utilFile.getName(), ((J2EEModuleVirtualArchiveComponent)component).getRuntimePath().makeRelative());
		} else {
			File extFile = ((J2EEModuleVirtualArchiveComponent)component).getUnderlyingDiskFile();
			mf = new ModuleFile(extFile, extFile.getName(), ((J2EEModuleVirtualArchiveComponent)component).getRuntimePath().makeRelative());
		}
		return new IModuleResource[] {mf};
	}
	
	public IModuleResource[] members() throws CoreException {
		members.clear();
		classpathComponentDependencyURIs.clear();

		// Handle binary components
		if (component instanceof J2EEModuleVirtualArchiveComponent)
			return getBinaryModuleMembers();

		if (J2EEProjectUtilities.isEARProject(component.getProject())) {
			// If an EAR, add classpath contributions for all referenced modules
			addReferencedComponentClasspathDependencies(component, false);
		} else {
			if (J2EEProjectUtilities.isDynamicWebProject(component.getProject())) {
				// If a web, add classpath contributions for all WEB-INF/lib modules
				addReferencedComponentClasspathDependencies(component, true);
			}
			if (canExportClasspathComponentDependencies(component)){
				saveClasspathDependencyURIs(component);
			}
			// Add all Java output folders that have publish/export attributes
			addClassFolderDependencies(component);
		}
		
		// If j2ee project structure is a single root structure, just return optimized members
		if (isSingleRootStructure()) {
			final IModuleResource[] resources = getOptimizedMembers();
			if (!classpathComponentDependencyURIs.isEmpty()) {
				for (int i = 0; i < resources.length; i++) {
					if (resources[i] instanceof IModuleFolder) {
						IModuleFolder folder = (IModuleFolder) resources[i];
						if (folder.getName().equals(J2EEConstants.META_INF)) {
							IModuleResource[] files = folder.members();
							for (int j = 0; j < files.length; j++) {
								if (files[j] instanceof IModuleFile)
								{
									files[j] = replaceManifestFile((IModuleFile) files[j]);
								}
							}
						}
					}
				}
			}
			// add to any potentially mapped Java class folders
			for (int i = 0; i < resources.length; i++) {
				members.add(resources[i]);
			}
			return (IModuleResource[]) members.toArray(new IModuleResource[members.size()]);
		}
		
		cachedSourceContainers = J2EEProjectUtilities.getSourceContainers(getProject());
		try {
			IPath javaPath = Path.EMPTY;
			if (J2EEProjectUtilities.isDynamicWebProject(component.getProject()))
				javaPath = WEB_CLASSES_PATH;
			
			if (component != null) {
				IVirtualFolder vFolder = component.getRootFolder();
				IModuleResource[] mr = getMembers(vFolder, Path.EMPTY);
				int size = mr.length;
				for (int j = 0; j < size; j++) {
					members.add(mr[j]);
				}
			}
			
			IContainer[] javaCont = getJavaOutputFolders();		
			int size = javaCont.length;
			for (int i = 0; i < size; i++) {
				//If the java output is in the scope of the virtual component, ignore to avoid duplicates
				if (ComponentCore.createResources(javaCont[i]).length > 0) 
					continue;
				IModuleResource[] mr = getMembers(javaCont[i], javaPath, javaPath, javaCont);
				int size2 = mr.length;
				for (int j = 0; j < size2; j++) {
					members.add(mr[j]);
				}
			}
									
			if (component != null) {
				addUtilMembers(component);
				List consumableMembers = getConsumableReferencedMembers(component);
				if (!consumableMembers.isEmpty())
					members.addAll(consumableMembers);
			}
			
			IModuleResource[] mr = new IModuleResource[members.size()];
			members.toArray(mr);
			return mr;
		} finally {
			cachedSourceContainers = null;
			cachedOutputContainers = null;
			cachedOutputMappings = null;
			cachedSourceOutputPairs = null;
		}
	}
	
	protected IModuleFile createModuleFile(IFile file, IPath path) {
		// if this is the MANIFEST.MF file and we have classpath component dependencies, 
		// update it
		return replaceManifestFile(super.createModuleFile(file, path));
	}
	
	protected IModuleFile replaceManifestFile(IModuleFile moduleFile) {
		final IFile file = (IFile) moduleFile.getAdapter(IFile.class);
		final IPath path = moduleFile.getModuleRelativePath();
		// if the MANIFEST.MF is being requested and we have classpath component dependencies, 
		// dynamically generate a customized MANIFEST.MF and return that 
		if (path.append(file.getName()).equals(MANIFEST_PATH) && !classpathComponentDependencyURIs.isEmpty()) {
			final IProject project = file.getProject();
			final IPath workingLocation = project.getWorkingLocation(J2EEPlugin.PLUGIN_ID);
			// create path to temp MANIFEST.MF
			final IPath tempManifestPath = workingLocation.append(MANIFEST_PATH);
			final File fsFile = tempManifestPath.toFile();
			if (!fsFile.exists()) {
				// create parent dirs for temp MANIFEST.MF
				final File parent = fsFile.getParentFile();
				if (!parent.exists()) {
					if (!parent.mkdirs()) {
						return moduleFile;
					}
				}
			}
			// create temp MANIFEST.MF using util method
			try {
				ClasspathDependencyManifestUtil.updateManifestClasspath(file, classpathComponentDependencyURIs, fsFile);
				// create new ModuleFile that points to temp MANIFEST.MF
				return new ModuleFile(fsFile, file.getName(), path);
			} catch (IOException ioe) {
				return moduleFile;
			}
		}
		return moduleFile;
	}
	
	protected IModuleResource[] handleJavaPath(IPath path, IPath javaPath, IPath curPath, IContainer[] javaCont, IModuleResource[] mr, IContainer cc) throws CoreException {
		if (curPath.equals(javaPath)) {
			int size = javaCont.length;
			for (int i = 0; i < size; i++) {
				IModuleResource[] mr2 = getMembers(javaCont[i], path.append(cc.getName()), null, null);
				IModuleResource[] mr3 = new IModuleResource[mr.length + mr2.length];
				System.arraycopy(mr, 0, mr3, 0, mr.length);
				System.arraycopy(mr2, 0, mr3, mr.length, mr2.length);
				mr = mr3;
			}
		} else {
			boolean containsFolder = false;
			String name = javaPath.segment(curPath.segmentCount());
			int size = mr.length;
			for (int i = 0; i < size && !containsFolder; i++) {
				if (mr[i] instanceof IModuleFolder) {
					IModuleFolder mf2 = (IModuleFolder) mr[i];
					if (name.equals(mf2.getName())) {
						containsFolder = true;
					}
				}
			}
			
			if (!containsFolder && javaCont.length > 0) {
				ModuleFolder mf2 = new ModuleFolder(javaCont[0], name, curPath);
				IModuleResource[] mrf = new IModuleResource[0];
				size = javaCont.length;
				for (int i = 0; i < size; i++) {
					IModuleResource[] mrf2 = getMembers(javaCont[i], javaPath, null, null);
					IModuleResource[] mrf3 = new IModuleResource[mrf.length + mrf2.length];
					System.arraycopy(mrf, 0, mrf3, 0, mrf.length);
					System.arraycopy(mrf2, 0, mrf3, mrf.length, mrf2.length);
					mrf = mrf3;
				}
				
				mf2.setMembers(mrf);
				
				IModuleResource[] mr3 = new IModuleResource[mr.length + 1];
				System.arraycopy(mr, 0, mr3, 0, mr.length);
				mr3[mr.length] = mf2;
				mr = mr3;
			}
		}
		return mr;
	}

    /**
     * Returns the classpath as a list of absolute IPaths.
     * 
     * @return an array of paths
     */
    public IPath[] getClasspath() {
		List paths = new ArrayList();
        IJavaProject proj = JemProjectUtilities.getJavaProject(getProject());
        URL[] urls = JemProjectUtilities.getClasspathAsURLArray(proj);
		for (int i = 0; i < urls.length; i++) {
			URL url = urls[i];
			paths.add(Path.fromOSString(url.getPath()));
		}
        return  (IPath[]) paths.toArray(new IPath[paths.size()]);
    }
    
    public String getJNDIName(String ejbName) {
    	if (!J2EEProjectUtilities.isEJBProject(component.getProject()))
    		return null;
		EjbModuleExtensionHelper modHelper = null;
		EJBJar jar = null;
		ArtifactEdit ejbEdit = null;
		try {
			ejbEdit = ComponentUtilities.getArtifactEditForRead(component);
			if (ejbEdit != null) {
				jar = (EJBJar) ejbEdit.getContentModelRoot();
				modHelper = IEJBModelExtenderManager.INSTANCE.getEJBModuleExtension(null);
				return modHelper == null ? null : modHelper.getJNDIName(jar, jar.getEnterpriseBeanNamed(ejbName));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (ejbEdit != null)
				ejbEdit.dispose();
		}
		return null;
	}

    /**
     * This method will handle a number of J2EE related scenarios.  If this is an ear and a child module is passed in,
     * the URI for that child module will be returned.  If no child module was passed, the URI of the EAR is returned.
     * If this is a child component and the module passed in is the EAR, we grab the module uri for this compared to that
     * EAR.  If no ear module is passed in we look for one and use it and return URI relative to found EAR.  If no EAR's 
     * are found the URI is returned in a default manner.
     * 
     * @return URI string
     */
    public String getURI(IModule module) {
    	// If the component is an ear and the module passed in is a child module
    	if (component!=null && module!=null && J2EEProjectUtilities.isEARProject(component.getProject()))
 			return getContainedURI(module);

    	IVirtualComponent ear = null;
    	String aURI = null;
    	// If the component is a child module and the module passed in is the ear
    	if (module != null && J2EEProjectUtilities.isEARProject(module.getProject()))
    		ear = ComponentCore.createComponent(module.getProject());
    	// else if the component is a child module and the module passed in is null, search for first ear
    	else if (module==null && component != null) {
    		IProject[] earProjects = J2EEProjectUtilities.getReferencingEARProjects(component.getProject());
	        if (earProjects.length>0)
	        	ear = ComponentCore.createComponent(earProjects[0]);
    	}
    	// We have a valid ear and the component is a valid child
    	if (ear != null && component != null) {
    		EARArtifactEdit earEdit = null;
			try {
				earEdit = EARArtifactEdit.getEARArtifactEditForRead(ear);
				if (earEdit != null)
					aURI = earEdit.getModuleURI(component);
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				if (earEdit != null)
					earEdit.dispose();
			}
    	} 
    	// We have an ear component and no child module
    	else if (component!=null && J2EEProjectUtilities.isEARProject(component.getProject())) {
			aURI = component.getDeployedName()+IJ2EEModuleConstants.EAR_EXT;
    	} 
    	// We have child components but could not find valid ears
    	else if (component != null && J2EEProjectUtilities.isDynamicWebProject(component.getProject())) {
			if (module != null) {
				IVirtualComponent webComp = ComponentCore.createComponent(component.getProject());
				String extension = IJ2EEModuleConstants.JAR_EXT;
				if (J2EEProjectUtilities.isDynamicWebProject(module.getProject())) {
					extension = IJ2EEModuleConstants.WAR_EXT;
				} else if (J2EEProjectUtilities.isJCAProject(module.getProject())) {
					extension = IJ2EEModuleConstants.RAR_EXT;
				}
				IVirtualReference reference = webComp.getReference(module.getProject().getName());
				if(reference != null){
					aURI = ComponentUtilities.getDeployUriOfComponent(reference, extension);
				} else {
					aURI = webComp.getDeployedName() + extension;
				}
			}
			else {
				aURI = component.getDeployedName() + IJ2EEModuleConstants.WAR_EXT;
			}
		} 
    	else if (component!=null && (J2EEProjectUtilities.isEJBProject(component.getProject()) || J2EEProjectUtilities.isApplicationClientProject(component.getProject()))) {
    		aURI = component.getDeployedName()+IJ2EEModuleConstants.JAR_EXT;
    	} 
    	else if (component!=null && J2EEProjectUtilities.isJCAProject(component.getProject())) {
    		aURI = component.getDeployedName()+IJ2EEModuleConstants.RAR_EXT;
    	}
    	
    	if (aURI !=null && aURI.length()>1 && aURI.startsWith("/")) //$NON-NLS-1$
    		aURI = aURI.substring(1);
    	return aURI;
	}
    
    protected boolean isBinaryModuleArchive(IModule module) {
    	if (module!=null && module.getName().endsWith(IJ2EEModuleConstants.JAR_EXT) || module.getName().endsWith(IJ2EEModuleConstants.WAR_EXT) ||
    			module.getName().endsWith(IJ2EEModuleConstants.RAR_EXT)) {
    		if (component!=null && J2EEProjectUtilities.isEARProject(component.getProject()))
    			return true;
    	}
    	return false;
    }
    
    private String getContainedURI(IModule module) {
    	if (component instanceof J2EEModuleVirtualArchiveComponent || isBinaryModuleArchive(module))
    		return new Path(module.getName()).lastSegment();
    	
    	IVirtualComponent comp = ComponentCore.createComponent(module.getProject());
    	String aURI = null;
    	if (comp!=null && component!=null && J2EEProjectUtilities.isEARProject(component.getProject())) {
			EARArtifactEdit earEdit = null;
			try {
				earEdit = EARArtifactEdit.getEARArtifactEditForRead(component);
				if (earEdit != null)
					aURI = earEdit.getModuleURI(comp);
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				if (earEdit != null)
					earEdit.dispose();
			}
    	}
    	if (aURI !=null && aURI.length()>1 && aURI.startsWith("/")) //$NON-NLS-1$
    		aURI = aURI.substring(1);
    	return aURI;
	}
    
    /**
     * This method returns the context root property from the deployable project's .component file
     */
    public String getContextRoot() {
		Properties props = component.getMetaProperties();
		if(props.containsKey(J2EEConstants.CONTEXTROOT))
			return props.getProperty(J2EEConstants.CONTEXTROOT);
	    return component.getName();
    }
    
    /**
     * This method is applicable for a web deployable.  The module passed in should either be null or
     * the EAR module the web deployable is contained in.  It will return the context root from the EAR
     * if it has one or return the .component value in the web project if it is standalone.
     *  
     * @param module
     * @return contextRoot String
     */
    public String getContextRoot(IModule earModule) {
    	IProject deployProject = component.getProject();
    	String contextRoot = null;
    	if (earModule == null)
    		return getContextRoot();
    	else if (J2EEProjectUtilities.isEARProject(earModule.getProject()) && J2EEProjectUtilities.isDynamicWebProject(deployProject)) {
    		EARArtifactEdit edit = null;
    		try {
    			edit = EARArtifactEdit.getEARArtifactEditForRead(earModule.getProject());
    			contextRoot = edit.getWebContextRoot(deployProject);
    		} finally {
    			if (edit!=null)
    				edit.dispose();
    		}
    	}
    	return contextRoot;
    }
    
    /**
     * Find the source container, if any, for the given file.
     * 
     * @param file
     * @return IPackageFragmentRoot sourceContainer for IFile
     */
    protected IPackageFragmentRoot getSourceContainer(IFile file) {
    	if (file == null)
    		return null;
    	IPackageFragmentRoot[] srcContainers = getSourceContainers();
    	for (int i=0; i<srcContainers.length; i++) {
    		IPath srcPath = srcContainers[i].getPath();
    		if (srcPath.isPrefixOf(file.getFullPath()))
    			return srcContainers[i];
    	}
    	return null;
    }
    
    /**
     * Either returns value from cache or stores result as value in cache for the corresponding
     * output container for the given source container.
     * 
     * @param sourceContainer
     * @return IContainer output container for given source container
     */
    protected IContainer getOutputContainer(IPackageFragmentRoot sourceContainer) {
    	if (sourceContainer == null)
    		return null;
    	
    	HashMap pairs = getCachedSourceOutputPairs();
    	IContainer output = (IContainer) pairs.get(sourceContainer);
    	if (output == null) {
    		output = J2EEProjectUtilities.getOutputContainer(getProject(), sourceContainer);
    		pairs.put(sourceContainer,output);
    	}
    	return output;
    }
    
	private IPackageFragmentRoot[] getSourceContainers() {
		if (cachedSourceContainers != null)
			return cachedSourceContainers;
		return J2EEProjectUtilities.getSourceContainers(getProject());
	}
    
    protected List getConsumableReferencedMembers(IVirtualComponent vc) throws CoreException {
		List consumableMembers = new ArrayList();
		IVirtualReference[] refComponents = vc.getReferences();
    	for (int i = 0; i < refComponents.length; i++) {
    		IVirtualReference reference = refComponents[i];
    		if (reference != null && reference.getDependencyType()==IVirtualReference.DEPENDENCY_TYPE_CONSUMES) {
    			IVirtualComponent consumedComponent = reference.getReferencedComponent();
    			if (consumedComponent!=null && isProjectOfType(consumedComponent.getProject(),IModuleConstants.JST_UTILITY_MODULE)) {
    				if (consumedComponent != null && consumedComponent.getRootFolder()!=null) {
    					IVirtualFolder vFolder = consumedComponent.getRootFolder();
    					IModuleResource[] mr = getMembers(vFolder, reference.getRuntimePath().makeRelative());
    					int size = mr.length;
    					for (int j = 0; j < size; j++) {
    						if (!members.contains(mr[j]))
    							members.add(mr[j]);
    					}
    					addUtilMembers(consumedComponent);
    					List childConsumableMembers = getConsumableReferencedMembers(consumedComponent);
    					if (!childConsumableMembers.isEmpty())
    						members.addAll(childConsumableMembers);
    				}
    				
    				IContainer[] javaCont = getJavaOutputFolders(consumedComponent.getProject());		
    				int size = javaCont.length;
    				for (int j = 0; j < size; j++) {
    					IModuleResource[] mr = getMembers(javaCont[j], reference.getRuntimePath(), reference.getRuntimePath(), javaCont);
    					int size2 = mr.length;
    					for (int k = 0; k < size2; k++) {
    						if (!members.contains(mr[k]))
    							members.add(mr[k]);
    					}
    				}
    			}
    		}
    	}
		return consumableMembers;
	}
    
    protected IModule gatherModuleReference(IVirtualComponent component, IVirtualComponent targetComponent ) {
    	IModule module = super.gatherModuleReference(component, targetComponent);
    	// Handle binary module components
    	if (targetComponent instanceof J2EEModuleVirtualArchiveComponent) {
    		if (J2EEProjectUtilities.isEARProject(component.getProject()) || targetComponent.getProject()!=component.getProject())
    			module = ServerUtil.getModule(J2EEDeployableFactory.ID+":"+targetComponent.getName()); //$NON-NLS-1$
    	}
		return module;
    }
    
    /**
     * Determine if the component is nested J2EE module on the application.xml of this EAR
     * @param aComponent
     * @return boolean is passed in component a nested J2EE module on this EAR
     */
    private boolean isNestedJ2EEModule(IVirtualComponent aComponent, IVirtualReference[] references, EARArtifactEdit edit) {
    	if (edit==null) 
			return false;
		Application app = edit.getApplication();
		if (app == null) { // if no application.xml, return false
			return false;
		}
		IVirtualReference reference = getReferenceNamed(references,aComponent.getName());
		// Ensure module URI exists on EAR DD for binary archive
		boolean inDD = app.getFirstModule(reference.getArchiveName()) != null;
		return inDD && JavaEEBinaryComponentHelper.getJavaEEQuickPeek(aComponent).getType() != JavaEEQuickPeek.UNKNOWN;
    }
    
    protected IVirtualReference getReferenceNamed(IVirtualReference[] references, String name) {
    	for (int i=0; i<references.length; i++) {
    		if (references[i].getReferencedComponent().getName().equals(name))
    			return references[i];
    	}
    	return null;
    }
    
    protected ArtifactEdit getComponentArtifactEditForRead() {
		return EARArtifactEdit.getEARArtifactEditForRead(component.getProject());
	}
    
    /**
     * The references for J2EE module deployment are only those child modules of EARs or web modules
     */
    protected IVirtualReference[] getReferences(IVirtualComponent aComponent) {
    	if (aComponent == null || aComponent.isBinary()) {
    		return new IVirtualReference[] {};
    	} else if (J2EEProjectUtilities.isDynamicWebProject(aComponent.getProject())) {
    		return getWebLibModules((J2EEModuleVirtualComponent)aComponent);
    	} else if (J2EEProjectUtilities.isEARProject(aComponent.getProject())) {
    		return super.getReferences(aComponent);
    	} else {
    		return new IVirtualReference[] {};
    	}
    }
    
    /**
	 * This method will return the list of dependent modules which are utility jars in the web lib
	 * folder of the deployed path of the module. It will not return null.
	 * 
	 * @return array of the web library dependent modules
	 */
	private IVirtualReference[] getWebLibModules(J2EEModuleVirtualComponent comp) {
		List result = new ArrayList();
		IVirtualReference[] refComponents = comp.getNonManifestReferences();
		// Check the deployed path to make sure it has a lib parent folder and matchs the web.xml
		// base path
		for (int i = 0; i < refComponents.length; i++) {
			if (refComponents[i].getRuntimePath().equals(WEBLIB))
				result.add(refComponents[i]);
		}
		return (IVirtualReference[]) result.toArray(new IVirtualReference[result.size()]);
	}
	
	/*
	 * Add any classpath component dependencies from this component
	 */
	private void addReferencedComponentClasspathDependencies(final IVirtualComponent component, final boolean web) {
		final IVirtualReference[] refs = component.getReferences();
		final Set absolutePaths = new HashSet();
		for (int i = 0; i < refs.length; i++) {
			final IVirtualReference reference = refs[i];
			final IPath runtimePath = reference.getRuntimePath();
			final IVirtualComponent referencedComponent = reference.getReferencedComponent();
			
			// if we are adding to a web project, only process references with the /WEB-INF/lib runtime path
			if (web && !runtimePath.equals(WEBLIB)) {
				continue;
			}

			// if the reference cannot export dependencies, skip
			if (!canExportClasspathComponentDependencies(referencedComponent)) {
				continue;
			}
			
			if (!referencedComponent.isBinary() && referencedComponent instanceof J2EEModuleVirtualComponent) {
				final IVirtualReference[] cpRefs = ((J2EEModuleVirtualComponent) referencedComponent).getJavaClasspathReferences();
				for (int j = 0; j < cpRefs.length; j++) {
					final IVirtualReference cpRef = cpRefs[j];
					IPath cpRefRuntimePath = cpRef.getRuntimePath();

					if (cpRef.getReferencedComponent() instanceof ClasspathDependencyVirtualComponent) {
						// want to avoid adding dups
						ClasspathDependencyVirtualComponent cpComp = (ClasspathDependencyVirtualComponent) cpRef.getReferencedComponent();
						// don't want to process class folder refs here
						if (cpComp.isClassFolder()) {
							continue;
						}
						if (cpRefRuntimePath.equals(IClasspathDependencyConstants.RUNTIME_MAPPING_INTO_CONTAINER_PATH)) {
							// runtime path within deployed app will be runtime path of parent component
							cpRefRuntimePath = runtimePath;
						} 						
						final IPath absolutePath = ClasspathDependencyUtil.getClasspathVirtualReferenceLocation(cpRef);
						if (absolutePaths.contains(absolutePath)) {
							// have already added a member for this archive
							continue;
						} else {
							addUtilMember(component, cpRef, cpRefRuntimePath);
							absolutePaths.add(absolutePath);
						}
					}
				}
			}
		}
	}
	
	private boolean canExportClasspathComponentDependencies(IVirtualComponent component) {
		final IProject project = component.getProject();
		// check for valid project type
		if (J2EEProjectUtilities.isEJBProject(project) 
				|| J2EEProjectUtilities.isDynamicWebProject(project)
				|| J2EEProjectUtilities.isJCAProject(project)
    			|| J2EEProjectUtilities.isUtilityProject(project)) {
			return true;
		}
		return false;
	}
	
	private void saveClasspathDependencyURIs(IVirtualComponent component) {
		if (!component.isBinary() && component instanceof J2EEModuleVirtualComponent) {
			final IVirtualReference[] cpRefs = ((J2EEModuleVirtualComponent) component).getJavaClasspathReferences();
			for (int j = 0; j < cpRefs.length; j++) {
				final IVirtualReference cpRef = cpRefs[j];
				// if we are adding to an EAR project, only process references with the root mapping
				if (!cpRef.getRuntimePath().equals(IClasspathDependencyConstants.RUNTIME_MAPPING_INTO_CONTAINER_PATH)) {
					// fails the runtime path test
					continue;
				}
				if (cpRef.getReferencedComponent() instanceof VirtualArchiveComponent) {
					classpathComponentDependencyURIs.add(cpRef.getArchiveName());
				}
			}
		}
	}
	
	private void addClassFolderDependencies(final IVirtualComponent component) throws CoreException {
		if (!component.isBinary() && component instanceof J2EEModuleVirtualComponent) {
			final IVirtualReference[] cpRefs = ((J2EEModuleVirtualComponent) component).getJavaClasspathReferences();
			for (int i = 0; i < cpRefs.length; i++) {
				final IVirtualReference cpRef = cpRefs[i];
				final IPath runtimePath = cpRef.getRuntimePath();
				final IVirtualComponent comp = cpRef.getReferencedComponent();
				if (comp instanceof ClasspathDependencyVirtualComponent) {
					final ClasspathDependencyVirtualComponent cpComp = (ClasspathDependencyVirtualComponent) comp;
					if (cpComp.isClassFolder()) {
						IPath targetPath = null;
						if (runtimePath.equals(IClasspathDependencyConstants.RUNTIME_MAPPING_INTO_COMPONENT_PATH)) {
							targetPath = Path.EMPTY;
						} else if (runtimePath.equals(IClasspathDependencyConstants.WEB_INF_CLASSES_PATH)) {
							targetPath =  WEB_CLASSES_PATH;
						} else {
							continue;
						}
						final IContainer container = cpComp.getClassFolder();
						final IModuleResource[] mr = getMembers(container, targetPath, targetPath, new IContainer[]{container});
						for (int j = 0; j < mr.length; j++) {
							members.add(mr[j]);
						}						
					}
				}
			}
		}
	}
	
    /*
     * If the resource to check is a file then this method will return true if the file is linked. If the resource to
     * check is a folder then this method will return true if it, any of its sub directories, or any file contained
     * with-in this directory of any of it's sub directories are linked. Otherwise false is returned.
     */
    private boolean hasLinkedContent(final IResource resourceToCheck) throws CoreException {

    	if ((resourceToCheck != null) && resourceToCheck.isAccessible()) {
    		// skip non-accessible files
    		if (resourceToCheck.isLinked()) {
    			return true;
    		}
    		else {
    			switch (resourceToCheck.getType()) {
    				case IResource.FOLDER:
    					// recursively check sub directory contents
    					final IResource[] subDirContents = ((IFolder) resourceToCheck).members();
    					for (int i = 0; i < subDirContents.length; i++) {
    						if (hasLinkedContent(subDirContents[i])) {
    							return true;
    						}
    					}
    					break;
    				case IResource.FILE:
    					return resourceToCheck.isLinked();
    				default:
    					// skip as we only care about files and folders
    					break;
    			}
    		}
    	}
    	return false;
    }

    /*
     * This method returns true if the root folders of this component have any linked resources (folder or file);
     * Otherwise false is returned.
     */
    private boolean rootFoldersHaveLinkedContent() {

    	if (this.component != null) {
    		final IContainer[] rootFolders = this.component.getRootFolder().getUnderlyingFolders();
    		for (int i = 0; i < rootFolders.length; i++) {
    			try {
    				boolean hasLinkedContent = this.hasLinkedContent(rootFolders[i]);
    				if (hasLinkedContent) {
    					return true;
    				}
    			}
    			catch (CoreException coreEx) {
    				J2EEPlugin.logError(coreEx);
    			}
    		}
    	}
    	return false;
    }
	
	/**
	 * Returns <code>true</code> if this module has a simple structure based on a
	 * single root folder, and <code>false</code> otherwise.
	 * <p>
	 * In a single root structure, all files that are contained within the root folder
	 * are part of the module, and are already in the correct module structure. No
	 * module resources exist outside of this single folder.
	 * 
	 * For J2EE, this method will check if the project is already in J2EE spec standard output form.  
	 * The project must follow certain rules, but in general, the project's content roots must be source folders
	 * and the output folder must also be the the content root folder.
	 * </p>
	 * 
	 * @return <code>true</code> if this module has a single root structure, and
	 *    <code>false</code> otherwise
	 */
	public boolean isSingleRootStructure() {
		isSingleJavaOutputNonSource = false;
		StructureEdit edit = null;
		try {
			edit = StructureEdit.getStructureEditForRead(getProject());
			if (edit == null || edit.getComponent() == null)
				return false;
			WorkbenchComponent wbComp = edit.getComponent();
			List resourceMaps = wbComp.getResources();
			
			// 229650 - check to see if the property 'useSingleRoot' is defined. If it is set and
			// the value of the property is true then it will override the logic checks below
			final List componentProperties = wbComp.getProperties();
			if (componentProperties != null) {
				final Iterator componentPropertiesIterator = componentProperties.iterator();
				while (componentPropertiesIterator.hasNext()) {
					Property wbProperty = (Property) componentPropertiesIterator.next();
					if (J2EEFlexProjDeployable.USE_SINGLE_ROOT_PROPERTY.equals(wbProperty.getName())) {
						boolean useSingleRoot = Boolean.valueOf(wbProperty.getValue()).booleanValue();
						if (useSingleRoot) {
							return true;
						}
					}
				}
			}
			
			if (J2EEProjectUtilities.isEARProject(getProject())) {
				// Always return false for EARs so that members for EAR are always calculated and j2ee modules
				// are filtered out
				return false;
			} else if (J2EEProjectUtilities.isDynamicWebProject(getProject())) {
				// if there are any linked resources then this is not a singleroot module
				if (this.rootFoldersHaveLinkedContent()) {
					return false;
				}
				// Ensure there are only basic component resource mappings -- one for the content folder 
				// and any for src folders mapped to WEB-INF/classes
				if (hasDefaultWebResourceMappings(resourceMaps)) {
					// Verify only one java output folder
					if (getJavaOutputFolders().length==1) {
						// Verify the java output folder is to <content root>/WEB-INF/classes
						IPath javaOutputPath = getJavaOutputFolders()[0].getProjectRelativePath();
						IPath compRootPath = component.getRootFolder().getUnderlyingFolder().getProjectRelativePath();
						if (compRootPath.append(J2EEConstants.WEB_INF_CLASSES).equals(javaOutputPath)) 
							return true;
					}
				}
				return false;
			} else if (JavaEEProjectUtilities.isEJBProject(getProject()) || JavaEEProjectUtilities.isJCAProject(getProject())
					|| JavaEEProjectUtilities.isApplicationClientProject(getProject()) || JavaEEProjectUtilities.isUtilityProject(getProject())) {
				// if there are any linked resources then this is not a singleroot module
				if (this.rootFoldersHaveLinkedContent()) {
					return false;
				}
				// Ensure there are only source folder component resource mappings to the root content folder
				if (isRootResourceMapping(resourceMaps,false)) {
					IContainer[] javaOutputFolders = getJavaOutputFolders();
					// Verify only one java outputfolder
					if (javaOutputFolders.length==1) {
						// By the time we get here we know: for any folders defined as source in the 
						// .component file that they are also java source folders.
						if (JavaEEProjectUtilities.isUtilityProject(getProject()) || 
								JavaEEProjectUtilities.isEJBProject(getProject()) || 
								JavaEEProjectUtilities.isApplicationClientProject(getProject())) {
							if (! isSourceContainer(javaOutputFolders[0].getFullPath())) {
								// The single output folder is NOT a source folder so this is single-rooted. Since the
								// output folder (something like classes or bin) is not a source folder, JDT copies all files
								// (including non Java files) to this folder, so every resource needed at runtime is located 
								// in a single directory.
								isSingleJavaOutputNonSource = true;
								return true;
							} else {
// Don't implement at this time. Currently, we claim single-rooted when ejbModlule is the output folder.  However,
// we know this is not true because it cannot contain non Java files unless it is the only source folder. But, fixing
// at this time would break all current users.
//								// The single output folder IS a source folder. If there is more than one source folder
//								// then this cannot be single-rooted because JDT does NOTcopy non Java resources into the
//								// output folder when it is a source folder.
//								if (getSourceContainers().length > 1) {
//									return false;
//								} else {
//									// There is only one source folder and since the output folder is a source folder
//									// this is single-rooted.
//									return true;
//								}
							}
						}
//						// At this point for utility projects, this project is optimized, we can just use the output folder
//						if (J2EEProjectUtilities.isUtilityProject(getProject()))
//							return true;
						// Verify the java output folder is the same as one of the content roots
						IPath javaOutputPath = getJavaOutputFolders()[0].getProjectRelativePath();
						IContainer[] rootFolders = component.getRootFolder().getUnderlyingFolders();
						for (int i=0; i<rootFolders.length; i++) {
							IPath compRootPath = rootFolders[i].getProjectRelativePath();
							if (javaOutputPath.equals(compRootPath))
								return true;
						}
					}
				}
				return false;
			}
			return true;
		} finally {
			if (edit !=null)
				edit.dispose();
		}
	}
	
	/**
	 * Ensure that any component resource mappings are for source folders and 
	 * that they map to the root content folder
	 * 
	 * @param resourceMaps
	 * @return boolean
	 */
	private boolean isRootResourceMapping(List resourceMaps, boolean isForEAR) {
		// If the list is empty, return false
		if (resourceMaps.size()<1)
			return false;
		
		for (int i=0; i<resourceMaps.size(); i++) {
			ComponentResource resourceMap = (ComponentResource) resourceMaps.get(i);
			// Verify it maps to "/" for the content root
			if (!resourceMap.getRuntimePath().equals(Path.ROOT))
				return false;
			// If this is not for an EAR, verify it is also a src container
			if (!isForEAR) {
				IPath sourcePath = getProject().getFullPath().append(resourceMap.getSourcePath());
				if (!isSourceContainer(sourcePath))
					return false;
			}
		}
		return true;
	}
	
	/**
	 * Checks if the path argument is to a source container for the project.
	 * 
	 * @param a workspace relative full path
	 * @return is path a source container?
	 */
	private boolean isSourceContainer(IPath path) {
		IPackageFragmentRoot[] srcContainers = getSourceContainers();
		for (int i=0; i<srcContainers.length; i++) {
			if (srcContainers[i].getPath().equals(path))
				return true;
		}
		return false;
	}

	/**
	 * Checks if the path argument exists relative to this workspace root.
	 * 
	 * @param a workspace relative full path
	 * @return is path in the workspace?
	 */
	private boolean exists(IPath path) {
		IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
		return workspaceRoot.exists(path);
	}

	/**
	 * Ensure the default web setup is correct with one resource map and any number of java 
	 * resource maps to WEB-INF/classes
	 * 
	 * @param resourceMaps
	 * @return boolean
	 */
	private boolean hasDefaultWebResourceMappings(List resourceMaps) {
		int rootValidMaps = 0;
		int javaValidRoots = 0;
		
		// If there aren't at least 2 maps, return false
		if (resourceMaps.size()<2)
			return false;
		
		IPath webInfClasses = new Path(J2EEConstants.WEB_INF_CLASSES).makeAbsolute();
		for (int i=0; i<resourceMaps.size(); i++) {
			ComponentResource resourceMap = (ComponentResource) resourceMaps.get(i);
			IPath sourcePath = getProject().getFullPath().append(resourceMap.getSourcePath());
			
			// Verify if the map is for the content root
			if (resourceMap.getRuntimePath().equals(Path.ROOT)) {
				rootValidMaps++;
			// Verify if the map is for a java src folder and is mapped to "WEB-INF/classes"
			} else if (resourceMap.getRuntimePath().equals(webInfClasses) && isSourceContainer(sourcePath)) {
				javaValidRoots++;
			// Otherwise we bail because we have a non optimized map
			// Except if  the source path is to a nonexistent resource then just ignore the map and keep trying
			} else if (exists(sourcePath)) {
				return false;
			}
		}
		// Make sure only one of the maps is the content root, and that at least one is for the java folder
		return rootValidMaps==1 && javaValidRoots>0;
	}
	
	/**
	 * This method is added for performance reasons. It can ONLY be called when the project is single root.
	 * @see isSingleRootStructure().  If the project has an output folder that is also a source folder then,
	 * it assumes the virtual component is not using any flexible features and is in a standard J2EE format
	 * with one component root folder and an output folder the same as its content folder.  This will bypass 
	 * the virtual component API and just return the module resources as they are on disk.
	 * 
	 * @return array of ModuleResources
	 * @throws CoreException
	 */
	private IModuleResource[] getOptimizedMembers() throws CoreException {
		if (component != null) {
			if (isSingleJavaOutputNonSource) {
				// We determined when testing for a single root structure that this project has
				// one output folder and that output folder is not a source folder. Since the
				// output folder (for example, classes or bin) is not a source folder, JDT copies all files
				// (including non Java files) to this folder, so every resource needed at runtime is located 
				// in that single output directory.
				return getModuleResources(Path.EMPTY, getJavaOutputFolders()[0]);
			}
			// For J2EE modules, we use the contents of the content root
			else {
				IVirtualFolder vFolder = component.getRootFolder();
				return getModuleResources(Path.EMPTY, vFolder.getUnderlyingFolder());
			}
		}
		return new IModuleResource[] {};
	}
	
	/**
	 * This method will return from cache or add to cache whether or not an output container
	 * is mapped in the virtual component.
	 * 
	 * @param outputContainer
	 * @return if output container is mapped
	 */
	private boolean isOutputContainerMapped(IContainer outputContainer) {
		if (outputContainer == null)
			return false;
		
		HashMap outputMaps = getCachedOutputMappings();
		Boolean result = (Boolean) outputMaps.get(outputContainer);
		if (result == null) {
			// If there are any component resources for the container, we know it is mapped
			if (ComponentCore.createResources(outputContainer).length > 0)
				result = Boolean.TRUE;	
			// Otherwise it is not mapped
			else
				result = Boolean.FALSE;
			// Cache the result in the map for this output container
			outputMaps.put(outputContainer, result);
		}
		return result.booleanValue();
	}
	
	/**
	 * Lazy initialize the cached output mappings
	 * @return HashMap
	 */
	private HashMap getCachedOutputMappings() {
		if (cachedOutputMappings==null)
			cachedOutputMappings = new HashMap();
		return cachedOutputMappings;
	}
	
	/**
	 * Lazy initialize the cached source - output pairings
	 * @return HashMap
	 */
	private HashMap getCachedSourceOutputPairs() {
		if (cachedSourceOutputPairs==null)
			cachedSourceOutputPairs = new HashMap();
		return cachedSourceOutputPairs;
	}
	
	/**
	 * This file should be added to the members list from the virtual component maps only if:
	 * a) it is not in a source folder
	 * b) it is in a source folder, and the corresponding output folder is a mapped component resource
	 * 
	 * @return boolean should file be added to members
	 */
	protected boolean shouldAddComponentFile(IFile file) {
		IPackageFragmentRoot sourceContainer = getSourceContainer(file);
		// If the file is not in a source container, return true
		if (sourceContainer==null) {
			return true;
		// Else if it is a source container and the output container is mapped in the component, return true
		// Otherwise, return false.
		} else {
			IContainer outputContainer = getOutputContainer(sourceContainer);
			return outputContainer!=null && isOutputContainerMapped(outputContainer);		
		}
	}
}
