/** \file xmideserializer.cpp .
-----------------------------------------------------------------------------


 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.

-----------------------------------------------------------------------------

   Description:

-----------------------------------------------------------------------------


-------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------- */
/*       Include dependencies                                              */
/* ----------------------------------------------------------------------- */
#include "uima/pragmas.hpp"
#include <memory>

#include <xercesc/sax2/XMLReaderFactory.hpp>
#include <xercesc/sax2/SAX2XMLReader.hpp>
#include <xercesc/sax2/DefaultHandler.hpp>


#include "uima/xmlerror_handler.hpp"
#include "uima/xmideserializer.hpp"
#include "uima/xmideserializer_handler.hpp"

#include "uima/arrayfs.hpp"
#include "uima/lowlevel_indexrepository.hpp"
#include "uima/lowlevel_indexiterator.hpp"
#include "uima/internal_casimpl.hpp"
#include "uima/internal_fspromoter.hpp"
#include "uima/fsindexrepository.hpp"
#include "uima/annotator_context.hpp"

#include "uima/msg.h"
#include "uima/resmgr.hpp"

/* ----------------------------------------------------------------------- */
/*       Constants                                                         */
/* ----------------------------------------------------------------------- */


/* ----------------------------------------------------------------------- */
/*       Forward declarations                                              */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Types / Classes                                                   */
/* ----------------------------------------------------------------------- */

namespace uima {

  XmiDeserializer::XmiDeserializer() {}

  XmiDeserializer::~XmiDeserializer() {}

  void XmiDeserializer::deserialize(char const * xmiFilename, CAS & cas) {

    XMLCh* native = XMLString::transcode(xmiFilename);
	LocalFileInputSource fileIS (native);
	XMLString::release(&native);
    XmiDeserializer::deserialize(fileIS, cas);

  }

  void XmiDeserializer::deserialize(UnicodeString & xmiFilename, CAS & cas) {
    char buff[1024];
    xmiFilename.extract(0, xmiFilename.length(), buff);
    XMLCh* native = XMLString::transcode(buff);
    LocalFileInputSource fileIS (native);
	XMLString::release(&native);
    XmiDeserializer::deserialize(fileIS, cas);
  }

  void XmiDeserializer::deserialize(InputSource const & crInputSource, CAS & cas) {
    // Create a SAX2 parser object.
    SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();

    //register content handler
    XmiDeserializerHandler * contentHandler = new XmiDeserializerHandler(cas, NULL);
    parser->setContentHandler(contentHandler);

    //register error handler
    XMLErrorHandler* errorHandler = new XMLErrorHandler();
    parser->setErrorHandler(errorHandler);

    // Parse the XML document.
    // Document content sent to registered ContentHandler instance.
    try {
      parser->parse(crInputSource);
    } catch (const XMLException& e) {
      char* message = XMLString::transcode(e.getMessage());
      cerr << "XMLException message is: \n"
      << message << "\n";
	  delete message;

      ErrorInfo errInfo;
      errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
      ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR);
      assertWithMsg(sizeof(XMLCh) == sizeof(UChar), "Port required");
      msg.addParam((UChar const *) e.getMessage() );
      msg.addParam( 0 );
      msg.addParam( 0 );
      errInfo.setMessage(msg);
      errInfo.setSeverity(ErrorInfo::unrecoverable);
      ExcIllFormedInputError exc(errInfo);
      delete contentHandler;
      delete errorHandler;
      delete parser;
      throw exc;
    }
    catch (const SAXParseException& e) {
      char* message = XMLString::transcode(e.getMessage());
      cerr << "SaxParseException message is: \n"
      << message << "\n";
	  delete message;

      ErrorInfo errInfo;
      errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
      ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR);
      assertWithMsg(sizeof(XMLCh) == sizeof(UChar), "Port required");
      msg.addParam((UChar const *) e.getMessage() );
      msg.addParam( 0 );
      msg.addParam( 0 );
      errInfo.setMessage(msg);
      errInfo.setSeverity(ErrorInfo::unrecoverable);
      ExcIllFormedInputError exc(errInfo);
      delete contentHandler;
      delete errorHandler;
      delete parser; 
      throw exc;
    } catch (Exception e) {
       ErrorInfo errInfo;
      errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
      ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR);
      assertWithMsg(sizeof(XMLCh) == sizeof(UChar), "Port required");
      msg.addParam( e.asString() );
      msg.addParam( 0 );
      msg.addParam( 0 );
      errInfo.setMessage(msg);
      errInfo.setSeverity(ErrorInfo::unrecoverable);
      ExcIllFormedInputError exc(errInfo);
      delete contentHandler;
      delete errorHandler;
      delete parser;
      throw exc;

    } catch (...) {
       ErrorInfo errInfo;
      errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
      ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR);
      assertWithMsg(sizeof(XMLCh) == sizeof(UChar), "Port required");
      msg.addParam("Unknown Exception when parsing XMI document." );
      msg.addParam( 0 );
      msg.addParam( 0 );
      errInfo.setMessage(msg);
      errInfo.setSeverity(ErrorInfo::unrecoverable);
      ExcIllFormedInputError exc(errInfo);
      if (contentHandler != NULL) {
        delete contentHandler;
      }
      if (errorHandler !=NULL) {
        delete errorHandler;
      }
      if (parser != NULL) {
        delete parser;
      }
      throw exc;
    }

    // Delete the parser instance and handlers
    delete contentHandler;
    delete errorHandler;
    delete parser;
  }


  void XmiDeserializer::deserialize(InputSource const & crInputSource, 
								CAS & cas,
								XmiSerializationSharedData & sharedData) {
    // Create a SAX2 parser object.
    SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();

    //register content handler
    XmiDeserializerHandler * contentHandler = new XmiDeserializerHandler(cas, &sharedData);
    parser->setContentHandler(contentHandler);

    //register error handler
    XMLErrorHandler* errorHandler = new XMLErrorHandler();
    parser->setErrorHandler(errorHandler);

    // Parse the XML document.
    // Document content sent to registered ContentHandler instance.
    try {
      parser->parse(crInputSource);
    } catch (const XMLException& e) {
      char* message = XMLString::transcode(e.getMessage());
      cerr << "XMLException message is: \n"
      << message << "\n";
	  delete message;

      ErrorInfo errInfo;
      errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
      ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR);
      assertWithMsg(sizeof(XMLCh) == sizeof(UChar), "Port required");
      msg.addParam((UChar const *) e.getMessage() );
      msg.addParam( 0 );
      msg.addParam( 0 );
      errInfo.setMessage(msg);
      errInfo.setSeverity(ErrorInfo::unrecoverable);
      ExcIllFormedInputError exc(errInfo);
      delete contentHandler;
    delete errorHandler;
    delete parser;
      throw exc;
    }
    catch (const SAXParseException& e) {
      char* message = XMLString::transcode(e.getMessage());
      cerr << "SaxParseException message is: \n"
      << message << "\n";
	  delete message;

      ErrorInfo errInfo;
      errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
      ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR);
      assertWithMsg(sizeof(XMLCh) == sizeof(UChar), "Port required");
      msg.addParam((UChar const *) e.getMessage() );
      msg.addParam( 0 );
      msg.addParam( 0 );
      errInfo.setMessage(msg);
      errInfo.setSeverity(ErrorInfo::unrecoverable);
      ExcIllFormedInputError exc(errInfo);
      delete contentHandler;
    delete errorHandler;
    delete parser;
      throw exc;
    }  catch (Exception e) {
       ErrorInfo errInfo;
      errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
      ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR);
      assertWithMsg(sizeof(XMLCh) == sizeof(UChar), "Port required");
      msg.addParam( e.asString() );
      msg.addParam( 0 );
      msg.addParam( 0 );
      errInfo.setMessage(msg);
      errInfo.setSeverity(ErrorInfo::unrecoverable);
      ExcIllFormedInputError exc(errInfo);
      delete contentHandler;
      delete errorHandler;
      delete parser;
      throw exc;

    } catch (...) {
       ErrorInfo errInfo;
      errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
      ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR);
      assertWithMsg(sizeof(XMLCh) == sizeof(UChar), "Port required");
      msg.addParam("Unknown Exception when parsing XMI document." );
      msg.addParam( 0 );
      msg.addParam( 0 );
      errInfo.setMessage(msg);
      errInfo.setSeverity(ErrorInfo::unrecoverable);
      ExcIllFormedInputError exc(errInfo);
      if (contentHandler != NULL) {
        delete contentHandler;
      }
      if (errorHandler !=NULL) {
        delete errorHandler;
      }
      if (parser != NULL) {
        delete parser;
      }
      throw exc;
    }


    // Delete the parser instance and handlers
    delete contentHandler;
    delete errorHandler;
    delete parser;
  }

 void XmiDeserializer::deserialize(char const * xmiFilename, 
									CAS & cas,
									XmiSerializationSharedData & sharedData) {

    XMLCh* native = XMLString::transcode(xmiFilename);
	LocalFileInputSource fileIS (native);
	XMLString::release(&native);
    XmiDeserializer::deserialize(fileIS, cas, sharedData);

 }

 void XmiDeserializer::deserialize(UnicodeString & xmiFilename, 
									CAS & cas,
									XmiSerializationSharedData & sharedData) {
    char buff[1024];
    xmiFilename.extract(0, xmiFilename.length(), buff);
    XMLCh* native = XMLString::transcode(buff);
    LocalFileInputSource fileIS (native);
	XMLString::release(&native);
    XmiDeserializer::deserialize(fileIS, cas, sharedData);
  }
}





