/*******************************************************************************
 * 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.HashMap;
import java.util.Map;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jst.j2ee.internal.classpathdep.UpdateClasspathAttributesDataModelProperties;
import org.eclipse.jst.j2ee.internal.classpathdep.UpdateClasspathAttributesDataModelProvider;
import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.frameworks.datamodel.IDataModelOperation;

/**
 * Contains utility code for executing the UpdateClasspathAttributeOperation.
 * @since 3.0
 */
public class UpdateClasspathAttributeUtil implements IClasspathDependencyConstants {

	/**
	 * Creates an IClasspathAttribute with the special WTP "org.eclipse.jst.component.dependency" name whose runtime path
	 * (represented by the value) is unspecified and will therefore take the default value for the project in which it is
	 * added. 
	 * @return The created IClasspathAttribute.
	 * @throws CoreException Thrown if a problem is encountered.
	 */
	public static IClasspathAttribute createDependencyAttribute() throws CoreException {
		return createDependencyAttribute(""); //$NON-NLS-1$
	}
	
	/**
	 * Creates an IClasspathAttribute with the special WTP "org.eclipse.jst.component.dependency" name whose runtime path
	 * (represented by the value) is set to the default for either a web project (/WEB-INF/lib) or non-web project (../).
	 * @param isWebApp True if this attribute is being created for a classpath entry on a dynamic web project.
	 * @param isClassFolder True if this attribute is being created for a class folder.
	 * @return The created IClasspathAttribute.
	 * @throws CoreException Thrown if a problem is encountered.
	 */
	public static IClasspathAttribute createDependencyAttribute(final boolean isWebApp, final boolean isClassFolder) throws CoreException {
		return createDependencyAttribute(ClasspathDependencyUtil.getDefaultRuntimePath(isWebApp, isClassFolder));
	}

	/**
	 * Creates an IClasspathAttribute with the special WTP "org.eclipse.jst.component.dependency" name whose runtime path
	 * (represented by the value) is set to the default for either a web project (/WEB-INF/lib) or non-web project (../).
	 * @param isWebApp True if this attribute is being created for a classpath entry on a dynamic web project.
	 * @return The created IClasspathAttribute.
	 * @throws CoreException Thrown if a problem is encountered.
	 */
	public static IClasspathAttribute createDependencyAttribute(final boolean isWebApp) throws CoreException {
		return createDependencyAttribute(ClasspathDependencyUtil.getDefaultRuntimePath(isWebApp));
	}

	/**
	 * Creates an IClasspathAttribute with the special WTP "org.eclipse.jst.component.dependency" name with the
	 * specified runtime path (will be used to set the attribute value).
	 * @param runtimePath The runtime path in the deployed/exported module where resolved classpath components should
	 * be added. Must be non-null.
	 * @return The created IClasspathAttribute.
	 * @throws CoreException Thrown if a problem is encountered.
	 */
	public static IClasspathAttribute createDependencyAttribute(final IPath runtimePath) throws CoreException {
		return createDependencyAttribute(runtimePath.toString());
	}
	
	private static IClasspathAttribute createDependencyAttribute(final String runtimePath) throws CoreException {
		return JavaCore.newClasspathAttribute(IClasspathDependencyConstants.CLASSPATH_COMPONENT_DEPENDENCY, runtimePath);
	}
	
	/**
	 * Creates an IClasspathAttribute with the special WTP "org.eclipse.jst.component.nondependency" name. This attribute is
	 * used on the resolved entries of classpath containers to prevent them from being exported/published.
	 * @return The created IClasspathAttribute.
	 * @throws CoreException Thrown if a problem is encountered.
	 */
	public static IClasspathAttribute createNonDependencyAttribute() throws CoreException {
		return JavaCore.newClasspathAttribute(IClasspathDependencyConstants.CLASSPATH_COMPONENT_NON_DEPENDENCY, ""); //$NON-NLS-1$
	}
	
	/**
	 * Updates the specified Java project so that only the specified classpath entries have
	 * the WTP component dependency attribute.
	 * @param projectName Name of the target Java project.
	 * @param entryToRuntimePath Map from IClasspathEntry to runtime path for all entries that should 
	 * have the component dependency attribute.
	 * @return Status from the operation.
	 * @throws ExecutionException Thrown if an error is encountered.
	 */	
	public static IStatus updateDependencyAttributes(final IProgressMonitor monitor, final String projectName, final Map entryToRuntimePath) 
		throws ExecutionException {
		return createUpdateDependencyAttributesOperation(projectName, entryToRuntimePath).execute(monitor, null);
	}
	
	/**
	 * Creates the IDataModelOperation that will update the classpath for the specified Java project so that
	 * only the specified list of classpath entries will have WTP component dependency attribute. 
	 * @param projectName Name of the target Java project.
	 * @param entryToRuntimePath Map from IClasspathEntry to runtime path for all entries that should 
	 * have the component dependency attribute.
	 * @return The operation.
	 */
	public static IDataModelOperation createUpdateDependencyAttributesOperation(final String projectName, final Map entryToRuntimePath) {
		return createOperation(projectName, entryToRuntimePath, UpdateClasspathAttributesDataModelProperties.ENTRIES_WITH_ATTRIBUTE, true);
	}
	
	/**
	 * Creates the IDataModelOperation that will update the classpath for the specified Java project so that
	 * the WTP component dependency attribute will be added to the specified list of classpath entries. 
	 * @param projectName Name of the target Java project.
	 * @param entryToRuntimePath Map from IClasspathEntry to runtime path for all entries that should have the attribute added.
	 * @return The operation.
	 */
	public static IDataModelOperation createAddDependencyAttributesOperation(final String projectName, final Map entryToRuntimePath) {
		return createOperation(projectName, entryToRuntimePath, UpdateClasspathAttributesDataModelProperties.ENTRIES_TO_ADD_ATTRIBUTE, true);
	}
	
	/**
	 * Creates the IDataModelOperation that will update the classpath for the specified Java project so that
	 * the WTP component dependency attribute will be removed from the specified list of classpath entries. 
	 * @param projectName Name of the target Java project.
	 * @param entryToRuntimePath Map from IClasspathEntry to runtime path for all entries that should have the attribute removed.
	 * @return The operation.
	 */
	public static IDataModelOperation createRemoveDependencyAttributesOperation(final String projectName, final Map entryToRuntimePath) {
		return createOperation(projectName, entryToRuntimePath, UpdateClasspathAttributesDataModelProperties.ENTRIES_TO_REMOVE_ATTRIBUTE, true);
	}
	
	/**
	 * Adds the WTP component dependency attribute to the specified classpath entry using the default runtime path for the project. Does NOT check that the
	 * specified entry is a valid entry for the dependency attribute.
	 * 
	 * @param monitor Progress monitor. Can be null.
	 * @param projectName Name of the target Java project.
	 * @param entry Classpath entry to which the attribute should be added.
	 * @return Status from the operation.
	 * @throws ExecutionException Thrown if an error is encountered.
	 */	
	public static IStatus addDependencyAttribute(final IProgressMonitor monitor, final String projectName, final IClasspathEntry entry) 
		throws ExecutionException {
		return addDependencyAttribute(monitor, projectName, entry, null);
	}
	
	/**
	 * Adds the WTP component non-dependency attribute to the specified classpath entry using the default runtime path for the project. 
	 * 
	 * @param monitor Progress monitor. Can be null.
	 * @param projectName Name of the target Java project.
	 * @param entry Classpath entry to which the attribute should be added.
	 * @return Status from the operation.
	 * @throws ExecutionException Thrown if an error is encountered.
	 */	
	public static IStatus addNonDependencyAttribute(final IProgressMonitor monitor, final String projectName, final IClasspathEntry entry) 
		throws ExecutionException {
		final Map entryToRuntimePath = new HashMap();
		entryToRuntimePath.put(entry, null);
		return createOperation(projectName, entryToRuntimePath, UpdateClasspathAttributesDataModelProperties.ENTRIES_TO_ADD_ATTRIBUTE, false).execute(monitor, null);
	}
	
	/**
	 * Adds the WTP component dependency attribute to the specified classpath entry. Does NOT check that the
	 * specified entry is a valid entry for the dependency attribute.
	 * 
	 * @param monitor Progress monitor. Can be null.
	 * @param projectName Name of the target Java project.
	 * @param entry Classpath entry to which the attribute should be added.
	 * @param runtimePath Runtime path to which entry elements should be deployed. Null if the default runtime path for the project should be used.
	 * @return Status from the operation.
	 * @throws ExecutionException Thrown if an error is encountered.
	 */	
	public static IStatus addDependencyAttribute(final IProgressMonitor monitor, final String projectName, final IClasspathEntry entry, final IPath runtimePath) 
		throws ExecutionException {
		final Map entryToRuntimePath = new HashMap();
		entryToRuntimePath.put(entry, runtimePath);
		return createOperation(projectName, entryToRuntimePath, UpdateClasspathAttributesDataModelProperties.ENTRIES_TO_ADD_ATTRIBUTE, true).execute(monitor, null);
	}
	
	/**
	 * Removes the WTP component dependency attribute from the specified classpath entry. Does NOT check that the
	 * specified entry is a valid entry for the dependency attribute.
	 * 
	 * @param monitor Progress monitor. Can be null.
	 * @param projectName Name of the target Java project.
	 * @param entry Classpath entry from which the attribute should be removed.
	 * @return Status from the operation.
	 * @throws ExecutionException Thrown if an error is encountered.
	 */	
	public static IStatus removeDependencyAttribute(final IProgressMonitor monitor, final String projectName, final IClasspathEntry entry) 
	throws ExecutionException {
		final Map entryToRuntimePath = new HashMap();
		entryToRuntimePath.put(entry, null);
		return createOperation(projectName, entryToRuntimePath, UpdateClasspathAttributesDataModelProperties.ENTRIES_TO_REMOVE_ATTRIBUTE, true).execute(monitor, null);
	}
	
	private static IDataModelOperation createOperation(String projectName, final Map entryToRuntimePath, final String entryMapProperty, final boolean modifyComponentClasspathDependency) { 
		IDataModel dataModel = DataModelFactory.createDataModel(new UpdateClasspathAttributesDataModelProvider());
		dataModel.setProperty(UpdateClasspathAttributesDataModelProperties.PROJECT_NAME, projectName);
		dataModel.setProperty(entryMapProperty, entryToRuntimePath);
		dataModel.setProperty(UpdateClasspathAttributesDataModelProperties.MODIFY_CLASSPATH_COMPONENT_DEPENDENCY, new Boolean(modifyComponentClasspathDependency));
		return dataModel.getDefaultOperation();
	}
	
}
