/*******************************************************************************
 * Copyright (c) 2007 BEA Systems, Inc. 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:
 * BEA Systems, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.j2ee.classpathdep;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
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.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jst.common.internal.modulecore.IClasspathDependencyComponent;
import org.eclipse.jst.common.jdt.internal.javalite.IJavaProjectLite;
import org.eclipse.jst.common.jdt.internal.javalite.JavaCoreLite;
import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent;
import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
import org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator;
import org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyVirtualComponent;
import org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator.ClasspathDependencyValidatorData;
import org.eclipse.jst.j2ee.model.ModelProviderManager;
import org.eclipse.jst.j2ee.project.EarUtilities;
import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
import org.eclipse.jst.javaee.application.Application;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.impl.ModuleURIUtil;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;

/**
 * Contains utility code for working manipulating the WTP classpath component
 * dependency attribute.
 */
public class ClasspathDependencyUtil implements IClasspathDependencyConstants {
	
	/**
	 * This is equivalent to calling getRawComponentClasspathDependencies(javaProject, DependencyAttributeType.CLASSPATH_COMPONENT_DEPENDENCY);
	 * 
	 * @deprecated use {@link #getRawComponentClasspathDependencies(IJavaProject, org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants.DependencyAttributeType)}
	 * 
	 * @param javaProject
	 * @return
	 * @throws CoreException
	 */
	@Deprecated
	public static Map <IClasspathEntry, IClasspathAttribute> getRawComponentClasspathDependencies(final IJavaProject javaProject) throws CoreException {
		return getRawComponentClasspathDependencies(javaProject, DependencyAttributeType.CLASSPATH_COMPONENT_DEPENDENCY);
	}
	
	/**
	 * @deprecated use {@link #getRawComponentClasspathDependencies(IJavaProjectLite, org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants.DependencyAttributeType)}
	 * @param javaProject
	 * @param attributeType
	 * @return
	 * @throws CoreException
	 */
	@Deprecated
	public static Map <IClasspathEntry, IClasspathAttribute> getRawComponentClasspathDependencies(final IJavaProject javaProject, DependencyAttributeType attributeType) throws CoreException {
		return getRawComponentClasspathDependencies(JavaCoreLite.create(javaProject), attributeType);
	}
	/**
	 * Returns all unresolved classpath entries for the specified Java project that
	 * have the special WTP classpath component dependency attribute.
	 *  
	 * @param javaProjectLite Java project whose component classpath dependencies are being retrieved.
	 * @parem attributeType the attribute to search for
	 * @return Map from IClasspathEntry to IClasspathAttribute for classpath component dependency.
	 * @return IClasspathEntries with the special component dependency attribute.
	 * @throws CoreException Thrown if an error is encountered accessing the unresolved classpath.
	 */
	public static Map <IClasspathEntry, IClasspathAttribute> getRawComponentClasspathDependencies(final IJavaProjectLite javaProjectLite, DependencyAttributeType attributeType) throws CoreException {
		return getRawComponentClasspathDependencies(javaProjectLite, attributeType, false);
	}
	public static Map <IClasspathEntry, IClasspathAttribute> getRawComponentClasspathDependencies(final IJavaProjectLite javaProjectLite, DependencyAttributeType attributeType, final boolean isLegacyJ2EE) throws CoreException {
		if (javaProjectLite == null) {
			return Collections.emptyMap();
		}
		final Map<IClasspathEntry, IClasspathAttribute> referencedRawEntries = new HashMap<IClasspathEntry, IClasspathAttribute>();
		final IClasspathEntry[] entries = javaProjectLite.readRawClasspath();
        for (IClasspathEntry entry : entries) {
            final IClasspathAttribute attrib = checkForComponentDependencyAttribute(entry, attributeType, isLegacyJ2EE);
            if (attrib != null) {
            	referencedRawEntries.put(entry, attrib);
            }
        }
        return referencedRawEntries;
	}
	
	/**
	 * @deprecated use {@link #getPotentialComponentClasspathDependencies(IJavaProjectLite)}
	 * @param javaProject
	 * @return
	 * @throws CoreException
	 */
	@Deprecated
	public static List <IClasspathEntry> getPotentialComponentClasspathDependencies(final IJavaProject javaProject) throws CoreException {
		return getPotentialComponentClasspathDependencies(JavaCoreLite.create(javaProject));
	}
	
	/**
	 * Retrieves the unresolved classpath entries for the specified Java project that
	 * could potentially be mapped into the virtual component tree for the project via
	 * the special WTP classpath component dependence attribute. Classpath entries that
	 * currently have the attribute are not returned by this method (@see {@link #getRawComponentClasspathDependencies(IJavaProject, boolean)})
	 * 
	 * @param javaProjectLite Java project whose potential component classpath dependencies will be retrieved.
	 * @return List of raw IClasspathEntries for potential classpath component dependencies.
	 * @throws CoreException Thrown if an error is encountered. 
	 */
	public static List <IClasspathEntry> getPotentialComponentClasspathDependencies(final IJavaProjectLite javaProjectLite) throws CoreException {
		return getPotentialComponentClasspathDependencies(javaProjectLite, false);
	}		
	public static List <IClasspathEntry> getPotentialComponentClasspathDependencies(final IJavaProjectLite javaProjectLite, final boolean isLegacyJ2EE) throws CoreException {

		final List <IClasspathEntry> potentialRawEntries = new ArrayList<IClasspathEntry>();

		if (javaProjectLite == null || !javaProjectLite.getProject().isAccessible()) {
			return Collections.emptyList();
		}
		final IProject project = javaProjectLite.getProject();
		final boolean isWebApp = JavaEEProjectUtilities.isDynamicWebProject(project);
		final boolean isRAR = JavaEEProjectUtilities.isJCAProject(project);
		final ClasspathDependencyValidatorData data = new ClasspathDependencyValidatorData(project);
		final IClasspathEntry[] entries = javaProjectLite.readRawClasspath();
        for (int i = 0; i < entries.length; i++) {
            final IClasspathEntry entry = entries[i];
            final IClasspathAttribute attrib = checkForComponentDependencyAttribute(entry, DependencyAttributeType.DEPENDENCY_OR_NONDEPENDENCY, isLegacyJ2EE);
            if (attrib != null) {
            	continue; // already has the attribute
            }
        	// check validation logic for entry
        	// always mark the "isWebApp" param as true so that we get both exported and non-exported entries; for non-web projects,
        	// want to let a user have the option to see and select the non-exported entries and then just generate a validation
        	// error if they happen to select one.
        	final IMessage[] msgs = ClasspathDependencyValidator.validateVirtualComponentEntry(entry, null, true, project, data);
        	boolean error = false;
        	for (int j = 0; j < msgs.length; j++) {
        		if (msgs[j].getSeverity() == IMessage.HIGH_SEVERITY) {
        			error = true;
        			break;
        		}
        	}
        	if (error) {
        		continue;
        	}
        	if (IClasspathEntry.CPE_LIBRARY == entry.getEntryKind()) {
				final boolean isFile = !ClasspathDependencyUtil.isClassFolderEntry(entry);
				if (isFile) {
					boolean foundEntry = false;
					IVirtualComponent component = ComponentCore.createComponent(project);
					if (isWebApp) { // checks for web libs
						IContainer[] webLibFolders = component.getRootFolder().getFolder(WEB_INF_LIB_PATH).getUnderlyingFolders();
						for (IContainer webLib : webLibFolders) {
							IPath webLibFolderPath = webLib.getFullPath();
							if (webLibFolderPath.equals(entry.getPath().removeLastSegments(1))) {
								foundEntry = true;
								break;
							}
						}
					} else if(isRAR){
						IContainer [] rootFolders = component.getRootFolder().getUnderlyingFolders();
						for(IContainer root: rootFolders){
							IPath rootPath = root.getFullPath();
							if(rootPath.isPrefixOf(entry.getPath())){
								foundEntry = true;
								break;
							}
						}
					}
					if (foundEntry) {
						continue;
					}
					// checks for manifest references
					List manifestRefs = J2EEModuleVirtualComponent.getManifestReferences(component, null);
					if(manifestRefs != null){
						for (int j = 0; j < manifestRefs.size(); j++) {
							IVirtualReference ref = (IVirtualReference) manifestRefs.get(j);
							IVirtualComponent c = ref.getReferencedComponent();
							if (c.isBinary()) {
								IFile file = (IFile)c.getAdapter(IFile.class);
								if (file != null && file.getFullPath().equals(entry.getPath())) {
										foundEntry = true;
										break;
								}
							}
						}
						if (foundEntry) {
							continue;
						}
					}
					// checks for ear library-directory entries
					IProject[] earProjects = EarUtilities.getReferencingEARProjects(project);
					for (IProject earProject : earProjects) {
						String earDDVersion = EarUtilities.getJ2EEDDProjectVersion(earProject);
						if(!earDDVersion.equals(J2EEVersionConstants.VERSION_1_2_TEXT) && !earDDVersion.equals(J2EEVersionConstants.VERSION_1_3_TEXT) && !earDDVersion.equals(J2EEVersionConstants.VERSION_1_4_TEXT)) {
							IVirtualComponent earComponent = ComponentCore.createComponent(earProject);
							Application app = (Application) ModelProviderManager.getModelProvider(earComponent).getModelObject();
							String libDir = app.getLibraryDirectory();
							if (libDir == null) {
								// lib is the default if no library-directory is set
								libDir = "lib"; //$NON-NLS-1$
							}
							IContainer[] earLibFolders = earComponent.getRootFolder().getFolder(new Path(libDir)).getUnderlyingFolders();
							for (IContainer earLib : earLibFolders) {
								IPath earLibFolderPath = earLib.getFullPath();
								if (earLibFolderPath.equals(entry.getPath().removeLastSegments(1))) {
									foundEntry = true;
									break;
								}
							}
							if (foundEntry) {
								break;
							}
						}
					}
					if (foundEntry) {
						continue;
					}
				}
			}
        	
        	// entry can potentially be tagged as a component dependency
        	potentialRawEntries.add(entry);
        }
        return potentialRawEntries;
	}
	
	private static boolean isValid(final IClasspathEntry entry, final IClasspathAttribute attrib, final boolean isWebApp, final IProject project, final ClasspathDependencyValidatorData data) {
		final IMessage[] msgs = ClasspathDependencyValidator.validateVirtualComponentEntry(entry, attrib, isWebApp, project, data);
		boolean valid = true;
		for (int j = 0; j < msgs.length; j++) {
			if (msgs[j].getSeverity() == IMessage.HIGH_SEVERITY) {
				valid = false;
				break;
			}
		}
		return valid;
	}
	
	/**
	 * Returns all resolved classpath entries for the specified Java project that
	 * have one of the special WTP classpath component dependency attributes and pass the set of rules
	 * that govern valid classpath dependencies.
	 *  
	 * @param javaProject Java project whose component classpath dependencies are being retrieved.
	 * @param isWebApp True if the target project is associated with a web project.
	 * @return Map from IClasspathEntry to IClasspathAttribute for classpath component dependencies.
	 * @throws CoreException Thrown if an error is encountered accessing the unresolved classpath.
	 */
	public static Map <IClasspathEntry, IClasspathAttribute> getComponentClasspathDependencies(final IJavaProjectLite javaProjectLite, final boolean isLegacyJ2EE) throws CoreException {
		return getComponentClasspathDependencies(javaProjectLite, isLegacyJ2EE, true);
	}

	/**
	 * @deprecated use {@link #getComponentClasspathDependencies(IJavaProjectLite, boolean)}
	 * @param javaProject
	 * @param isWebApp
	 * @return
	 * @throws CoreException
	 */
	@Deprecated
	public static Map <IClasspathEntry, IClasspathAttribute> getComponentClasspathDependencies(final IJavaProject javaProject, final boolean isLegacyJ2EE) throws CoreException {
		return getComponentClasspathDependencies(JavaCoreLite.create(javaProject), isLegacyJ2EE);
	}

	/**
	 * @deprecated use {@link #getComponentClasspathDependencies(IJavaProjectLite, boolean, boolean)}
	 * @param javaProject
	 * @param isWebApp
	 * @param onlyValid
	 * @return
	 * @throws CoreException
	 */
	@Deprecated
	public static Map  <IClasspathEntry, IClasspathAttribute> getComponentClasspathDependencies(final IJavaProject javaProject, final boolean isWebApp, final boolean onlyValid) throws CoreException {
		return getComponentClasspathDependencies(JavaCoreLite.create(javaProject), isWebApp, onlyValid);
	}

	/**
	 * Returns all resolved classpath entries for the specified Java project that
	 * have one of the special WTP classpath component dependency attributes.
	 *  
	 * @param javaProject Java project whose component classpath dependencies are being retrieved.
	 * @param isWebApp True if the target project is associated with a web project.
	 * @param onlyValid If true, only valid dependencies will be returned. If false, the raw entry must be valid but the
	 * resolved can be invalid. 
	 * @return Map from IClasspathEntry to IClasspathAttribute for classpath component dependencies.
	 * @throws CoreException Thrown if an error is encountered accessing the unresolved classpath.
	 */
	public static Map <IClasspathEntry, IClasspathAttribute> getComponentClasspathDependencies(final IJavaProjectLite javaProjectLite, final boolean isLegacyJ2EE, final boolean onlyValid) throws CoreException {
		final ClasspathDependencyValidatorData data = new ClasspathDependencyValidatorData(javaProjectLite.getProject());
		final boolean isWebApp = JavaEEProjectUtilities.isDynamicWebProject(javaProjectLite.getProject());
		// get the raw entries
		final Map<IClasspathEntry, IClasspathAttribute> referencedRawEntries = getRawComponentClasspathDependencies(javaProjectLite, DependencyAttributeType.CLASSPATH_COMPONENT_DEPENDENCY, isLegacyJ2EE);
		final Map<IClasspathEntry, IClasspathAttribute> validRawEntries = new HashMap<IClasspathEntry, IClasspathAttribute>();
		final Map <IClasspathEntry, IClasspathAttribute> validRawClassPathContainerEntries = new HashMap <IClasspathEntry, IClasspathAttribute>();

		// filter out non-valid referenced raw entries
		final Iterator<IClasspathEntry> i = referencedRawEntries.keySet().iterator();
		while (i.hasNext()) {
			final IClasspathEntry entry = i.next();
			final IClasspathAttribute attrib = referencedRawEntries.get(entry);
			if (isValid(entry, attrib, isWebApp, javaProjectLite.getProject(), data)) {
				if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER)
				{
					//Put in a separate map the classpath container entries, since they will be handled differently
					validRawClassPathContainerEntries.put(entry, attrib);
				}
				else {
					validRawEntries.put(entry, attrib);
				}
			}
		}

		// if we have no valid raw entries, return empty map
		if (validRawEntries.isEmpty() && validRawClassPathContainerEntries.isEmpty()) {
        	return Collections.emptyMap();
		}

		// XXX Would like to replace the code below with use of a public JDT API that returns
		// the raw IClasspathEntry for a given resolved IClasspathEntry (see see https://bugs.eclipse.org/bugs/show_bug.cgi?id=183995)
		// The code must currently leverage IPackageFragmentRoot to determine this
		// mapping and, because IPackageFragmentRoots do not maintain IClasspathEntry data, a prior
		// call is needed to getResolvedClasspath() and the resolved IClasspathEntries have to be stored in a Map from IPath-to-IClasspathEntry to
		// support retrieval using the resolved IPackageFragmentRoot
		
		// retrieve the resolved classpath
		//TODO this call to javaProject needs to be removed.  Need to figure out what exactly this is attempting to do.
		IJavaProject javaProject = JavaCore.create(javaProjectLite.getProject());
		//TODO this call to javaProject needs to be removed.  Need to figure out what exactly this is attempting to do.
		final IClasspathEntry[] entries = javaProject.getResolvedClasspath(true);
		final Map <IPath, IClasspathEntry> pathToResolvedEntry = new HashMap<IPath, IClasspathEntry>();
		
		// store in a map from path to entry
		for (int j = 0; j < entries.length; j++) {
			pathToResolvedEntry.put(entries[j].getPath(), entries[j]);
		}

		//Gather all resolved entries from the package roots and the classpath containers
		final Map <IClasspathEntry, IClasspathAttribute> resolvedEntries = new LinkedHashMap <IClasspathEntry, IClasspathAttribute>();

		
		// grab all IPackageFragmentRoots
		
		// TODO this ignores project cp entries; can easily add in the raw project cp entries, however, do not have a good way to 
		// map project cp entries resolved from cp containers back to the corresponding raw entry (and thereby determine if the
		// entry has the publish/export attribute)
		//TODO this call to javaProject needs to be removed.  Need to figure out what exactly this is attempting to do.
		final IPackageFragmentRoot[] roots = javaProject.getPackageFragmentRoots();
		
		for (IPackageFragmentRoot root : roots) {
			final IClasspathEntry rawEntry = root.getRawClasspathEntry();
			
			// is the raw entry valid?
			IClasspathAttribute attrib = validRawEntries.get(rawEntry);
			if (attrib == null) {
				continue;
			}
			
			final IPath pkgFragPath = root.getPath();
			final IClasspathEntry resolvedEntry = pathToResolvedEntry.get(pkgFragPath);
			resolvedEntries.put(resolvedEntry, attrib);
		}
		
		// Add entries coming from classpath containers to the list of resolved entries
		for (Map.Entry <IClasspathEntry, IClasspathAttribute> entry : validRawClassPathContainerEntries.entrySet()) {
			IClasspathContainer classpathContainer = JavaCore.getClasspathContainer(entry.getKey().getPath(), javaProject);
			if(classpathContainer != null)
			{
				IClasspathEntry[] classpathContainerEntries = classpathContainer.getClasspathEntries();
				if(classpathContainerEntries != null) {
					for (int j = 0; j < classpathContainerEntries.length; j++) {
						resolvedEntries.put(classpathContainerEntries[j], entry.getValue());
					}
				}
			}
		}

		//Setup the final result
		final Map <IClasspathEntry, IClasspathAttribute> referencedEntries = new LinkedHashMap <IClasspathEntry, IClasspathAttribute>();
		for (Map.Entry <IClasspathEntry, IClasspathAttribute> mapEntry : resolvedEntries.entrySet()) {
			final IClasspathEntry resolvedEntry = mapEntry.getKey();
			IClasspathAttribute attrib = mapEntry.getValue();
			
			final IClasspathAttribute resolvedAttrib = checkForComponentDependencyAttribute(resolvedEntry, DependencyAttributeType.DEPENDENCY_OR_NONDEPENDENCY, isLegacyJ2EE);
			// attribute for the resolved entry must either be unspecified or it must be the
			// dependency attribute for it to be included
			if (resolvedAttrib == null || resolvedAttrib.getName().equals(CLASSPATH_COMPONENT_DEPENDENCY)) {
				// filter out resolved entry if it doesn't pass the validation rules
				if (!onlyValid || isValid(resolvedEntry, resolvedAttrib != null?resolvedAttrib:attrib,isWebApp, javaProjectLite.getProject(), data)) {
					if (resolvedAttrib != null) {
						// if there is an attribute on the sub-entry, use that
						attrib = resolvedAttrib;
					}
					referencedEntries.put(resolvedEntry, attrib);
				}
			} 
		}
		
        return referencedEntries;
	}
	
	/**
	 * Retrieves the location (as a absolute file system path) for the specified classpath entry.
	 * @param entry Classpath entry. If null, returns null.
	 * @return Absolute file system path.
	 */
	public static IPath getEntryLocation(final IClasspathEntry entry) {

		if (entry == null) {
			return null;
		}
		final IPath entryPath = entry.getPath();
		IPath entryLocation = entryPath;
		final IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(entryPath);		
		if (resource != null) {
			entryLocation = resource.getLocation();
		}
		return entryLocation;
	}
	
	/**
	 * Retrieves the IResource corresponding to the specified classpath entry or null if it does not represent a Workspace resource.
	 * @param entry Classpath entry. If null, returns null.
	 * @return IResource or null.
	 */
	public static IResource getEntryResource(final IClasspathEntry entry) {
		if (entry == null) {
			return null;
		}
		final IPath entryPath = entry.getPath();
		return ResourcesPlugin.getWorkspace().getRoot().findMember(entryPath);
	}
	
	/**
	 * Checks if the specified IVirtualReference represents an project cp entry. If so, returns the underlying IProject, otherwise,
	 * returns null.
	 * @param ref The IVirtualReference
	 * @return IProject referenced by the project cp entry or null if the specified reference is null or does not refer to 
	 * a VirtualArchiveComponent with type VirtualArchiveComponent.CLASSPATHARCHIVETYPE that represents a project cp entry.
	 */
	public static IProject isClasspathProjectReference(final IVirtualReference ref) {
		if (ref != null && ref.getReferencedComponent() instanceof IClasspathDependencyComponent)
			return ref.getReferencedComponent().getProject();
		return null;
	}
	
	/**
	 * Checks if the specified classpath entry represents a class folder.
	 * @param entry The entry to check.
	 * @return True if it is a library entry that points to a class folder. False otherwise.
	 */
	public static boolean isClassFolderEntry(final IClasspathEntry entry) {
		if (entry == null || entry.getEntryKind() != IClasspathEntry.CPE_LIBRARY) {
			return false;
		}
		// does the path refer to a file or a folder?
		final IPath entryPath = entry.getPath();
		IPath entryLocation = entryPath;
		final IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(entryPath);
		if (resource != null) {
			entryLocation = resource.getLocation();
		}
		boolean isFile = true; // by default, assume a jar file
		if (entryLocation.toFile().isDirectory()) {
			isFile = false;
		}
		return !isFile;
	}

	/**
	 * Retrieves the location (as an absolute local file system path) for the classpath dependency represented
	 * by the specified IVirtualReference. Will return null for a project cp entry.
	 * @param ref The IVirtualReference
	 * @return Absolute path in the local file system or null if the specified reference is null or does not refer to 
	 * a VirtualArchiveComponent with type VirtualArchiveComponent.CLASSPATHARCHIVETYPE.
	 */
	public static IPath getClasspathVirtualReferenceLocation(final IVirtualReference ref) {
		if (ref != null && ref.getReferencedComponent() instanceof IClasspathDependencyComponent) {
			return (IPath)ref.getReferencedComponent().getAdapter(IPath.class);
		}
		return null;
	}
	
	/**
	 * Retrieves the runtime path to which the resolved classpath entry components will be
	 * added within the deployed application.
	 * @param attrib The IClasspathAttribute with the WTP classpath component dependency value. If null,
	 * will return the default path.
	 * @param isWebApp True for web projects, false otherwise.
	 * @param isClassFolder True if the default value should be computed for a class folder. Ignored if calculating for
	 * a valid IClasspathAttribute.
	 * @return Runtime path. Will be null if the attribute is not a WTP classpath component dependency 
	 * attribute.
	 */
	public static IPath getRuntimePath(final IClasspathAttribute attrib, final boolean isWebApp, final boolean isClassFolder) {
    	if (attrib != null && !attrib.getName().equals(CLASSPATH_COMPONENT_DEPENDENCY)) {
    		return null;
    	}
    	if (attrib == null || attrib.getValue()== null || attrib.getValue().length() == 0) {
    		return getDefaultRuntimePath(isWebApp, isClassFolder);
    	}
    	return new Path(attrib.getValue());
	}

	/**
	 * Checks if the specified IVirtualReference represents a class folder that has been marked for publish/export.
	 * @param ref IVirtualReference to test.
	 * @return True if this is a publish/export class folder.
	 */
	public static boolean isClassFolderReference(final IVirtualReference ref) {
		final IVirtualComponent comp = ref.getReferencedComponent();
		// must refer to a ClasspathDependencyVirtualComponent
		if (comp instanceof ClasspathDependencyVirtualComponent) {
			final ClasspathDependencyVirtualComponent cpComp= (ClasspathDependencyVirtualComponent) comp;
			return cpComp.isClassFolder();
		}
		return false;
	}
	
	/**
	 * Returns the container for the specified VirtualArchiveComponent or null if this reference does not match to a container.
	 * @param comp IVirtualComponent.
	 * @return IContainer for the class folder or null if this reference does not match a container.
	 */
	public static IContainer getClassFolder(final IVirtualComponent comp) {
		if (comp instanceof ClasspathDependencyVirtualComponent) {
			final ClasspathDependencyVirtualComponent cpComp= (ClasspathDependencyVirtualComponent) comp;
			return cpComp.getClassFolder();
		}
		return null;
	}
	
	/**
	 * Retrieves the default runtime path to which the resolved classpath entry components will be
	 * added within the deployed application. This method is only valid for non-class folder entries.
	 * @param isWebApp True if the default runtime path for web apps should be returned, false otherwise.
	 * @return The default runtime path. 
	 */
	public static IPath getDefaultRuntimePath(final boolean isWebApp) {
		return getDefaultRuntimePath(isWebApp, false);
	}
	
	/**
	 * Retrieves the default runtime path to which the resolved classpath entry components will be
	 * added within the deployed application.
	 * @param isWebApp True if the default runtime path for web apps should be returned, false otherwise.
	 * @param isClassFolder True if the path is a class folder.
	 * @return The default runtime path. 
	 */
	public static IPath getDefaultRuntimePath(final boolean isWebApp, final boolean isClassFolder) {
		if (isWebApp) {
			return isClassFolder ? WEB_INF_CLASSES_PATH : WEB_INF_LIB_PATH;			
		}
		return isClassFolder ? RUNTIME_MAPPING_INTO_COMPONENT_PATH : RUNTIME_MAPPING_INTO_CONTAINER_PATH;
	}
	
	public static IPath getDefaultRuntimePath(final IVirtualComponent virtualComponent, IClasspathEntry entry){
		boolean isClassFolderEntry = isClassFolderEntry(entry);
		if(virtualComponent == null){
			//null, use default
			return getDefaultRuntimePath(false, isClassFolderEntry);
		}
		boolean isWebApp = JavaEEProjectUtilities.isDynamicWebComponent(virtualComponent);
		if(isWebApp || isClassFolderEntry){
			return getDefaultRuntimePath(isWebApp, isClassFolderEntry);
		}

		//not a WAR
		//if part of EE5 or greature ear, map into the EAR's lib folder
		IProject [] earProjects = EarUtilities.getReferencingEARProjects(virtualComponent.getProject());
		if (earProjects.length > 0) {
			IVirtualComponent earComponent = ComponentCore.createComponent(earProjects[0]);
			if (earComponent != null) {
				return calculateDefaultRuntimePath(earComponent, virtualComponent);
			}
		}
		return getDefaultRuntimePath(false, false);
		
	}
	
	public static IPath calculateDefaultRuntimePath(IVirtualComponent parentComponent, IVirtualComponent targetComponent) {
		IVirtualReference targetRef = parentComponent.getReference(targetComponent.getName());
		String libDir = EarUtilities.getEARLibDir(parentComponent);
		if (libDir != null && libDir.length() > 0) {
			IPath libDirPath = new Path(libDir);

			// If project is at root level, go up a level and add lib dir path absolute path
			if(targetRef == null || targetRef.getRuntimePath().equals("/")) //$NON-NLS-1$
				return new Path(RUNTIME_MAPPING_INTO_CONTAINER).append(libDirPath.makeAbsolute());
			IPath childProjectRuntimePath = targetRef.getRuntimePath();

			String[] childProjectFolders = childProjectRuntimePath.segments();
			String[] libFolders = libDirPath.segments();
			int commonFolderCount = 0;
			for(int i = 0; i < childProjectFolders.length; i++) {
				if(i >= libFolders.length || !childProjectFolders[i].equals(libFolders[i]))
					break;
				commonFolderCount++;
			}
			String resultString = RUNTIME_MAPPING_INTO_CONTAINER;
			for(int i = 0; i < childProjectFolders.length - commonFolderCount; i++) {
				resultString += RUNTIME_MAPPING_INTO_CONTAINER;
			}
			return new Path(resultString).append(libDirPath.removeFirstSegments(commonFolderCount));
		}
		return getDefaultRuntimePath(false, false);
	}
	
	/**
	 * Retrieves the archive name for the specified classpath entry
	 * @param entry The entry.
	 * @return The archive name.
	 */
	public static String getArchiveName(final IClasspathEntry entry) {
		if (entry == null) {
			return null;
		}
		final boolean isClassFolder = isClassFolderEntry(entry);
		if (isClassFolder) {
			IResource resource = getEntryResource(entry);
			if (resource == null) {
				return getEntryLocation(entry).lastSegment();
			}
			return resource.getFullPath().toString();
		}
		final IPath entryLocation = getEntryLocation(entry);
		return entryLocation.lastSegment();
	}
	

	
	/**
	 * Checks if the specified IClasspathEntry has either of the special WTP component dependency
	 * attributes that indicate it should be mapped into the virtual component for the associated project.
	 * 
	 * @param entry The IClasspathEntry.
	 * @return The IClasspathAttribute that holds the special WTP attribute or null if one was not found.
	 */
	public static IClasspathAttribute checkForComponentDependencyAttribute(final IClasspathEntry entry) {
		return checkForComponentDependencyAttribute(entry, DependencyAttributeType.DEPENDENCY_OR_NONDEPENDENCY);
	}
	
	/**
	 * Checks if the specified IClasspathEntry has one of the special WTP component dependency
	 * attributes that indicate it should be mapped into the virtual component for the associated project.
	 * 
	 * @param entry The IClasspathEntry.
	 * @param componentDependency Controls which type of dependency attribute should be checked for (or whether both should be checked).
	 * @return The IClasspathAttribute that holds the special WTP attribute or null if one was not found.
	 */
	public static IClasspathAttribute checkForComponentDependencyAttribute(final IClasspathEntry entry, final DependencyAttributeType attributeType) {
		return checkForComponentDependencyAttribute(entry, attributeType, false);
	}
	public static IClasspathAttribute checkForComponentDependencyAttribute(final IClasspathEntry entry, final DependencyAttributeType attributeType, final boolean isLegacyJ2EE) {
		if (entry == null)
			return null;
		
		
	    final IClasspathAttribute[] attributes = entry.getExtraAttributes();
	    for (int i = 0; i < attributes.length; i++) {
	    	final IClasspathAttribute attribute = attributes[i];
	    	final String name = attribute.getName();
	    	if (name.equals(CLASSPATH_COMPONENT_DEPENDENCY)) {
	    		if (attributeType == DependencyAttributeType.DEPENDENCY_OR_NONDEPENDENCY
	    				|| attributeType == DependencyAttributeType.CLASSPATH_COMPONENT_DEPENDENCY) {
	    			return attribute;
	    		}
	    	} else if (name.equals(CLASSPATH_COMPONENT_NON_DEPENDENCY)) {
	    		if (attributeType == DependencyAttributeType.DEPENDENCY_OR_NONDEPENDENCY
	    				|| attributeType == DependencyAttributeType.CLASSPATH_COMPONENT_NONDEPENDENCY) {
	    			return attribute;
	    		}
	    	}
	    }
	    return null;
	}
	
	/**
	 * Determines if the specified virtual component represents a classpath component dependency.
	 * @param component Virtual component to test
	 * @return True if a classpath component dependency, false otherwise.
	 */
	public static boolean isClasspathComponentDependency(final IVirtualComponent component) {
		return component != null && component instanceof IClasspathDependencyComponent;
	}
	
	/**
	 * Retrieves the classpath component display string for the specified component.
	 * @param component Component that represents a classpath component.
	 * @return Display string.
	 */
	public static String getClasspathComponentDependencyDisplayString(final IVirtualComponent component) {
		final URI archiveURI = URI.createURI(ModuleURIUtil.getHandleString(component));
		return archiveURI.lastSegment();
	}
	
	public static boolean isMappedIntoContainer(String path) {
		if (path.startsWith(IClasspathDependencyConstants.RUNTIME_MAPPING_INTO_CONTAINER))
			return true;
		
		return false;
	}
	
	public static IClasspathEntry modifyDependencyPath(IClasspathEntry entry, IPath dependencyPath){
		IClasspathEntry newEntry = null;
		IClasspathAttribute [] newAttributes = modifyDependencyPath(entry.getExtraAttributes(), dependencyPath);
		
		switch(entry.getEntryKind()) {
		case IClasspathEntry.CPE_CONTAINER:
			newEntry = JavaCore.newContainerEntry(entry.getPath(), entry.getAccessRules(), newAttributes, entry.isExported());
			break;
		case IClasspathEntry.CPE_LIBRARY:
			newEntry = JavaCore.newLibraryEntry(entry.getPath(), entry.getSourceAttachmentPath(), entry.getSourceAttachmentRootPath(), entry.getAccessRules(), newAttributes, entry.isExported());
			break;
		case IClasspathEntry.CPE_VARIABLE:
			newEntry = JavaCore.newVariableEntry(entry.getPath(), entry.getSourceAttachmentPath(), entry.getSourceAttachmentRootPath(), entry.getAccessRules(), newAttributes, entry.isExported());
			break;					
		case IClasspathEntry.CPE_PROJECT:
			newEntry = JavaCore.newProjectEntry(entry.getPath(), entry.getAccessRules(), entry.combineAccessRules(), newAttributes, entry.isExported());
			break;										
		case IClasspathEntry.CPE_SOURCE:
			newEntry = JavaCore.newSourceEntry(entry.getPath(), entry.getInclusionPatterns(), entry.getExclusionPatterns(), entry.getOutputLocation(), newAttributes);
			break;															
		}
		return newEntry;
	}
	
	public static IPath getRuntimePath(final IClasspathEntry entry){
		IClasspathAttribute [] attributes = entry.getExtraAttributes();
		for(IClasspathAttribute attribute : attributes){
			if(attribute.getName().equals(CLASSPATH_COMPONENT_DEPENDENCY)){
				return new Path(attribute.getValue());
			}
		}
		return null;
	}
	
	private static IClasspathAttribute[] modifyDependencyPath(final IClasspathAttribute[] currentAttributes, IPath runtimePath) {
		final List <IClasspathAttribute> updatedAttributes = new ArrayList<IClasspathAttribute> ();
		boolean modified = false;
		for(IClasspathAttribute currentAttribute : currentAttributes){
			if(currentAttribute.getName().equals(CLASSPATH_COMPONENT_DEPENDENCY)){
				modified = true;
				if(runtimePath == null){
					continue;
				}
				try {
					IClasspathAttribute newAttribute = UpdateClasspathAttributeUtil.createDependencyAttribute(runtimePath);
					updatedAttributes.add(newAttribute);
				} catch (CoreException e) {
					org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin.logError(e);
				}
			} else {
				updatedAttributes.add(currentAttribute);
			}
		}
		if(!modified){
			try {
				IClasspathAttribute newAttribute = UpdateClasspathAttributeUtil.createDependencyAttribute(runtimePath);
				updatedAttributes.add(newAttribute);
			} catch (CoreException e) {
				org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin.logError(e);
			}
		}
		return updatedAttributes.toArray(new IClasspathAttribute[updatedAttributes.size()]);
	}
	
}
