/** \file xcasdeserializer.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/xcasdeserializer.hpp"
#include "uima/xcasdeserializer_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                                                   */
/* ----------------------------------------------------------------------- */
using namespace std;
namespace uima {

  XCASDeserializer::XCASDeserializer() {}

  XCASDeserializer::~XCASDeserializer() {}

  void XCASDeserializer::deserialize(char const * xcasFilename, CAS & cas) {

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

  }

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

  void XCASDeserializer::deserialize(char const * xcasFilename, CAS & cas,  uima::AnnotatorContext  * const ctx) {

    XMLCh* native = XMLString::transcode(xcasFilename);
    LocalFileInputSource fileIS (native);
	XMLString::release(&native);
    XCASDeserializer::deserialize(fileIS, cas, ctx);

  }

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

    //register content handler
    XCASDeserializerHandler * contentHandler = new XCASDeserializerHandler(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";

      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);
      throw exc;
    }
    catch (const SAXParseException& e) {
      char* message = XMLString::transcode(e.getMessage());
      cerr << "SaxParseException message is: \n"
      << message << "\n";
      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);
      throw exc;
    }

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

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

    //register content handler
    XCASDeserializerHandler * contentHandler = new XCASDeserializerHandler(cas, ctx);
    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";

      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);
      throw exc;
    }
    catch (const SAXParseException& e) {
      char* message = XMLString::transcode(e.getMessage());
      cerr << "SaxParseException message is: \n"
      << message << "\n";
      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);
      throw exc;
    }

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


}




