/*******************************************************************************
 * Copyright (c) 2001, 2004 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.validation.internal.wsdl11;

import java.io.Reader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.wsdl.Import;
import javax.wsdl.WSDLException;

import org.apache.xerces.impl.XMLErrorReporter;
import org.apache.xerces.parsers.DOMParser;
import org.apache.xerces.parsers.StandardParserConfiguration;
import org.apache.xerces.xni.XNIException;
import org.eclipse.wst.wsdl.validation.internal.util.MessageGenerator;
import org.eclipse.wst.wsdl.validation.internal.xml.LineNumberDOMParser;
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;

import com.ibm.wsdl.DefinitionImpl;
import com.ibm.wsdl.util.StringUtils;

/**
 * A WSDL reader that supports cyclic WSDL imports, schema imports and inline schemas.
 * This reader is based on the WSDLReaderImpl from WSDL4J. 
 */
public class WSDLReaderImpl
{
  protected MessageGenerator messagegenerator;
  protected IWSDL11ValidationInfo wsdlvalinfo;
  
  /**
   * Constructor.
   * 
   * @param wsdlvalinfo The WSDL 1.1 validation info object to use.
   */
  public WSDLReaderImpl(IWSDL11ValidationInfo wsdlvalinfo)
  {
    this.wsdlvalinfo = wsdlvalinfo;
  }
  
  /**
   * Parse the root document. This method will find all imports and parse them as 
   * well creating a WSDLDocument for each unique WSDL file. This method supports
   * cyclic WSDL import statements such that file A can import file B and file B
   * can import file A.
   * 
   * @param documentBaseURI The base URI of the root document.
   * @param defEl The definition element of the root document.
   * @return An array of WSDLDocuments containing all of the unique files in the description.
   * @throws WSDLException
   */
  protected WSDLDocument[] parseDocument(String documentBaseURI, Element defEl) throws WSDLException
  {
    int initialImportArraySize = 20;
    List[] filesAtDepth = new ArrayList[initialImportArraySize];
    Map filesImporting = new Hashtable();
    SortedSet parsedImports = new TreeSet();
    SortedSet importsToParse = new TreeSet();
    int maxdepth = 0;

    WSDLDocument rootdoc = new WSDLDocument(documentBaseURI, defEl, 0, messagegenerator, wsdlvalinfo);
    String targetNamespace = rootdoc.getDefinition().getTargetNamespace();
    ImportHolder rootImport = new ImportHolder(targetNamespace, documentBaseURI, documentBaseURI, rootdoc, 0, null, messagegenerator, wsdlvalinfo);
    rootImport.createWSDLImport(rootdoc);
    parsedImports.add(rootImport);
    List rootList = new ArrayList();
    filesImporting.put(rootImport.getLocation(), new ArrayList());
    rootList.add(rootdoc);
    filesAtDepth[0] = rootList;
    importsToParse.addAll(rootdoc.getImports());
    Set imps = rootdoc.getImports();
    Iterator impIter = imps.iterator();
    while(impIter.hasNext())
    {
      ImportHolder imp = (ImportHolder)impIter.next();
      List tempList = new ArrayList();
      tempList.add(imp.getImportingDocument());
      filesImporting.put(imp.getLocation(), tempList);
    }
    
    while(!importsToParse.isEmpty())
    {
      ImportHolder imp = (ImportHolder)importsToParse.first();
      // It's important to initialize the import here so each import
      // is only created once. In the case of reciprical imports this
      // avoids an infinite loop.
      imp.initialize();
      WSDLDocument impDoc = imp.getWSDLDocument();
      
      importsToParse.remove(imp);
      
      parsedImports.add(imp);
      
      // Add new imports to the list of imports to parse.
      // Remove all the imports that have already been parsed.
      if(impDoc != null)
      {
        // Increate import array if necessary.
        if(imp.getDepth() >= initialImportArraySize)
        {
          List[] tempArray = new List[filesAtDepth.length + initialImportArraySize];
          System.arraycopy(filesAtDepth, 0, tempArray, 0, filesAtDepth.length);
          filesAtDepth = tempArray;
        }
        // Create the list for the depth if necessary.
        int impDepth = imp.getDepth();
        if(filesAtDepth[impDepth] == null)
        {
          if(maxdepth < impDepth)
          {
            maxdepth = impDepth;
          }
          filesAtDepth[impDepth] = new ArrayList();
        }
        filesAtDepth[imp.getDepth()].add(impDoc);
        
        Set imports = impDoc.getImports();
        ImportHolder[] importsArray = (ImportHolder[])imports.toArray(new ImportHolder[imports.size()]);
        for(int i = 0; i < importsArray.length; i++)
        {
          ImportHolder ih = importsArray[i];
          // If already parsed, add the definition importing this file to the list.
          if(filesImporting.containsKey(ih.getLocation()))
          {
            ((List)filesImporting.get(ih.getLocation())).add(ih.getImportingDocument());
          }
          // Otherwise add it to the list to parse.
          else
          {
            // Add this import to the list of files importing list.
            List tempList = new ArrayList();
            tempList.add(ih.getImportingDocument());
            filesImporting.put(ih.getLocation(), tempList);
            importsToParse.add(ih);
          }
        }
      }
    }
    
    // Add all of the imports to the respective documents.
    Iterator importElementsIter = parsedImports.iterator();
    while(importElementsIter.hasNext())
    {
      ImportHolder imp = (ImportHolder)importElementsIter.next();
      List files = (List)filesImporting.get(imp.getLocation());
      Iterator filesIter = files.iterator();
      while(filesIter.hasNext())
      {
        WSDLDocument doc = (WSDLDocument)filesIter.next();
        
        DefinitionImpl def = (DefinitionImpl)doc.getDefinition();
        Import impElem = imp.getImport();
        if(impElem != null)
        {
          def.addImport(impElem);
          if(!imp.isWSDLFileImport())
          {
            doc.addSchemas(imp.getSchemas());
          }
        }
        
      }
    }
    
    // Parse the WSDL documents.
    // Parse the Messages.
    for(int i = maxdepth; i >=0; i--)
    {
      List docs = filesAtDepth[i];
      Iterator docsIter = docs.iterator();
      while(docsIter.hasNext())
      {
        WSDLDocument doc = (WSDLDocument)docsIter.next();
        doc.parseMessages();
      }
    }
    // Parse the Porttypes.
    for(int i = maxdepth; i >=0; i--)
    {
      List docs = filesAtDepth[i];
      Iterator docsIter = docs.iterator();
      while(docsIter.hasNext())
      {
        WSDLDocument doc = (WSDLDocument)docsIter.next();
        doc.parsePorttypes();
      }
    }
    // Parse the Bindings.
    for(int i = maxdepth; i >=0; i--)
    {
      List docs = filesAtDepth[i];
      Iterator docsIter = docs.iterator();
      while(docsIter.hasNext())
      {
        WSDLDocument doc = (WSDLDocument)docsIter.next();
        doc.parseBindings();
      }
    }
    // Parse the Services.
    for(int i = maxdepth; i >=0; i--)
    {
      List docs = filesAtDepth[i];
      Iterator docsIter = docs.iterator();
      while(docsIter.hasNext())
      {
        WSDLDocument doc = (WSDLDocument)docsIter.next();
        doc.parseServices();
      }
    }
    // Parse the Extensibility Elements.
    for(int i = maxdepth; i >=0; i--)
    {
      List docs = filesAtDepth[i];
      Iterator docsIter = docs.iterator();
      while(docsIter.hasNext())
      {
        WSDLDocument doc = (WSDLDocument)docsIter.next();
        doc.parseExtensibilityElements();
      }
    }
    
    List wsdlDocs = new ArrayList();
    for(int i = maxdepth; i >=0; i--)
    {
      List docs = filesAtDepth[i];
      Iterator docsIter = docs.iterator();
      while(docsIter.hasNext())
      {
        WSDLDocument doc = (WSDLDocument)docsIter.next();
        wsdlDocs.add(doc);
      }
    }
    
    return (WSDLDocument[])wsdlDocs.toArray(new WSDLDocument[wsdlDocs.size()]);
  }
  
  /**
   * Get the WSDL document.
   * 
   * @param inputSource The source of the document being retrieved.
   * @param desc The description of the document being retrieved.
   * @return The WSDL document.
   * @throws WSDLException
   */
  public static Document getDocument(InputSource inputSource, String desc) throws WSDLException
  {
    try
    {
      StandardParserConfiguration configuration = new StandardParserConfiguration()
      {
        protected XMLErrorReporter createErrorReporter()
        {
          return new XMLErrorReporter()
          {
            public void reportError(String domain, String key, Object[] arguments, short severity) throws XNIException
            {
              boolean reportError = true;
              if (key.equals("PrematureEOF"))
               {         
                reportError = false;
              }

              if (reportError)
               {
                super.reportError(domain, key, arguments, severity);
              }
            }
          };
        }
      };
      
      ErrorHandler errorHandler = new ErrorHandler()
      {
            /* (non-Javadoc)
           * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
           */
          public void error(SAXParseException exception) throws SAXException
          {
            // TODO Auto-generated method stub

          }
          /* (non-Javadoc)
           * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
           */
          public void fatalError(SAXParseException exception) throws SAXException
          {
            // TODO Auto-generated method stub

          }
          /* (non-Javadoc)
           * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
           */
          public void warning(SAXParseException exception) throws SAXException
          {
            // TODO Auto-generated method stub

          }
      };

      DOMParser builder = new LineNumberDOMParser(configuration);
      builder.setErrorHandler(errorHandler);
      builder.parse(inputSource);
      Document doc = builder.getDocument();

      return doc;
    }
    catch (Throwable t)
    {
      throw new WSDLException(WSDLException.PARSER_ERROR, "Problem parsing '" + desc + "'.", t);
    }
  }

  /**
   * Read a WSDL document using a context URI and file URI.
   * 
   * @param contextURI The context URI to use.
   * @param wsdlURI The WSDL URI to use.
   * @return An array of WSDLDocuments.
   * @throws WSDLException
   */
  public WSDLDocument[] readWSDL(String contextURI, String wsdlURI) throws WSDLException
  {
    try
    {
      URL contextURL = (contextURI != null) ? StringUtils.getURL(null, contextURI) : null;
      URL url = StringUtils.getURL(contextURL, wsdlURI);
      Reader reader = StringUtils.getContentAsReader(url);
      InputSource inputSource = new InputSource(reader);
      Document doc = getDocument(inputSource, wsdlURI);
      reader.close();
      WSDLDocument[] wsdlDocs = null;
      // only parse the document if it isn't empty
      if(doc.getDocumentElement() != null)
       {      
        wsdlDocs = readWSDL(url.toString(), doc);
      }
      return wsdlDocs;
    }
    catch (WSDLException e)
    {
      throw e;
    }
    catch (Throwable t)
    {
      throw new WSDLException(
        WSDLException.OTHER_ERROR,
        "Unable to resolve imported document at '" + wsdlURI + "'.",
        t);
    }
  }

  /**
   * Set the messagegenerator for the reader.
   * 
   * @param mg The message generator to set.
   */
  public void setMessageGenerator(MessageGenerator mg)
  {
    messagegenerator = mg;
  }
  
  /**
   * Read the WSDL document accessible via the specified
   * URI into a WSDL definition.
   *
   * @param wsdlURI A URI pointing to a WSDL file.
   * @return An array of WSDLDocuments.
   */
  public WSDLDocument[] readWSDL(String wsdlURI) throws WSDLException
  {
    return readWSDL(null, wsdlURI);
  }

  /**
   * Read the WSDL document described by a URI and its definitions element.
   * 
   * @param documentBaseURI The URI of the WSDL document.
   * @param definitionsElement The definitions element for the WSDL document.
   * @return An array of WSDLDocuments.
   * @throws WSDLException
   */
  protected WSDLDocument[] readWSDL(String documentBaseURI,
                                Element definitionsElement)
                                  throws WSDLException
  {
    return parseDocument(documentBaseURI, definitionsElement);
  }

  /**
   * Read the specified WSDL document.
   *
   * @param documentBaseURI The document base URI.
   * @param wsdlDocument The WSDL document.
   * @return An array of WSDLDocuments.
   */
  public WSDLDocument[] readWSDL(String documentBaseURI, Document wsdlDocument)
    throws WSDLException
  {
    return readWSDL(documentBaseURI, wsdlDocument.getDocumentElement());
  }
  
  
  
}

