/*******************************************************************************
 * Copyright (c) 2007, 2009 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
 * -------- -------- -----------------------------------------------------------
 * 20070125   171071 makandre@ca.ibm.com - Andrew Mak, Create public utility method for copying WSDL files
 * 20070409   181635 makandre@ca.ibm.com - Andrew Mak, WSDLCopier utility should create target folder
 * 20071205   211262 ericdp@ca.ibm.com - Eric Peters, CopyWSDLTreeCommand fails to copy ?wsdl
 * 20080324   215552 makandre@ca.ibm.com - Andrew Mak, WSDLCopier expects not encoded URI
 * 20080501   229728 makandre@ca.ibm.com - Andrew Mak, uppercase .WSDL cannot be found by the Web Service Client wizard
 * 20090128   262639 ericdp@ca.ibm.com - Eric D. Peters, WSDLCopier gives NPE in projects with spaces
 * 20090204   262913 ericdp@ca.ibm.com - Eric D. Peters, Top-down WS fails when .wsdl imports .xsd or .wsdl which resides in folder containing URI encoded chars like " ", ")"
 * 20091106   294486 yenlu@ca.ib,.com - Yen Lu, WSDLCopier may not write WSDLs and XSDs with the correct XML encoding
 *******************************************************************************/

package org.eclipse.wst.ws.internal.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.wsdl.Definition;
import javax.wsdl.Import;
import javax.wsdl.Types;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.extensions.UnknownExtensibilityElement;
import javax.wsdl.extensions.schema.Schema;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.command.internal.env.core.common.StatusUtils;
import org.eclipse.wst.common.environment.EnvironmentService;
import org.eclipse.wst.common.environment.uri.IURIScheme;
import org.eclipse.wst.common.environment.uri.SimpleURIFactory;
import org.eclipse.wst.common.environment.uri.URIException;
import org.eclipse.wst.common.uriresolver.internal.util.URIEncoder;
import org.eclipse.wst.ws.internal.WstWSPluginMessages;
import org.eclipse.wst.ws.internal.parser.discovery.NetUtils;
import org.eclipse.wst.ws.internal.parser.wsil.WWWAuthenticationException;
import org.eclipse.wst.ws.internal.parser.wsil.WebServicesParser;
import org.eclipse.wst.wsdl.XSDSchemaExtensibilityElement;
import org.eclipse.wst.wsdl.internal.impl.DefinitionImpl;
import org.eclipse.wst.wsdl.util.WSDLResourceImpl;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDSchemaDirective;
import org.eclipse.xsd.impl.XSDSchemaImpl;
import org.eclipse.xsd.util.XSDParser;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * <p>This is a utility class that can be used to copy a WSDL file and its relative imports
 * (both wsdl:import and xsd:import) to a folder in the filesystem.  The code will analyze
 * the directory structure and does the following:
 * <ol>
 *    <li>find all files that needs to be copied and tag them as such.</li>
 *    <li>find the common parent directory of all the files that are tagged; this is the 
 *    root of the directory structure.</li>
 * </ol>
 * During the copy, the root of the directory structure is be mapped to the 
 * specified target folder and all tagged files will be duplicated under it.</p>
 * 
 * <p>If the WSDL source and the target location are the same, this utility only guarantees
 * that the starting WSDL file is "re-copied" onto itself (since the WSDL definition could 
 * have been altered).  No guarantee is made for the other files that the WSDL file imports.</p>
 * 
 * <p>Note that WSDLCopier does not do a direct file copy.  The source files are read into
 * a model and then written out to the target folder, hence the output file might not be
 * syntactically identical to the source file but they will be structurally identical.</p>
 * 
 * <p>Since this utility implements IWorkspaceRunnable, it can be run by the workspace as
 * an atomic workspace operation.</p>
 */
public class WSDLCopier implements IWorkspaceRunnable {

	private static final String XSD = ".xsd";
	
	/**
	 * Helper class holding information about the files we need to copy
	 */
	private class XMLObjectInfo {
	  	
		public IPath  path;
	  	public Object content;
	  	public String encoding;
	  	  	
	  	/**
	  	 * Constructor.
	  	 * 
	  	 * @param path The path of the source file.
	  	 * @param content A representation of the source file (either wsdl or xsd)
	  	 */
	  	public XMLObjectInfo(IPath path, Object content) {
	  		this.path    = path.setDevice(null); // we want a device independent path  		
	  		this.content = content;	  		
	  	}
	  	
	  	/**
	  	 * Constructor.
	  	 * 
	  	 * @param path The path of the source file.
	  	 * @param content A representation of the source file (either wsdl or xsd)
	  	 * @param encoding The encoding of the content.
	  	 */	  	
	  	public XMLObjectInfo(IPath path, Object content, String encoding)
	  	{
	  		this(path, content);
	  		this.encoding = encoding;
	  	}
	}	  
	
	private WebServicesParser parser	= null;					// parser to parse the wsdl and xsd files
	
	private URI sourceURI				= URI.create("");		// uri of the starting wsdl
	private Definition definition		= null;					// representation of the starting wsdl
	
	private URI targetFolderURI			= null;					// uri of the folder to copy to
	private String targetFilename		= null;					// optional new filename for the starting wsdl
	
	private IPath pathPrefix			= null;  				// the shortest common path of all files we need to copy
	private IPath wsdlRelPath			= null;					// relative path of the starting wsdl to the target folder
		
	private Map xmlObjectInfos			= new LinkedHashMap();	// table to store info about the files we need to copy
	
	private SimpleURIFactory uriFactory = null;
	
	/**
	 * Default constructor.  A new WebServicesParser is constructed for use.
	 */
	public WSDLCopier() {
		this(null);
	}
	
	/**
	 * Constructor.  The given WebServicesParser will be used.
	 * 
	 * @param parser A WebServicesParser for WSDLCopier to use.  If null, a new one will be constructed.
	 */
	public WSDLCopier(WebServicesParser parser) {
		if (parser == null)
			this.parser = new WebServicesParser();
		else
			this.parser = parser;
		
		IURIScheme eclipseScheme = EnvironmentService.getEclipseScheme();
	    IURIScheme fileScheme    = EnvironmentService.getFileScheme();
	    uriFactory = new SimpleURIFactory();
	    uriFactory.registerScheme("platform", eclipseScheme);
	    uriFactory.registerScheme("file", fileScheme);
	}

	/**
	 * Sets the URI of the starting wsdl document.  The URI must be an absolute URI
	 * with a valid protocol.  For local files, both file:/ and platform:/resource 
	 * protocol are acceptable. 
	 * 
	 * @param uri The URI of the starting wsdl document.
	 * 
	 * @deprecated
	 */
	public void setSourceURI(String uri) {
		setSourceURI(uri, null);
	}
	
	/**
	 * Sets the URI of the starting wsdl document.  The URI must be an absolute URI
	 * with a valid protocol.  For local files, both file:/ and platform:/resource 
	 * protocol are acceptable. 
	 * 
	 * @param uri The URI of the starting wsdl document. 
	 */
	public void setSourceURI(URI uri) {
		setSourceURI(uri, null);
	}
	
	/**
	 * Same as setSourceURI(String uri) version, except that an already parsed
	 * representation of the wsdl document can be passed to this method to avoid
	 * having to parse it a second time.
	 * 
	 * @param uri The URI of the starting wsdl document.
	 * @param definition A parsed representation of the starting wsdl document.
	 * 
	 * @deprecated
	 */
	public void setSourceURI(String uri, Definition definition) {
		if (uri != null)
			uri = uri.replace('\\', '/');
		URI uriObj = null;		
		try {
			try {
				uriObj = new URI(uri);
			}
			catch (URISyntaxException e) {				
				uriObj = URI.create(URIEncoder.encode(uri, "UTF-8"));
			}
			setSourceURI(uriObj, definition);		
		}
		catch (UnsupportedEncodingException e) {
			// ignore, default URI("") is used, operation will be a no-op
		}		
	}
	
	/**
	 * Same as setSourceURI(String uri) version, except that an already parsed
	 * representation of the wsdl document can be passed to this method to avoid
	 * having to parse it a second time.
	 * 
	 * @param uri The URI of the starting wsdl document.
	 * @param definition A parsed representation of the starting wsdl document. 
	 */
	public void setSourceURI(URI uri, Definition definition) {
		sourceURI = uri;
		this.definition = definition;
	}
	
	/**
	 * Specify the target folder URI for WSDLCopier to copy the wsdl to.  The URI must be
	 * an absolute URI with a valid protocol.  Both file:/ and platform:/resource protocol
	 * are acceptable.  The entire directory structure with all the files that the wsdl 
	 * imports will be duplicated under this folder.  If the target folder does not exist, 
	 * it will be created. 
	 * 
	 * @param uri The target folder URI where the wsdl structure is copied to.
	 * 
	 * @deprecated
	 */
	public void setTargetFolderURI(String uri) {
		if (uri != null)
			uri = uri.replace('\\', '/');
		URI uriObj = null;		
		try {
			try {
				uriObj = new URI(uri);
			}
			catch (URISyntaxException e) {				
				uriObj = URI.create(URIEncoder.encode(uri, "UTF-8"));
			}
			setTargetFolderURI(uriObj);		
		}
		catch (UnsupportedEncodingException e) {
			// ignore, targetFolderURI will be checked for null later
		}		
	}
	
	/**
	 * Specify the target folder URI for WSDLCopier to copy the wsdl to.  The URI must be
	 * an absolute URI with a valid protocol.  Both file:/ and platform:/resource protocol
	 * are acceptable.  The entire directory structure with all the files that the wsdl 
	 * imports will be duplicated under this folder.  If the target folder does not exist, 
	 * it will be created. 
	 * 
	 * @param uri The target folder URI where the wsdl structure is copied to. 
	 */
	public void setTargetFolderURI(URI uri) {		
		targetFolderURI = uri;
	}
	
	/**
	 * Optionally set a new filename for the starting wsdl document to use after it is
	 * copied.  If not specified, the original name of the wsdl is used.
	 * 
	 * @param filename A filename.
	 */
	public void setTargetFilename(String filename) {
		targetFilename = filename;
	} 
	
	/*
	 * Compare the path prefix with the path in the info object,
	 * modify the path prefix accordingly.
	 */
	private void updatePathPrefix(XMLObjectInfo info) {
	  	if (pathPrefix == null)
	        pathPrefix = info.path.removeLastSegments(1);
	    else {
	    	int matching = pathPrefix.matchingFirstSegments(info.path);
	    	
	    	if (matching < pathPrefix.segmentCount())
	    		pathPrefix = pathPrefix.uptoSegment(matching);
	    }
	}    	
	
	/*
	 * Determine if the given URI is a relative URI. 
	 */
	private boolean isRelative(String uri) {
		return uri.indexOf(':') == -1;
	}

	/*
	 * Analyze the wsdl document at the given URI, and traverse any relative files that
	 * it imports. Can optionally pass in a parsed Definition if one's available so
	 * we don't have to parse the wsdl again (otherwise just pass in null). 
	 */
	private void analyzeWSDL(URI uri, Definition definition) throws 
		MalformedURLException, IOException, WSDLException, WWWAuthenticationException {
		
		uri = uri.normalize();
		
		// already seen this wsdl, skip
		if (xmlObjectInfos.containsKey(uri.toString()))
			return;
				
		// need to parse the wsdl ourselves
		if (definition == null)
			definition = parser.getWSDLDefinitionVerbose(uri.toString());
		
		// save a reference to the starting wsdl
		if (this.definition == null)
			this.definition = definition;
		
		IPath path = new Path(uri.getPath());
		
		// a target filename was given, so we need to modify the path with the new name
		if (definition == this.definition && targetFilename != null)
			path = path.removeLastSegments(1).append(targetFilename);
		 		
	    XMLObjectInfo info = new XMLObjectInfo(path, definition);	    
	    xmlObjectInfos.put(uri.toString(), info);
	    updatePathPrefix(info);
		
	    // now look at wsdl imports
	    
	    for (Iterator it = definition.getImports().values().iterator(); it.hasNext();) {

	    	List list = (List) it.next();
	      
	    	for (Iterator listIt = list.iterator(); listIt.hasNext();) {
	    		
		        Import wsdlImport = (Import) listIt.next();
		        String wsdlImportLocation = wsdlImport.getLocationURI();

		        // analyze any relative imports we find
		        if (wsdlImportLocation != null && isRelative(wsdlImportLocation)) {

		        	// bad form, importing xsd with wsdl:import, but need to handle
		        	if (wsdlImportLocation.toLowerCase().endsWith(XSD))
		        		analyzeXSD(uri.resolve(uriCreate(wsdlImportLocation)));
		        	else	
		        		analyzeWSDL(uri.resolve(uriCreate(wsdlImportLocation)), null);
		        }
	    	}
	    }
	    
	    // now look at xsd imports

	    Types types = definition.getTypes();
	    
	    // there's no wsdl:types, we're done
	    if (types == null)
	    	return;
	        	
    	for (Iterator it = types.getExtensibilityElements().iterator(); it.hasNext();) {			
			
    		ExtensibilityElement extElement = (ExtensibilityElement) it.next();    		
    		Element element;
    		
    		// we'll try to parse any UnknownExtensibilityElements and
    		// XSDSchemaExtensibilityElements into an XSD schema    		
    		
    		if (extElement instanceof UnknownExtensibilityElement)
    			element = ((UnknownExtensibilityElement) extElement).getElement();
   			else if (extElement instanceof XSDSchemaExtensibilityElement)
   				element = ((XSDSchemaExtensibilityElement) extElement).getElement();
   			else if (extElement instanceof Schema)
   				element = ((Schema) extElement).getElement();
   			else
   				continue;
    			    			
			try {
				XSDSchema xsdSchema = XSDSchemaImpl.createSchema(element);
				
				// analyze the inlined schema at the current uri
				analyzeXSD(uri, xsdSchema);
			}
			catch (Exception t) {
				// ignore any extensibility elements that cannot be parsed into a
				// XSDSchema instance
			}
        }
	}
	
	/*
	 * Analyze the schema at the given URI, traverse its imports and includes.
	 * The schema information is not stored in XMLObjectInfos because it's
	 * either not neccessary (schema inlined in a wsdl) or it has already
	 * been stored.
	 */
	private void analyzeXSD(URI uri, XSDSchema schema) {
		
		if (schema == null)
			return;
		
		// look at the imports and includes
	    
		for (Iterator it = schema.getContents().iterator(); it.hasNext();) {
	        
			Object content = it.next();
	        
			if (!(content instanceof XSDSchemaDirective))
				continue;
					        
			XSDSchemaDirective xsdSchemaDirective = (XSDSchemaDirective) content;
			String xsdSchemaDirectiveLocation = xsdSchemaDirective.getSchemaLocation();
	          
			// analyze any relative imports and includes we find
			if (xsdSchemaDirectiveLocation != null && isRelative(xsdSchemaDirectiveLocation))
				try {
					analyzeXSD(uri.resolve(uriCreate(xsdSchemaDirectiveLocation)));
				} catch (Exception e) {
					// ignore any xsd's we cannot resolve
				}
		}
	}
	
	/*
	 * Analyze the schema at the given URI, the schema is parsed and stored in
	 * XMLObjectInfos.
	 */
	private void analyzeXSD(URI uri) {
		
		uri = uri.normalize();
		
		// already seen this xsd, skip it
		if (xmlObjectInfos.containsKey(uri.toString()))
			return;
		
		XSDSchema xsdSchema = XSDSchemaImpl.getSchemaForSchema(uri.toString());

		String encoding = null;
		// if schema is not cached, parse it
	    if (xsdSchema == null) {
	    	XSDParser p = new XSDParser(null);
	    	InputStream is = NetUtils.getURLInputStream(uri.toString());
	      
	    	if (is != null) {
	    		p.parse(is);
	    		xsdSchema = p.getSchema();
	    		encoding = p.getEncoding();
	    	}
	    }
	    else
	    	encoding = xsdSchema.getDocument().getXmlEncoding();
	    
	    if (xsdSchema != null) {
	        
	    	if (encoding == null)
	    		encoding = "UTF-8";
	    	
	    	XMLObjectInfo info = new XMLObjectInfo(new Path(uri.getPath()), xsdSchema, encoding);	    	
	    	xmlObjectInfos.put(uri.toString(), info);
	    	updatePathPrefix(info);
	      
	    	// analyze its imports and includes
	    	analyzeXSD(uri, xsdSchema);
	    }
	}
		
	/*
	 * Appends a path to a URI and returns the new combined URI in an array of 2 elements,
	 * where the first element is in decoded form and the second element is in encoded form.
	 */
	private String[] appendPathToURI(URI uriObj, IPath path) {
		
		String schemeSpecificPart = uriObj.getSchemeSpecificPart(); 
		
		if (schemeSpecificPart.endsWith("/"))
			path = path.makeRelative();
		else
			path = path.makeAbsolute();
		
		return new String[] {
				uriObj.getScheme() + ':' + schemeSpecificPart + path,
				uriObj.getScheme() + ':' + uriObj.getRawSchemeSpecificPart() + path
		};
	}
	
	/*
	 * Writes the wsdl definition to the file at the given path, relative to the target folder.
	 */
	private String writeXMLObj(IPath path, Definition definition, IProgressMonitor monitor) throws
		WSDLException, URIException, IOException, CoreException {				
			  
	    String[] targetURI = appendPathToURI(targetFolderURI, path);
	    
	    OutputStream os = uriFactory.newURI(targetURI[0]).getOutputStream();
	    
	    DefinitionImpl definitionImpl = (DefinitionImpl)definition;
		WSDLResourceImpl resource = (WSDLResourceImpl) definitionImpl.eResource();
		Document document = definitionImpl.getDocument();
		resource.serialize(os, document, document.getXmlEncoding());
	    
	    os.close();
	    
	    return targetURI[1];
	}
  
	/*
	 * Writes the xsd schema to the file at the given path, relative to the target folder.
	 */
	private String writeXMLObj(IPath path, XSDSchema xsdSchema, String encoding, IProgressMonitor monitor) throws
		TransformerConfigurationException, TransformerException, URIException, IOException, CoreException {			
		Transformer serializer = TransformerFactory.newInstance().newTransformer();
		Document document = xsdSchema.getDocument();
		serializer.setOutputProperty(OutputKeys.INDENT, "yes");
		serializer.setOutputProperty(OutputKeys.ENCODING, encoding);
		serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
		
		Element e = xsdSchema.getElement();
		DOMSource domSource = new DOMSource(e);		
		
		String[] targetURI = appendPathToURI(targetFolderURI, path);
		
		OutputStream os = uriFactory.newURI(targetURI[0]).getOutputStream();
		serializer.transform(domSource, new StreamResult(os));
		os.close();
		
		return targetURI[1];
	}  

	/*
	 * Compares the 2 uris and see if they point to the same file. 
	 * We need to convert both uris to file: protocal uris in order to compare.
	 */	
	private boolean isSameLocation(String uri1, String uri2) {

		// if either uri is null, we cannot make any meaningful comparison
		if (uri1 == null || uri2 == null)
			return false;
		try {
			//we have an encoded URI and want to compare if they resolve to the same file on the file system
			uri1 = UniversalPathTransformer.uriToLocation(uri1);
			uri2 = UniversalPathTransformer.uriToLocation(uri2);
			if (uri1 == null || uri2 == null || uri1.length() == 0 || uri2.length() == 0)
				return false;
			return uri1.equals(uri2);
		} catch (Exception e) {
			return false;
		}
	}
	
	/**
	 * Executes the copying action.
	 * 
	 * @param monitor An optional progress monitor.
	 * @throws CoreException Thrown if the copying is unsuccessful.  Possible causes include:
	 * target folder URI was not specified; source URI has incorrect format; problem parsing wsdl 
	 * or xsd documents; problem writing to filesystem.
	 */
	public void run(IProgressMonitor monitor) throws CoreException {
		
		xmlObjectInfos.clear();

		// target folder must be set
		if (targetFolderURI == null)
			throw new CoreException(StatusUtils.errorStatus(WstWSPluginMessages.MSG_ERROR_TARGET_FOLDER_NOT_SPECIFIED));		
				
  		try {
  			analyzeWSDL(sourceURI, definition);  			 
  			
  			// begin writing out files
  			
  			Iterator iter = xmlObjectInfos.values().iterator(); 			  			
  			
  			while (iter.hasNext()) {
  				XMLObjectInfo info = (XMLObjectInfo) iter.next();  				
  				IPath relPath = info.path.removeFirstSegments(pathPrefix.segmentCount());
  				
  				if (info.content instanceof Definition) {
  					Definition definition = (Definition) info.content;
  					
  					// if this is the starting wsdl, remember its path relative to the target folder
  					if (definition == this.definition)
  						wsdlRelPath = relPath;

  					String targetURI = writeXMLObj(relPath, definition, monitor);
  					
  					if (definition == this.definition && isSameLocation(sourceURI.toString(), targetURI))
  						return;
  				}
  				else
  					writeXMLObj(relPath, (XSDSchema) info.content, info.encoding, monitor);  					
  			}  			
  		} catch (Exception t) {
  			throw new CoreException(StatusUtils.errorStatus(
  					NLS.bind(WstWSPluginMessages.MSG_ERROR_COPY_WSDL, new String[] {sourceURI.toString(), targetFolderURI.toString()}), t));
  		}
	}
	
	/**
	 * Returns the path of the starting wsdl document, relative to the target folder after
	 * copying completes.
	 * 
	 * @return The relative path of the starting wsdl document.
	 */
	public IPath getRelativePath() {
		return wsdlRelPath;
	}

	private static java.net.URI uriCreate(String uri) {
		if (uri != null)
			uri = uri.replace('\\', '/');
		try {
			try {
				return java.net.URI.create(uri);
			}
			catch (IllegalArgumentException e) {				
				return java.net.URI.create(URIEncoder.encode(uri, "UTF-8"));
			}
		}
		catch (UnsupportedEncodingException e) {
			return java.net.URI.create("");
		}	
	}
}
