/* * (c) Siemens Business Services GmbH */ package at.gv.egovernment.moa.ss.erechtclient.init; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.apache.log4j.Logger; import org.apache.xerces.parsers.DOMParser; import org.apache.xerces.parsers.XMLGrammarPreparser; import org.apache.xerces.util.SymbolTable; import org.apache.xerces.util.XMLGrammarPoolImpl; import org.apache.xerces.xni.grammars.XMLGrammarDescription; import org.apache.xerces.xni.grammars.XMLGrammarPool; import org.apache.xerces.xni.parser.XMLInputSource; import org.xml.sax.SAXException; /** * @author Gregor Karlinger (mailto:gregor.karlinger@siemens.com) */ public class ContextListener implements ServletContextListener { private static final String SAX_NAMESPACES_FEATURE = "http://xml.org/sax/features/namespaces"; private static final String SAX_VALIDATION_FEATURE = "http://xml.org/sax/features/validation"; private static final String XERCES_SCHEMA_VALIDATION_FEATURE = "http://apache.org/xml/features/validation/schema"; private static final String XERCES_NORMALIZED_VALUE_FEATURE = "http://apache.org/xml/features/validation/schema/normalized-value"; private static final String XERCES_INCLUDE_IGNORABLE_WHITESPACE_FEATURE = "http://apache.org/xml/features/dom/include-ignorable-whitespace"; private static final String XERCES_CREATE_ENTITY_REF_NODES_FEATURE = "http://apache.org/xml/features/dom/create-entity-ref-nodes"; protected static final String XERCES_DEFER_NODE_EXPANSION_ = "http://apache.org/xml/features/dom/defer-node-expansion"; protected static final String XERCES_AUGMENT_PSI_ = "http://apache.org/xml/features/validation/schema/augment-psvi"; private static final int BIG_PRIME = 2039; private static Logger logger_ = Logger.getLogger(Constants.LH_INIT_); /* ---------------------------------------------------------------------------------------------------- */ /** * Initializes the web application. * * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent) */ public void contextInitialized(ServletContextEvent event) { logger_.debug("Context is being initialized."); ServletContext context = event.getServletContext(); String initPropsLoc = System.getProperty(Constants.INIT_PROPS_LOC_); if (initPropsLoc == null) { logger_.fatal("System property \"" + Constants.INIT_PROPS_LOC_ + "\" not set."); logger_.fatal("Web application initialization failed."); return; } // Load init properties try { logger_.debug("Init properties location \"" + initPropsLoc + "\" will be used."); // Try to interpret init properties location as relative to the web application root InputStream initPropsIS = context.getResourceAsStream(initPropsLoc); if (initPropsIS == null) { // If this does not work, try to interpret init properties location as an absolute file system path initPropsIS = new FileInputStream(initPropsLoc); } Properties initProps = new Properties(); initProps.load(initPropsIS); context.setAttribute(Constants.WSCP_INIT_PROPS_, initProps); // Prepare application bean knowing about init properties InitPropertiesBean initPropsBean = new InitPropertiesBean(initProps); context.setAttribute(Constants.WSCP_INITPROPS_BEAN_, initPropsBean); } catch (IOException e) { logger_.fatal("Cannot load initialization properties from location \"" + initPropsLoc + "\".", e); logger_.fatal("Web application initialization failed."); return; } // Initialize XML parser SymbolTable symbolTable = new SymbolTable(BIG_PRIME); XMLGrammarPool grammarPool = new XMLGrammarPoolImpl(); XMLGrammarPreparser preparser = new XMLGrammarPreparser(symbolTable); preparser.registerPreparser(XMLGrammarDescription.XML_SCHEMA, null); preparser.setProperty(org.apache.xerces.impl.Constants.XERCES_PROPERTY_PREFIX + org.apache.xerces.impl.Constants.XMLGRAMMAR_POOL_PROPERTY, grammarPool); preparser.setFeature(SAX_NAMESPACES_FEATURE, true); preparser.setFeature(SAX_VALIDATION_FEATURE, true); // Schema for MOA 1.3 // TODO Maybe remove this? Properties initProps = (Properties) context.getAttribute(Constants.WSCP_INIT_PROPS_); String moaSchemaLoc = initProps.getProperty(Constants.IP_MOA_SCHEMA_); if (!preparseSchema(context, preparser, moaSchemaLoc)) { logger_.fatal("Web application initialization failed."); return; } // TODO parser is not threadsafe DOMParser xmlParser = new DOMParser(symbolTable, grammarPool); try { xmlParser.setFeature(SAX_NAMESPACES_FEATURE, true); xmlParser.setFeature(SAX_VALIDATION_FEATURE, true); xmlParser.setFeature(XERCES_SCHEMA_VALIDATION_FEATURE, true); xmlParser.setFeature(XERCES_NORMALIZED_VALUE_FEATURE, false); xmlParser.setFeature(XERCES_INCLUDE_IGNORABLE_WHITESPACE_FEATURE, true); xmlParser.setFeature(XERCES_CREATE_ENTITY_REF_NODES_FEATURE, false); xmlParser.setFeature(XERCES_DEFER_NODE_EXPANSION_, true); xmlParser.setFeature(XERCES_AUGMENT_PSI_, false); xmlParser.setErrorHandler(new XMLParserErrorHandler(false, true, true)); } catch (SAXException e) { String message = "Initialization of XML parser failed."; logger_.fatal(message, e); logger_.fatal("Web application initialization failed."); return; } context.setAttribute(Constants.WSCP_XMLPARSER_, xmlParser); String message = "Web application initialization succeeded."; logger_.info(message); } /* ---------------------------------------------------------------------------------------------------- */ /** * Does some clean up at finalization of the web application. * * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent) */ public void contextDestroyed(ServletContextEvent event) { // Remove init properties from web service context Properties initProps = (Properties) event.getServletContext().getAttribute(Constants.WSCP_INIT_PROPS_); if (initProps != null) event.getServletContext().removeAttribute(Constants.WSCP_INIT_PROPS_); } /* ---------------------------------------------------------------------------------------------------- */ private boolean preparseSchema(ServletContext context, XMLGrammarPreparser preparser, String schemaLoc) { InputStream schemaIS = context.getResourceAsStream(schemaLoc); if (schemaIS == null) { String message = "Cannot load schema from location \"" + schemaLoc + "\"."; logger_.fatal(message); return false; } try { String schemaSystemId = context.getResource(schemaLoc).toExternalForm(); preparser.preparseGrammar(XMLGrammarDescription.XML_SCHEMA, new XMLInputSource(null, schemaSystemId, null, schemaIS, null)); } catch (Exception e) { String message = "Parsing schema loaded from location \"" + schemaLoc + "\" failed."; logger_.fatal(message, e); return false; } return true; } }