aboutsummaryrefslogtreecommitdiff
path: root/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient
diff options
context:
space:
mode:
Diffstat (limited to 'erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient')
-rw-r--r--erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/ERechtClientException.java111
-rw-r--r--erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/init/Constants.java104
-rw-r--r--erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/init/ContextListener.java187
-rw-r--r--erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/init/InitPropertiesBean.java33
-rw-r--r--erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/init/XMLParserErrorHandler.java65
-rw-r--r--erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/moainvoker/DOMErrorHandler.java55
-rw-r--r--erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/moainvoker/MOAInvoker.java157
-rw-r--r--erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/moainvoker/RequestBuilder.java190
-rw-r--r--erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/servlets/Dispatcher.java428
-rw-r--r--erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/util/DOMUtils.java169
-rw-r--r--erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/util/Utils.java106
-rw-r--r--erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/util/XPathUtils.java162
12 files changed, 1767 insertions, 0 deletions
diff --git a/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/ERechtClientException.java b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/ERechtClientException.java
new file mode 100644
index 000000000..1650e1641
--- /dev/null
+++ b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/ERechtClientException.java
@@ -0,0 +1,111 @@
+package at.gv.egovernment.moa.ss.erechtclient;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.Writer;
+
+import javax.servlet.ServletOutputStream;
+
+/**
+ * Base class of MOA specific exceptions.
+ *
+ * This class has the ability to wrap other exceptions which may be seen
+ * as the root cause for this exception.
+ *
+ * @author Gregor Karlinger
+ * @version $Id$
+ */
+public class ERechtClientException extends Exception {
+
+ /** The wrapped <code>Throwable</code>. */
+ private Throwable wrapped_;
+
+ /**
+ * Create a <code>MOAException</code>.
+ *
+ * @param message The message contained in the created <code>ERechtClientException</code>.
+ */
+ public ERechtClientException(String message)
+ {
+ super(message);
+ }
+
+ /**
+ * Create a <code>MOAException</code>.
+ *
+ * @param message The message contained in the created <code>ERechtClientException</code>.
+ *
+ * @param wrapped The exception wrapped by the created <code>ERechtClientException</code>.
+ */
+ public ERechtClientException(String message, Throwable wrapped)
+ {
+ super(message, wrapped);
+ this.wrapped_ = wrapped;
+ }
+
+ /**
+ * Print a stack trace of this exception to <code>System.err</code>.
+ *
+ * @see java.lang.Throwable#printStackTrace()
+ */
+ public void printStackTrace()
+ {
+ printStackTrace(System.err);
+ }
+
+ /**
+ * Print a stack trace of this exception, including the wrapped exception.
+ *
+ * @param s The stream to write the stack trace to.
+ *
+ * @see java.lang.Throwable#printStackTrace(java.io.PrintStream)
+ */
+ public void printStackTrace(PrintStream s)
+ {
+ super.printStackTrace(s);
+ if (wrapped_ != null)
+ {
+ s.print("Caused by: ");
+ wrapped_.printStackTrace(s);
+ }
+ }
+
+ /**
+ * Print a stack trace of this exception, including the wrapped exception.
+ *
+ * @param s The stream to write the stacktrace to.
+ *
+ * @see java.lang.Throwable#printStackTrace(java.io.PrintWriter)
+ */
+ public void printStackTrace(PrintWriter s) {
+ super.printStackTrace(s);
+ if (wrapped_ != null)
+ {
+ s.print("Caused by: ");
+ wrapped_.printStackTrace(s);
+ }
+ }
+
+ /**
+ * Print a stack trace of this exception, including the wrapped exception.
+ *
+ * @param s The stream to write the stacktrace to.
+ *
+ * @see java.lang.Throwable#printStackTrace(java.io.PrintWriter)
+ */
+ public String getStackTracePrint()
+ {
+ ByteArrayOutputStream bAOS = new ByteArrayOutputStream();
+ PrintWriter s = new PrintWriter(bAOS);
+ super.printStackTrace(s);
+ if (wrapped_ != null)
+ {
+ s.print("Caused by: ");
+ wrapped_.printStackTrace(s);
+ }
+ s.flush();
+ return bAOS.toString();
+ }
+}
diff --git a/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/init/Constants.java b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/init/Constants.java
new file mode 100644
index 000000000..a9cfdac62
--- /dev/null
+++ b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/init/Constants.java
@@ -0,0 +1,104 @@
+/*
+ * Created on 18.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.ss.erechtclient.init;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class Constants
+{
+ // System properties
+ public static final String INIT_PROPS_LOC_ =
+ "at.gv.egovernment.moa.ss.erechtclient.PropertiesLocation";
+
+ // Init properties
+
+ // TODO Revisit if constants can be removed
+ public static final String IP_WEBAPP_HOST_PORT_ = "location.webAppHostPort";
+ public static final String IP_WEBAPP_HOST_PORT_FROM_MOA_SS_ = "location.webAppHostPortFromMOASS";
+
+ public static final String IP_MOA_SCHEMA_ = "location.schema.moa";
+ public static final String IP_SS_REQUEST_TEMPLATE_ = "location.ss.requestTemplate";
+
+ public static final String IP_TEMP_DIR_ = "location.tempdir";
+ public static final String IP_SS_STYLESHEET_ = "location.ss.stylesheet";
+
+ public static final String IP_SS_ENDPOINT_ = "service.ss.endpoint";
+ public static final String IP_SS_KEYID_ = "service.ss.keyIdentifier";
+
+ // Logging hierarchies
+
+ public static final String LH_BASE_ = "erechtclient";
+ public static final String LH_INIT_ = LH_BASE_ + ".init";
+ public static final String LH_XMLPARSER_ = LH_BASE_ + ".xmlparser";
+ public static final String LH_SERVLETS_ = LH_BASE_ + ".servlets";
+ public static final String LH_BEANS_ = LH_BASE_ + ".beans";
+ public static final String LH_MOAINVOKER_ = LH_BASE_ + ".moainvoker";
+
+ // Web service context parameters
+
+ public static final String WSCP_INIT_PROPS_ = "initProperties";
+ public static final String WSCP_INITPROPS_BEAN_ = "initPropertiesBean";
+ public static final String WSCP_XMLPARSER_ = "xmlParser";
+
+ // Session parameters
+
+ public static final String SCP_XMLBGBL_FNAME_ = "xMLBGBl";
+ public static final String SCP_STYLESHEET_FNAME_ = "stylesheet";
+ public static final String SCP_IMAGE_NAMES_LIST_ = "imageNames";
+ public static final String SCP_IMAGES_LIST_ = "images";
+ public static final String SCP_SIGNATURE_URL_ = "signatureURL";
+
+ // Reqeust context parameters
+
+ public static final String RCP_ERROR_THROWABLE_ = "throwable";
+
+ // Namespace URIs
+
+ public static final String NSURI_MOA_13_ = "http://reference.e-government.gv.at/namespace/moa/20020822#";
+ public static final String NSURI_NAMESPACES_ = "http://www.w3.org/2000/xmlns/";
+ public static final String NSURI_XML_ = "http://www.w3.org/XML/1998/namespace";
+ public static final String NSURI_DSIG_ = "http://www.w3.org/2000/09/xmldsig#";
+ public static final String NSURI_XMLBGBL_ = "http://www.bka.gv.at";
+
+ // Namespace prefixes
+
+ public static final String NSPRE_MOA_13_ = "moa";
+ public static final String NSPRE_DSIG_ = "dsig";
+ public static final String NSPRE_XMLBGBL_ = "bka";
+
+ // Local XML element's names
+
+ public static final String XML_LN_XMLBGBL_ROOT_ = "erechtdok";
+ public static final String XML_LN_XMLBGBL_IMG_ = "binary";
+ public static final String XML_LN_XMLBGBL_IMG_SRC_ = "src";
+ public static final String XML_LN_XMLBGBL_IMG_REF_ = "ref";
+
+ // MOA invoker constants
+
+ public static final String MI_SS_QNAME_ = "SignatureCreation";
+
+ // Default values
+
+ public static final String DV_WEBAPP_HOST_PATH_ = "http://localhost:8080";
+
+ // HTML form parameter names
+
+ public static final String FPN_UPLOAD_XML_XMLBGBL_ = "xMLBGBl";
+ public static final String FPN_UPLOAD_STYLESHEET_ = "stylesheet";
+ public static final String FPN_UPLOAD_IMG_IMG_ = "image.";
+
+ // JSP page names
+
+ public static final String JSPPN_ERROR_ = "pages/Error.jsp";
+ public static final String JSPPN_UPLOAD_XML_ = "pages/UploadXML.jsp";
+ public static final String JSPPN_UPLOAD_IMG_ = "pages/UploadImages.jsp";
+ public static final String JSPPN_DOWNLOAD_SIG_ = "pages/DownloadSignature.jsp";
+
+ // Servlet url names
+ public static final String SRVN_UPLOAD_XML_ = "/UploadXML";
+ public static final String SRVN_UPLOAD_IMG_ = "/UploadImages";
+}
diff --git a/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/init/ContextListener.java b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/init/ContextListener.java
new file mode 100644
index 000000000..6cc5988ac
--- /dev/null
+++ b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/init/ContextListener.java
@@ -0,0 +1,187 @@
+/*
+ * (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;
+ }
+}
diff --git a/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/init/InitPropertiesBean.java b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/init/InitPropertiesBean.java
new file mode 100644
index 000000000..7b7e1eb11
--- /dev/null
+++ b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/init/InitPropertiesBean.java
@@ -0,0 +1,33 @@
+package at.gv.egovernment.moa.ss.erechtclient.init;
+
+import java.util.Properties;
+
+import org.apache.log4j.Logger;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@siemens.com)
+ */
+public class InitPropertiesBean
+{
+ private Properties initProps_;
+
+ private static Logger logger_ = Logger.getLogger(Constants.LH_BEANS_);
+
+ public InitPropertiesBean(Properties props)
+ {
+ initProps_ = props;
+ }
+
+ public String getWebAppHostPort()
+ {
+ String webAppHostPort = initProps_.getProperty(Constants.IP_WEBAPP_HOST_PORT_);
+ logger_.debug("MOA SS E-Recht Client web application host/port: " + webAppHostPort);
+ if (webAppHostPort == null || webAppHostPort.trim().length() == 0)
+ {
+ String defaultWebAppHostPath = Constants.DV_WEBAPP_HOST_PATH_;
+ logger_.info("MOA SS E-Recht Client web application host/port property not available, using default (" + defaultWebAppHostPath + ")");
+ return defaultWebAppHostPath;
+ }
+ else return webAppHostPort;
+ }
+}
diff --git a/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/init/XMLParserErrorHandler.java b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/init/XMLParserErrorHandler.java
new file mode 100644
index 000000000..a954d35d9
--- /dev/null
+++ b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/init/XMLParserErrorHandler.java
@@ -0,0 +1,65 @@
+/*
+ * Created on 02.12.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.ss.erechtclient.init;
+
+import org.apache.log4j.Logger;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import at.gv.egovernment.moa.ss.erechtclient.init.Constants;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class XMLParserErrorHandler implements ErrorHandler
+{
+ private static Logger logger_ = Logger.getLogger(Constants.LH_XMLPARSER_);
+
+ private boolean reportWarning_, reportError_, reportFatal_;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public XMLParserErrorHandler(boolean reportWarning, boolean reportError, boolean reportFatal)
+ {
+ reportWarning_ = reportWarning;
+ reportError_ = reportError;
+ reportFatal_ = reportFatal;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
+ */
+ public void warning(SAXParseException exception) throws SAXException
+ {
+ logger_.warn("XML parser reported a warning.", exception);
+ if (reportWarning_) throw exception;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
+ */
+ public void error(SAXParseException exception) throws SAXException
+ {
+ logger_.error("XML parser reported an error.", exception);
+ if (reportError_) throw exception;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
+ */
+ public void fatalError(SAXParseException exception) throws SAXException
+ {
+ logger_.error("XML parser reported a fatal error.", exception);
+ if (reportFatal_) throw exception;
+ }
+}
diff --git a/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/moainvoker/DOMErrorHandler.java b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/moainvoker/DOMErrorHandler.java
new file mode 100644
index 000000000..47b389c31
--- /dev/null
+++ b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/moainvoker/DOMErrorHandler.java
@@ -0,0 +1,55 @@
+package at.gv.egovernment.moa.ss.erechtclient.moainvoker;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.DOMError;
+
+import at.gv.egovernment.moa.ss.erechtclient.init.Constants;
+
+public class DOMErrorHandler implements org.w3c.dom.DOMErrorHandler
+{
+ private LinkedList errors_;
+
+ private static Logger logger_ = Logger.getLogger(Constants.LH_MOAINVOKER_);
+
+ public DOMErrorHandler()
+ {
+ errors_ = new LinkedList();
+ }
+ public boolean handleError(DOMError error)
+ {
+ if (error.getSeverity() == DOMError.SEVERITY_WARNING)
+ {
+ logger_.warn("A warning occured while parsing: " + error.getMessage());
+ return true;
+ }
+ else
+ {
+ logger_.error("A (fatal) error occured while parsing: " + error.getMessage());
+ errors_.add(error.getMessage());
+ return false;
+ }
+ }
+
+ public int getErrorCount()
+ {
+ return errors_.size();
+ }
+
+ public String getErrorSummaryMsg()
+ {
+ if (errors_.size() <= 0) return null;
+
+ StringBuffer errorSummaryMsg = new StringBuffer();
+ errorSummaryMsg.append("The following errors have been reported during parsing:\n");
+ for (int i = 0; i < errors_.size(); i++)
+ {
+ errorSummaryMsg.append("Error no. " + i + ":\n");
+ errorSummaryMsg.append(errors_.get(i) + "\n");
+ }
+ return errorSummaryMsg.toString();
+ }
+
+}
diff --git a/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/moainvoker/MOAInvoker.java b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/moainvoker/MOAInvoker.java
new file mode 100644
index 000000000..65cb55c04
--- /dev/null
+++ b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/moainvoker/MOAInvoker.java
@@ -0,0 +1,157 @@
+/*
+ * Created on 19.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.ss.erechtclient.moainvoker;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.rmi.RemoteException;
+import java.util.Vector;
+
+import javax.xml.namespace.QName;
+import javax.xml.rpc.Call;
+import javax.xml.rpc.Service;
+import javax.xml.rpc.ServiceException;
+import javax.xml.rpc.ServiceFactory;
+
+import org.apache.axis.message.SOAPBodyElement;
+import org.apache.log4j.Logger;
+import org.apache.xerces.parsers.DOMParser;
+import org.apache.xerces.xni.parser.XMLInputSource;
+import org.apache.xml.serialize.OutputFormat;
+import org.apache.xml.serialize.XMLSerializer;
+import org.w3c.dom.DOMConfiguration;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import at.gv.egovernment.moa.ss.erechtclient.ERechtClientException;
+import at.gv.egovernment.moa.ss.erechtclient.init.Constants;
+import at.gv.egovernment.moa.ss.erechtclient.util.DOMUtils;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class MOAInvoker
+{
+ private static Logger logger_ = Logger.getLogger(Constants.LH_MOAINVOKER_);
+
+ private static final String NAME_ERROR_ = "ErrorResponse";
+ private static final String NAME_ERROR_CODE_ = "ErrorCode";
+ private static final String NAME_ERROR_INFO_ = "Info";
+
+ /**
+ * Invokes MOA SS.
+ *
+ * @param request The XML request to be sent to MOA SS.
+ *
+ * @param endpoint The endpoint of the SOAP service where to send the XML request to.
+ *
+ * @param mOASchemaLoc The schema location URI for the MOA schema (for validating the MOA SS service response).
+ *
+ * @return the XML response from the service.
+ *
+ * @throws Exception if getting the XML response from the SOAP response body fails.
+ *
+ * @throws RemoteException if MOA SS signals an error.
+ *
+ * @throws ServiceException if the SOAP client invoking MOA SS signals an error.
+ */
+ public static Document invokeSS(Document request, String endpoint, String mOASchemaLoc) throws ERechtClientException
+ {
+ QName serviceQName = new QName(Constants.MI_SS_QNAME_);
+ return invoke(request, endpoint, serviceQName, mOASchemaLoc);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private static Document invoke(Document request, String endpoint, QName serviceQName, String mOASchemaLoc) throws ERechtClientException
+ {
+ Document response;
+ try {
+ // Instantiate AXIS service
+ Service service = ServiceFactory.newInstance().createService(serviceQName);
+
+ // Create and configure service call
+ Call call = service.createCall();
+ call.setTargetEndpointAddress(endpoint);
+
+ // Create SOAP body
+ SOAPBodyElement body = new SOAPBodyElement(request.getDocumentElement());
+ SOAPBodyElement[] params = new SOAPBodyElement[] {body};
+
+ // Make call
+ Vector responses = (Vector) call.invoke(params);
+
+ // Get response
+ SOAPBodyElement responseBody = (SOAPBodyElement) responses.get(0);
+ response = responseBody.getAsDocument();
+ }
+ catch (Exception e)
+ {
+ String message = "MOA SS Service invocation failed.";
+ logger_.error(message, e);
+ throw new ERechtClientException(message, e);
+ }
+
+ // Validate response
+ DOMConfiguration docConfig = response.getDomConfig();
+ DOMErrorHandler errorHandler = new DOMErrorHandler();
+ docConfig.setParameter("namespaces", Boolean.FALSE);
+ docConfig.setParameter("schema-location", mOASchemaLoc);
+ docConfig.setParameter("schema-type", "http://www.w3.org/2001/XMLSchema");
+ docConfig.setParameter("validate", Boolean.TRUE);
+ docConfig.setParameter("error-handler", errorHandler);
+ response.normalizeDocument();
+ if (errorHandler.getErrorCount() > 0)
+ {
+ String message = "Parsing the MOA SS service response failed:\n" + errorHandler.getErrorSummaryMsg();
+ logger_.error(message);
+ throw new ERechtClientException(message);
+ }
+
+ // Check if first child of response root element is an error element
+ Element responseElem = response.getDocumentElement();
+ Element errorElem = DOMUtils.getChildElem(responseElem, Constants.NSURI_MOA_13_, NAME_ERROR_);
+ if (errorElem != null)
+ {
+ String errorCode = DOMUtils.getChildText(errorElem, Constants.NSURI_MOA_13_, NAME_ERROR_CODE_);
+ String errorInfo = DOMUtils.getChildText(errorElem, Constants.NSURI_MOA_13_, NAME_ERROR_INFO_);
+ String message = "MOA SS Service indicated an error:\n" +
+ "Error code: " + errorCode + "\n" +
+ "Error info: " + errorInfo;
+ logger_.error(message);
+ throw new ERechtClientException(message);
+ }
+
+ return response;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public static void serializeElement(Element rootElem, OutputStream out) throws ERechtClientException
+ {
+
+ // TODO Replace with DOMImplementationLS
+ OutputFormat format = new OutputFormat(rootElem.getOwnerDocument());
+
+ format.setLineSeparator("\n");
+ format.setIndenting(false);
+ format.setPreserveSpace(true);
+ format.setOmitXMLDeclaration(false);
+ format.setEncoding("UTF-8");
+
+ XMLSerializer serializer = new XMLSerializer(out, format);
+ try
+ {
+ serializer.serialize(rootElem);
+ }
+ catch (Exception e)
+ {
+ String message = "Serializing the XML document failed.";
+ logger_.error(message);
+ throw new ERechtClientException(message);
+ }
+ }
+}
diff --git a/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/moainvoker/RequestBuilder.java b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/moainvoker/RequestBuilder.java
new file mode 100644
index 000000000..2c6e0d0e8
--- /dev/null
+++ b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/moainvoker/RequestBuilder.java
@@ -0,0 +1,190 @@
+package at.gv.egovernment.moa.ss.erechtclient.moainvoker;
+
+import java.io.InputStream;
+import java.util.Properties;
+
+import javax.servlet.ServletContext;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import at.gv.egovernment.moa.ss.erechtclient.ERechtClientException;
+import at.gv.egovernment.moa.ss.erechtclient.init.Constants;
+import at.gv.egovernment.moa.ss.erechtclient.util.DOMUtils;
+import at.gv.egovernment.moa.ss.erechtclient.util.Utils;
+import at.gv.egovernment.moa.ss.erechtclient.util.XPathUtils;
+
+public class RequestBuilder
+{
+ private static final String XPATH_KEYID_ =
+ "/" + Constants.NSPRE_MOA_13_ + ":" + "CreateXMLSignatureRequest" +
+ "/" + Constants.NSPRE_MOA_13_ + ":" + "KeyIdentifier";
+
+ private static final String XPATH_XMLDOC_ =
+ "/" + Constants.NSPRE_MOA_13_ + ":" + "CreateXMLSignatureRequest" +
+ "/" + Constants.NSPRE_MOA_13_ + ":" + "SingleSignatureInfo" +
+ "/" + Constants.NSPRE_MOA_13_ + ":" + "DataObjectInfo" +
+ "/" + Constants.NSPRE_MOA_13_ + ":" + "DataObject" +
+ "/" + Constants.NSPRE_MOA_13_ + ":" + "LocRefContent";
+
+ private static final String XPATH_STYLESHEET_ =
+ "/" + Constants.NSPRE_MOA_13_ + ":" + "CreateXMLSignatureRequest" +
+ "/" + Constants.NSPRE_MOA_13_ + ":" + "SingleSignatureInfo" +
+ "/" + Constants.NSPRE_MOA_13_ + ":" + "DataObjectInfo" +
+ "/" + Constants.NSPRE_MOA_13_ + ":" + "CreateTransformsInfoProfile" +
+ "/" + Constants.NSPRE_MOA_13_ + ":" + "Supplement" +
+ "/" + Constants.NSPRE_MOA_13_ + ":" + "Content" + "[@Reference=\"stylesheet.xsl\"]" +
+ "/" + Constants.NSPRE_MOA_13_ + ":" + "LocRefContent";
+
+ private static final String XPATH_IMAGE_ =
+ "/" + Constants.NSPRE_MOA_13_ + ":" + "CreateXMLSignatureRequest" +
+ "/" + Constants.NSPRE_MOA_13_ + ":" + "SingleSignatureInfo";
+
+ private static final String ELEM_NAME_DOI_ = "DataObjectInfo";
+
+ private static final String ATTR_VALUE_DO_STRUCTURE_ = "detached";
+
+ private static final String ELEM_NAME_DO_ = "DataObject";
+
+ private static final String ATTR_NAME_DOI_STRUCTURE_ = "Structure";
+
+ private static final String ATTR_NAME_DO_REFERENCE_ = "Reference";
+
+ private static final String ELEM_NAME_CTIP_ = "CreateTransformsInfoProfile";
+
+ private static final String ELEM_NAME_CTI_ = "CreateTransformsInfo";
+
+ private static final String ELEM_NAME_FDMI_ = "FinalDataMetaInfo";
+
+ private static final String ELEM_NAME_FDMIMIMETYPE_ = "MimeType";
+
+ private static final String ELEM_VALUE_FDMIMIMETYPE_ = "image";
+
+ private static final String ELEM_NAME_FDMITYPE_ = "Type";
+
+ private static final String ELEM_VALUE_FDMITYPE_ = "http://www.buergerkarte.at/specifications/" +
+ "Security-Layer/20031113?Name=SignedImage&InstanceDocRef=0";
+
+ private static final String ELEM_NAME_LOCREF_ = "LocRefContent";
+
+ private Document requestDoc_;
+
+ private String contextPath_;
+
+ private Properties initProps_;
+
+ private ServletContext context_;
+
+ private static Logger logger_ = Logger.getLogger(Constants.LH_MOAINVOKER_);
+
+ public RequestBuilder(ServletContext context, String contextPath) throws ERechtClientException
+ {
+ contextPath_ = contextPath;
+ context_ = context;
+ initProps_ = (Properties) context.getAttribute(Constants.WSCP_INIT_PROPS_);
+
+ // Load template
+ String requestTemplateLocation = Utils.readInitProperty(initProps_, Constants.IP_SS_REQUEST_TEMPLATE_, logger_);
+ try
+ {
+ InputStream requestTemplateIS = context_.getResourceAsStream(requestTemplateLocation);
+ requestDoc_ = DOMUtils.parseWellFormed(requestTemplateIS);
+ } catch (Exception e)
+ {
+ String message = "Could not parse MOA SS signature creation request template.";
+ logger_.error(message, e);
+ throw new ERechtClientException(message, e);
+ }
+
+ // Insert key identifier
+ Element keyIdentifierElem = xPathGetElement(XPATH_KEYID_, requestDoc_);
+ String keyIdentifierStr = Utils.readInitProperty(initProps_, Constants.IP_SS_KEYID_, logger_);
+ keyIdentifierElem.appendChild(requestDoc_.createTextNode(keyIdentifierStr));
+ }
+
+ public void setXMLDocument(String locationRef) throws ERechtClientException
+ {
+ // Set XML document location reference
+ Element xMLDocLocRefElem = xPathGetElement(XPATH_XMLDOC_, requestDoc_);
+ String webAppHostPortFromMOASS = Utils.readInitProperty(initProps_, Constants.IP_WEBAPP_HOST_PORT_FROM_MOA_SS_, logger_);
+ xMLDocLocRefElem.appendChild(requestDoc_.createTextNode(webAppHostPortFromMOASS + contextPath_ + locationRef));
+ }
+
+ public void setStylesheet(String locationRef) throws ERechtClientException
+ {
+ Element stylesheetLocRefElem = xPathGetElement(XPATH_STYLESHEET_, requestDoc_);
+ String webAppHostPortFromMOASS = Utils.readInitProperty(initProps_, Constants.IP_WEBAPP_HOST_PORT_FROM_MOA_SS_, logger_);
+ String stylesheetLocRefStr = webAppHostPortFromMOASS + contextPath_ + locationRef;
+ stylesheetLocRefElem.appendChild(requestDoc_.createTextNode(webAppHostPortFromMOASS + contextPath_ + locationRef));
+ logger_.debug("Setting stylesheet location to: " + stylesheetLocRefStr);
+ }
+
+ public void useDefaultStylesheet() throws ERechtClientException
+ {
+ // Insert stylesheet reference, if it has not been set explicitly
+ Element stylesheetLocRefElem = xPathGetElement(XPATH_STYLESHEET_, requestDoc_);
+ String stylesheetLocRefStr = Utils.readInitProperty(initProps_, Constants.IP_SS_STYLESHEET_, logger_);
+ String webAppHostPortFromMOASS = Utils.readInitProperty(initProps_, Constants.IP_WEBAPP_HOST_PORT_FROM_MOA_SS_, logger_);
+ stylesheetLocRefStr = webAppHostPortFromMOASS + contextPath_ + stylesheetLocRefStr;
+ stylesheetLocRefElem.appendChild(requestDoc_.createTextNode(stylesheetLocRefStr));
+ logger_.debug("No stylesheet set explicitly, using default one: " + stylesheetLocRefStr);
+ }
+
+ public void addImage(String name, String locationRef) throws ERechtClientException
+ {
+ // Add supplement for image to be signed
+ Element parentElem = xPathGetElement(XPATH_IMAGE_, requestDoc_);
+ String webAppHostPortFromMOASS = Utils.readInitProperty(initProps_, Constants.IP_WEBAPP_HOST_PORT_FROM_MOA_SS_, logger_);
+
+ Element dataObjInfo = requestDoc_.createElementNS(Constants.NSURI_MOA_13_, ELEM_NAME_DOI_);
+ dataObjInfo.setAttributeNS(null, ATTR_NAME_DOI_STRUCTURE_, ATTR_VALUE_DO_STRUCTURE_);
+ Element dataObj = requestDoc_.createElementNS(Constants.NSURI_MOA_13_, ELEM_NAME_DO_);
+ Element locRefCont = requestDoc_.createElementNS(Constants.NSURI_MOA_13_, ELEM_NAME_LOCREF_);
+ locRefCont.appendChild(requestDoc_.createTextNode(webAppHostPortFromMOASS + contextPath_ + locationRef));
+ dataObj.appendChild(locRefCont);
+ dataObj.setAttributeNS(null, ATTR_NAME_DO_REFERENCE_, name);
+ dataObjInfo.appendChild(dataObj);
+ Element createTIProf = requestDoc_.createElementNS(Constants.NSURI_MOA_13_, ELEM_NAME_CTIP_);
+ Element createTI = requestDoc_.createElementNS(Constants.NSURI_MOA_13_, ELEM_NAME_CTI_);
+ Element finalDataMI = requestDoc_.createElementNS(Constants.NSURI_MOA_13_, ELEM_NAME_FDMI_);
+ Element finalDataMIMimeType = requestDoc_.createElementNS(Constants.NSURI_MOA_13_, ELEM_NAME_FDMIMIMETYPE_);
+ finalDataMIMimeType.appendChild(requestDoc_.createTextNode(ELEM_VALUE_FDMIMIMETYPE_));
+ finalDataMI.appendChild(finalDataMIMimeType);
+ Element finalDataMIType = requestDoc_.createElementNS(Constants.NSURI_MOA_13_, ELEM_NAME_FDMITYPE_);
+ finalDataMIType.appendChild(requestDoc_.createTextNode(ELEM_VALUE_FDMITYPE_));
+ finalDataMI.appendChild(finalDataMIType);
+
+ createTI.appendChild(finalDataMI);
+ createTIProf.appendChild(createTI);
+ dataObjInfo.appendChild(createTIProf);
+
+ parentElem.appendChild(dataObjInfo);
+ }
+
+ public Document getRequest()
+ {
+ return requestDoc_;
+ }
+
+ private Element xPathGetElement(String xPath, Document doc) throws ERechtClientException
+ {
+ try {
+ XPathUtils xpUtils = new XPathUtils();
+ String additionalNSPrefixes = Constants.NSPRE_MOA_13_ + " " + Constants.NSURI_MOA_13_;
+ xpUtils.setupContext(xPath, doc.getDocumentElement(), additionalNSPrefixes);
+ NodeList nodeList = xpUtils.selectNodeSet(doc);
+ if (nodeList == null) return null;
+ if (nodeList.getLength() < 1) return null;
+ if (!(nodeList.item(0) instanceof Element)) return null;
+ return (Element) nodeList.item(0);
+ }
+ catch (Exception e)
+ {
+ String message = "MOA SS signature request template seems to be corrupted.";
+ logger_.error(message, e);
+ throw new ERechtClientException(message, e);
+ }
+ }
+} \ No newline at end of file
diff --git a/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/servlets/Dispatcher.java b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/servlets/Dispatcher.java
new file mode 100644
index 000000000..23c4dbb53
--- /dev/null
+++ b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/servlets/Dispatcher.java
@@ -0,0 +1,428 @@
+/*
+ * Created on 25.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.ss.erechtclient.servlets;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileItemFactory;
+import org.apache.commons.fileupload.FileUploadException;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.log4j.Logger;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import at.gv.egovernment.moa.ss.erechtclient.ERechtClientException;
+import at.gv.egovernment.moa.ss.erechtclient.init.Constants;
+import at.gv.egovernment.moa.ss.erechtclient.moainvoker.MOAInvoker;
+import at.gv.egovernment.moa.ss.erechtclient.moainvoker.RequestBuilder;
+import at.gv.egovernment.moa.ss.erechtclient.util.DOMUtils;
+import at.gv.egovernment.moa.ss.erechtclient.util.Utils;
+import at.gv.egovernment.moa.ss.erechtclient.util.XPathUtils;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class Dispatcher extends HttpServlet
+{
+ private static Logger logger_ = Logger.getLogger(Constants.LH_SERVLETS_);
+
+ private static final String XPATH_ALL_IMGS_ = "//" + Constants.NSPRE_XMLBGBL_ + ":" + Constants.XML_LN_XMLBGBL_IMG_;
+
+ private static final String FN_XMLBGBL_ = "xMLBGBl";
+ private static final String FN_STYLESHEET_ = "stylesheet";
+ private static final String FN_IMAGE_ = "image.";
+ private static final String FN_XMLSIG_ = "signature";
+
+ private static final String TS_XMLBGBL_ = "xml";
+ private static final String TS_STYLESHEET_ = "xsl";
+ private static final String TS_IMAGE_ = "img";
+ private static final String TS_XMLSIG_ = "xml";
+
+ private static final String LN_XMLSIG_ = "Signature";
+ private static final String LN_SIGENV_ = "SignatureEnvironment";
+
+ public Dispatcher()
+ {
+ super();
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException
+ {
+ try {
+ String screenName = request.getServletPath();
+ if (Constants.SRVN_UPLOAD_XML_.equals(screenName))
+ {
+ // Invalidate session if one exist from a previous use of the web application
+ HttpSession session = ((HttpServletRequest) request).getSession(false);
+ if (session != null) session.invalidate();
+
+ RequestDispatcher dispatcher = request.getRequestDispatcher(Constants.JSPPN_UPLOAD_XML_);
+ dispatcher.forward(request, response);
+ }
+ else
+ {
+ String message = "Unproper use of servlet \"" + screenName + "\". Please start with servlet \"" +
+ Constants.SRVN_UPLOAD_XML_ + "\".";
+ throw new ERechtClientException(message);
+ }
+ }
+ catch (Exception e)
+ {
+ Utils.returnErrorPage(request, response, e);
+ }
+
+ }
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException
+ {
+ try
+ {
+ String screenName = request.getServletPath();
+ if (Constants.SRVN_UPLOAD_XML_.equals(screenName))
+ {
+ // Evaluate uploaded XML BGBl
+ HttpSession session = request.getSession(true);
+
+ // Read BGBl XML upload from POST request
+ List params = parseParameters(request);
+ FileItem xMLBGBlFI = getFileItem(Constants.FPN_UPLOAD_XML_XMLBGBL_, params);
+ String xMLBGBlFileName = saveFileItem(xMLBGBlFI, FN_XMLBGBL_, TS_XMLBGBL_, session.getId(), this.getServletContext());
+ session.setAttribute(Constants.SCP_XMLBGBL_FNAME_, xMLBGBlFileName);
+
+ // Read stylesheet upload from POST request
+ FileItem stylesheetFI = getFileItem(Constants.FPN_UPLOAD_STYLESHEET_, params);
+ if (stylesheetFI.getName() != null && !"".equals(stylesheetFI.getName().trim()))
+ {
+ // Stylesheet has been uploaded
+ String stylesheetFileName = saveFileItem(stylesheetFI, FN_STYLESHEET_, TS_STYLESHEET_, session.getId(), this.getServletContext());
+ session.setAttribute(Constants.SCP_STYLESHEET_FNAME_, stylesheetFileName);
+ }
+
+ // Scan BGBl XML for potential images
+ Document xMLBGBlDoc = parseXMLBGBlDocument(xMLBGBlFileName, this.getServletContext());
+ ArrayList imageNames = scanXMLBGBlForImages(xMLBGBlDoc);
+
+ if (!imageNames.isEmpty())
+ {
+ // Images exist in the BGBl XML, therefore continue with image upload
+ session.setAttribute(Constants.SCP_IMAGE_NAMES_LIST_, imageNames);
+ RequestDispatcher dispatcher = request.getRequestDispatcher(Constants.JSPPN_UPLOAD_IMG_);
+ dispatcher.forward(request, response);
+ return;
+ }
+ else
+ {
+ // Indicate with empty List in session that there are no images available
+ session.setAttribute(Constants.SCP_IMAGES_LIST_, new ArrayList(0));
+ }
+ }
+ else if (Constants.SRVN_UPLOAD_IMG_.equals(screenName))
+ {
+ HttpSession session = ((HttpServletRequest) request).getSession(false);
+ if (session == null)
+ {
+ String message = "Could not read session object.";
+ throw new ERechtClientException(message);
+ }
+
+ List images = parseImageParameters(request, this.getServletContext());
+ session.setAttribute(Constants.SCP_IMAGES_LIST_, images);
+ }
+ else
+ {
+ String message = "Unproper use of servlet \"" + screenName + "\". Please start with servlet \"" +
+ Constants.SRVN_UPLOAD_XML_ + "\".";
+ logger_.error(message);
+ throw new ERechtClientException(message);
+ }
+
+ // Create and store signature
+ HttpSession session = request.getSession(false);
+ Document signatureResponse = createXMLSignature(request, session);
+ String signatureFileName = saveXMLSignature(signatureResponse, session.getId(), this.getServletContext());
+ Properties initProps = (Properties) this.getServletContext().getAttribute(Constants.WSCP_INIT_PROPS_);
+ String webAppHostPortFromMOASS = Utils.readInitProperty(initProps, Constants.IP_WEBAPP_HOST_PORT_FROM_MOA_SS_, logger_);
+ session.setAttribute(Constants.SCP_SIGNATURE_URL_, webAppHostPortFromMOASS + request.getContextPath() + signatureFileName);
+
+ // Dispatch Download JSP page
+ RequestDispatcher dispatcher = request.getRequestDispatcher(Constants.JSPPN_DOWNLOAD_SIG_);
+ dispatcher.forward(request, response);
+ }
+ catch (Exception e)
+ {
+ Utils.returnErrorPage(request, response, e);
+ }
+ }
+
+ private Document createXMLSignature(HttpServletRequest request, HttpSession session) throws ERechtClientException
+ {
+ RequestBuilder requestBuilder = new RequestBuilder(this.getServletContext(), request.getContextPath());
+ String xMLBGBlFileName = (String) session.getAttribute(Constants.SCP_XMLBGBL_FNAME_);
+ if (xMLBGBlFileName == null)
+ {
+ String message = "Could not read XML BGBl file name from session.";
+ logger_.error(message);
+ throw new ERechtClientException(message);
+ }
+ requestBuilder.setXMLDocument(xMLBGBlFileName);
+
+ String stylesheetFileName = (String) session.getAttribute(Constants.SCP_STYLESHEET_FNAME_);
+ if (stylesheetFileName != null)
+ {
+ requestBuilder.setStylesheet(stylesheetFileName);
+ }
+ else
+ {
+ requestBuilder.useDefaultStylesheet();
+ }
+
+ List images = (List) session.getAttribute(Constants.SCP_IMAGES_LIST_);
+ if (images == null)
+ {
+ String message = "Could not read images from session.";
+ logger_.error(message);
+ throw new ERechtClientException(message);
+ }
+ Iterator imagesIt = images.iterator();
+ while (imagesIt.hasNext())
+ {
+ Image currImg = (Image) imagesIt.next();
+ requestBuilder.addImage(currImg.name_, currImg.fileLocation_);
+ }
+ Document signatureRequest = requestBuilder.getRequest();
+ Properties initProps = (Properties) this.getServletContext().getAttribute(Constants.WSCP_INIT_PROPS_);
+ String serviceEndpoint = Utils.readInitProperty(initProps, Constants.IP_SS_ENDPOINT_, logger_);
+ String mOASchemaLoc = Utils.readInitProperty(initProps, Constants.IP_MOA_SCHEMA_, logger_);
+ String webAppHostPort = Utils.readInitProperty(initProps, Constants.IP_WEBAPP_HOST_PORT_, logger_);
+ Document signatureResponse = MOAInvoker.invokeSS(signatureRequest, serviceEndpoint,
+ "file:" + this.getServletContext().getRealPath(mOASchemaLoc));
+ return signatureResponse;
+ }
+
+ private List parseImageParameters(HttpServletRequest request, ServletContext context) throws ERechtClientException
+ {
+ HttpSession session = request.getSession(false);
+ if (session == null)
+ {
+ String message = "Could not read session object.";
+ throw new ERechtClientException(message);
+ }
+
+ ArrayList imageNames = (ArrayList) session.getAttribute(Constants.SCP_IMAGE_NAMES_LIST_);
+ List params = parseParameters(request);
+ ArrayList images = new ArrayList(imageNames.size());
+ for (int i = 0; i < params.size(); i++)
+ {
+ FileItem currItem = (FileItem) params.get(i);
+ if (currItem.getFieldName().startsWith(Constants.FPN_UPLOAD_IMG_IMG_))
+ {
+ if (currItem.getSize() <= 0)
+ {
+ String message = "No content received for image \"" + currItem.getFieldName() + "\".";
+ logger_.error(message);
+ throw new ERechtClientException(message);
+ }
+ String imgFileName = saveFileItem(currItem, FN_IMAGE_ + images.size(), TS_IMAGE_, session.getId(), context);
+ images.add(new Image(currItem.getFieldName().substring(Constants.FPN_UPLOAD_IMG_IMG_.length()), imgFileName));
+ }
+ }
+
+ // Check if there is a file item for each image name
+ if (imageNames.size() != images.size())
+ {
+ String message = "No correct number of immages has been uploaded (Expected " +
+ imageNames.size() + ", actually received " + images.size() + ").";
+ logger_.error(message);
+ throw new ERechtClientException(message);
+ }
+
+ return images;
+ }
+
+ private Document parseXMLBGBlDocument(String docFileName, ServletContext context) throws ERechtClientException
+ {
+ // TODO Change to validating parsing?
+ // DOMParser xmlParser = (DOMParser) context.getAttribute(Constants.WSCP_XMLPARSER_);
+ // InputSource docInputSource = new InputSource(docIS);
+ Document parsedDoc = null;
+ try
+ {
+ // xmlParser.parse(docInputSource);
+ FileInputStream docIS = new FileInputStream(context.getRealPath(docFileName));
+ parsedDoc = DOMUtils.parseWellFormed(docIS);
+
+ }
+ catch (Exception e)
+ {
+ String message = "Parsing XML BGBl document failed.";
+ logger_.error(message, e);
+ throw new ERechtClientException(message, e);
+ }
+
+ Element docElem = parsedDoc.getDocumentElement();
+ if (docElem.getNamespaceURI() != Constants.NSURI_XMLBGBL_ || docElem.getLocalName() != Constants.XML_LN_XMLBGBL_ROOT_)
+ {
+ String message = "XML BGBl has wrong root element (Local name equals \"" + docElem.getLocalName() + "\", NS-URI equals \"" + docElem.getNamespaceURI() + "\").";
+ logger_.error(message);
+ throw new ERechtClientException(message);
+ }
+
+ return parsedDoc;
+ }
+
+ private ArrayList scanXMLBGBlForImages(Document xMLBGBlDoc) throws ERechtClientException
+ {
+ // Get all bka:binary elements in XML BGBl document
+ NodeList imgElems;
+ try {
+ XPathUtils xpUtils = new XPathUtils();
+ String additionalNSPrefixes = Constants.NSPRE_XMLBGBL_ + " " + Constants.NSURI_XMLBGBL_;
+ xpUtils.setupContext(XPATH_ALL_IMGS_, xMLBGBlDoc.getDocumentElement(), additionalNSPrefixes);
+ imgElems = xpUtils.selectNodeSet(xMLBGBlDoc);
+ }
+ catch (Exception e)
+ {
+ String message = "Scanning for image elements in XML BGBl failed.";
+ logger_.error(message, e);
+ throw new ERechtClientException(message, e);
+ }
+
+ // Collect the file refs of all bka:binary elements (either in bka:binary/@ref or in bka:binary/bka:src)
+ ArrayList list = new ArrayList(imgElems.getLength());
+ for (int i = 0; i < imgElems.getLength(); i++)
+ {
+ Element currElem = (Element) imgElems.item(i);
+ Attr refAttr = currElem.getAttributeNodeNS(null, Constants.XML_LN_XMLBGBL_IMG_REF_);
+ if (refAttr != null)
+ {
+ list.add(i, refAttr.getValue());
+ }
+ else
+ {
+ list.add(DOMUtils.getChildText(currElem, Constants.NSURI_XMLBGBL_, Constants.XML_LN_XMLBGBL_IMG_SRC_));
+ }
+ }
+ return list;
+ }
+
+ private List parseParameters(HttpServletRequest request) throws ERechtClientException
+ {
+
+ if (ServletFileUpload.isMultipartContent(request))
+ {
+ // Request is encoded as multipart/form-data
+ List items;
+ try
+ {
+ FileItemFactory factory = new DiskFileItemFactory();
+ ServletFileUpload upload = null;;
+ upload = new ServletFileUpload(factory);
+ items = upload.parseRequest(request);
+ return items;
+ }
+ catch (FileUploadException e)
+ {
+ String message = "Parsing HTML form parameter failed.";
+ logger_.error(message, e);
+ throw new ERechtClientException(message, e);
+ }
+ }
+ else
+ {
+ // Request must be encoded als multipart/form-data
+ throw new ERechtClientException("HTML form encoding is not mulitpart/form-data.");
+ }
+ }
+
+ private FileItem getFileItem(String fileItemName, List fileItemParams)
+ {
+ Iterator iter = fileItemParams.iterator();
+ while (iter.hasNext())
+ {
+ FileItem currentFI = (FileItem) iter.next();
+ if (currentFI.getFieldName().equals(fileItemName)) return currentFI;
+ }
+ return null;
+ }
+
+ private String saveFileItem(FileItem fileItem, String name, String typeSuffix, String sessionId,
+ ServletContext context) throws ERechtClientException
+ {
+ Properties initProps = (Properties) this.getServletContext().getAttribute(Constants.WSCP_INIT_PROPS_);
+ String tempDir = Utils.readInitProperty(initProps, Constants.IP_TEMP_DIR_, logger_);
+ String fileName = tempDir + sessionId + "." + name + "." + typeSuffix;
+ String realFileName = context.getRealPath(fileName);
+ try {
+ fileItem.write(new File(realFileName));
+ } catch (Exception e)
+ {
+ String message = "Writing item \"" + name + "\" to file system failed.";
+ logger_.error(message, e);
+ throw new ERechtClientException(message, e);
+ }
+ return fileName;
+ }
+
+ private String saveXMLSignature(Document mOAResponse, String sessionId, ServletContext context)
+ throws ERechtClientException
+ {
+ Element sigEnvElem = DOMUtils.getChildElem(mOAResponse.getDocumentElement(), Constants.NSURI_MOA_13_, LN_SIGENV_);
+ Element signatureElem = DOMUtils.getChildElem(sigEnvElem, Constants.NSURI_DSIG_, LN_XMLSIG_);
+
+ Properties initProps = (Properties) this.getServletContext().getAttribute(Constants.WSCP_INIT_PROPS_);
+ String tempDir = Utils.readInitProperty(initProps, Constants.IP_TEMP_DIR_, logger_);
+ String fileName = tempDir + sessionId + "." + FN_XMLSIG_ + "." + TS_XMLSIG_;
+ String realFileName = context.getRealPath(fileName);
+ try {
+ FileOutputStream fileOS = new FileOutputStream(realFileName);
+ MOAInvoker.serializeElement(signatureElem, fileOS);
+ fileOS.close();
+ } catch (Exception e)
+ {
+ String message = "Writing xml signature to file system failed.";
+ logger_.error(message, e);
+ throw new ERechtClientException(message, e);
+ }
+ return fileName;
+ }
+
+ class Image
+ {
+ public String name_;
+ public String fileLocation_;
+
+ public Image(String name, String fileLocation)
+ {
+ name_ = name;
+ fileLocation_ = fileLocation;
+ }
+ }
+}
diff --git a/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/util/DOMUtils.java b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/util/DOMUtils.java
new file mode 100644
index 000000000..d82cf1d1b
--- /dev/null
+++ b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/util/DOMUtils.java
@@ -0,0 +1,169 @@
+/*
+ * Created on 28.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.ss.erechtclient.util;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.xerces.parsers.DOMParser;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import at.gv.egovernment.moa.ss.erechtclient.init.XMLParserErrorHandler;
+
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class DOMUtils
+{
+ private static final String SAX_NAMESPACES_FEATURE = "http://xml.org/sax/features/namespaces";
+ 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";
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Gets the first text node of the specified element.
+ *
+ * @param elem The element.
+ *
+ * @return the first text node of the specified element, or <code>null</code> if <code>element</code>
+ * equals <code>null</code>, or if the element has no text node.
+ */
+ public static String getText(Element elem)
+ {
+ if (elem == null) return null;
+ NodeList childNodes = elem.getChildNodes();
+ for (int i = 0; i < childNodes.getLength(); i++)
+ {
+ Node currNode = childNodes.item(i);
+ if (currNode.getNodeType() == Node.TEXT_NODE) return currNode.getNodeValue();
+ }
+ return null;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Gets the first text node of the specified child element from the specified parent element.
+ *
+ * @param parent The parent.
+ *
+ * @param childNS The namespace of the child element.
+ *
+ * @param childLocName The local name of the child element.
+ *
+ * @return the first text node of the specified child, or <code>null</code> if <code>parent</code> equals
+ * <code>null</code> or has no child element with the specified namespace and local name, or if
+ * the child element has no text node.
+ */
+ public static String getChildText(Element parent, String childNS, String childLocName)
+ {
+ if (parent == null) return null;
+ Element child = getChildElem(parent, childNS, childLocName);
+ if (child == null) return null;
+ return getText(child);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Gets the first child element of the specified parent with the specified namspace and local name.
+ *
+ * @param parent The parent.
+ *
+ * @param childNS The namespace of the child element to be searched for.
+ *
+ * @param childLocName The local name of the child element to be searched for.
+ *
+ * @return the first child element as described above, or <code>null</code> if <code>parent</code> is
+ * null or has no child elements with for the specified namespace and local name.
+ */
+ public static Element getChildElem(Element parent, String childNS, String childLocName)
+ {
+ List childElems = getChildElems(parent, childNS, childLocName, true);
+ return (childElems == null) ? null : (Element) childElems.get(0);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Gets all or the first child element(s) of the specified parent with the specified namspace and local
+ * name.
+ *
+ * @param parent The parent.
+ *
+ * @param childNS The namespace of the child elements to be searched for.
+ *
+ * @param childLocName The local name of the child elements to be searched for.
+ *
+ * @param firstOnly Specifies wheter only the first or all child elements with the specified namespace and
+ * local name should be returned.
+ *
+ * @return a <code>java.util.List</code> with objects of type <code>org.w3c.dom.Element</code>; each
+ * element in the list represents a child element as specified above. If <code>parent</code>
+ * equals <code>null</code>, or if there are no child elements as specified above, <code>null
+ * </code> will be returned.
+ */
+ public static List getChildElems(Element parent, String childNS, String childLocName, boolean firstOnly)
+ {
+ if (parent == null) return null;
+
+ ArrayList childElems = new ArrayList();
+ NodeList childNodes = parent.getChildNodes();
+ for (int i = 0; i < childNodes.getLength(); i++)
+ {
+ Node currNode = childNodes.item(i);
+ if (currNode.getNodeType() == Node.ELEMENT_NODE)
+ {
+ Element currElem = (Element) currNode;
+ if (childNS.equals(currElem.getNamespaceURI()) && childLocName.equals(currElem.getLocalName()))
+ {
+ childElems.add(currElem);
+ if (firstOnly) break;
+ }
+ }
+ }
+ return (childElems.size() == 0) ? null : childElems;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public static Document parseWellFormed(InputStream is) throws Exception
+ {
+ DOMParser xmlParser = new DOMParser();
+ try
+ {
+ xmlParser.setFeature(SAX_NAMESPACES_FEATURE, true);
+ xmlParser.setFeature(XERCES_CREATE_ENTITY_REF_NODES_FEATURE, false);
+ xmlParser.setFeature(XERCES_DEFER_NODE_EXPANSION_, false);
+ xmlParser.setErrorHandler(new XMLParserErrorHandler(false, true, true));
+ }
+ catch (SAXException e)
+ {
+ String message = "Initialization of XML parser failed.";
+ throw new Exception(message, e);
+ }
+ try
+ {
+ xmlParser.parse(new InputSource(is));
+ return xmlParser.getDocument();
+ }
+ catch (Exception e)
+ {
+ String message = "Wellformed parsing failed.";
+ throw new Exception(message, e);
+ }
+ }
+}
diff --git a/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/util/Utils.java b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/util/Utils.java
new file mode 100644
index 000000000..2f9e01057
--- /dev/null
+++ b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/util/Utils.java
@@ -0,0 +1,106 @@
+/*
+ * Created on 25.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.ss.erechtclient.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.Properties;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.log4j.Logger;
+
+import at.gv.egovernment.moa.ss.erechtclient.ERechtClientException;
+import at.gv.egovernment.moa.ss.erechtclient.init.Constants;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class Utils
+{
+ public static byte[] readFromInputStream(InputStream inputStream) throws IOException
+ {
+ byte[] currentBytes = new byte[500];
+ int bytesRead;
+ ByteArrayOutputStream result = new ByteArrayOutputStream();
+ do
+ {
+ bytesRead = inputStream.read(currentBytes);
+ if (bytesRead > 0)
+ {
+ result.write(currentBytes, 0, bytesRead);
+ }
+ }
+ while (bytesRead != -1);
+ return result.toByteArray();
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public static void transferStreams(InputStream in, OutputStream out) throws IOException
+ {
+ byte[] currentBytes = new byte[500];
+ int bytesRead;
+ do
+ {
+ bytesRead = in.read(currentBytes);
+ if (bytesRead > 0)
+ {
+ out.write(currentBytes, 0, bytesRead);
+ }
+ }
+ while (bytesRead != -1);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public static void returnErrorPage(HttpServletRequest request, HttpServletResponse response, Throwable t)
+ throws ServletException
+ {
+ Logger logger = Logger.getLogger(Constants.LH_SERVLETS_);
+
+ // Store Throwable in request context
+ request.setAttribute(Constants.RCP_ERROR_THROWABLE_, t);
+
+ RequestDispatcher dispatcher = request.getRequestDispatcher(Constants.JSPPN_ERROR_);
+ try
+ {
+ dispatcher.include(request, response);
+ }
+ catch (ServletException e)
+ {
+ logger.error("Returning error JSP page failed.", e);
+ throw e;
+ }
+ catch (IOException e)
+ {
+ String message = "Returning error JSP page failed.";
+ logger.error(message, e);
+ throw new ServletException(message, e);
+ }
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public static String readInitProperty(Properties initProps, String name, Logger logger)
+ throws ERechtClientException
+ {
+ String value = initProps.getProperty(name);
+ if (value == null)
+ {
+ String message = "Could not read property \"" + name + "\" from configuration properties.";
+ logger.error(message);
+ throw new ERechtClientException(message);
+ }
+ return value;
+ }
+}
diff --git a/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/util/XPathUtils.java b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/util/XPathUtils.java
new file mode 100644
index 000000000..4f2862f58
--- /dev/null
+++ b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/util/XPathUtils.java
@@ -0,0 +1,162 @@
+/*
+ * Created on 02.12.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.ss.erechtclient.util;
+
+import java.util.HashMap;
+import java.util.StringTokenizer;
+
+import org.apache.xml.utils.PrefixResolverDefault;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class XPathUtils
+{
+ /**
+ * The XPath context for the XPath engine.
+ */
+ protected XPathContext xPathContext_;
+
+ /**
+ * The prefix resolver for the XPath engine.
+ */
+ protected PrefixResolver prefixResolver_;
+
+ /**
+ * The XPath engine.
+ */
+ protected XPath xPath_;
+
+ /* ==================================================================================================== */
+
+ public void setupContext(String xPathExpr, Node namespaceNode, String additionalNSPrefixes)
+ throws Exception
+ {
+
+ try
+ {
+ // Set up a new evaluation context
+ xPathContext_ = new XPathContext();
+
+ // Set up the namespace prefix resolver for the XPath engine
+ prefixResolver_ = new PrefixResolver(namespaceNode, additionalNSPrefixes);
+
+ // Initialize XPath engine
+ xPath_ = new XPath(xPathExpr, null, prefixResolver_, XPath.SELECT, null);
+ }
+ catch (Exception e)
+ {
+ throw new Exception("Setting up XPath evaluation context failed.", e);
+ }
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public NodeList selectNodeSet(Node contextNode) throws Exception
+ {
+ XObject xObject;
+ try
+ {
+ xObject = xPath_.execute(xPathContext_, contextNode, prefixResolver_);
+ return xObject.nodelist();
+ }
+ catch (Exception e)
+ {
+ throw new Exception("Executing XPath expression failed.", e);
+ }
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public boolean selectBoolean(Node contextNode) throws Exception
+ {
+ XObject xObject;
+ try
+ {
+ xObject = xPath_.execute(xPathContext_, contextNode, prefixResolver_);
+ return xObject.bool();
+ }
+ catch (Exception e)
+ {
+ throw new Exception("Executing XPath expression failed.", e);
+ }
+ }
+
+ /* ==================================================================================================== */
+
+ /**
+ * Special extension of the {@link org.apache.xml.utils.PrefixResolverDefault} interface. Used to
+ * configure the Apache Xalan XPath engine which is employed as the backbone of this class.
+ */
+ protected class PrefixResolver extends PrefixResolverDefault
+ {
+
+ /**
+ * Contains the additionally specified namespace prefix (key) to namespace URI (value) attributions.
+ */
+ protected HashMap additionalNSPrefixesMap_;
+
+ /* ================================================================================================== */
+
+ /**
+ * Basic constructor.
+ *
+ * @param xpathExpressionContext The namespace declarations in scope for this node will be used to get
+ * the namespace uri for a prefix specified in the XPath expression.
+ *
+ * @param additionalNSPrefixes Allows the specification of additional prefix to uri attributions apart
+ * from the declarations in scope for the parameter <code>
+ * xpathExpressionContext</code>. May be <code>null</code>.
+ */
+ public PrefixResolver(Node xpathExpressionContext, String additionalNSPrefixes) throws Exception
+ {
+ super(xpathExpressionContext);
+ additionalNSPrefixesMap_ = new HashMap();
+
+ // Register the specified additional namespace prefix to namespace uri attributions
+ if (additionalNSPrefixes != null)
+ {
+ StringTokenizer tokenizer = new StringTokenizer(additionalNSPrefixes, " ");
+ while (tokenizer.hasMoreTokens())
+ {
+ String prefix = tokenizer.nextToken();
+ if (!tokenizer.hasMoreTokens())
+ {
+
+ // There must be an even number of tokens in the string
+ throw new Exception("Parameter \"additionalNSPrefixes\" must have an even number of tokens.");
+ }
+ String uri = tokenizer.nextToken();
+ additionalNSPrefixesMap_.put(prefix, uri);
+ }
+ }
+ }
+
+ /* -------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Gets the namespace uri for the specified namespace prefix. The additionally specified prefixes
+ * overrule the prefixes found in the specified namespace node.
+ *
+ * @param prefix The namespace prefix for which a namespace uri should be found.
+ *
+ * @return the namespace uri for the specified namespace prefix.
+ */
+ public String getNamespaceForPrefix(String prefix)
+ {
+ String additionalURI = (String) additionalNSPrefixesMap_.get(prefix);
+ return (additionalURI != null)
+ ? additionalURI
+ : super.getNamespaceForPrefix(prefix);
+ }
+ }
+}
+