/** @name resmgr.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: This file contains class {\tt ResourceManager}.
                Note: code parts which should be made thread-safe
                      are marked with "mutex" (suhre)

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


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

/* ----------------------------------------------------------------------- */
/*       Interface dependencies                                            */
/* ----------------------------------------------------------------------- */
//#define DEBUG_VERBOSE
#include "uima/resmgr.hpp"
#include "apr.h"

/* ----------------------------------------------------------------------- */
/*       Implementation dependencies                                       */
/* ----------------------------------------------------------------------- */
#if (__GNUC__ < 3)
#include <clocale>
#else
#include <locale>
#endif

#if defined(_MSC_VER)
int rc = _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
// Send all reports to STDOUT
int rc1 =   _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
_HFILE h1 =  _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
int rc3 =   _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
_HFILE h2 = _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
int rc5 =   _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
_HFILE h3 = _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
#endif

#include <jni.h>
#include "uima/envvar.hpp"
#include "uima/trace.hpp"
#include "uima/dirwalk.hpp"
#include "uima/dllfile.hpp"

#include "uima/macros.h"
#include "uima/comp_ids.h"
#include "uima/res_abase.hpp"
#include "uima/res_annotator.hpp"
#include "uima/envvars.h"
#include "uima/exceptions.hpp"
#include "uima/language.hpp"
#include "uima/msg.h"
#include "uima/msgstrtab.h"
#include "uima/casexception.hpp"

#include "xercesc/util/PlatformUtils.hpp"
#include "unicode/uclean.h"
#include "uima/stltools.hpp"

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

#define JAVA_PROXY "org/apache/uima/uimacpp/UimacppAnalysisComponent"

#ifndef UIMA_VERSION
#error UIMA_VERSION must be defined in the compilation environment
#endif

/* max. number of characters in a valid filename for shipment */
const size_t UIMA_MAX_VALID_FILENAME_SIZE = 8;   /* DOS 8+3 */

XERCES_CPP_NAMESPACE_USE

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

namespace uima {

  /*
   * The class ResourceManagerAutomaticInstanceDestructor is used to call method
   * ResourceManager::deleteInstance().
   * There needs to be one instance of ResourceManagerAutomaticInstanceDestructor
   * for which the destructor will be called whenever the DLL goes out of scope.
   * This destructor will then call ResourceManager::deleteInstance()
   * automatically shutting down the resource manager.
   */
  class ResourceManagerAutomaticInstanceDestructor {
  public:
    ResourceManagerAutomaticInstanceDestructor(void) {
      ; /* do nothing */
      UIMA_TPRINT(_TEXT("INIT ..."));
    }
    ~ResourceManagerAutomaticInstanceDestructor(void) {
      UIMA_TPRINT(_TEXT("deleting ResourceManagerInstance ..."));
      ResourceManager::deleteInstance();
    }
  }
  ; /* ResourceManagerAutomaticInstanceDestructor */

  /* ----------------------------------------------------------------------- */
  /*       Globals                                                           */
  /* ----------------------------------------------------------------------- */
  

  ResourceManager * ResourceManager::cv_pclSingletonInstance = 0;
  TyProcedure               iv_traceProc;

  /* see docu for class ResourceManagerAutomaticInstanceDestructor above */
  static ResourceManagerAutomaticInstanceDestructor gs_clResourceManagerAutomaticInstanceDestructor;

  /* ----------------------------------------------------------------------- */
  /*       Function declarations                                             */
  /* ----------------------------------------------------------------------- */

  /* ----------------------------------------------------------------------- */
  /*       Macro definitions                                                 */
  /* ----------------------------------------------------------------------- */

  /* ----------------------------------------------------------------------- */
  /*       Private implementation                                            */
  /* ----------------------------------------------------------------------- */

  ResourceManager::ResourceManager(const TCHAR * cpszInstance, const TCHAR * cpszProductPrefix) :
      iv_utLastErrorId(UIMA_ERR_NONE),
      iv_locationWork("."),
      iv_locationData("."),
      iv_frameworkLogger(NULL),
      iv_logLevel(LogStream::EnMessage),
      iv_fileLogger(NULL),
      iv_loggers()
      /* ----------------------------------------------------------------------- */
  {
    
    string                    str;

    assert(EXISTS(cpszInstance));
    UIMA_TPRINT(_TEXT("instance: ") << cpszInstance);

    /* set the product prefix -- dropped this code */

    /* after the trace instance has been created and enabled,
       we may instantiate a first trace object */
    util::Trace                 clTrace(util::enTraceDetailLow, UIMA_TRACE_ORIGIN, UIMA_TRACE_COMPID_RESOURCE_MGR);
    clTrace.dump(_TEXT("UIMACPP Instance"), cpszInstance);

    /* determine xsd path ... use $UIMACPP_HOME/data instead of iv_locationData
       (which defaults to $UIMACPP_DATAPATH) as the latter is for user data. */
    bDoSchemaValidation=true;
    str = UIMA_ENVVAR_HOME;
    util::EnvironmentVariableQueryOnly clEnvVarSchemaPath(str.c_str());
    UIMA_TPRINT(_TEXT("querying envvar: ") << str.c_str());
    schemaInfo[0] = '\0';                   // Play safe
    if (clEnvVarSchemaPath.hasValue()) {
      string schemaloc = clEnvVarSchemaPath.getValue();
      UIMA_TPRINT(_TEXT("value: ") << schemaloc);
      schemaloc += "/data";

      // Create full name & transform path to absolute s.t. the XML parser can handle it
      util::Filename schemaFilename(schemaloc.c_str(),UIMA_XSD_FILENAME);
      schemaFilename.normalizeAbsolute();
      bIsSchemaAvailable = schemaFilename.isExistent();

      // schema filename must not contain blanks as the parser schemaLocation
      // attribute is a blank-separated pair of strings
      if (bIsSchemaAvailable) {
        icu::UnicodeString schemaPath(schemaFilename.getAsCString());
        schemaPath.findAndReplace(" ", "%20");
        int len = strlen(UIMA_XML_NAMESPACE);
        memcpy(schemaInfo, UIMA_XML_NAMESPACE, len);
        schemaInfo[len] = ' ';
        schemaPath.extract(0, schemaPath.length(), schemaInfo+len+1, "UTF-8");
      }
    } else {
      bIsSchemaAvailable = false;
    }

    /* determine data path */
    str = UIMA_ENVVAR_SUFFIX_DATAPATH;
    util::EnvironmentVariableQueryOnly clEnvVarDataPath(str.c_str());
    UIMA_TPRINT(_TEXT("querying envvar: ") << str.c_str());
    if (clEnvVarDataPath.hasValue()) {
      iv_locationData = util::Location(clEnvVarDataPath.getValue());
    } else {
      iv_locationData = util::Location(".");
    }
    assert(EXISTS(iv_locationData));
    UIMA_TPRINT(_TEXT("value: ") << iv_locationData);

    /* determine work path */
    str = UIMA_ENVVAR_SUFFIX_WORKPATH;
    util::EnvironmentVariableQueryOnly clEnvVarWorkPath(str.c_str());
    UIMA_TPRINT(_TEXT("querying envvar: ") << str.c_str());
    if (clEnvVarWorkPath.hasValue()) {
      iv_locationWork = util::Location(clEnvVarWorkPath.getValue());
    } else {
      iv_locationWork = util::Location();                   // TMP directory
    }
    assert(EXISTS(iv_locationWork));
    UIMA_TPRINT(_TEXT("value: ") << iv_locationWork);

    /* determine iv_bIgnoreAnnotatorPathSpec flag */       // ** Dropped this

    // we must make sure real values our ini files are read with . (e.g. "0.5")
    setlocale(LC_NUMERIC, "C");

    UIMA_TPRINT(_TEXT("workpath: ") << (const char*)iv_locationWork);
    UIMA_TPRINT(_TEXT("datapath: ") << (const char*)iv_locationData);
    clTrace.dump(_TEXT("Work path"), iv_locationWork.getAsCString());
    clTrace.dump(_TEXT("Data path"), iv_locationData.getAsCString());

#ifndef NDEBUG
    /* check whether the message string table apepars correct and consistent */
    ErrorMessage                clMsgSig1(UIMA_MSG_ID_SIGNATURE_BEGIN);
    ErrorMessage                clMsgSig2(UIMA_MSG_ID_SIGNATURE_END);

    /* the signatures at the start and end must match! */
    if (strcmp(clMsgSig1.asString().c_str(), clMsgSig2.asString().c_str()) != 0) {
      cerr << "Internal build error"
      << "String table in uima/msgstrtab.h is inconsistent!" << endl
      << "Signature Id BEGIN: " << clMsgSig1.getMessageID() << endl
      << "   Found message: "   << clMsgSig1 << endl
      << "Signature Id END: "   << clMsgSig2.getMessageID() << endl
      << "   Found message:"    << clMsgSig2 << endl;
      assert(false);
    }
#endif

    //read environement setting to register Sofa Stream handlers
    //mappings are specified as:
    //         UIMACPP_STREAMHANDLERS=urischeme:dllfilename urischeme2:dllfilename2
    str = UIMA_ENVVAR_SOFA_STREAM_HANDLERS;
    util::EnvironmentVariableQueryOnly clEnvVarStreamHandlers(str.c_str());
    UIMA_TPRINT(_TEXT("querying envvar: ") << str.c_str());
    TCHAR *  cpszURIToStreamHandlerMap=0;
    if (clEnvVarStreamHandlers.hasValue()) {
      cpszURIToStreamHandlerMap = (TCHAR*) clEnvVarStreamHandlers.getValue();
      assert(EXISTS(cpszURIToStreamHandlerMap));
      UIMA_TPRINT(_TEXT("value: ") << cpszURIToStreamHandlerMap);

      TCHAR * urischeme =0;
      TCHAR * handlerdllfilename=0;

      TCHAR * curptr = cpszURIToStreamHandlerMap;
      TCHAR * chptr  = 0;

      //parse string to get each uri:dllfilename pair ... separated by one or more spaces
      while (curptr != NULL) {
        while (*curptr == ' ')
          ++curptr;
        chptr = strchr(curptr, ':');

        int len = chptr - curptr;
        if (len > 0) {
          //get the uri scheme
          urischeme = new char[len+1];
          strncpy(urischeme, curptr, len);
          urischeme[len]='\0';

          curptr = chptr+1;
          chptr = strchr(curptr, ' ');
          if (chptr == NULL)
            len =  strlen(curptr);
          else
            len = chptr - curptr;

          //get dll and register
          if (len > 0) {
            handlerdllfilename = new char[len+1];
            strncpy(handlerdllfilename,curptr, len);
            handlerdllfilename[len]='\0';
            registerStreamHandlerForURIScheme(urischeme, handlerdllfilename);
            delete [] handlerdllfilename;
          }
          delete [] urischeme;
        }

        //move ptr
        if (chptr==NULL)
          curptr=chptr;
        else
          curptr = chptr+1;
      }  //while
    } //if

    //register the Sofa Data Stream Handler for the 'file' URI scheme
    //registerStreamHandlerForURIScheme("file", "sofafilestreamhandler");
  }


  void ResourceManager::deleteResourceList( TyResourceList & rResList) {
    int i;
    for (i=rResList.size()-1; i>=0 ;--i) {
      ResourceABase * rResource = rResList[i];
      UIMA_TPRINT("   deleting resource " << i << ": " << rResource);
      assert( EXISTS(rResource) );
      UIMA_TPRINT("       key: " << rResource->getKey() );
      UIMA_TPRINT("  de-initing resource");
      rResource->deInit();
      assert( EXISTS(rResource) );
      delete rResource;
      rResList[i] = NULL;
      UIMA_TPRINT("   done");
    }
  }


  /* ----------------------------------------------------------------------- */
  /*       Protected implementation                                          */
  /* ----------------------------------------------------------------------- */

  /* ----------------------------------------------------------------------- */
  /*       Public implementation                                             */
  /* ----------------------------------------------------------------------- */

  ResourceManager::~ResourceManager(void)
  /* ----------------------------------------------------------------------- */
  {
    UIMA_TPRINT("Searching...");
    // it is important that annotators are deInited (unloaded)
    // last due to the following scenario:
    // a annotator p derives a class from ResourceABase, the class definition
    // is thus only valid during the lifetime in p. However, all resources
    // are handled by the resource manager. After the annotator is unloaded
    // the virtual function table of the resource is destroyed
    // (MS .NET and MSVC++6), thus the deInit() call fails.

    // use this factory just to get the kind string
    internal::ResourceAnnotatorFileFactory annotatorFactory;
    icu::UnicodeString const & crAnnotatorKind = annotatorFactory.getKind();

    TyResourceList * pAnnotators = NULL;

    TyResources::iterator it;
    for (it = iv_resources.begin(); it != iv_resources.end(); ++it) {
      TyResourceList & rResList = (*it).second;
      UIMA_TPRINT("Deleting all resources with kind: " << (*it).first);
      if ( (*it).first == crAnnotatorKind ) {
        assert( pAnnotators == NULL );
        pAnnotators = & rResList;
      } else {
        deleteResourceList( rResList );
      }
    }

    TyURIStreamHandlers::iterator ite;
    for (ite = iv_streamhandlers.begin(); ite != iv_streamhandlers.end(); ++ite) {
      util::Filename * pDllFile = (util::Filename *) (*ite).second;
      UIMA_TPRINT("Deleting stream handler dll file for uri scheme: " << (*ite).first);
      delete pDllFile;
    }


    // unload annotators at last, if any
    if (pAnnotators != NULL) {
      deleteResourceList( *pAnnotators );
    }
    iv_resources.clear();

    UIMA_TPRINT("  ...seek and destroy!");
  }

  const util::Location & ResourceManager::getLocationWork(void) const
  /* ----------------------------------------------------------------------- */
  {
    assert(iv_utLastErrorId != UIMA_ERR_RESMGR_OUT_OF_MEMORY );
    return iv_locationWork;
  }

  const util::Location & ResourceManager::getLocationData(void) const
  /* ----------------------------------------------------------------------- */
  {
    assert(iv_utLastErrorId != UIMA_ERR_RESMGR_OUT_OF_MEMORY );
    return iv_locationData;
  }

  void ResourceManager::setNewLocationWork(const util::Location & crclLocation)
  /* ----------------------------------------------------------------------- */
  {
    util::Trace                 clTrace(util::enTraceDetailLow, UIMA_TRACE_ORIGIN, UIMA_TRACE_COMPID_RESOURCE_MGR);

    assert(iv_utLastErrorId != UIMA_ERR_RESMGR_OUT_OF_MEMORY );
    clTrace.dump(_TEXT("New work path"), crclLocation.getAsCString());
    iv_locationWork = crclLocation;
  }

  void ResourceManager::setNewLocationData(const util::Location & crclLocation)
  /* ----------------------------------------------------------------------- */
  {
    util::Trace                 clTrace(util::enTraceDetailLow, UIMA_TRACE_ORIGIN, UIMA_TRACE_COMPID_RESOURCE_MGR);

    assert(iv_utLastErrorId != UIMA_ERR_RESMGR_OUT_OF_MEMORY );
    clTrace.dump(_TEXT("New data path"), crclLocation.getAsCString());
    iv_locationData = crclLocation;
  }

  util::DllProcLoaderFile * ResourceManager::requestAnnotatorFile(const util::Filename & crclFilename)
  /* ----------------------------------------------------------------------- */
  {
    internal::ResourceAnnotatorFileFactory factory;

    icu::UnicodeString us( crclFilename.getAsCString() );
    uima::ErrorInfo errInfo;
    internal::ResourceAnnotatorFile const * cpResAnnotatorFile = (internal::ResourceAnnotatorFile const *) getResource( us, factory, errInfo);
	if (errInfo.getErrorId()==UIMA_ERR_NONE && EXISTS(cpResAnnotatorFile)) {
      return cpResAnnotatorFile->getAnnotatorFile();
	} else {
		std::string err = "ResourceManager::requestAnnotatorFile() failed to find ";
        err += crclFilename;
        ResourceManager::getInstance().getLogger().logError(err);
        UIMA_EXC_THROW_NEW(Uima_runtime_error,
                              errInfo.getErrorId(),
                              errInfo.getMessage(),
                              errInfo.getMessage().getMessageID(),
                              ErrorInfo::unrecoverable);
	}
  }

  ResourceABase const * ResourceManager::getResource(uima::Language const & crLang,
      ResourceFactoryABase const & crFactory,
      ErrorInfo & rErrInfo) {
    icu::UnicodeString us( crLang.asString().c_str() );
    return getResource(us, crFactory, rErrInfo);
  }

  ResourceABase const * ResourceManager::getResource(icu::UnicodeString const & crKey,
      ResourceFactoryABase const & crFactory,
      uima::ErrorInfo & rErrInfo) {
//      assertWithMsg(false, "Implement caching functionality");
    icu::UnicodeString const & crKind = crFactory.getKind();
    UIMA_TPRINT("Creating resource with kind " << crKind << " and key " << crKey);
    // acquire mutex lock

    TyResourceList & rResList = iv_resources[crKind];
    ResourceABase * pResource = NULL;

    TyResourceList::const_iterator cit;
    for (cit = rResList.begin(); cit != rResList.end(); ++cit) {
      if ( (*cit)->getKey() == crKey ) {
        pResource = *cit;
        break;
      }
    }
    // if the resource was not found
    if (pResource == NULL) {
      pResource = crFactory.createResource( crKey );
      pResource->init(rErrInfo);
      if (rErrInfo.getErrorId() != UIMA_ERR_NONE) {
        delete pResource;
        return NULL;
      }
      rResList.push_back(pResource);
    }
    // release mutex lock
    UIMA_TPRINT("...resource created: " << pResource);
    assert( EXISTS( pResource ) );
    return pResource;

  }

  void ResourceManager::enableSchemaValidation(bool aEnable) {
    bDoSchemaValidation=aEnable;
  }

  bool ResourceManager::doSchemaValidation() {
    return bDoSchemaValidation;
  }

  bool  ResourceManager::isSchemaAvailable() {
    return bIsSchemaAvailable;
  }

  LogStream::EnEntryType  ResourceManager::getLoggingLevel() {
    return iv_logLevel;
  }

  void ResourceManager::setLoggingLevel(LogStream::EnEntryType level) {
    iv_logLevel=level;
  }

  TCHAR const *  ResourceManager::getSchemaInfo() {
    return schemaInfo;
  }

  void ResourceManager::registerLogger(Logger * pLogger) {
 	iv_loggers.push_back(pLogger);
  }

  vector<Logger*> & ResourceManager::getLoggers() {
 	return iv_loggers;
  }
  
  void ResourceManager::unregisterLogger(Logger * pLogger) {
      vector<Logger*>::iterator iter;
 	for (iter=iv_loggers.begin(); iter  != iv_loggers.end();iter++) {
  		if (*iter == pLogger) {
		    iv_loggers.erase(iter);
                return;
            }
      }
 	
      string str = "Logger not found. Could not unregister.";
      UIMA_EXC_THROW_NEW(Uima_runtime_error,
                  UIMA_MSG_ID_LITERAL_STRING,
                  UIMA_MSG_ID_LITERAL_STRING,
                  ErrorMessage(UIMA_MSG_ID_LITERAL_STRING, str.c_str()),
                  ErrorInfo::unrecoverable);

  }


  void ResourceManager::registerFactory(icu::UnicodeString const & crKind, ResourceFactoryABase & crFactory) {
    iv_resourceFactories.insert(TyResourceFactories::value_type(crKind, &crFactory));
  }

  void ResourceManager::deRegisterFactory(icu::UnicodeString const & crKind, ResourceFactoryABase & crFactory) {
    TyResourceFactories::iterator it = iv_resourceFactories.find(crKind);
    if (it != iv_resourceFactories.end()) {
      assert( (*it).second == &crFactory );
      iv_resourceFactories.erase(it);
    }
  }

  ResourceABase const * ResourceManager::getResource(
    icu::UnicodeString const & crKey,
    icu::UnicodeString const & crKind,
    ErrorInfo &                errorInfo) {
    TyResourceFactories::iterator  it = iv_resourceFactories.find(crKind);
    if (it == iv_resourceFactories.end()) {
      errorInfo.setErrorId(UIMA_ERR_RESMGR_NO_RESOURCE_FACTORY_FOR_KIND);
      return NULL;
    }
    assert(it->first == crKind);
    assert(EXISTS(it->second));

    return getResource(crKey, *(it->second), errorInfo);
  }


  /**
   * Register a stream handler dll filename for a given URI scheme.
   * A URI scheme may be registered only once in an application. 
   */
  util::Filename const * ResourceManager::registerStreamHandlerForURIScheme(TCHAR const * uriScheme,
      TCHAR const * dllFilename) {
    std::string uriSchemeStr(uriScheme);
    TyURIStreamHandlers::iterator  ite;
    ite = iv_streamhandlers.find(uriSchemeStr);
    if (ite != iv_streamhandlers.end() ) {
      ErrorMessage errMsg = ErrorMessage(UIMA_MSG_ID_EXC_SCHEMEHANDLER_DUPLICATE);
      errMsg.addParam(dllFilename);
      errMsg.addParam(uriScheme);
      UIMA_EXC_THROW_NEW(SofaDataStreamException,
                         UIMA_ERR_SOFADATASTREAM,
                         errMsg,
                         UIMA_MSG_ID_EXCON_SOFADATASTREAM,
                         ErrorInfo::unrecoverable);
    }
    util::Filename * pDllFile = new util::Filename(dllFilename);
    if (pDllFile == NULL) {
      ErrorMessage errMsg = ErrorMessage(UIMA_MSG_ID_EXC_SCHEMEHANDLER_LOAD);
      errMsg.addParam(dllFilename);
      errMsg.addParam(uriScheme);
      UIMA_EXC_THROW_NEW(SofaDataStreamException,
                         UIMA_ERR_SOFADATASTREAM,
                         errMsg,
                         UIMA_MSG_ID_EXCON_SOFADATASTREAM,
                         ErrorInfo::unrecoverable);
    }
    iv_streamhandlers.insert(TyURIStreamHandlers::value_type(uriSchemeStr, pDllFile));
    return(util::Filename*)pDllFile;
  }


  /**
   * Return the dll file registered for the specified uri scheme if found.
   * Otherwise, returns null.
   */
  util::Filename const * ResourceManager::getStreamHandlerForURIScheme(std::string uriScheme) {

    TyURIStreamHandlers::iterator  ite = iv_streamhandlers.find(uriScheme);
    if (ite == iv_streamhandlers.end() ) {
      return NULL;
    } else {
      return(util::Filename *) ite->second;
    }

  }




  /* ----------------------------------------------------------------------- */
  /*       Static implementation                                             */
  /* ----------------------------------------------------------------------- */

  /* static */ ResourceManager & ResourceManager::createInstance(const TCHAR * cpszInstance, const TCHAR * cpszProductPrefix)
  /* ----------------------------------------------------------------------- */
  {
    // acquire mutex
    if (NOTEXISTS(cv_pclSingletonInstance)) {

      // First must initialize apr (re-init is OK)
      apr_status_t rv = apr_initialize();
      if (rv != APR_SUCCESS) {
        char errBuf[256];
        apr_strerror(rv, errBuf, sizeof(errBuf));
        UIMA_EXC_THROW_NEW(AprFailureException,
                           UIMA_ERR_APR_FAILURE,
                           ErrorMessage(UIMA_MSG_ID_EXC_APR_ERROR,errBuf),
                           ErrorMessage(UIMA_MSG_ID_EXCON_APR_FUNCTION,"apr_initialize"),
                           ErrorInfo::unrecoverable);
      }

      cv_pclSingletonInstance = new ResourceManager(cpszInstance, cpszProductPrefix);
      assert(EXISTS(cv_pclSingletonInstance));
      // Initialize the ICU
      UErrorCode status = U_ZERO_ERROR;
      u_init(&status);
      if (status != U_ZERO_ERROR) {
        char buffer[100];
        sprintf(buffer, "ICU init failed with %d", status);
        UIMA_EXC_THROW_NEW(Uima_runtime_error,
                           UIMA_MSG_ID_LITERAL_STRING,
                           UIMA_MSG_ID_LITERAL_STRING,
                           ErrorMessage(UIMA_MSG_ID_LITERAL_STRING, buffer),
                           ErrorInfo::unrecoverable);
      }
      try {
        // initialize XML4C stuff
        XMLPlatformUtils::Initialize();
      } catch (XMLException& ) {
        cv_pclSingletonInstance->iv_utLastErrorId = UIMA_ERR_RESMGR_COULD_NOT_INITIALIZE_XML4C;
        assertWithMsg(false, "XML4C initialization failed");
      }

      //create the fileLogger if UIMACPP_LOGFILE env variable is set
      /* determine log file name */
      string str = UIMA_ENVVAR_LOG_FILE;
      util::EnvironmentVariableQueryOnly clEnvVarLogFilePath(str.c_str());
      UIMA_TPRINT(_TEXT("querying envvar: ") << str.c_str());
      if (clEnvVarLogFilePath.hasValue()) {
        const TCHAR *  cpszLogFile = clEnvVarLogFilePath.getValue();
        UIMA_TPRINT(_TEXT("value: ") << cpszLogFile);

        /* create an instance of FileLogger and register it. */
        cv_pclSingletonInstance->iv_fileLogger = new FileLogger(cpszLogFile);

        if (cv_pclSingletonInstance->iv_fileLogger == NULL) {   //Need to handle this better
          //cerr << "Could not open the log file " << cpszLogFile << endl;
          str = "Could not create FileLogger";
          str += cpszLogFile;
          UIMA_EXC_THROW_NEW(Uima_runtime_error,
                           UIMA_MSG_ID_LITERAL_STRING,
                           UIMA_MSG_ID_LITERAL_STRING,
                           ErrorMessage(UIMA_MSG_ID_LITERAL_STRING, str.c_str()),
                           ErrorInfo::unrecoverable);
        } else {
          cv_pclSingletonInstance->registerLogger(cv_pclSingletonInstance->iv_fileLogger);
        }
      } 

      //instantiate framework logger
      cv_pclSingletonInstance->iv_frameworkLogger = new LogFacility(UnicodeString("org.apache.uima.cpp"), cv_pclSingletonInstance->iv_logLevel);

      cv_pclSingletonInstance->iv_frameworkLogger->logMessage("ResourceManager Instance created.");
    } // release mutex
    UIMA_TPRINT("ResourceManager instance created");
    return(*cv_pclSingletonInstance);
  }

  /* static */ ResourceManager & ResourceManager::getInstance(void)
  /* ----------------------------------------------------------------------- */
  {
    assert(EXISTS(cv_pclSingletonInstance));
    return(*cv_pclSingletonInstance);
  }

  /* static */ bool ResourceManager::hasInstance(void)
  /* ----------------------------------------------------------------------- */
  {
    return((bool) EXISTS(cv_pclSingletonInstance));
  }
  /* ----------------------------------------------------------------------- */
  void ResourceManager::deleteInstance(void) {
    UIMA_TPRINT(_TEXT("deleting..."));
    // acquire mutex
    if (cv_pclSingletonInstance != 0 ) {
      try {
        XMLPlatformUtils::Terminate();
      }
      catch (const XMLException& ) {
        cv_pclSingletonInstance->iv_utLastErrorId = UIMA_ERR_RESMGR_COULD_NOT_TERMINATE_XML4C;
        assertWithMsg(false, "XML4C termination failed");
      }
     
      if (cv_pclSingletonInstance->iv_frameworkLogger != NULL) {
        delete cv_pclSingletonInstance->iv_frameworkLogger;
      }

      if (cv_pclSingletonInstance->iv_fileLogger != NULL) {
        delete cv_pclSingletonInstance->iv_fileLogger;
      }

      assert(EXISTS(cv_pclSingletonInstance));
      delete cv_pclSingletonInstance;
      cv_pclSingletonInstance = 0;

      // Terminate apr (undo matching apr_initialize)
      apr_terminate();
//#if !defined( NDEBUG ) && defined(_MSC_VER) && defined(_CRTDBG_MAP_ALLOC)   
//      int iRetVal = _CrtDumpMemoryLeaks();
//#endif
      UIMA_TPRINT("ResMgr instance deleted");
    }
    assert( cv_pclSingletonInstance == 0 );
    // release mutex
  }

  bool
  ResourceManager::createFilenameForLanguage(Language & rclLanguage,
      const TCHAR * cpszExtension,
      bool bUseAlternateTerritories,
      const util::Location & crclDirToUse,
      util::Filename & rclFilename)  {
    string                     str(rclLanguage.asString());

    assert(EXISTS(cpszExtension));
    assert(*cpszExtension == _TEXT('.'));              /* extension starts with a dot */
    /* we need to restrict ourselves to DOS 8+3 filenames */
    if (str.length() > UIMA_MAX_VALID_FILENAME_SIZE) {
      str.resize(UIMA_MAX_VALID_FILENAME_SIZE);
    }
    /* create a filename based on the complete language name
       e.g. language is en-us and file is en-us.tsw */
    util::Filename              clFilename(crclDirToUse, str.c_str(), cpszExtension);
    UIMA_TPRINT(_TEXT("1st Filename: '") << clFilename.getAsCString() << _TEXT("' existent: ") << clFilename.isExistent());
    if (clFilename.isExistent()) {
      rclFilename = clFilename;
      return(true);                                   /* done! */
    } else {
      /* if the user did specify a territory, we could look a little bit further... */
      if (rclLanguage.hasTerritory()) {
        /* give it another try using just the language name without the territory
           e.g. language is en-us and file is en.tsw */
        clFilename.setNew( crclDirToUse,rclLanguage.getLanguageCode(),cpszExtension );
        UIMA_TPRINT(_TEXT("2nd Filename: '") << clFilename.getAsCString() << _TEXT("' existent: ") << clFilename.isExistent());
      }
    }
    if (bUseAlternateTerritories && !clFilename.isExistent()) {
      /* give it another try using just the language name without the territory
         e.g. language is en and file is en-us.tsw
         this means a little bit more effort - we need to walk the directory */
      util::DirectoryWalk     clDirWalk(crclDirToUse.getAsCString());
      string                  strSearchPattern(rclLanguage.getLanguageCode());

      strSearchPattern += _TEXT("*");
      strSearchPattern += cpszExtension;
      UIMA_TPRINT(_TEXT("Search pattern: '") << strSearchPattern.c_str() << _TEXT("'"));
      while (clDirWalk.isValid()) {
        if (clDirWalk.isFile() && clDirWalk.matchesWildcardPattern(strSearchPattern.c_str())) {
          clFilename.setNewName(clDirWalk.getNameWithoutPath());
          break;
        }
        clDirWalk.setToNext();
      }
      UIMA_TPRINT(_TEXT("3rd Filename: '") << clFilename.getAsCString() << _TEXT("' existent: ") << clFilename.isExistent());
    }
    rclFilename = clFilename;
    return(clFilename.isExistent());
  }

  LogFacility & ResourceManager::getLogger() {
    return *iv_frameworkLogger;
  }

  icu::UnicodeString ResourceManager::resolveFilename(icu::UnicodeString const & filename, icu::UnicodeString const & lastFilename) {
    auto_array<char> filename_cstr( new char[filename.length() + 1] );
    filename.extract(0, filename.length(), filename_cstr.get());

    auto_array<char> lastFilename_cstr( new char[lastFilename.length() + 1] );
    lastFilename.extract(0, lastFilename.length(), lastFilename_cstr.get());

    //build the filename
    util::Filename fileLoc(filename_cstr.get());

    // don't try our search mimic for absolute paths
    if (fileLoc.isAbsolute()) {
      return filename;
    }

    // relative path to the current directory
    if (fileLoc.isExistent()) {
      return filename;
    }

    // try in the same directory as lastFilename
    util::Filename locSameDirAsLast(lastFilename_cstr.get());
    locSameDirAsLast.setNewName(filename_cstr.get());

    if (locSameDirAsLast.isExistent()) {
      return locSameDirAsLast.getAsCString();
    }

    // try in the UIMACPP data directory
    util::Location const & fallbackLoc = ResourceManager::getInstance().getLocationData();

    std::string nameInDataDir( fallbackLoc.getAsCString() );
    nameInDataDir += filename_cstr.get();
    util::Filename fileInDataDir( nameInDataDir.c_str() );
    fileInDataDir.normalizeAbsolute();                // Normalize to native / or \ separators
    if (fileInDataDir.isExistent()) {
      return icu::UnicodeString(fileInDataDir.getAsCString());
    }

    nameInDataDir.clear();
    nameInDataDir = fallbackLoc.getAsCString();
    nameInDataDir += "descriptors/";
    nameInDataDir += filename_cstr.get();
    fileInDataDir.setNew(nameInDataDir.c_str());
    fileInDataDir.normalizeAbsolute();
    if (fileInDataDir.isExistent()) {
      return icu::UnicodeString(fileInDataDir.getAsCString());
    }

    nameInDataDir.clear();
    nameInDataDir = fallbackLoc.getAsCString();
    nameInDataDir += "specifiers/";
    nameInDataDir += filename_cstr.get();
    fileInDataDir.setNew(nameInDataDir.c_str());
    fileInDataDir.normalizeAbsolute();
    if (fileInDataDir.isExistent()) {
      return icu::UnicodeString(fileInDataDir.getAsCString());
    }

    // return the original filename here, will trigger an XML exception since
    // it couldn't be found anywhere
    return filename;
  }



}

/* <EOF> */




