| /** @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 */ |
| /* ----------------------------------------------------------------------- */ |
| using namespace std; |
| 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> */ |
| |
| |
| |
| |