/*
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License");  you may not use this file except in 
 * compliance with the License.  You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 *
 * The Original Code is Protege-2000.
 *
 * The Initial Developer of the Original Code is Stanford University. Portions
 * created by Stanford University are Copyright (C) 2007.  All Rights Reserved.
 *
 * Protege was developed by Stanford Medical Informatics
 * (http://www.smi.stanford.edu) at the Stanford University School of Medicine
 * with support from the National Library of Medicine, the National Science
 * Foundation, and the Defense Advanced Research Projects Agency.  Current
 * information about Protege can be obtained at http://protege.stanford.edu.
 *
 */


package edu.stanford.smi.protegex.owl.swrl.bridge.builtins.swrlxml;

import org.jdom.*;
import org.jdom.output.*;
import org.jdom.input.*;
import org.jdom.filter.*;

import java.io.*;
import java.util.*;
import java.net.*;

public class XMLProcessor
{
  private XMLOutputter serializer;

  public XMLProcessor()
  {
    serializer = new XMLOutputter(Format.getPrettyFormat());
  } // XMLProcessor

  /**
   ** Method that writes an XML file from an instance of a Document.
   */
  public void generateXMLFile(Document doc, String outputXMLFileName) throws XMLProcessorException
  {
    OutputStream xmlStream = createOutputXMLStream(outputXMLFileName);

    if ((doc == null) || !doc.hasRootElement()) throw new XMLProcessorException("document is empty");

    try {
      serializer.output(doc, xmlStream);
      xmlStream.close();
    } catch (IOException e) {
      throw new XMLProcessorException("error writing XML file '" + outputXMLFileName + "': " + e.getMessage());
    } // try
  } // generateXMLFile

  /**
   ** Method that writes an XML string from an instance of a Document.
   */
  public String generateXMLString(Document doc) throws XMLProcessorException
  {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

    if ((doc == null) || !doc.hasRootElement()) throw new XMLProcessorException("document is empty");

    try {
      serializer.output(doc, outputStream);
    } catch (IOException e) {
      throw new XMLProcessorException("error writing XML string: " + e.getMessage());
    } // try

    return outputStream.toString();
  } // generateXMLString

  /**
   ** Method that reads a simple XML file and generates an instance of a Document from it.
   */
  public Document processXMLStream(String inputXMLStreamName) throws XMLProcessorException
  {
    Document doc = null;
    try {
      SAXBuilder builder = new SAXBuilder();
      InputStream xmlStream = createInputXMLStream(inputXMLStreamName);
      doc = builder.build(xmlStream);
      xmlStream.close();
    } catch (Exception e) {
      throw new XMLProcessorException("error opening XML file '" + inputXMLStreamName + "': " + e.getMessage());
    } // try

    return doc;
  } // processXMLStream

  /**
   ** Method that reads an XML string and generates an instance of a Document from it.
   */
  public Document processXMLString(String inputXMLString) throws XMLProcessorException
  {
    Document doc = null;
    try {
      SAXBuilder builder = new SAXBuilder();
      doc = builder.build(new StringReader(inputXMLString));
    } catch (Exception e) {
      throw new XMLProcessorException("error processing XML string: " + e.getMessage());
    } // try
    
    return doc;
  } // processXMLString 

  private OutputStream createOutputXMLStream(String outputXMLStreamName) throws XMLProcessorException
  {
    OutputStream xmlStream = null;

    try {
      xmlStream = new FileOutputStream(outputXMLStreamName);
    } catch (IOException e) {
      throw new XMLProcessorException("error creating XML serializer for XML stream '" + outputXMLStreamName + "': " + e.getMessage());
    } // try

    return xmlStream;
  } // createOutputXMLStream

  private InputStream createInputXMLStream(String inputXMLStreamName) throws XMLProcessorException
  {
    InputStream xmlStream = null;

    try {
      URL url = new URL(inputXMLStreamName);
      String protocol = url.getProtocol();
      if (protocol.equals("file")) {
        String path = url.getPath();
        xmlStream = new FileInputStream(path);
      } else xmlStream = url.openStream();
    } catch (MalformedURLException e) {
      throw new XMLProcessorException("invalid URL for XML stream '" + inputXMLStreamName + "': " + e.getMessage());
    } catch (IOException e) {
      throw new XMLProcessorException("IO error opening XML stream '" + inputXMLStreamName + "': " + e.getMessage());
    } // try

    return xmlStream;
  } // createOutputXMLStream

} // XMLProcessor
