/*******************************************************************************
 * Copyright (c) 2001, 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.wst.wsdl.util;


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
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.runtime.IProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.resource.impl.ResourceImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.wst.wsdl.Definition;
import org.eclipse.wst.wsdl.ExtensibilityElement;
import org.eclipse.wst.wsdl.Types;
import org.eclipse.wst.wsdl.WSDLFactory;
import org.eclipse.wst.wsdl.WSDLPlugin;
import org.eclipse.wst.wsdl.XSDSchemaExtensibilityElement;
import org.eclipse.wst.wsdl.internal.impl.DefinitionImpl;
import org.eclipse.wst.wsdl.internal.util.WSDLResourceFactoryImpl;
import org.eclipse.wst.wsdl.internal.util.XSDSchemaLocatorAdapterFactory;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.util.XSDSchemaLocator;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;


/**
 * <!-- begin-user-doc -->
 * The <b>Resource</b> implementation for the model.
 * This specialized resource implementation supports it's own way of making keys and 
 * hrefs, and it's own serialization. This class is not intended for subclassing 
 * outside of the model implementation; it is intended to be used as is with the 
 * Resource framework.
 * <p>
 * <b>Note:</b> This class/interface is part of an interim API that is still under development and expected to
 * change significantly before reaching stability. It is being made available at this early stage to solicit feedback
 * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
 * (repeatedly) as the API evolves.
 * </p>
 * @since 1.0
 * @ignore
 * <!-- end-user-doc -->
 * @see org.eclipse.wst.wsdl.internal.util.WSDLResourceFactoryImpl
 * @generated
 */
public class WSDLResourceImpl extends ResourceImpl
{

  private boolean useExtensionFactories = true;

  private boolean continueOnLoadError = true;

  public static final String USE_EXTENSION_FACTORIES = "USE_EXTENSION_FACTORIES"; //$NON-NLS-1$

  public static final String CONTINUE_ON_LOAD_ERROR = "CONTINUE_ON_LOAD_ERROR"; //$NON-NLS-1$

  public static final String WSDL_ENCODING = "WSDL_ENCODING"; //$NON-NLS-1$

  public static final String WSDL_PROGRESS_MONITOR = "WSDL_PROGRESS_MONITOR"; //$NON-NLS-1$

  /**
   * Add this option with a value of Boolean.TRUE to the options map when
   * loading a resource to instruct the loader to track source code location for
   * each node in the source document.
   * 
   * @see WSDLParser#getUserData(org.w3c.dom.Node)
   * @see WSDLParser#getStartColumn(org.w3c.dom.Node)
   * @see WSDLParser#getEndColumn(org.w3c.dom.Node)
   * @see WSDLParser#getStartLine(org.w3c.dom.Node)
   * @see WSDLParser#getEndLine(org.w3c.dom.Node)
   */
  public static final String TRACK_LOCATION = "TRACK_LOCATION"; //$NON-NLS-1$

  /**
   * Creates an instance of the resource. 
   * <!-- begin-user-doc --> 
   * <!-- end-user-doc -->
   * 
   * @param uri the URI of the new resource. 
   * @generated
   */
  public WSDLResourceImpl(URI uri)
  {
    super(uri);
  }

  protected void doSave(OutputStream os, Map options) throws IOException
  {
    Definition definition = getDefinition();
    if (definition != null)
    {
      Document document = definition.getDocument();
      if (document == null)
      {
        ((DefinitionImpl)definition).updateDocument();
        document = definition.getDocument();
      }

      if (definition.getElement() == null)
      {
        ((DefinitionImpl)definition).updateElement();
      }

      doSerialize(os, document, options == null ? null : (String)options.get(WSDL_ENCODING));
    }
  }

  /**
   * Returns the resource's Definition.
   */
  public Definition getDefinition()
  {
    return getContents().size() == 1 && getContents().get(0) instanceof Definition ? (Definition)getContents().get(0) : null;
  }

  private static void doSerialize(OutputStream outputStream, Document document, String encoding)
  {
    try
    {
      TransformerFactory transformerFactory = TransformerFactory.newInstance();
      Transformer transformer = transformerFactory.newTransformer();

      transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
      transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$

      // Unless a width is set, there will be only line breaks but no indentation.
      // The IBM JDK and the Sun JDK don't agree on the property name,
      // so we set them both.
      //
      transformer.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "2"); //$NON-NLS-1$ //$NON-NLS-2$
      transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); //$NON-NLS-1$ //$NON-NLS-2$
      if (encoding != null)
      {
        transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
      }

      transformer.transform(new DOMSource(document), new StreamResult(outputStream));
    }
    catch (TransformerException exception)
    {
      WSDLPlugin.INSTANCE.log(exception);
    }
  }

  /**
   * Loads a new {@link WSDLResourceImpl} into the resource set.
   * @param inputSource the contents of the new resource.
   * @param options any options to influence loading behavior.
   */
  protected void doLoad(InputSource inputSource, Map options) throws IOException
  {
    // This pattern avoids loading the IProgressMonitor class when there is no progress monitor.
    // This is important for stand-alone execution to work correctly.
    //
    IProgressMonitor progressMonitor = null;
    Object monitor = options == null ? null : options.get(WSDL_PROGRESS_MONITOR);
    if (monitor != null)
    {
      progressMonitor = (IProgressMonitor)monitor;
      progressMonitor.setTaskName(WSDLPlugin.INSTANCE.getString("_UI_ResourceLoad_progress")); //$NON-NLS-1$
      progressMonitor.subTask(getURI().toString());
    }

    Object bindings = options == null ? null : options.get(USE_EXTENSION_FACTORIES);
    if (bindings != null && bindings instanceof Boolean)
      // true by default
      useExtensionFactories = ((Boolean)bindings).booleanValue();

    Object continueOnError = options == null ? null : options.get(CONTINUE_ON_LOAD_ERROR);
    if (continueOnError != null && continueOnError instanceof Boolean)
      // true by default
      continueOnLoadError = ((Boolean)continueOnError).booleanValue();

    Document doc = null;
    try
    {
      boolean trackLocation = options != null && Boolean.TRUE.equals(options.get(TRACK_LOCATION));

      if (trackLocation)
      {
        doc = getDocumentUsingSAX(inputSource);
      }
      else
      {
        // Create a DOM document
        doc = getDocument(inputSource, new InternalErrorHandler());
      }

      if (doc != null && doc.getDocumentElement() != null)
      {
        if (!findDefinition(doc.getDocumentElement()))
        {
          if (continueOnLoadError)
            handleDefinitionElement(doc.getDocumentElement());
          else
            throw new IOException(WSDLPlugin.getPlugin().getString("_ERROR_INVALID_WSDL")); //$NON-NLS-1$
        }
      }
      else
      {
        handleDefinitionElement(null);
      }
    }
    catch (IOException exception)
    {
      if (continueOnLoadError)
      {
        WSDLPlugin.INSTANCE.log(exception);
        handleDefinitionElement(null);
      }
      else
        throw exception;
    }

    Definition definition = null;

    for (Iterator i = getContents().iterator(); i.hasNext();)
    {
      definition = (Definition)i.next();

      // Initialize the inline schemas location 
      Types types = definition.getETypes();
      if (types != null)
      {
        XSDSchemaExtensibilityElement el = null;
        for (Iterator j = types.getEExtensibilityElements().iterator(); j.hasNext();)
        {
          ExtensibilityElement extensibilityElement = (ExtensibilityElement)j.next();
          if (!(extensibilityElement instanceof XSDSchemaExtensibilityElement))
          {
            continue;
          }
          
          el = (XSDSchemaExtensibilityElement) extensibilityElement;
          XSDSchema schema = el.getSchema();
          if (schema != null)
            schema.setSchemaLocation(getURI().toString());
        }
      }
    }

    if (progressMonitor != null)
    {
      progressMonitor.worked(1);
    }
  }

  /**
   * Loads a new {@link WSDLResourceImpl} into the resource set.
   * @param inputStream the contents of the new resource.
   * @param options any options to influence loading behavior.
   */
  protected void doLoad(InputStream inputStream, Map options) throws IOException
  {
    InputSource inputSource = inputStream instanceof URIConverter.ReadableInputStream ? new InputSource(
      ((URIConverter.ReadableInputStream)inputStream).asReader()) : new InputSource(inputStream);

    if (getURI() != null)
    {
      String id = getURI().toString();
      inputSource.setPublicId(id);
      inputSource.setSystemId(id);
    }
    doLoad(inputSource, options);
  }

  /**
   * Use a custom SAX parser to allow us to track the source location of 
   * each node in the source XML document.
   * @param inputSource the parsing source. Must not be null. 
   * @return the DOM document created by parsing the input stream. 
   */
  private Document getDocumentUsingSAX(InputSource inputSource)
  {
    WSDLParser wsdlParser = new WSDLParser();
    wsdlParser.parse(inputSource);

    Collection errors = wsdlParser.getDiagnostics();

    if (errors != null)
    {
      Iterator iterator = errors.iterator();

      while (iterator.hasNext())
      {
        WSDLDiagnostic wsdlDiagnostic = (WSDLDiagnostic)iterator.next();
        switch (wsdlDiagnostic.getSeverity().getValue())
        {
          case WSDLDiagnosticSeverity.FATAL:
          case WSDLDiagnosticSeverity.ERROR:
          {
            getErrors().add(wsdlDiagnostic);
            break;
          }
          case WSDLDiagnosticSeverity.WARNING:
          case WSDLDiagnosticSeverity.INFORMATION:
          {
            getWarnings().add(wsdlDiagnostic);
            break;
          }
        }
      }
    }

    Document doc = wsdlParser.getDocument();
    return doc;
  }

  /**
   * Builds a document using Xerces.
   * @param inputSource the contents to parse.
   * @param errorHandler the handled used by the parser.
   * @return a document.
   */
  private static Document getDocument(InputSource inputSource, ErrorHandler errorHandler) throws IOException
  {
    ClassLoader previousClassLoader = Thread.currentThread().getContextClassLoader();
    try
    {
      Thread.currentThread().setContextClassLoader(WSDLResourceFactoryImpl.class.getClassLoader());

      DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
      documentBuilderFactory.setNamespaceAware(true);
      documentBuilderFactory.setValidating(false);

      try
      {
        // Using a deferred DOM document in the WSDL model may cause a
        // performance problem in terms of memory consumption in particular.
        // We're attempting to use the feature which instructs the Xerces parser
        // to not use deferred DOM trees.
        // TODO Convert to use setFeature when it becomes available. The Xerces
        // versions < 2.7.1 do not fully support setFeature, so we have to use
        // setAttribute.
        documentBuilderFactory.setAttribute("http://apache.org/xml/features/dom/defer-node-expansion", Boolean.FALSE); //$NON-NLS-1$
      }
      catch (IllegalArgumentException e)
      {
        // Ignore, as the code will have to run with parsers other than Xerces.
      }

      DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();

      // TBD - Revisit
      //EntityResolver entityResolver = createEntityResolver();
      //documentBuilder.setEntityResolver(entityResolver);

      documentBuilder.setErrorHandler(errorHandler);

      Document document = documentBuilder.parse(inputSource);
      return document;
    }
    catch (ParserConfigurationException exception)
    {
      throw new IOWrappedException(exception);
    }
    catch (SAXException exception)
    {
      throw new IOWrappedException(exception);
    }
    finally
    {
      Thread.currentThread().setContextClassLoader(previousClassLoader);
    }
  }

  private boolean findDefinition(Element element)
  {
    if (WSDLConstants.nodeType(element) == WSDLConstants.DEFINITION)
    {
      handleDefinitionElement(element);
      return true;
    }
    else
    {
      boolean result = false;
      /*
       for (Node child = element.getFirstChild(); child != null; child = child.getNextSibling())
       {
       if (child instanceof Element)
       {
       if (findDefinition((Element) child))
       {
       result = true;
       }
       }
       }
       */
      return result;
    }
  }

  private void handleDefinitionElement(Element element)
  {
    Definition definition = null;
    if (element == null)
    {
      definition = WSDLFactory.eINSTANCE.createDefinition();
      ((DefinitionImpl)definition).setUseExtensionFactories(useExtensionFactories);
    }
    else
    {
      definition = DefinitionImpl.createDefinition(element, getURI().toString(), useExtensionFactories);
    }
    getContents().add(definition);
    // Do we need the next line?
    ((DefinitionImpl)definition).reconcileReferences(true);
  }

  public static void serialize(OutputStream outputStream, Document document)
  {
    serialize(outputStream, document, null);
  }

  public static void serialize(OutputStream outputStream, Document document, String encoding)
  {
    doSerialize(outputStream, document, encoding);
  }

  public static void serialize(OutputStream outputStream, Element element)
  {
    serialize(outputStream, element, null);
  }

  public static void serialize(OutputStream outputStream, Element element, String encoding)
  {
    try
    {
      doSerialize(outputStream, element, encoding);
    }
    catch (Exception exception)
    {
      exception.printStackTrace();
    }
  }

  private static void doSerialize(OutputStream outputStream, Element element, String encoding) throws IOException
  {
    try
    {
      TransformerFactory transformerFactory = TransformerFactory.newInstance();
      Transformer transformer = transformerFactory.newTransformer();

      transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
      transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
      if (encoding != null)
      {
        transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
      }

      transformer.transform(new DOMSource(element), new StreamResult(outputStream));
    }
    catch (TransformerException exception)
    {
      WSDLPlugin.INSTANCE.log(exception);
    }
  }

  private class InternalErrorHandler implements ErrorHandler
  {
    public void error(SAXParseException e)
    {
      System.out.println("WSDL PARSE ERROR: " + e);
    }

    public void fatalError(SAXParseException e)
    {
      System.out.println("WSDL PARSE FATAL ERROR: " + e);
    }

    public void warning(SAXParseException e)
    {
      System.out.println("WSDL PARSE WARNING: " + e);
    }
  }

  public void attached(EObject eObject)
  {
    super.attached(eObject);

    // we need to attach a XSDSchemaLocator in order to resolve inline schema locations
    // if there's not already one attached
    XSDSchemaLocator xsdSchemaLocator = (XSDSchemaLocator)EcoreUtil.getRegisteredAdapter(this, XSDSchemaLocator.class);
    if (xsdSchemaLocator == null)
    {
      getResourceSet().getAdapterFactories().add(new XSDSchemaLocatorAdapterFactory());
    }

    if (eObject instanceof DefinitionImpl)
    {
      DefinitionImpl definition = (DefinitionImpl)eObject;
      definition.setInlineSchemaLocations(this);
    }
  }
  /*
   public void setInlineSchemaLocations(Definition definition)
   {
   // Initialize the inline schemas location 
   Types types = definition.getETypes();
   if (types != null)
   {
   for (Iterator j = types.getEExtensibilityElements().iterator(); j.hasNext();)
   {
   XSDSchemaExtensibilityElement el = (XSDSchemaExtensibilityElement) j.next();
   XSDSchema schema = el.getSchema();
   if (schema != null)
   {  
   schema.setSchemaLocation(getURI().toString());
   }  
   }        
   }      
   }*/
} //WSDLResourceFactoryImpl
