/*******************************************************************************
 * 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
 * yyyymmdd bug      Email and other contact information
 * -------- -------- -----------------------------------------------------------
 * 20060509   125094 sengpl@ca.ibm.com - Seng Phung-Lu, Use WorkspaceModifyOperation
 * 20060515   115225 sengpl@ca.ibm.com - Seng Phung-Lu
 * 20060517   142342 kathy@ca.ibm.com - Kathy Chan
 * 20060828	  155439 mahutch@ca.ibm.com - Mark Hutchinson
 * 20070501   184505 kathy@ca.ibm.com - Kathy Chan
 * 20070502   184505 kathy@ca.ibm.com - Kathy Chan, Update JAR sizes
 *******************************************************************************/
package org.eclipse.jst.ws.internal.axis.consumption.ui.task;


import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jst.ws.internal.axis.consumption.ui.AxisConsumptionUIMessages;
import org.eclipse.jst.ws.internal.common.J2EEUtils;
import org.eclipse.jst.ws.internal.common.ResourceUtils;
import org.eclipse.jst.ws.internal.consumption.ConsumptionMessages;
import org.eclipse.wst.command.internal.env.common.FileResourceUtils;
import org.eclipse.wst.command.internal.env.core.common.ProgressUtils;
import org.eclipse.wst.command.internal.env.core.common.StatusUtils;
import org.eclipse.wst.command.internal.env.core.context.ResourceContext;
import org.eclipse.wst.command.internal.env.core.context.TransientResourceContext;
import org.eclipse.wst.common.environment.IEnvironment;
import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelOperation;
import org.eclipse.wst.ws.internal.common.BundleUtils;


public class CopyAxisJarCommand extends AbstractDataModelOperation {
  
  public static String AXIS_JAR = "axis.jar"; //$NON-NLS-1$
  public static String AXIS_RUNTIME_PLUGIN_ID = "org.apache.axis"; //$NON-NLS-1$
  public static String COMMON_DISCOVERY_PLUGIN_ID = "org.apache.commons.discovery"; //$NON-NLS-1$
  public static String COMMON_DISCOVERY_JAR = "commons-discovery-0.2.jar"; //$NON-NLS-1$
  public static String JAVAX_XML_RPC_PLUGIN_ID = "javax.xml.rpc"; //$NON-NLS-1$
  public static String JAVAX_XML_RPC_JAR = "jaxrpc.jar"; //$NON-NLS-1$
  public static String JAVAX_XML_SOAP_PLUGIN_ID = "javax.xml.soap"; //$NON-NLS-1$
  public static String JAVAX_XML_SOAP_JAR = "saaj.jar"; //$NON-NLS-1$
  public static String JAVAX_WSDL_PLUGIN_ID = "javax.wsdl"; //$NON-NLS-1$
  public static String JAVAX_WSDL_JAR = "wsdl4j-1.5.1.jar"; //$NON-NLS-1$
  public static String COMMON_LOGGING_PLUGIN_ID = "org.apache.commons.logging"; //$NON-NLS-1$
  public static String COMMON_LOGGING_JAR = "commons-logging.jar"; //$NON-NLS-1$
  private static long AXIS_JAR_SIZE = 1586943L;
  private static long COMMON_DISCOVERY_JAR_SIZE = 71105L;
  private static long JAVAX_XML_RPC_JAR_SIZE = 32141L;
  private static long JAVAX_XML_SOAP_JAR_SIZE = 19506L;
  private static long JAVAX_WSDL_JAR_SIZE = 126775L;
  private static long COMMON_LOGGING_JAR_SIZE = 38895L;
  
//Web Services Jars Used in previous Versions of WTP but now obsolete
  private static String[] OBSOLETE_JARS = new String[]{
	  "commons-discovery.jar",
	  "commons-logging-1.0.4.jar",
	  "log4j-1.2.4.jar",
	  "log4j-1.2.8.jar",
	  "wsdl4j.jar",
	  "axis-ant.jar"
  };
  
  public static String PATH_TO_JARS_IN_PLUGIN = "lib/";

  private IProject project;
  private Boolean projectRestartRequired_ = Boolean.FALSE;
  private IClasspathEntry[] oldClasspath;
  private ArrayList newJarNamesList = new ArrayList();
  
  /**
   * Default CTOR;
   */
  public CopyAxisJarCommand( ) {
  }

  /**
   * Execute the command
   */
	public IStatus execute( IProgressMonitor monitor, IAdaptable adaptable ) 
	{
		
		IEnvironment env = getEnvironment();
		IStatus status = Status.OK_STATUS;
	    ProgressUtils.report(monitor, AxisConsumptionUIMessages.PROGRESS_INFO_COPY_AXIS_CFG);
	    
	    if (J2EEUtils.isWebComponent(project))
	    {
	    	copyAxisJarsToProject(project, status, env, monitor);	
	    }
	    else
	    {
	    	//Check if it's a plain old Java project
	 		 if (J2EEUtils.isJavaComponent(project))
	 		 {
	 			status = addAxisJarsToBuildPath(project, env, monitor);
	 			if (status.getSeverity()==Status.ERROR)
	 			{
	 				env.getStatusHandler().reportError(status);
	 				return status;
	 			}
	 		 }
	 		 else
	 		 {
	 		   status = StatusUtils.errorStatus( AxisConsumptionUIMessages.MSG_WARN_NO_JAVA_NATURE);	
	 		   env.getStatusHandler().reportError(status);
	 		   return status;
	 		 }

	    }
	    
	    return status;

	}

  private void copyAxisJarsToProject(IProject project, IStatus status, IEnvironment env, IProgressMonitor monitor) {

	IPath webModulePath = J2EEUtils.getWebContentPath( project );
    if (webModulePath == null) {
      status = StatusUtils.errorStatus( ConsumptionMessages.MSG_ERROR_PROJECT_NOT_FOUND);
      env.getStatusHandler().reportError(status);
      return;
    }
	
    deleteObsoleteJars(webModulePath);
    
	
    copyIFile(AXIS_RUNTIME_PLUGIN_ID, "lib/"+AXIS_JAR, webModulePath, "WEB-INF/lib/"+AXIS_JAR, status, env, monitor); 
    if (status.getSeverity() == Status.ERROR)
    	return;	
	copyIFile(COMMON_DISCOVERY_PLUGIN_ID, "lib/"+COMMON_DISCOVERY_JAR, webModulePath, "WEB-INF/lib/"+COMMON_DISCOVERY_JAR, status, env, monitor); 
    if (status.getSeverity() == Status.ERROR)
      return;
    copyIFile(JAVAX_XML_RPC_PLUGIN_ID, "lib/"+JAVAX_XML_RPC_JAR, webModulePath, "WEB-INF/lib/"+JAVAX_XML_RPC_JAR, status, env, monitor); 
    if (status.getSeverity() == Status.ERROR)
      return;
    copyIFile(JAVAX_XML_SOAP_PLUGIN_ID, "lib/"+JAVAX_XML_SOAP_JAR, webModulePath, "WEB-INF/lib/"+JAVAX_XML_SOAP_JAR, status, env, monitor); 
    if (status.getSeverity() == Status.ERROR)
      return;
    copyIFile(JAVAX_WSDL_PLUGIN_ID, "lib/"+JAVAX_WSDL_JAR, webModulePath, "WEB-INF/lib/"+JAVAX_WSDL_JAR, status, env, monitor); 
    if (status.getSeverity() == Status.ERROR)
      return;

    copyPluginJar(COMMON_LOGGING_PLUGIN_ID, webModulePath, "WEB-INF/lib/"+COMMON_LOGGING_JAR, status, env, monitor);
    if (status.getSeverity() == Status.ERROR)
      return;
    return;
  }

  /**
   *  
   */
  private void copyIFile(String pluginId, String source, IPath targetPath, String targetFile, IStatus status, IEnvironment env, IProgressMonitor monitor) {
    IPath target = targetPath.append(new Path(targetFile));
    ProgressUtils.report(monitor,ConsumptionMessages.PROGRESS_INFO_COPYING_FILE);

    try {
      ResourceContext context = new TransientResourceContext();
      context.setOverwriteFilesEnabled(true);
      context.setCreateFoldersEnabled(true);
      context.setCheckoutFilesEnabled(true);
      URL sourceURL = BundleUtils.getURLFromBundle( pluginId, source );
      IFile resource = ResourceUtils.getWorkspaceRoot().getFile(target);
      if (!resource.exists()) {
        IFile file = FileResourceUtils.createFile(context, target, sourceURL.openStream(), monitor, 
            env.getStatusHandler());
        if (projectRestartRequired_.booleanValue() == false && file.exists()) {
          projectRestartRequired_ = Boolean.TRUE;
        }

      }
    }
    catch (Exception e) {
      status = StatusUtils.errorStatus( AxisConsumptionUIMessages.MSG_ERROR_FILECOPY, e);
      env.getStatusHandler().reportError(status);

    }
  }
  
  /**
   * Copy plugins that has been JARed
 */
private void copyPluginJar(String pluginId, IPath targetPath, String targetFile, IStatus status, IEnvironment env, IProgressMonitor monitor) {
	  IPath target = targetPath.append(new Path(targetFile));
	  ProgressUtils.report(monitor,ConsumptionMessages.PROGRESS_INFO_COPYING_FILE);

	  try {
		  ResourceContext context = new TransientResourceContext();
		  context.setOverwriteFilesEnabled(true);
		  context.setCreateFoldersEnabled(true);
		  context.setCheckoutFilesEnabled(true);

		  IPath jarPath = BundleUtils.getJarredPluginPath(pluginId);
		  if (jarPath != null) {
			  IFile resource = ResourceUtils.getWorkspaceRoot().getFile(target);

			  if (!resource.exists()) {    	  
				  InputStream is = new FileInputStream (new File (jarPath.toString()));
				  IFile file = FileResourceUtils.createFile(context, target, is, monitor, 
						  env.getStatusHandler());
				  if (projectRestartRequired_.booleanValue() == false && file.exists()) {
					  projectRestartRequired_ = Boolean.TRUE;
				  }

			  }
		  }
	  }
	  catch (Exception e) {
		  status = StatusUtils.errorStatus( AxisConsumptionUIMessages.MSG_ERROR_FILECOPY, e);
		  env.getStatusHandler().reportError(status);

	  }
  }

  /*
   * Check for any obsolete Jars in WEB-INF/lib folder
   * Obsolete jars would be found in projects migrated
   * from older versions of WTP
   */
  private void deleteObsoleteJars(IPath webModulePath)
  {  
	  //First check for Any jars that have names that are known to be obsolete
	  for (int i=0; i <OBSOLETE_JARS.length; i++)
	  {
		  IPath path = webModulePath.append("WEB-INF/lib/" + OBSOLETE_JARS[i]);
		  
		  IFile resource = ResourceUtils.getWorkspaceRoot().getFile(path);
		  if (resource.exists())
		  {
			  deleteResource(resource);
		  }
	  }
	  
	  // delete older JARs of the same name 
	  deleteOldJar(webModulePath.append("WEB-INF/lib/" + AXIS_JAR), AXIS_JAR_SIZE);
	  deleteOldJar(webModulePath.append("WEB-INF/lib/" + COMMON_DISCOVERY_JAR), COMMON_DISCOVERY_JAR_SIZE);
	  deleteOldJar(webModulePath.append("WEB-INF/lib/" + JAVAX_XML_RPC_JAR), JAVAX_XML_RPC_JAR_SIZE);
	  deleteOldJar(webModulePath.append("WEB-INF/lib/" + JAVAX_XML_SOAP_JAR), JAVAX_XML_SOAP_JAR_SIZE);
	  deleteOldJar(webModulePath.append("WEB-INF/lib/" + JAVAX_WSDL_JAR), JAVAX_WSDL_JAR_SIZE);
	  deleteOldJar(webModulePath.append("WEB-INF/lib/" + COMMON_LOGGING_JAR), COMMON_LOGGING_JAR_SIZE);
	  
  }
  
  private void deleteOldJar (IPath jarPath, long jarSize) {
	  IFile resource = ResourceUtils.getWorkspaceRoot().getFile(jarPath);
	  if (resource.exists())
	  {
		  //calculate the size of the resource by getting the java.io.File    	  
		  long fileSize =resource.getLocation().toFile().length();
		  if (fileSize != jarSize)
		  {
			  deleteResource(resource);
		  }
	  }
  }
  private void deleteResource(IFile resource)
  {	  //delete the resource
	  try
	  {
		  //System.out.println("Obsolete Jar!! " + resource.getName());
		  resource.delete(true, null);
	  }
	  catch (Exception e)
	  {  //e.printStackTrace();
	  }
  }
 

  /**
   * Addes Axis JARs to the build path of Java project
 * @param env
 * @param monitor
 * @return
 */
public IStatus addAxisJarsToBuildPath(IProject project, IEnvironment env, IProgressMonitor monitor)
  {
	    
	  IStatus status;
	  
	  try {
	  getJavaProjectClasspath(env, monitor);
	  
	  addNewJarEntry(PATH_TO_JARS_IN_PLUGIN+AXIS_JAR, getTheJarPath(AXIS_RUNTIME_PLUGIN_ID, PATH_TO_JARS_IN_PLUGIN+AXIS_JAR));
	  addNewJarEntry(PATH_TO_JARS_IN_PLUGIN+COMMON_DISCOVERY_JAR, getTheJarPath(COMMON_DISCOVERY_PLUGIN_ID, PATH_TO_JARS_IN_PLUGIN+COMMON_DISCOVERY_JAR));
	  addNewJarEntry(PATH_TO_JARS_IN_PLUGIN+JAVAX_XML_RPC_JAR, getTheJarPath(JAVAX_XML_RPC_PLUGIN_ID, PATH_TO_JARS_IN_PLUGIN+JAVAX_XML_RPC_JAR));
	  addNewJarEntry(PATH_TO_JARS_IN_PLUGIN+JAVAX_XML_SOAP_JAR, getTheJarPath(JAVAX_XML_SOAP_PLUGIN_ID, PATH_TO_JARS_IN_PLUGIN+JAVAX_XML_SOAP_JAR));
	  addNewJarEntry(PATH_TO_JARS_IN_PLUGIN+JAVAX_WSDL_JAR, getTheJarPath(JAVAX_WSDL_PLUGIN_ID, PATH_TO_JARS_IN_PLUGIN+JAVAX_WSDL_JAR));
	  
	  IPath commonLoggingJarPath = BundleUtils.getJarredPluginPath(COMMON_LOGGING_PLUGIN_ID);
	  if (commonLoggingJarPath != null) {
		  addNewJarEntry(commonLoggingJarPath.toString(), commonLoggingJarPath);
	  }
	  updateClasspath(monitor);
	  } catch (Exception e) {
		  status = StatusUtils.errorStatus( AxisConsumptionUIMessages.MSG_ERROR_BAD_BUILDPATH, e);
	      return status;
	}
	  
	  return Status.OK_STATUS;
  }
  
  /**
 * @param env
 * @param monitor
 * @return The Java project classpath
 * @throws JavaModelException
 */
private IStatus getJavaProjectClasspath(IEnvironment env, IProgressMonitor monitor) throws JavaModelException
  {

	  IStatus status = Status.OK_STATUS;

	  IJavaProject javaProject_ = null;
	  oldClasspath = null;
	  javaProject_ = JavaCore.create(project);

	  oldClasspath = javaProject_.getRawClasspath();

	  return status;
  }
  
  /**
   * Store new JAR name in newJarNamesList if it's not already on build path
 * @param jarName name of the JAR
 * @param jarPath Absolute path to the JAR
 */
private void addNewJarEntry(String jarName, IPath jarPath)
  {

	  boolean found = false;
	  for (int i = 0; i < oldClasspath.length; i++)
	  {
		  found = oldClasspath[i].getPath().toString().toLowerCase().endsWith(jarName.toLowerCase());
		  if (found)
		  {
			  break;
		  }
	  }

	  if (!found)
	  {
		  newJarNamesList.add(new JarEntry (jarName, jarPath));
	  }

  }
  
  /**
   * Update the Java project classpath adding classpath from newJarNamesList to oldClasspath 
 * @param monitor
 * @return
 * @throws JavaModelException
 */
private IStatus updateClasspath(IProgressMonitor monitor) throws JavaModelException
  {

    IStatus status = Status.OK_STATUS;
    
    if (newJarNamesList.size() > 0)
    {
      JarEntry[] newJarEntries = (JarEntry[]) newJarNamesList.toArray(new JarEntry[] {});

      IClasspathEntry[] newClasspath = new IClasspathEntry[oldClasspath.length + newJarEntries.length];
      int i = 0;
      // Add oldClasspath entries
      while (i < oldClasspath.length)
      {
        newClasspath[i] = oldClasspath[i];
        i++;
      }

        int m = 0;
        while (i < newClasspath.length)
        {
          newClasspath[i] = JavaCore.newLibraryEntry(newJarEntries[m].getJarPath(), null, null);
          m++;
          i++;
        }

      //
      // Then update the project classpath.
      //

    	IJavaProject javaProject = JavaCore.create(project);
        javaProject.setRawClasspath(newClasspath, monitor);
      
    }

    return status;

  }

		//
		// Returns the local native pathname of the jar.
		//
  private IPath getTheJarPath(String pluginId, String theJar) throws MalformedURLException, IOException
  {
	  if (pluginId != null) {
			URL localURL =	Platform.asLocalURL(BundleUtils.getURLFromBundle( pluginId, theJar ) );
			return new Path(localURL.getFile());
		} else {
			return new Path(theJar);
		}

  }  
  
  public void setProject(IProject project) {
    this.project = project;
  }

  public boolean getProjectRestartRequired() {
    return projectRestartRequired_.booleanValue();
  }
  
  public class JarEntry {
		private String jarName;
		private IPath jarPath;
		
		public JarEntry(String name, IPath path)
		{
			jarName = name;
			jarPath = path;
		}

		public String getJarName() {
			return jarName;
		}

		public IPath getJarPath() {
			return jarPath;
		}

	}
}
