aboutsummaryrefslogtreecommitdiff
path: root/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa
diff options
context:
space:
mode:
Diffstat (limited to 'spss.slinterface/WEB-INF/src/at/gv/egovernment/moa')
-rw-r--r--spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/Constants.java55
-rw-r--r--spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/RequestWrapper.java57
-rw-r--r--spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/ResponseWrapper.java44
-rw-r--r--spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/SL2MOAFilter.java341
-rw-r--r--spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletInputStream.java55
-rw-r--r--spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletOutputStream.java50
-rw-r--r--spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/listeners/ContextListener.java153
-rw-r--r--spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/moainvoker/MOAInvoker.java92
-rw-r--r--spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/servlets/MOAServlet.java111
9 files changed, 958 insertions, 0 deletions
diff --git a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/Constants.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/Constants.java
new file mode 100644
index 000000000..c6ea9e88d
--- /dev/null
+++ b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/Constants.java
@@ -0,0 +1,55 @@
+/*
+ * Created on 18.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class Constants
+{
+ // System properties
+ public static final String SP_INIT_PROPS_LOC_ =
+ "at.gv.egovernment.moa.spss.slinterface.PropertiesLocation";
+
+ // Init properties
+ public static final String IP_SL2MOA_STYLESHEET_ = "location.stylesheet.sl2moa";
+ public static final String IP_MOA2SL_STYLESHEET_ = "location.stylesheet.moa2sl";
+ public static final String IP_SL_SCHEMA_ = "location.schema.sl";
+ public static final String IP_MOA_SCHEMA_ = "location.schema.moa";
+ public static final String IP_SP_ENDPOINT_ = "service.endpoint.sp";
+
+ // Logging hierarchies
+
+ public static final String LH_BASE_ = "slinterface";
+ public static final String LH_LISTENERS_ = LH_BASE_ + ".listeners";
+ public static final String LH_FILTERS_ = LH_BASE_ + ".filters";
+ public static final String LH_SERVLETS_ = LH_BASE_ + ".servlets";
+
+ // Web service context parameters
+
+ public static final String WSCP_INIT_PROPS_ = "initProperties";
+ public static final String WSCP_SL2MOA_TRANSFORMER_ = "sl2MoaTransformer";
+ public static final String WSCP_MOA2SL_TRANSFORMER_ = "moa2SlTransformer";
+ public static final String WSCP_XMLPARSER_ = "xmlParser";
+
+ // Security-Layer constants
+
+ public static final String SLC_NAME_HTTP_REQUEST_ = "http-security-layer-request";
+ public static final String SLC_NAME_XML_REQUEST_ = "XMLRequest";
+ public static final String SLC_NAME_DATA_URL_ = "DataURL";
+ public static final String SLC_NAME_STYLESHEET_URL_ = "StylesheetURL";
+ public static final String SLC_NAME_REDIRECT_URL_ = "RedirectURL";
+
+ // Namespace URIs
+
+ public static final String NSURI_SL_11_ = "http://www.buergerkarte.at/namespaces/securitylayer/20020831#";
+ public static final String NSURI_SL_12_ = "http://www.buergerkarte.at/namespaces/securitylayer/20031231#";
+ public static final String NSURI_MOA_12_ = "http://reference.e-government.gv.at/namespace/moa/20020822#";
+
+ // MOA invoker constants
+
+ public static final String MI_SP_QNAME_ = "SignatureVerification";
+}
diff --git a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/RequestWrapper.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/RequestWrapper.java
new file mode 100644
index 000000000..a6652a56e
--- /dev/null
+++ b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/RequestWrapper.java
@@ -0,0 +1,57 @@
+/*
+ * Created on 19.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.filters;
+
+import java.io.ByteArrayInputStream;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class RequestWrapper extends HttpServletRequestWrapper
+{
+
+ private ServletInputStream inputStream_;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Generates a request wrapper around a particular request.
+ *
+ * @param request The request to be wrapped.
+ *
+ * @param inputStream The new inputstream, which will be returned by method {@link #getInputStream}, and
+ * whose length will be returned by method {@link #getContentLength}.
+ */
+ public RequestWrapper(HttpServletRequest request, ByteArrayInputStream inputStream)
+ {
+ super(request);
+ inputStream_ = new ServletInputStream(inputStream);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see #RequestWrapper(HttpServletRequest, ByteArrayInputStream)
+ */
+ public javax.servlet.ServletInputStream getInputStream()
+ {
+ return inputStream_;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see #RequestWrapper(HttpServletRequest, ByteArrayInputStream)
+ */
+ public int getContentLength()
+ {
+ return inputStream_.getContentLength();
+ }
+
+}
diff --git a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/ResponseWrapper.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/ResponseWrapper.java
new file mode 100644
index 000000000..420723abb
--- /dev/null
+++ b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/ResponseWrapper.java
@@ -0,0 +1,44 @@
+/*
+ * Created on 18.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.filters;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class ResponseWrapper extends HttpServletResponseWrapper
+{
+ private ServletOutputStream outputStream_;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public ResponseWrapper(HttpServletResponse response)
+ {
+ super(response);
+ outputStream_ = new ServletOutputStream();
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public javax.servlet.ServletOutputStream getOutputStream()
+ {
+ return outputStream_;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Returns the wrapped response as a byte array.
+ *
+ * @return the response as a byte array.
+ */
+ public byte[] toByteArray()
+ {
+ return outputStream_.toByteArray();
+ }
+}
diff --git a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/SL2MOAFilter.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/SL2MOAFilter.java
new file mode 100644
index 000000000..4632c80f5
--- /dev/null
+++ b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/SL2MOAFilter.java
@@ -0,0 +1,341 @@
+/*
+ * Created on 18.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.filters;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.CharArrayReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.commons.fileupload.DiskFileUpload;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileUpload;
+import org.apache.commons.fileupload.FileUploadException;
+import org.apache.log4j.Logger;
+import org.apache.xerces.parsers.DOMParser;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+
+import at.gv.egovernment.moa.spss.slinterface.Constants;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class SL2MOAFilter implements Filter
+{
+ private static Logger logger_ = Logger.getLogger(Constants.LH_FILTERS_);
+
+ private FilterConfig config_;
+ private SLRequest slRequest_;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
+ */
+ public void init(FilterConfig config) throws ServletException
+ {
+ // Store filter configuration
+ config_ = config;
+
+ slRequest_ = new SLRequest();
+
+ // Initialize stylesheet transform SL2MOA
+ ServletContext context = config_.getServletContext();
+ Transformer sl2MoaTransformer = (Transformer) context.getAttribute(Constants.WSCP_SL2MOA_TRANSFORMER_);
+ if (sl2MoaTransformer == null)
+ {
+ initTransformer(context, Constants.IP_SL2MOA_STYLESHEET_);
+ }
+
+ // Initialize stylesheet transform MOA2SL
+ Transformer moa2SlTransformer = (Transformer) context.getAttribute(Constants.WSCP_MOA2SL_TRANSFORMER_);
+ if (moa2SlTransformer == null)
+ {
+ initTransformer(context, Constants.IP_MOA2SL_STYLESHEET_);
+ }
+
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /*
+ * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse,
+ * javax.servlet.FilterChain)
+ */
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+ throws IOException, ServletException
+ {
+ // Check if request is HTTP-POST
+ checkHttpPost((HttpServletRequest) request);
+
+ // Get SL request from content of request
+ parseRequest((HttpServletRequest) request);
+
+ // Schema validate SL request
+ CharArrayReader slXmlRequestCAR = new CharArrayReader(slRequest_.xmlRequest_.toCharArray());
+ Document slXMLRequestDoc = parseSlXmlRequest(slXmlRequestCAR);
+
+ // Transform SL request into a MOA SPSS request
+ Transformer sl2MoaTransformer =
+ (Transformer) config_.getServletContext().getAttribute(Constants.WSCP_SL2MOA_TRANSFORMER_);
+ DOMSource slXMLRequestDS = new DOMSource(slXMLRequestDoc);
+ ByteArrayOutputStream moaRequestBOS = new ByteArrayOutputStream();
+ StreamResult moaRequestResult = new StreamResult(moaRequestBOS);
+ try
+ {
+ sl2MoaTransformer.transform(slXMLRequestDS, moaRequestResult);
+ }
+ catch (TransformerException e)
+ {
+ String message = "Transforming SL XML request into MOA XML request failed.";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+ logger_.debug("MOA XML Request:\n" + moaRequestBOS.toString());
+ ByteArrayInputStream moaRequestIS = new ByteArrayInputStream(moaRequestBOS.toByteArray());
+
+ // Invoke MOA SPSS
+ RequestWrapper requestWrapper = new RequestWrapper((HttpServletRequest) request, moaRequestIS);
+ ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse) response);
+ chain.doFilter(requestWrapper, responseWrapper);
+
+ // Prepare response to client
+ response.setContentType("text/xml");
+
+ // Transform MOA response into a SL response and send SL response back to client
+ Transformer moa2SlTransformer =
+ (Transformer) config_.getServletContext().getAttribute(Constants.WSCP_MOA2SL_TRANSFORMER_);
+ ServletOutputStream moaResponseSOS = (ServletOutputStream) responseWrapper.getOutputStream();
+ ByteArrayInputStream moaResponseBIS = new ByteArrayInputStream(moaResponseSOS.toByteArray());
+ StreamSource moaResponseSource = new StreamSource(moaResponseBIS);
+ StreamResult slResponseResult = new StreamResult(response.getOutputStream());
+ try
+ {
+ moa2SlTransformer.transform(moaResponseSource, slResponseResult);
+ }
+ catch (TransformerException e)
+ {
+ String message = "Transforming MOA XML response into SL XML response failed.";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see javax.servlet.Filter#destroy()
+ */
+ public void destroy()
+ {
+ // Nothing to do here at the moment.
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private void initTransformer(ServletContext context, String initPropStylesheetLoc) throws ServletException
+ {
+ String stylesheetName =
+ (Constants.IP_SL2MOA_STYLESHEET_.equals(initPropStylesheetLoc))
+ ? "sl2Moa"
+ : "moa2Sl";
+
+ String contextAttrName =
+ (Constants.IP_SL2MOA_STYLESHEET_.equals(initPropStylesheetLoc))
+ ? Constants.WSCP_SL2MOA_TRANSFORMER_
+ : Constants.WSCP_MOA2SL_TRANSFORMER_;
+
+ TransformerFactory transformerFactory = TransformerFactory.newInstance();
+ Properties initProps = (Properties) context.getAttribute(Constants.WSCP_INIT_PROPS_);
+ String stylesheetLoc = initProps.getProperty(initPropStylesheetLoc);
+ InputStream stylesheetIS = context.getResourceAsStream(stylesheetLoc);
+ if (stylesheetIS == null)
+ {
+ String message =
+ "Cannot load " + stylesheetName + " stylesheet from location \"" + stylesheetLoc + "\".";
+ logger_.error(message);
+ throw new ServletException(message);
+ }
+ Transformer transformer;
+ try
+ {
+ StreamSource stylesheetSS = new StreamSource(stylesheetIS);
+ transformer = transformerFactory.newTransformer(stylesheetSS);
+ }
+ catch (TransformerConfigurationException e)
+ {
+ String message = "Cannot create XSLT transformer with " + stylesheetName + " stylesheet.";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+ context.setAttribute(contextAttrName, transformer);
+ }
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Parses the http request.
+ */
+ private void parseRequest(HttpServletRequest request) throws IOException
+ {
+ // Check if request URL ends with "http-security-layer-request"
+ // @TODO Don't know if this check is sufficient - spec says request URL must have this value as path
+ String requestURI = request.getRequestURI();
+ if (!requestURI.endsWith(Constants.SLC_NAME_HTTP_REQUEST_))
+ {
+ String message = "Request does not end with \"" + Constants.SLC_NAME_HTTP_REQUEST_ + "\".";
+ logger_.error(message);
+ throw new IOException(message);
+ }
+
+ if (FileUpload.isMultipartContent(request))
+ {
+ // Request is encoded as mulitpart/form-data
+ List items;
+ try
+ {
+ DiskFileUpload upload = new DiskFileUpload();
+ items = upload.parseRequest(request);
+ }
+ catch (FileUploadException e)
+ {
+ String message = "Cannot parse multipart/form-data request.";
+ logger_.error(message);
+ throw new IOException(message);
+ }
+
+ Iterator itemsIt = items.iterator();
+ while (itemsIt.hasNext())
+ {
+ FileItem currItem = (FileItem) itemsIt.next();
+ String currItemName = currItem.getFieldName();
+ if (Constants.SLC_NAME_XML_REQUEST_.equals(currItemName))
+ slRequest_.xmlRequest_ = currItem.getString();
+ else if (Constants.SLC_NAME_DATA_URL_.equals(currItemName))
+ slRequest_.dataUrl_ = currItem.getString();
+ else if (Constants.SLC_NAME_STYLESHEET_URL_.equals(currItemName))
+ slRequest_.stylesheetUrl_ = currItem.getString();
+ else if (Constants.SLC_NAME_REDIRECT_URL_.equals(currItemName))
+ slRequest_.redirectUrl_ = currItem.getString();
+ else
+ continue; // @TODO Do not evaluate other params at the moment
+ }
+ }
+ else
+ {
+ // Request is encoded as application/x-www-form-urlencoded
+ Map paramsMap = request.getParameterMap();
+ Iterator paramNames = paramsMap.keySet().iterator();
+ while (paramNames.hasNext())
+ {
+ String currName = (String) paramNames.next();
+ String[] currValues = (String[]) paramsMap.get(currName);
+ if (Constants.SLC_NAME_XML_REQUEST_.equals(currName))
+ slRequest_.xmlRequest_ = currValues[0];
+ else if (Constants.SLC_NAME_DATA_URL_.equals(currName))
+ slRequest_.dataUrl_ = currValues[0];
+ else if (Constants.SLC_NAME_STYLESHEET_URL_.equals(currName))
+ slRequest_.stylesheetUrl_ = currValues[0];
+ else if (Constants.SLC_NAME_REDIRECT_URL_.equals(currName))
+ slRequest_.redirectUrl_ = currValues[0];
+ else
+ continue; // @TODO Do not evaluate other params at the moment
+ }
+ }
+
+ if (slRequest_.xmlRequest_ == null || slRequest_.dataUrl_ == null ||
+ slRequest_.stylesheetUrl_ != null || slRequest_.redirectUrl_ != null)
+ {
+ // @TODO Only combindation of XMLRequest and StylesheetURL allowed at the moment
+ String message = "Currently only (XMLRequest + DataURL) is supported.";
+ logger_.error(message);
+ throw new IOException(message);
+ }
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private Document parseSlXmlRequest(Reader slXmlRequest) throws ServletException
+ {
+ // Parse sl request
+ InputSource slXMLRequestIS = new InputSource(slXmlRequest);
+ Document slXmlRequestDoc = null;
+ try
+ {
+ DOMParser xmlParser = (DOMParser) config_.getServletContext().getAttribute(Constants.WSCP_XMLPARSER_);
+ xmlParser.parse(slXMLRequestIS);
+ slXmlRequestDoc = xmlParser.getDocument();
+ }
+ catch (Exception e)
+ {
+ String message = "Parsing Security-Layer request failed.";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+
+ // Check if namespace is correct
+ String namespaceURI = slXmlRequestDoc.getDocumentElement().getNamespaceURI();
+ if (!Constants.NSURI_SL_11_.equals(namespaceURI) && !Constants.NSURI_SL_12_.equals(namespaceURI))
+ {
+ String message = "XML request has invalid namespace: \"" + namespaceURI + "\".";
+ logger_.error(message);
+ throw new ServletException(message);
+ }
+
+ return slXmlRequestDoc;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private void checkHttpPost(HttpServletRequest request) throws ServletException
+ {
+ String method = request.getMethod();
+ if (!"POST".equals(method))
+ {
+ String message = "HTTP method \"" + method + "\" not supported. Must be \"POST\".";
+ logger_.error(message);
+ throw new ServletException(message);
+ }
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Helper class, representing the fields of a Security-Layer request.
+ *
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+ class SLRequest
+ {
+ public String xmlRequest_;
+ public String dataUrl_;
+ public String stylesheetUrl_;
+ public String redirectUrl_;
+ }
+}
diff --git a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletInputStream.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletInputStream.java
new file mode 100644
index 000000000..b0609c2f8
--- /dev/null
+++ b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletInputStream.java
@@ -0,0 +1,55 @@
+/*
+ * Created on 19.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.filters;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class ServletInputStream extends javax.servlet.ServletInputStream
+{
+ private ByteArrayInputStream inputStream_;
+ private int length_;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Generates a new <code>ServletInputStram</code> from the specified stream.
+ *
+ * @param inputStream See above.
+ */
+ public ServletInputStream(ByteArrayInputStream inputStream)
+ {
+ super();
+ inputStream_ = inputStream;
+ length_ = inputStream_.available();
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Reads a single byte from the underlying <code>ByteArrayInputStream</code>.
+ *
+ * @see java.io.InputStream#read()
+ */
+ public int read() throws IOException
+ {
+ return inputStream_.read();
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Gets the length of the content from this input stream. This equals to the number of bytes which where
+ * available at the time of creating this <code>ServletInputStream</code>.
+ */
+ public int getContentLength()
+ {
+ return length_;
+ }
+}
diff --git a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletOutputStream.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletOutputStream.java
new file mode 100644
index 000000000..b790ee55c
--- /dev/null
+++ b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletOutputStream.java
@@ -0,0 +1,50 @@
+/*
+ * Created on 18.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.filters;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class ServletOutputStream extends javax.servlet.ServletOutputStream
+{
+ private ByteArrayOutputStream outputStream_;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Default constructor.
+ */
+ public ServletOutputStream()
+ {
+ super();
+ outputStream_ = new ByteArrayOutputStream();
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see java.io.OutputStream#write(int)
+ */
+ public void write(int b) throws IOException
+ {
+ outputStream_.write(b);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Returns the content of this stream as a byte array.
+ *
+ * @return the content of this stream as a byte array.
+ */
+ public byte[] toByteArray()
+ {
+ return outputStream_.toByteArray();
+ }
+}
diff --git a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/listeners/ContextListener.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/listeners/ContextListener.java
new file mode 100644
index 000000000..5b32a482b
--- /dev/null
+++ b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/listeners/ContextListener.java
@@ -0,0 +1,153 @@
+/*
+ * Created on 18.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.listeners;
+
+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;
+
+import at.gv.egovernment.moa.spss.slinterface.Constants;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+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";
+
+ private static final int BIG_PRIME = 2039;
+
+ private static Logger logger_ = Logger.getLogger(Constants.LH_LISTENERS_);
+
+ /**
+ * 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.SP_INIT_PROPS_LOC_);
+ if (initPropsLoc == null)
+ {
+ logger_.error("System property \"" + Constants.SP_INIT_PROPS_LOC_ + "\" not set.");
+ return;
+ }
+
+ // Load init properties
+ try
+ {
+ InputStream initPropsIS = context.getResourceAsStream(initPropsLoc);
+ Properties initProps = new Properties();
+ initProps.load(initPropsIS);
+ context.setAttribute(Constants.WSCP_INIT_PROPS_, initProps);
+ }
+ catch (IOException e)
+ {
+ logger_.error("Cannot load initialization properties from location \"" + initPropsLoc + "\".", e);
+ }
+
+ // 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);
+
+ Properties initProps = (Properties) context.getAttribute(Constants.WSCP_INIT_PROPS_);
+ String slSchemaLoc = initProps.getProperty(Constants.IP_SL_SCHEMA_);
+ preparseSchema(context, preparser, slSchemaLoc);
+ String moaSchemaLoc = initProps.getProperty(Constants.IP_MOA_SCHEMA_);
+ preparseSchema(context, preparser, moaSchemaLoc);
+
+ 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);
+ }
+ catch (SAXException e)
+ {
+ String message = "Initialization of XML parser failed.";
+ logger_.error(message, e);
+ }
+ context.setAttribute(Constants.WSCP_XMLPARSER_, xmlParser);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * 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 void preparseSchema(ServletContext context, XMLGrammarPreparser preparser, String schemaLoc)
+ {
+ InputStream schemaIS = context.getResourceAsStream(schemaLoc);
+ if (schemaIS == null)
+ {
+ String message = "Cannot load schema from location \"" + schemaLoc + "\".";
+ logger_.error(message);
+ }
+ 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_.error(message, e);
+ }
+ }
+
+
+}
diff --git a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/moainvoker/MOAInvoker.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/moainvoker/MOAInvoker.java
new file mode 100644
index 000000000..e89d255f0
--- /dev/null
+++ b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/moainvoker/MOAInvoker.java
@@ -0,0 +1,92 @@
+/*
+ * Created on 19.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.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.xml.serialize.OutputFormat;
+import org.apache.xml.serialize.XMLSerializer;
+import org.w3c.dom.Document;
+
+import at.gv.egovernment.moa.spss.slinterface.Constants;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class MOAInvoker
+{
+ /**
+ * Invokes MOA SP.
+ *
+ * @param request The XML request to be sent to MOA SP.
+ *
+ * @param endpoint The endpoint of the SOAP service where to send the XML request to.
+ *
+ * @return the XML response from the service.
+ *
+ * @throws Exception if getting the XML response from the SOAP response body fails.
+ *
+ * @throws RemoteException if MOA SP signals an error.
+ *
+ * @throws ServiceException if the SOAP client invoking MOA SP signals an error.
+ */
+ public static Document invokeSP(Document request, String endpoint)
+ throws Exception, RemoteException, ServiceException
+ {
+ QName serviceQName = new QName(Constants.MI_SP_QNAME_);
+ return invoke(request, endpoint, serviceQName);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private static Document invoke(Document request, String endpoint, QName serviceQName) throws Exception
+ {
+ // 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);
+ Document response = responseBody.getAsDocument();
+ return response;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public static void serializeDocument(Document doc, OutputStream out) throws IOException
+ {
+ OutputFormat format = new OutputFormat(doc);
+
+ format.setLineSeparator("\n");
+ format.setIndenting(false);
+ format.setPreserveSpace(true);
+ format.setOmitXMLDeclaration(false);
+ format.setEncoding("UTF-8");
+
+ XMLSerializer serializer = new XMLSerializer(out, format);
+ serializer.serialize(doc);
+ }
+}
diff --git a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/servlets/MOAServlet.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/servlets/MOAServlet.java
new file mode 100644
index 000000000..1ec18e5cb
--- /dev/null
+++ b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/servlets/MOAServlet.java
@@ -0,0 +1,111 @@
+/*
+ * Created on 19.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.servlets;
+
+import java.io.IOException;
+import java.rmi.RemoteException;
+import java.util.Properties;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.rpc.ServiceException;
+
+import org.apache.log4j.Logger;
+import org.apache.xerces.parsers.DOMParser;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import at.gv.egovernment.moa.spss.slinterface.Constants;
+import at.gv.egovernment.moa.spss.slinterface.moainvoker.MOAInvoker;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class MOAServlet extends HttpServlet
+{
+ private static Logger logger_ = Logger.getLogger(Constants.LH_SERVLETS_);
+
+ /**
+ * Default constructor.
+ */
+ public MOAServlet()
+ {
+ super();
+ }
+
+ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException
+ {
+ // Get moa request form http request
+ Document moaXmlRequest = null;
+ DOMParser xmlParser = (DOMParser) this.getServletContext().getAttribute(Constants.WSCP_XMLPARSER_);
+ try
+ {
+ InputSource requestIS = new InputSource(request.getInputStream());
+ xmlParser.parse(requestIS);
+ moaXmlRequest = xmlParser.getDocument();
+ }
+ catch (IOException ioe)
+ {
+ String message = "Getting MOA XML request from http request input failed.";
+ logger_.error(message, ioe);
+ throw new ServletException(message, ioe);
+ }
+ catch (SAXException se)
+ {
+ String message = "Parsing MOA XML request got from http request failed.";
+ logger_.error(message, se);
+ throw new ServletException(message, se);
+ }
+
+ // Send request to MOA SP
+ Properties initProps = (Properties) this.getServletContext().getAttribute(Constants.WSCP_INIT_PROPS_);
+ String endPoint = initProps.getProperty(Constants.IP_SP_ENDPOINT_);
+ if (endPoint == null)
+ {
+ String message = "No endpoint configured for MOA SP service.";
+ logger_.error(message);
+ throw new ServletException(message);
+ }
+ Document moaXMLResponseDoc = null;
+ try
+ {
+ moaXMLResponseDoc = MOAInvoker.invokeSP(moaXmlRequest, endPoint);
+ }
+ catch (Exception e)
+ {
+ String message;
+ if (e instanceof RemoteException)
+ {
+ message = "MOA SP service indicated an error at request execution.";
+ }
+ else if (e instanceof ServiceException)
+ {
+ message = "MOA SP client indicated an error at request execution.";
+ }
+ else
+ {
+ message = "Could not create DOM Document from MOA SP service response.";
+ }
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+
+ // Write moa response to http response
+ try
+ {
+ MOAInvoker.serializeDocument(moaXMLResponseDoc, response.getOutputStream());
+ }
+ catch (IOException e)
+ {
+ String message = "Writing MOA SP XML response to http response failed.";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+ }
+}