/* * $Id: XDTPTransform.cpp,v 1.21 2006/06/29 07:26:42 ozawa Exp $ * * Copyright 2005- ONGS Inc. All rights reserved. * * author: Masanori OZAWA (ozawa@ongs.co.jp) * version: $Revision: 1.21 $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY ONGS INC ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL ONGS INC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of the ONGS Inc. * */ #include "xdtp.h" #include "XDTPTransform.h" #include "Exception.h" #include "Utilities.h" #include "xmlloader.h" #include "xmlsaver.h" #include "XMLTool.h" #include "modules/GLSDModule.h" #include "modules/GLSDModuleChecker.h" #include "modules/GLSDDocumentModule.h" #include "modules/GLSDDocumentModuleChecker.h" #include "modules/GLSDBanBunModule.h" #include "modules/GLSDBanBunModuleChecker.h" #include #define RESOURCE_TAG "res:" //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // objectwrapperの解放処理 namespace XDTP { static void objectwrapper_ustring_destractor(void *value) { Glib::ustring *string = (Glib::ustring*)value; if (string) delete string; } static void objectwrapper_mc_destractor(void *value) { XDTP_MC *mc = (XDTP_MC*)value; if (mc) delete mc; } static void objectwrapper_module_destractor(void *value) { XDTPModule *module = (XDTPModule*)value; if (module) delete module; } static void objectwrapper_checker_destractor(void *value) { XDTPChecker *checker = (XDTPChecker*)value; if (checker) delete checker; } }; //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // 雑多な処理 namespace XDTP { static Glib::ustring getOptionValue(const Glib::ustring& key, const StringList& options) { int length = key.length(); Glib::ustring result; StringList::const_iterator iter = options.begin(); StringList::const_iterator end = options.end(); for (; iter != end; iter++) { if (strncmp(key.c_str(), (*iter).c_str(), length) == 0) { result = (*iter).substr(length); if (0 < result.length() && '=' == result.at(0)) { result = result.substr(1); break; } else { result.clear(); } } } return result; } static mode_t getFileMask(const Glib::ustring& file) { struct stat sb; if (!stat(file.c_str(), &sb)) { return (sb.st_mode & 0777); } return 0600; } }; //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ using namespace XDTP; XDTPTransform::XDTPTransform() { m_XSL4OutputPos = -1; m_bSkipXMLCheck = false; m_nVerbose = 0; m_OutputType = DEFAULT_OUTPUT_TYPE; m_OutputEncoding = DEFAULT_OUTPUT_ENCODING; m_OutputMask = 0; XDTPObjectWrapper::setDestractor(OBJECT_TYPE_USTRING, objectwrapper_ustring_destractor); XDTPObjectWrapper::setDestractor(OBJECT_TYPE_XSL, objectwrapper_null_destractor); XDTPObjectWrapper::setDestractor(OBJECT_TYPE_MC, objectwrapper_mc_destractor); XDTPObjectWrapper::setDestractor(OBJECT_TYPE_XDTP_EXT_MODULE, objectwrapper_null_destractor); XDTPObjectWrapper::setDestractor(OBJECT_TYPE_XDTP_EXT_CHECKER, objectwrapper_null_destractor); XDTPObjectWrapper::setDestractor(OBJECT_TYPE_XDTP_LCL_MODULE, objectwrapper_module_destractor); XDTPObjectWrapper::setDestractor(OBJECT_TYPE_XDTP_LCL_CHECKER, objectwrapper_checker_destractor); } XDTPTransform::~XDTPTransform() { uninitialize(); } /** * 初期化処理を行います。 * 初期化後に set/get 系のメソッドを使用することは避けてください。 * 変換処理中に set/get 系メソッドを使用することはできません。 * * @return 初期化に成功した場合は true を戻します。 */ bool XDTPTransform::initialize() { bool result = true; uninitialize(); //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // モジュールのロード if (1 < m_nVerbose) { fprintf(stdout, "%s: load modules." LINE_SEP, APP_NAME); fflush(stdout); } if (!loadModules(m_libraries, m_modules, m_checkers)) { return false; } //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // モジュールの初期化 int count = 0; const int size = m_modules.size(); XDTPModule *module = NULL; if (1 < m_nVerbose) { fprintf(stdout, "%s: initiailze modules." LINE_SEP, APP_NAME); fflush(stdout); } try { for (; count < size; count++) { module = (XDTPModule*)m_modules.get(count); module->setXDTPTransform(this); module->setOutputType(m_OutputType); module->setOption(m_OptionList); module->setInputEncoding(m_InputEncoding); module->setOutputEncoding(m_OutputEncoding); } } catch (Exception exception) { uninitialize(); throw exception; } //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // 出力ファイルのアクセス権の決定 char *tmp; Glib::ustring mask = getOptionValue(OUTPUT_FILE_MASK_KEY, getOptionList()); m_OutputMask = 0; if (0 < mask.length()) { m_OutputMask = strtol(mask.c_str(), &tmp, 8); if ('\0' != *tmp || 0777 < m_OutputMask) { result = false; m_OutputMask = 0; } } if (1 < m_nVerbose) { fprintf(stdout, "%s: output file mask: %03o" LINE_SEP, APP_NAME, m_OutputMask); fflush(stdout); } return result; } /** * オブジェクトを解放する準備を行います。 * 変換処理後、オブジェクトを利用することがない場合や、状態を変更する * 場合は、事前に呼び出す必要があります。 */ void XDTPTransform::uninitialize() { unloadModules(m_libraries, m_modules, m_checkers); } /** * 変換処理を実行します。 * * @param anInput 変換元XMLファイル * @param anOutput 出力先ファイル(既存のファイルは上書きします) * @return 変換に成功した場合は true を戻します。 */ bool XDTPTransform::transform(const Glib::ustring& anInput, const Glib::ustring& anOutput) { bool result = true; XMLTool xmltool; // エラーメッセージをクリア m_ErrorMsg.clear(); if (0 < m_nVerbose) { fprintf(stdout, "%s: transform: %s" LINE_SEP, APP_NAME, anInput.c_str()); fflush(stdout); } //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // モジュールに入出力ファイルを通知する int count = 0; const int modules_size = m_modules.size(); XDTPModule *module = NULL; if (1 < m_nVerbose) { fprintf(stdout, "%s: transform: set input/output file to modules." LINE_SEP, APP_NAME); fflush(stdout); } try { for (; count < modules_size; count++) { module = (XDTPModule*)m_modules.get(count); module->setOutputFile(anOutput); module->setXMLFile(anInput); } } catch (Exception exception) { setErrorMsg(exception.what()); return false; } //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // 入力ファイルを複製 if (1 < m_nVerbose) { fprintf(stdout, "%s: transform: backup the input file." LINE_SEP, APP_NAME); fflush(stdout); } std::string tmpfile = "_xdtp_temp.XXXXXX"; int fd = Glib::mkstemp(tmpfile); if (0 > fd) { setErrorMsg("Unable to create temp file."); return false; } if (!Utilities::copy(anInput, fd)) { setErrorMsg("Unable to backup the input file. (" + anInput + ")"); close(fd); remove(tmpfile.c_str()); return false; } close(fd); //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // parse前処理 if (1 < m_nVerbose) { fprintf(stdout, "%s: transform: treatPreFile." LINE_SEP, APP_NAME); fflush(stdout); } try { for (count = 0; count < modules_size; count++) { module = (XDTPModule*)m_modules.get(count); module->treatPreFile(tmpfile); } } catch (Exception exception) { setErrorMsg(exception.what()); remove(tmpfile.c_str()); return false; } //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // parse if (1 < m_nVerbose) { fprintf(stdout, "%s: transform: parse the XML file." LINE_SEP, APP_NAME); fflush(stdout); } xmlDocPtr document = XMLLoader::load(tmpfile); if (!document) { setErrorMsg("Unable to parse the input xml file."); remove(tmpfile.c_str()); return false; } remove(tmpfile.c_str()); //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // check if (1 < m_nVerbose) { fprintf(stdout, "%s: transform: check the XML file." LINE_SEP, APP_NAME); fflush(stdout); } if (!m_bSkipXMLCheck) { const int checkers_size = m_checkers.size(); XDTPChecker *checker = NULL; for (count = 0; count < checkers_size; count++) { checker = (XDTPChecker*)m_checkers.get(count); if (!checker->checkFormat(document)) { setErrorMsg("checkFormat failed."); xmlFreeDoc(document); return false; } } } //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // parse後処理 if (1 < m_nVerbose) { fprintf(stdout, "%s: transform: treatPreDocument." LINE_SEP, APP_NAME); fflush(stdout); } try { for (count = 0; count < modules_size; count++) { module = (XDTPModule*)m_modules.get(count); module->treatPreDocument(document); } } catch (Exception exception) { setErrorMsg(exception.what()); xmlFreeDoc(document); return false; } //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // xslt { if (1 < m_nVerbose) { fprintf(stdout, "%s: transform: do xslt." LINE_SEP, APP_NAME); fflush(stdout); } int count = 0; const int size = m_XSLObjects.size(); xmlDocPtr doctmp = NULL; xsltStylesheetPtr xsl = NULL; for (; document && count < size; count++) { doctmp = NULL; xsl = parseXSL(count); if (xsl) { doctmp = xmltool.transform(document, xsl); xmlFreeDoc(document); xsltFreeStylesheet(xsl); document = doctmp; } if (!doctmp) { setErrorMsg("XSLT failed."); } } } if (!document) { return false; } //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // xslt後の処理 if (1 < m_nVerbose) { fprintf(stdout, "%s: transform: treatPostDocument." LINE_SEP, APP_NAME); fflush(stdout); } try { for (count = 0; count < modules_size; count++) { module = (XDTPModule*)m_modules.get(count); module->treatPostDocument(document); } } catch (Exception exception) { setErrorMsg(exception.what()); xmlFreeDoc(document); return false; } //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // 保存 if (1 < m_nVerbose) { fprintf(stdout, "%s: transform: save file." LINE_SEP, APP_NAME); fflush(stdout); } tmpfile = "_xdtp_temp.XXXXXX"; fd = Glib::mkstemp(tmpfile); if (0 > fd) { setErrorMsg("Unable to create temp file."); xmlFreeDoc(document); return false; } close(fd); xsltStylesheetPtr xsl = NULL; if (0 < m_XSLObjects.size()) { // 出力形式を保持するXSLファイルを決定 if (0 < m_XSL4OutputPos) xsl = parseXSL(m_XSL4OutputPos); if (!xsl) xsl = parseXSL(m_XSLObjects.size() -1); // XSLT変換処理後は、保存にスタイルシート情報が必要。 if (NULL == xsl) { setErrorMsg("Unable to load xsl file for output."); xmlFreeDoc(document); remove(tmpfile.c_str()); return false; } } if (!XMLSaver::save(tmpfile, document, xsl, m_OutputEncoding)) { setErrorMsg("Unable to save xml file. (" + tmpfile + ")"); if (xsl) xsltFreeStylesheet(xsl); xmlFreeDoc(document); remove(tmpfile.c_str()); return false; } if (xsl) xsltFreeStylesheet(xsl); xmlFreeDoc(document); //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // 保存後の処理 if (1 < m_nVerbose) { fprintf(stdout, "%s: transform: treatPostFile." LINE_SEP, APP_NAME); fflush(stdout); } try { for (count = 0; count < modules_size; count++) { module = (XDTPModule*)m_modules.get(count); module->treatPostFile(tmpfile); } } catch (Exception exception) { setErrorMsg(exception.what()); remove(tmpfile.c_str()); return false; } //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // 出力 mode_t outputMask = m_OutputMask; if (1 < m_nVerbose) { fprintf(stdout, "%s: transform: output file." LINE_SEP, APP_NAME); fflush(stdout); } // 標準出力 if (0 >= anOutput.length() || anOutput == "-") { if (!Utilities::printFile(tmpfile)) { setErrorMsg("Unable to print out."); result = false; } remove(tmpfile.c_str()); } // リネーム else { if (!Utilities::move(tmpfile, anOutput)) { setErrorMsg("Unable to move file. (" + tmpfile + " -> " + anOutput + ")"); remove(tmpfile.c_str()); result = false; } else { /* * パーミッションを変更 * 変更元ファイルは、mkstempの仕様により、通常は600である。 * リネーム時に同名のファイルが存在する場合は、その限りではない。 */ if (!outputMask) { // 変換元ファイルのパーミッションを引き継ぎます。 outputMask = getFileMask(anInput); } if (chmod(anOutput.c_str(), outputMask)) { setErrorMsg(strerror(errno)); //result = false; 現在はエラーとしません。 2006/03/02 ozawa } } } return result; } /** * 変換処理時に発生したエラーメッセージを出力します。 * エラーが発生しなかった場合は、何も表示しません。 * * @param out 出力先 */ void XDTPTransform::showErrorMsg(FILE* out) const { if (0 < m_ErrorMsg.length()) { fprintf(out, "%s: %s" LINE_SEP, APP_NAME, m_ErrorMsg.c_str()); } } /** * エラーメッセージを設定します。 * * @param aMsg エラーメッセージ */ void XDTPTransform::setErrorMsg(const Glib::ustring& aMsg) { m_ErrorMsg = aMsg; } /** * XML文章の正当性チェックをスキップします。 * * @param bCheck スキップする場合は true を指定します。 */ void XDTPTransform::skipXMLCheck(bool bCheck) { m_bSkipXMLCheck = bCheck; } /** * XML文章の正当性チェックをスキップするか調べます。 * * @return スキップする場合は true を戻します。 */ bool XDTPTransform::isXMLCheck() const { return m_bSkipXMLCheck; } /** * 変換用XSLファイルを追加します。 * * @param useOutputType 出力形式を保持し、これを利用する場合は true を指定します。 */ void XDTPTransform::addXSLFile(const Glib::ustring& aPath, bool useOutputType) { Glib::ustring *path = new Glib::ustring; if (!path) THROW("Out of memory!"); *path = aPath; m_XSLObjects.add(OBJECT_TYPE_USTRING, path); if (useOutputType) { m_XSL4OutputPos = m_XSLObjects.size() -1; } } /** * 変換用XSLオブジェクトを追加します。 * * @param aXSL XSLオブジェクト * @param useOutputType オブジェクトが出力形式を保持し、これを利用する場合は true を指定します。 */ void XDTPTransform::addXSLObject(xsltStylesheetPtr aXSL, bool useOutputType) { m_XSLObjects.add(OBJECT_TYPE_XSL, aXSL); if (useOutputType) { m_XSL4OutputPos = m_XSLObjects.size() -1; } } /** * 変換用XSLファイルの一覧をクリアします。 */ void XDTPTransform::clearXSLFile() { m_XSLObjects.clear(); m_XSL4OutputPos = -1; } /** * 変換用XSLファイルの一覧を取得します。 * * @deprecated * @return 変換用XSLファイルの一覧 */ const StringList& XDTPTransform::getXSLFileList() { int type; void *value; for (int count = 0; count < m_XSLObjects.size(); count++) { value = m_XSLObjects.get(count, &type); if (OBJECT_TYPE_USTRING == type) { __m_XSLFileList.push_back(*((Glib::ustring*)value)); } } return __m_XSLFileList; } /** * 変換用XSLファイルおよびオブジェクトの一覧を取得します。 * * @return 変換用XSLファイルおよびオブジェクトの一覧 */ const XDTPObjectWrapper& XDTPTransform::getXSLList() const { return m_XSLObjects; } /** * 変換用XDTPモジュールを追加します。 * * @param aPath XDTPモジュールへのパス */ void XDTPTransform::addXDTPModule(const Glib::ustring& aPath) { Glib::ustring *path = new Glib::ustring; if (!path) THROW("Out of memory!"); *path = aPath; m_XDTPModules.add(OBJECT_TYPE_USTRING, path); } /** * 変換用XDTPモジュールを追加します。 * * @param aModule XDTPモジュール * @param aChecker XDTPチェッカ。使用しない場合は NULL を指定できます。 */ void XDTPTransform::addXDTPModule(XDTPModule *aModule, XDTPChecker *aChecker) { if (!aModule) THROW("XDTPTransform::addXDTPModule: bad arguments."); XDTP_MC *mc = new XDTP_MC; if (!mc) THROW("Out of memory!"); mc->module = aModule; mc->checker = aChecker; m_XDTPModules.add(OBJECT_TYPE_MC, mc); } /** * 変換用XDTPモジュールをクリアします。 */ void XDTPTransform::clearXDTPModule() { m_XDTPModules.clear(); } /** * 変換用XDTPモジュールの一覧を取得します。 * * @return 変換用XDTPモジュールの一覧 */ const StringList& XDTPTransform::getXDTPModuleList() { int type; void *value; for (int count = 0; count < m_XDTPModules.size(); count++) { value = m_XDTPModules.get(count, &type); if (OBJECT_TYPE_USTRING == type) { __m_XDTPModuleList.push_back(*((Glib::ustring*)value)); } } return __m_XDTPModuleList; } /** * 変換用XDTPモジュールの一覧を取得します。 * * @return 変換用XDTPモジュールの一覧 */ const XDTPObjectWrapper& XDTPTransform::getXDTPMCList() const { return m_XDTPModules; } /** * 変換用XDTPモジュールへのオプションを追加します。 * * @param anOption 追加オプション */ void XDTPTransform::addOption(const Glib::ustring& anOption) { m_OptionList.push_back(anOption); } /** * 変換用XDTPモジュールへのオプションをクリアします。 */ void XDTPTransform::clearOption() { m_OptionList.clear(); } /** * 変換用XDTPモジュールへのオプションの一覧を取得します。 * * @return 変換用XDTPモジュールへのオプションの一覧 */ const StringList& XDTPTransform::getOptionList() const { return m_OptionList; } /** * 出力形式を指定します。 * * @param aType 出力形式 */ void XDTPTransform::setOutputType(const Glib::ustring& aType) { m_OutputType = aType.lowercase(); } /** * 出力形式を取得します。 * * @return 出力形式 */ const Glib::ustring& XDTPTransform::getOutputType() const { return m_OutputType; } /** * メッセージの表示レベルを指定します。 * * @param aMode メッセージの表示レベル */ void XDTPTransform::setVerboseMode(int aMode) { m_nVerbose = aMode; } /** * メッセージの表示レベルを取得します。 */ int XDTPTransform::getVerboseMode() const { return m_nVerbose; } /** * 入力ファイルのエンコードを指定します。 * * @param anEncoding 入力ファイルのエンコード */ void XDTPTransform::setInputEncoding(const Glib::ustring& anEncoding) { if ("getlocale" == anEncoding.lowercase()) { std::string encoding; Glib::get_charset(encoding); m_InputEncoding = encoding; } else { m_InputEncoding = anEncoding; } } /** * 入力ファイルのエンコードを取得します。 * * @return 入力ファイルのエンコード */ const Glib::ustring& XDTPTransform::getInputEncoding() const { return m_InputEncoding; } /** * 出力ファイルのエンコードを指定します。 * * @param anEncoding 出力ファイルのエンコード */ void XDTPTransform::setOutputEncoding(const Glib::ustring& anEncoding) { if ("getlocale" == anEncoding.lowercase()) { std::string encoding; Glib::get_charset(encoding); m_OutputEncoding = encoding; } else { m_OutputEncoding = anEncoding; } } /** * 出力ファイルのエンコードを取得します。 * * @return 出力ファイルのエンコード */ const Glib::ustring& XDTPTransform::getOutputEncoding() const { return m_OutputEncoding; } bool XDTPTransform::loadModules(LibraryList& libraries, XDTPObjectWrapper& modules, XDTPObjectWrapper& checkers) { bool result = true; int count = 0; int type = 0; const int size = m_XDTPModules.size(); void *value; XDTP_MC *mc; XDTPModuleLibrary *lib = NULL; XDTPModule *module = NULL; XDTPChecker *checker = NULL; Glib::ustring path; for (; count < size; count++) { value = m_XDTPModules.get(count, &type); if (type == OBJECT_TYPE_MC) { mc = (XDTP_MC*)value; modules.add(OBJECT_TYPE_XDTP_EXT_MODULE, mc->module); if (mc->checker) checkers.add(OBJECT_TYPE_XDTP_EXT_CHECKER, mc->checker); continue; } if (type != OBJECT_TYPE_USTRING) continue; path = *((Glib::ustring*)value); // 内部モジュールのロード if (4 < path.length() && path.substr(0, 4).lowercase() == RESOURCE_TAG) { path = path.substr(4); result &= loadLocalModule(path, modules, checkers); continue; } // 外部モジュールのロード lib = XDTPModuleLoader::loadModuleLibrary(path); if (!lib) { setErrorMsg("Unable to load module. (" + path + ")"); result = false; } else { module = XDTPModuleLoader::buildModule(lib); checker = XDTPModuleLoader::buildChecker(lib); if (!module) { XDTPModuleLoader::unloadModuleLibrary(lib); setErrorMsg("Unable to build module. (" + path + ")"); result = false; } else { libraries.push_back(lib); modules.add(OBJECT_TYPE_XDTP_EXT_MODULE, module); if (checker) checkers.add(OBJECT_TYPE_XDTP_EXT_CHECKER, checker); } } } if (!result) { unloadModules(libraries, modules, checkers); } return result; } void XDTPTransform::unloadModules(LibraryList& libraries, XDTPObjectWrapper& modules, XDTPObjectWrapper& checkers) { LibraryList::iterator iter = libraries.begin(); LibraryList::iterator end = libraries.end(); for (; iter != end; iter++) { XDTPModuleLoader::unloadModuleLibrary(*iter); } libraries.clear(); modules.clear(); checkers.clear(); } bool XDTPTransform::loadLocalModule(const Glib::ustring& module, XDTPObjectWrapper& modules, XDTPObjectWrapper& checkers) { if (module.lowercase() == "glsdmodule") { modules.add(OBJECT_TYPE_XDTP_LCL_MODULE, new GLSDModule()); checkers.add(OBJECT_TYPE_XDTP_LCL_CHECKER, new GLSDModuleChecker()); } else if (module.lowercase() == "glsddocumentmodule") { modules.add(OBJECT_TYPE_XDTP_LCL_MODULE, new GLSDDocumentModule()); checkers.add(OBJECT_TYPE_XDTP_LCL_CHECKER, new GLSDDocumentModuleChecker()); } else if (module.lowercase() == "glsdbanbunmodule") { modules.add(OBJECT_TYPE_XDTP_LCL_MODULE, new GLSDBanBunModule()); checkers.add(OBJECT_TYPE_XDTP_LCL_CHECKER, new GLSDBanBunModuleChecker()); } else { setErrorMsg("Unknown module name. (" + module + ")"); return false; } return true; } xsltStylesheetPtr XDTPTransform::parseXSL(int pos) { int type; void *value = m_XSLObjects.get(pos, &type); switch (type) { case OBJECT_TYPE_USTRING: return xsltParseStylesheetFile((const xmlChar *)((Glib::ustring*)value)->c_str()); case OBJECT_TYPE_XSL: return (xsltStylesheetPtr)value; default: THROW("XDTPTransform::parseXSL: Internal error! (Unknown object type)"); } return NULL; }