From a7af6d3f2871be0d4d522ce925c3f286e2676614 Mon Sep 17 00:00:00 2001 From: erickson Date: Wed, 9 Nov 2005 21:45:46 +0000 Subject: [PATCH] moving to new xmlbuilder code for XML / DTD / locale stuff git-svn-id: svn://svn.open-ils.org/ILS/trunk@1985 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- Open-ILS/src/apachemods/Makefile | 30 +- Open-ILS/src/apachemods/apachetools.c | 18 +- Open-ILS/src/apachemods/apachetools.h | 10 + Open-ILS/src/apachemods/mod_xmlbuilder.c | 337 +++++++++++++++++++++++ Open-ILS/src/apachemods/mod_xmlbuilder.h | 106 +++++++ Open-ILS/src/apachemods/mod_xmltools.c | 200 -------------- Open-ILS/src/apachemods/mod_xmltools.h | 51 ---- Open-ILS/src/apachemods/xmltools.c | 149 ---------- Open-ILS/src/apachemods/xmltools.h | 37 --- 9 files changed, 479 insertions(+), 459 deletions(-) create mode 100644 Open-ILS/src/apachemods/mod_xmlbuilder.c create mode 100644 Open-ILS/src/apachemods/mod_xmlbuilder.h delete mode 100644 Open-ILS/src/apachemods/mod_xmltools.c delete mode 100644 Open-ILS/src/apachemods/mod_xmltools.h delete mode 100644 Open-ILS/src/apachemods/xmltools.c delete mode 100644 Open-ILS/src/apachemods/xmltools.h diff --git a/Open-ILS/src/apachemods/Makefile b/Open-ILS/src/apachemods/Makefile index 816a885b34..324cb5b00a 100644 --- a/Open-ILS/src/apachemods/Makefile +++ b/Open-ILS/src/apachemods/Makefile @@ -1,14 +1,13 @@ LDLIBS += -lxml2 -lopensrf -lxslt -all: mod_xmltools.so mod_ils_rest_gateway.so +all: mod_xmlbuilder.so mod_ils_rest_gateway.so -install: mod_xmltools-install mod_ils_rest_gateway-install libfieldmapper-install +install: mod_xmlbuilder-install mod_ils_rest_gateway-install libfieldmapper-install -mod_xmltools.o: mod_xmltools.c mod_xmltools.h +mod_xmlbuilder.o: mod_xmlbuilder.h mod_xmlbuilder.c apachetools.o: apachetools.c apachetools.h -xmltools.o: xmltools.c xmltools.h json_xml.o: json_xml.c json_xml.h fieldmapper_lookup.o: fieldmapper_lookup.c fieldmapper_lookup.h ils_rest_gateway.o: mod_rest_gateway.c mod_rest_gateway.h @@ -20,9 +19,9 @@ fieldmapper_lookup.c: # ------------------------------------------------------ -mod_xmltools.so: mod_xmltools.o apachetools.o xmltools.o +mod_xmlbuilder.so: mod_xmlbuilder.o apachetools.o @echo $@ - $(CC) $(LDFLAGS) $(LDLIBS) -shared -W1 apachetools.o xmltools.o mod_xmltools.o -o $@ + $(CC) $(LDFLAGS) $(LDLIBS) -shared -W1 apachetools.o mod_xmlbuilder.o -o $@ libfieldmapper.so: fieldmapper_lookup.o @echo $@ @@ -58,23 +57,12 @@ mod_ils_rest_gateway-install: echo "-----------------------------------------------"; echo "" -mod_xmltools-install: - $(APXS2) -i -a -n mod_xmltools mod_xmltools.so - echo "-----------------------------------------------"; - echo -e "* Important * : Change httpd.conf from this: \n \ - LoadModule mod_xmltools_module modules/mod_xmltools.so \n \ - to this: \n \ - LoadModule mod_xmltools modules/mod_xmltools.so" - echo -e "Supported configuration options:\ - \nXMLToolsDefaultLocale \ - \nXMLToolsLocaleDir \ - \nXMLToolsPreXSL \ - \nXMLToolsPostXSL " - echo "-----------------------------------------------"; - echo "" +mod_xmlbuilder-install: + $(APXS2) -i -a -n xmlbuilder mod_xmlbuilder.so + clean: echo $@ - /bin/rm -f *.o xmltools mod_xmltools.so libfieldmapper.so mod_ils_rest_gateway.so + /bin/rm -f *.o mod_xmlbuilder.so libfieldmapper.so mod_ils_rest_gateway.so /bin/rm -f fieldmapper_lookup.c diff --git a/Open-ILS/src/apachemods/apachetools.c b/Open-ILS/src/apachemods/apachetools.c index 2891d159d1..204a192fb0 100644 --- a/Open-ILS/src/apachemods/apachetools.c +++ b/Open-ILS/src/apachemods/apachetools.c @@ -110,4 +110,20 @@ char* apacheGetFirstParamValue(string_array* params, char* key) { return NULL; } - + +int apacheDebug( char* msg, ... ) { + VA_LIST_TO_STRING(msg); + fprintf(stderr, "%s\n", VA_BUF); + fflush(stderr); + return 0; +} + + +int apacheError( char* msg, ... ) { + VA_LIST_TO_STRING(msg); + fprintf(stderr, "%s\n", VA_BUF); + fflush(stderr); + return HTTP_INTERNAL_SERVER_ERROR; +} + + diff --git a/Open-ILS/src/apachemods/apachetools.h b/Open-ILS/src/apachemods/apachetools.h index d082c5778a..94edf7c9d4 100644 --- a/Open-ILS/src/apachemods/apachetools.h +++ b/Open-ILS/src/apachemods/apachetools.h @@ -4,9 +4,12 @@ #include "http_protocol.h" #include "apr_compat.h" #include "apr_strings.h" +#include "apr_reslist.h" + #include "string_array.h" #include "utils.h" +#include "opensrf/utils.h" #ifndef APACHE_TOOLS_H #define APACHE_TOOLS_H @@ -33,5 +36,12 @@ string_array* apacheGetParamValues(string_array* params, char* key); char* must be freed by the caller */ char* apacheGetFirstParamValue(string_array* params, char* key); +/* Writes msg to stderr, flushes stderr, and returns 0 */ +int apacheDebug( char* msg, ... ); + +/* Writes to stderr, flushe stderr, and returns HTTP_INTERNAL_SERVER_ERROR; + */ +int apacheError( char* msg, ... ); + #endif diff --git a/Open-ILS/src/apachemods/mod_xmlbuilder.c b/Open-ILS/src/apachemods/mod_xmlbuilder.c new file mode 100644 index 0000000000..25be733479 --- /dev/null +++ b/Open-ILS/src/apachemods/mod_xmlbuilder.c @@ -0,0 +1,337 @@ +#include "mod_xmlbuilder.h" + +char* __xmlBuilderDynamicLocale = NULL; + + +/* set the base DTD directory */ +static const char* xmlBuilderSetBaseDir(cmd_parms *params, void *cfg, const char *arg) { + xmlBuilderConfig* config = ap_get_module_config( + params->server->module_config, &xmlbuilder_module ); + config->baseDir = (char*) arg; + return NULL; +} + +static const char* xmlBuilderSetDefaultLocale( + cmd_parms* params, void* cfg, const char* arg ) { + xmlBuilderConfig* config = ap_get_module_config( + params->server->module_config, &xmlbuilder_module ); + config->defaultLocale = (char*) arg; + return NULL; +} + +static const char* xmlBuilderSetDefaultDtd( + cmd_parms* params, void* cfg, const char* arg ) { + xmlBuilderConfig* config = ap_get_module_config( + params->server->module_config, &xmlbuilder_module ); + config->defaultDtd = (char*) arg; + return NULL; +} + + +static const char* xmlBuilderSetLocaleParam( + cmd_parms* params, void* cfg, const char* arg ) { + xmlBuilderConfig* config = ap_get_module_config( + params->server->module_config, &xmlbuilder_module ); + config->localeParam = (char*) arg; + return NULL; +} + + +static const char* xmlBuilderSetPostXSL( + cmd_parms* params, void* cfg, const char* arg ) { + xmlBuilderConfig* config = ap_get_module_config( + params->server->module_config, &xmlbuilder_module ); + config->postXSL = xsltParseStylesheetFile((xmlChar*) arg); + if( config->postXSL == NULL ) + apacheDebug("Unable to parse postXSL stylesheet: %s. No postXSL will be performed", arg); + return NULL; +} + +static const command_rec xmlBuilderCommands[] = { + AP_INIT_TAKE1( MODXMLB_CONFIG_LOCALE, + xmlBuilderSetDefaultLocale, NULL, ACCESS_CONF, "Default Locale"), + AP_INIT_TAKE1( MODXMLB_CONFIG_BASE_DIR, + xmlBuilderSetBaseDir, NULL, ACCESS_CONF, "Base Directory"), + AP_INIT_TAKE1( MODXMLB_CONFIG_POST_XSL, + xmlBuilderSetPostXSL, NULL, ACCESS_CONF, "Post XSL"), + AP_INIT_TAKE1( MODXMLB_CONFIG_DEFAULT_DTD, + xmlBuilderSetDefaultDtd, NULL, ACCESS_CONF, "Default DTD"), + AP_INIT_TAKE1( MODXMLB_CONFIG_LOCALE_PARAM, + xmlBuilderSetLocaleParam, NULL, ACCESS_CONF, "Default DTD"), + {NULL} +}; + +static void* xmlBuilderCreateConfig( apr_pool_t* p, server_rec* s ) { + xmlBuilderConfig* config = + (xmlBuilderConfig*) apr_palloc( p, sizeof(xmlBuilderConfig) ); + config->baseDir = MODXMLB_DEFAULT_BASE_DIR; + config->defaultLocale = MODXMLB_DEFAULT_LOCALE; + config->defaultDtd = NULL; + config->postXSL = NULL; + config->localeParam = MODXMLB_DEFAULT_LOCALE_PARAM; + return (void*) config; +} + + +/* Child Init handler ----------------------------------------------------------- */ +static void xmlBuilderChildInit( apr_pool_t *p, server_rec *s ) { +} + +static int xmlBuilderHandler( request_rec* r ) { + + if( strcmp(r->handler, MODULE_NAME ) ) return DECLINED; + + xmlBuilderConfig* config = ap_get_module_config( + r->server->module_config, &xmlbuilder_module ); + + r->allowed |= (AP_METHOD_BIT << M_GET); + r->allowed |= (AP_METHOD_BIT << M_POST); + ap_set_content_type(r, "text/html; charset=utf-8"); + + string_array* params = apacheParseParms(r); + char* locale = apacheGetFirstParamValue(params, config->localeParam); + if(locale) __xmlBuilderDynamicLocale = locale; + char* XMLFile = r->filename; + + apacheDebug("Processing file %s", XMLFile); + xmlDocPtr doc = xmlBuilderProcessFile( XMLFile, config ); + if(!doc) return apacheError( "Unable to parse XML file %s", XMLFile ); + + /* apply the post XSL */ + if(config->postXSL) { + xmlDocPtr newdoc; + newdoc = xsltApplyStylesheet(config->postXSL, doc, NULL ); + + if(newdoc == NULL) { + apacheDebug("Error applying postXSL... skipping."); + } else { + xmlFreeDoc(doc); + doc = newdoc; + } + } + + char* docXML = xmlDocToString( doc, 1 ); + ap_rputs(docXML, r); + free(docXML); + xmlFreeDoc( doc ); + doc = NULL; + xmlCleanupCharEncodingHandlers(); + xmlCleanupParser(); + + return OK; +} + + +/* frees the collected DTD's */ +static void __xmlBuilderFreeDtdHash( char* key, void* item ) { + if(!item) return; + xmlFreeDtd( item ); +} + + +xmlDocPtr xmlBuilderProcessFile( char* filename, xmlBuilderConfig* config ) { + if(!filename) { + apacheError( "No XML file provided" ); return NULL; } + + xmlBuilderContext context; + context.config = config; + context.doc = xmlNewDoc( BAD_CAST "1.0" ); + context.dtdHash = osrfNewHash(); + context.entHash = osrfNewHash(); + context.nodeList = osrfNewList(); + context.xmlError = 0; + context.xmlFile = filename; + context.dtdHash->freeItem = &__xmlBuilderFreeDtdHash; + + /* pre-parse the default dtd if defined */ + if( config->defaultDtd ) + xmlBuilderAddDtd( config->defaultDtd, &context ); + + xmlParserCtxtPtr parserCtx; + + parserCtx = xmlCreatePushParserCtxt(xmlBuilderSaxHandler, &context, "", 0, NULL); + xmlCtxtReadFile( parserCtx, filename, NULL, XML_PARSE_RECOVER ); + + xmlFreeParserCtxt( parserCtx ); + osrfListFree(context.nodeList); + osrfHashFree(context.entHash); + osrfHashFree(context.dtdHash); + return context.doc; +} + + +void xmlBuilderStartElement( void* context, const xmlChar *name, const xmlChar **atts ) { + apacheDebug( "Starting element: %s", name ); + xmlBuilderContext* ctx = (xmlBuilderContext*) context; + + xmlNodePtr node = NULL; + + /* process xincludes as a sub-doc */ + if( !strcmp( name, "xi:include" ) ) { + + char* href = strdup(xmlSaxAttr( atts, "href" )); + if(href) { + + /* find the relative path for the xinclude */ + if(href[0] != '/') { + int len = strlen(ctx->xmlFile) + strlen(href) + 1; + char buf[len]; + bzero(buf, len); + strcpy( buf, ctx->xmlFile ); + int i; + for( i = strlen(buf); i != 0; i-- ) { + if( buf[i] == '/' ) break; + buf[i] = '\0'; + } + strcat( buf, href ); + free(href); + href = strdup(buf); + } + + + apacheDebug( "Processing xinclude %s", href ); + xmlDocPtr subDoc = xmlBuilderProcessFile( href, ctx->config ); + node = xmlDocGetRootElement( subDoc ); + } + + if(!node) { + apacheError("Unable to parse xinclude: %s", href ); + return; + } + + } else { + node = xmlNewNode(NULL, name); + xmlAddAttrs( node, atts ); + } + + + xmlNodePtr parent = osrfListGetIndex( + ctx->nodeList, ctx->nodeList->size - 1 ); + + if( parent ) xmlAddChild( parent, node ); + else xmlDocSetRootElement(ctx->doc, node); + + osrfListPush( ctx->nodeList, node ); +} + +void xmlBuilderEndElement( void* context, const xmlChar* name ) { + xmlBuilderContext* ctx = (xmlBuilderContext*) context; + osrfListPop( ctx->nodeList ); +} + + +void xmlBuilderHandleCharacter(void* context, const xmlChar *ch, int len) { + xmlBuilderContext* ctx = (xmlBuilderContext*) context; + xmlNodePtr node = osrfListGetIndex( + ctx->nodeList, ctx->nodeList->size - 1 ); + + if(node) { + xmlNodePtr txt = xmlNewTextLen(ch, len); + xmlAddChild( node, txt ); + } + +} + + +void xmlBuilderParseError( void* context, const char* msg, ... ) { + xmlBuilderContext* ctx = (xmlBuilderContext*) context; + VA_LIST_TO_STRING(msg); + apacheDebug( "Parser Error Occurred: %s", VA_BUF); + ctx->xmlError = 1; +} + + +xmlEntityPtr xmlBuilderGetEntity( void* context, const xmlChar* name ) { + xmlBuilderContext* ctx = (xmlBuilderContext*) context; + return osrfHashGet( ctx->entHash, name ); +} + + +void xmlBuilderExtSubset( void* blob, + const xmlChar* name, const xmlChar* extId, const xmlChar* sysId ) { + + xmlBuilderContext* context = (xmlBuilderContext*) blob; + if( context->config->defaultDtd ) return; /* only use the default if defined */ + xmlBuilderAddDtd( sysId, context ); +} + + + +void xmlBuilderAddDtd( const char* sysId, xmlBuilderContext* context ) { + + if(!sysId) return; + if( osrfHashGet( context->dtdHash, sysId ) ) return; /* already parsed this hash */ + + /* use the dynamic locale if defined... default locale instead */ + char* locale; + if(__xmlBuilderDynamicLocale) locale = __xmlBuilderDynamicLocale; + else locale = context->config->defaultLocale; + + /* determine the path to the DTD file and load it */ + int len = strlen(context->config->baseDir) + strlen(locale) + strlen(sysId) + 4; + char buf[len]; bzero(buf,len); + snprintf( buf, len, "%s/%s/%s", context->config->baseDir, locale, sysId ); + + apacheDebug("Parsing DTD file %s", buf); + xmlDtdPtr dtd = xmlParseDTD(NULL, buf); + + + /* cycle through entities and push them into the entity hash */ + xmlNodePtr node = dtd->children; + while( node ) { + if( node->type == XML_ENTITY_DECL ) { /* shove the entities into the hash */ + xmlEntityPtr ent = (xmlEntityPtr) node; + osrfHashSet( context->entHash, ent, (char*) ent->name ); + } + node = node->next; + } + + /* cache the DTD so we can free it later */ + osrfHashSet( context->dtdHash, dtd, sysId ); +} + + +/* ------------------------------------------------------------------------ */ + +/* register callbacks */ +static void xmlBuilderRegisterHooks (apr_pool_t *p) { + ap_hook_handler(xmlBuilderHandler, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_child_init(xmlBuilderChildInit,NULL,NULL,APR_HOOK_MIDDLE); +} + + +/* finally, flesh the module */ +module AP_MODULE_DECLARE_DATA xmlbuilder_module = { + STANDARD20_MODULE_STUFF, + NULL, + NULL, + xmlBuilderCreateConfig, + NULL, + xmlBuilderCommands, + xmlBuilderRegisterHooks, +}; + + + + + + +/* +char* get_dtd_lang_file(string_array* params, char* default_locale, char* locale_dir) { + + char* locale = apacheGetFirstParamValue(params, PARAM_LOCALE); + if(!locale) locale = default_locale; + if(!locale) return NULL; + + int len = strlen(LANG_DTD) + strlen(locale) + strlen(locale_dir) + 1; + char dtdfile[len]; + bzero(dtdfile, len); + + if(locale) + sprintf(dtdfile, "%s/%s/%s", locale_dir, locale, LANG_DTD ); + + return strdup(dtdfile); +} +*/ + + diff --git a/Open-ILS/src/apachemods/mod_xmlbuilder.h b/Open-ILS/src/apachemods/mod_xmlbuilder.h new file mode 100644 index 0000000000..9cf7229bf6 --- /dev/null +++ b/Open-ILS/src/apachemods/mod_xmlbuilder.h @@ -0,0 +1,106 @@ +#include "apachetools.h" +#include "opensrf/xml_utils.h" +#include "opensrf/osrf_hash.h" +#include "opensrf/osrf_list.h" +#include +#include +#include + +#define MODULE_NAME "xmlbuilder_module" /* our module name */ + +/* ------------------------------------------------------------------------------ */ +/* Apache config items. These are defaults which are only used if they are not + overriden by the Apache config or URL where appropriate */ +/* ------------------------------------------------------------------------------ */ +/* The default directory where the DTD files are stored */ +#define MODXMLB_DEFAULT_LOCALE_PARAM "locale" +#define MODXMLB_DEFAULT_BASE_DIR "/openils/var/web/locale" +#define MODXMLB_DEFAULT_LOCALE "en-US" +#define MODXMLB_DEFAULT_DTD NULL /* if defined, use this DTD only */ +/* ------------------------------------------------------------------------------ */ + +#define MODXMLB_CONFIG_LOCALE "XMLBuilderDefaultLocale" +#define MODXMLB_CONFIG_BASE_DIR "XMLBuilderBaseDir" +#define MODXMLB_CONFIG_POST_XSL "XMLBuilderPostXSL" +#define MODXMLB_CONFIG_DEFAULT_DTD "XMLBuilderDefaultDTD" +#define MODXMLB_CONFIG_LOCALE_PARAM "XMLBuilderLocaleParam" + + + +/* This module */ +module AP_MODULE_DECLARE_DATA xmlbuilder_module; + + +/* our config structure */ +typedef struct { + + char* baseDir; /* directory on disk where the DTD files live */ + char* defaultLocale; /* locale dir from config or default */ + char* defaultDtd; /* if defined, we load this DTD only */ + char* localeParam; /* the CGI param used to choose the locale dir dynamically */ + xsltStylesheetPtr postXSL; /* if defined, run this XSL after parsing */ + +} xmlBuilderConfig; + +typedef struct { + xmlBuilderConfig* config; + xmlDocPtr doc; + osrfHash* entHash; + osrfHash* dtdHash; + osrfList* nodeList; + int xmlError; + char* xmlFile; +} xmlBuilderContext; + + + +xmlDocPtr xmlBuilderProcessFile( char* XMLFile, xmlBuilderConfig* config ); + +void xmlBuilderAddDtd( const char* sysId, xmlBuilderContext* context ); + + +/* SAX Callbacks */ +void xmlBuilderStartElement( void* blob, const xmlChar *name, const xmlChar **atts ); +void xmlBuilderEndElement( void* blob, const xmlChar* name ); +void xmlBuilderHandleCharacter(void* blob, const xmlChar *ch, int len); +void xmlBuilderParseError( void* blob, const char* msg, ... ); +xmlEntityPtr xmlBuilderGetEntity( void* blob, const xmlChar* name ); +void xmlBuilderExtSubset( void* blob, const xmlChar* name, const xmlChar* extId, const xmlChar* sysId ); + +static xmlSAXHandler xmlBuilderSaxHandlerStruct = { + NULL, /* internalSubset */ + NULL, /* isStandalone */ + NULL, /* hasInternalSubset */ + NULL, /* hasExternalSubset */ + NULL, /* resolveEntity */ + xmlBuilderGetEntity, /* getEntity */ + NULL, /* entityDecl */ + NULL, /* notationDecl */ + NULL, /* attributeDecl */ + NULL, /* elementDecl */ + NULL, /* unparsedEntityDecl */ + NULL, /* setDocumentLocator */ + NULL, /* startDocument */ + NULL, /* endDocument */ + xmlBuilderStartElement, /* startElement */ + xmlBuilderEndElement, /* endElement */ + NULL, /* reference */ + xmlBuilderHandleCharacter, /* characters */ + NULL, /* ignorableWhitespace */ + NULL, /* processingInstruction */ + NULL, /* comment */ + xmlBuilderParseError, /* xmlParserWarning */ + xmlBuilderParseError, /* xmlParserError */ + NULL, /* xmlParserFatalError : unused */ + NULL, /* getParameterEntity */ + NULL, /* cdataBlock; */ + xmlBuilderExtSubset, /* externalSubset; */ + 1, + NULL, + NULL, /* startElementNs */ + NULL, /* endElementNs */ + NULL /* xmlStructuredErrorFunc */ +}; +static const xmlSAXHandlerPtr xmlBuilderSaxHandler = &xmlBuilderSaxHandlerStruct; + + diff --git a/Open-ILS/src/apachemods/mod_xmltools.c b/Open-ILS/src/apachemods/mod_xmltools.c deleted file mode 100644 index 240bc06556..0000000000 --- a/Open-ILS/src/apachemods/mod_xmltools.c +++ /dev/null @@ -1,200 +0,0 @@ -#include "mod_xmltools.h" - - -/* Configuration handlers -------------------------------------------------------- */ -static const char* mod_xmltools_set_locale_dir(cmd_parms *parms, void *config, const char *arg) { - mod_xmltools_config *cfg = ap_get_module_config(parms->server->module_config, &mod_xmltools_module); - cfg->locale_dir = (char*) arg; - return NULL; -} - -static const char* mod_xmltools_set_default_locale(cmd_parms *parms, void *config, const char *arg) { - mod_xmltools_config *cfg = ap_get_module_config(parms->server->module_config, &mod_xmltools_module); - cfg->default_locale = (char*) arg; - return NULL; -} - -static const char* mod_xmltools_set_pre_xsl(cmd_parms *parms, void *config, const char *arg) { - mod_xmltools_config *cfg = ap_get_module_config(parms->server->module_config, &mod_xmltools_module); - cfg->pre_xsl = xsltParseStylesheetFile( (xmlChar*) arg ); - if(cfg->pre_xsl == NULL) { - fprintf(stderr, "Unable to parse PreXSL stylesheet %s\n", (char*) arg ); - fflush(stderr); - } - return NULL; -} - -static const char* mod_xmltools_set_post_xsl(cmd_parms *parms, void *config, const char *arg) { - mod_xmltools_config *cfg = ap_get_module_config(parms->server->module_config, &mod_xmltools_module); - cfg->post_xsl = xsltParseStylesheetFile( (xmlChar*) arg ); - if(cfg->post_xsl == NULL) { - fprintf(stderr, "Unable to parse PostXSL stylesheet %s\n", (char*) arg ); - fflush(stderr); - } - return NULL; -} - -/* tell apache about our commands */ -static const command_rec mod_xmltools_cmds[] = { - AP_INIT_TAKE1( CONFIG_LOCALE, mod_xmltools_set_default_locale, NULL, RSRC_CONF, "default locale"), - AP_INIT_TAKE1( CONFIG_LOCALE_DIR, mod_xmltools_set_locale_dir, NULL, RSRC_CONF, "locale directory"), - AP_INIT_TAKE1( CONFIG_PRE_XSL, mod_xmltools_set_pre_xsl, NULL, RSRC_CONF, "pre xsl"), - AP_INIT_TAKE1( CONFIG_POST_XSL, mod_xmltools_set_post_xsl, NULL, RSRC_CONF, "post xsl"), - {NULL} -}; - -/* build the config object */ -static void* mod_xmltools_create_config( apr_pool_t* p, server_rec* s) { - mod_xmltools_config* cfg = - (mod_xmltools_config*) apr_palloc(p, sizeof(mod_xmltools_config)); - cfg->default_locale = DEFAULT_LOCALE; - cfg->locale_dir = DEFAULT_LOCALE_DIR; - cfg->pre_xsl = NULL; - cfg->post_xsl = NULL; - return (void*) cfg; -} - - -/* Child Init handler ----------------------------------------------------------- */ -static void mod_xmltools_child_init(apr_pool_t *p, server_rec *s) { -} - - -/* Request handler -------------------------------------------------------------- */ -static int mod_xmltools_handler (request_rec* r) { - - /* make sure we're needed first thing*/ - if (strcmp(r->handler, MODULE_NAME )) - return DECLINED; - - mod_xmltools_config *cfg = ap_get_module_config(r->server->module_config, &mod_xmltools_module); - char* locale_dir = cfg->locale_dir; - char* default_locale = cfg->default_locale; - xsltStylesheetPtr pre_xsl = cfg->pre_xsl; - xsltStylesheetPtr post_xsl = cfg->post_xsl; - - /* we accept get/post requests */ - r->allowed |= (AP_METHOD_BIT << M_GET); - r->allowed |= (AP_METHOD_BIT << M_POST); - - ap_set_content_type(r, "text/html; charset=utf-8"); - - string_array* params = apacheParseParms(r); - - char* file = r->filename; - char* dtdfile = get_dtd_lang_file(params, default_locale, locale_dir ); - - xmlDocPtr doc; - - /* be explicit */ - xmlSubstituteEntitiesDefault(0); - - /* parse the doc */ - if( (doc = xmlParseFile(file)) == NULL) { - fprintf(stderr, "\n ^-- Error parsing XML file %s\n", file); - fflush(stderr); - return HTTP_INTERNAL_SERVER_ERROR; - } - - fflush(stderr); - - - if(pre_xsl) { - xmlDocPtr newdoc; - newdoc = xsltApplyStylesheet(pre_xsl, doc, NULL ); - if(newdoc == NULL) { - fprintf(stderr, "Error applying PreXSL stylesheet\n"); - fflush(stderr); - } - xmlFreeDoc(doc); - doc = newdoc; - } - - fflush(stderr); - - /* process xincludes */ - if( xmlXIncludeProcess(doc) < 0 ) { - fprintf(stderr, "\n ^-- Error processing XIncludes for file %s\n", file); - fflush(stderr); - return HTTP_INTERNAL_SERVER_ERROR; - } - - /* replace the DTD */ - if(xmlReplaceDtd(doc, dtdfile) < 0) { - fprintf(stderr, "Error replacing DTD file with file %s\n", dtdfile); - fflush(stderr); - return HTTP_INTERNAL_SERVER_ERROR; - } - - - /* force DTD entity replacement */ - doc = xmlProcessDtdEntities(doc); - - if(post_xsl) { - xmlDocPtr newdoc; - newdoc = xsltApplyStylesheet(post_xsl, doc, NULL ); - if(newdoc == NULL) { - fprintf(stderr, "Error applying PostXSL stylesheet\n"); - fflush(stderr); - } - xmlFreeDoc(doc); - doc = newdoc; - } - - /* stringify */ - char* xml = xmlDocToString(doc, 0); - - /* print the doc */ - ap_rputs(xml, r); - - /* deallocate */ - free(dtdfile); - free(xml); - xmlFreeDoc(doc); - xmlCleanupCharEncodingHandlers(); - xmlCleanupParser(); - - return OK; - -} - - -/* register callbacks */ -static void mod_xmltools_register_hooks (apr_pool_t *p) { - ap_hook_handler(mod_xmltools_handler, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_child_init(mod_xmltools_child_init,NULL,NULL,APR_HOOK_MIDDLE); -} - - -/* finally, flesh the module */ -module AP_MODULE_DECLARE_DATA mod_xmltools_module = { - STANDARD20_MODULE_STUFF, - NULL, - NULL, - mod_xmltools_create_config, - NULL, - mod_xmltools_cmds, - mod_xmltools_register_hooks, -}; - - - -/* UTILITY FUNCTIONS ----------------------------------------------------- */ -char* get_dtd_lang_file(string_array* params, char* default_locale, char* locale_dir) { - - /* if no locale is provided via URL, we use the default */ - char* locale = apacheGetFirstParamValue(params, PARAM_LOCALE); - if(!locale) locale = default_locale; - if(!locale) return NULL; - - int len = strlen(LANG_DTD) + strlen(locale) + strlen(locale_dir) + 1; - char dtdfile[len]; - bzero(dtdfile, len); - - if(locale) - sprintf(dtdfile, "%s/%s/%s", locale_dir, locale, LANG_DTD ); - - return strdup(dtdfile); -} - - diff --git a/Open-ILS/src/apachemods/mod_xmltools.h b/Open-ILS/src/apachemods/mod_xmltools.h deleted file mode 100644 index 18300009b8..0000000000 --- a/Open-ILS/src/apachemods/mod_xmltools.h +++ /dev/null @@ -1,51 +0,0 @@ -#include "apachetools.h" -#include "xmltools.h" -#include -#include -#include - -#define MODULE_NAME "mod_xmltools_module" /* our module name */ -#define PARAM_LOCALE "locale" /* the URL param for the local directory */ -#define LANG_DTD "lang.dtd" /* the DTD for the test entities */ - - -/* ------------------------------------------------------------------------------ */ -/* Apache config items. These are defaults which are only used if they are not - overriden by the Apache config or URL where appropriate */ -/* ------------------------------------------------------------------------------ */ -/* The default directory where the local files are stored */ -#define DEFAULT_LOCALE_DIR "/openils/var/locale" -#define DEFAULT_LOCALE "en-US" -/* ------------------------------------------------------------------------------ */ - -#define CONFIG_LOCALE "XMLToolsDefaultLocale" -#define CONFIG_LOCALE_DIR "XMLToolsLocaleDir" -#define CONFIG_PRE_XSL "XMLToolsPreXSL" -#define CONFIG_POST_XSL "XMLToolsPostXSL" - - - -/* This module */ -module AP_MODULE_DECLARE_DATA mod_xmltools_module; - - -/* our config structure */ -typedef struct { - - char* locale_dir; /* directory on disk where the locale directories live */ - char* default_locale; - - xsltStylesheetPtr pre_xsl; - xsltStylesheetPtr post_xsl; - -} mod_xmltools_config; - - - -/* allocates a char* to hold the name of the DTD language file - Prints to stderr and returns NULL if there was an error loading the file - default_locale comes from the apache config and is used only if no - locale is provided via URL - locale_dir also comes from the apache config. - */ -char* get_dtd_lang_file(string_array* params, char* default_locale, char* locale_dir); diff --git a/Open-ILS/src/apachemods/xmltools.c b/Open-ILS/src/apachemods/xmltools.c deleted file mode 100644 index 6f0b6e4519..0000000000 --- a/Open-ILS/src/apachemods/xmltools.c +++ /dev/null @@ -1,149 +0,0 @@ -#include "xmltools.h" - - -#ifdef XMLTOOLS_DEBUG // standalone debugging - -int main(int argc, char* argv[]) { - - char* file = argv[1]; - char* dtdfile = argv[2]; - - - printf("\n%s\n", xmlDocToString(xmlParseEntity(file), 1)); - - xmlDocPtr doc; - - xmlSubstituteEntitiesDefault(1); - xmlParserCtxtPtr ctxt = xmlNewParserCtxt(); - doc = xmlCtxtReadFile(ctxt, file, NULL, XML_PARSE_NOENT | XML_PARSE_RECOVER | XML_PARSE_NOERROR | XML_PARSE_NOWARNING ); - if(doc != NULL) - fprintf(stderr, "What we have so far:\n%s\n", xmlDocToString(doc, 1)); - else { - fprintf(stderr, "NO Doc\n"); - return 0; - } - - /* parse the doc */ - /* - if( (doc = xmlParseFile(file)) == NULL) { - fprintf(stderr, "\n ^-- Error parsing XML file %s\n", file); - fflush(stderr); - return 99; - } - */ - - /* process xincludes */ - if( xmlXIncludeProcessFlags(doc, XML_PARSE_NOENT) < 0 ) { - fprintf(stderr, "\n ^-- Error processing XIncludes for file %s\n", file); - if(doc != NULL) - fprintf(stderr, "What we have so far:\n%s\n", xmlDocToString(doc, 1)); - fflush(stderr); - return 99; - } - - - - /* replace the DTD */ - /* - if(xmlReplaceDtd(doc, dtdfile) < 0) { - fprintf(stderr, "Error replacing DTD file with file %s\n", dtdfile); - fflush(stderr); - return 99; - } - */ - - // - xmlAddDocEntity(doc, "test", XML_INTERNAL_GENERAL_ENTITY, NULL, NULL, "Here is my test"); - - xmlSubstituteEntitiesDefault(1); - printf("---------------------------------\n%s\n", xmlDocToString(doc,1)); - exit(99); - // - - /* force DTD entity replacement */ - doc = xmlProcessDtdEntities(doc); - - /* stringify */ - char* xml = xmlDocToString(doc, 0); - - fprintf(stderr, "%s\n", xml); - - /* deallocate */ - free(xml); - xmlFreeDoc(doc); - xmlCleanupCharEncodingHandlers(); - xmlCleanupParser(); - - -} - -#endif - -xmlDocPtr xmlProcessDtdEntities(xmlDocPtr doc) { - char* xml = xmlDocToString(doc, 1); - xmlFreeDoc(doc); - xmlSubstituteEntitiesDefault(1); - xmlDocPtr d = xmlParseMemory(xml, strlen(xml)); - free(xml); - return d; -} - - -int xmlReplaceDtd(xmlDocPtr doc, char* dtdfile) { - - if(!doc || !dtdfile) return 0; - - /* remove the original DTD */ - if(doc->children && doc->children->type == XML_DTD_NODE) { - xmlNodePtr p = doc->children; - xmlUnlinkNode(p); - xmlFreeNode(p); - } - - - xmlDtdPtr dtd = xmlParseDTD(NULL, dtdfile); - - if(!dtd) { - fprintf(stderr, "Error parsing DTD file %s\n", dtdfile); - fflush(stderr); - return -1; - } - - dtd->name = xmlStrdup((xmlChar*)"x"); - doc->extSubset = dtd; - dtd->doc = doc; - dtd->parent = doc; - xmlNodePtr x = doc->children; - doc->children = (xmlNodePtr)dtd; - dtd->next = x; - - return 1; -} - -char* xmlDocToString(xmlDocPtr doc, int full) { - - if(!doc) return NULL; - - char* xml; - - if(full) { - - xmlChar* xmlbuf; - int size; - xmlDocDumpMemory(doc, &xmlbuf, &size); - xml = strdup((char*) (xmlbuf)); - xmlFree(xmlbuf); - return xml; - - } else { - - xmlBufferPtr xmlbuf = xmlBufferCreate(); - xmlNodeDump( xmlbuf, doc, xmlDocGetRootElement(doc), 0, 0); - xml = strdup((char*) (xmlBufferContent(xmlbuf))); - xmlBufferFree(xmlbuf); - return xml; - - } -} - - diff --git a/Open-ILS/src/apachemods/xmltools.h b/Open-ILS/src/apachemods/xmltools.h deleted file mode 100644 index c09f3cfb88..0000000000 --- a/Open-ILS/src/apachemods/xmltools.h +++ /dev/null @@ -1,37 +0,0 @@ - -/* general headers */ -#include -#include -#include - -/* libxml2 headers */ -#include -#include -#include -#include -#include - - -#ifndef XMLTOOLS_H -#define XMLTOOLS_H - - -/* turns a doc into a string. string must be deallocated. - if 'full', then the entire doc is stringified, otherwise - the root node (on down) is stringified */ -char* xmlDocToString(xmlDocPtr doc, int full); - -int xmlReplaceDtd(xmlDocPtr doc, char* dtdfile); - -/* Inline DTD Entity replacement. - creates a new doc with the entities replaced, frees the - doc provided and returns a new one. - Do this and you'll be OK: - doc = xmlProcessDtdEntities(doc); - */ -xmlDocPtr xmlProcessDtdEntities(xmlDocPtr doc); - - -#endif - - -- 2.43.2