summaryrefslogtreecommitdiff
path: root/bkucommon/src/main/java/at/gv
diff options
context:
space:
mode:
authormcentner <mcentner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4>2009-09-29 17:36:06 +0000
committermcentner <mcentner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4>2009-09-29 17:36:06 +0000
commitbd070e82c276afb8c1c3a9ddc3b5712783760881 (patch)
treed33ea8232d66b339554b3fbf41cb5ca846efc1e3 /bkucommon/src/main/java/at/gv
parent9d4b3e9214f653d2556608958642d02814d4e7a3 (diff)
downloadmocca-bd070e82c276afb8c1c3a9ddc3b5712783760881.tar.gz
mocca-bd070e82c276afb8c1c3a9ddc3b5712783760881.tar.bz2
mocca-bd070e82c276afb8c1c3a9ddc3b5712783760881.zip
Logging issues fixed:
- Added possibility to configure logging of BKUWebstart. Logging is now configured from log4j configuration deployed with BKUWebstart in a first step. In a second step the webstart launcher looks for a log4j configuration file in the user's mooca configuration directory and updates the log4j configuration. - Logging of IAIK PKI properly initialized. IAIK PKI does not mess with the log4j configuration any longer. - Changed log4j accordingly (an appender is now needed as IAIK PKI does not reconfigure log4j any longer). Added css-stylesheet to ErrorResponses issued by the BKU to improve the presentation to the user. Changed dependencies of BKUWebStart (see Issue#469 https://egovlabs.gv.at/tracker/index.php?func=detail&aid=469&group_id=13&atid=134). DataURLConnection now uses the request encoding of SL < 1.2. application/x-www-form-urlencoded is now used as default encoding method. multipart/form-data is used only if transfer parameters are present in the request that require a Content-Type parameter. This can only be set with multipart/form-data. This is not in conformance with SL 1.2, however it should improve compatibility with applications. Therefore, removed the ability to configure the DataURLConnection implementation class. DataURLConnection now uses a streaming implementation for encoding of application/x-www-form-urlencoded requests. XWWWFormUrlImputDecoder now uses a streaming implementation for decoding of application/x-www-form-urlencoded requests. Fixed Bug in SLResultPart that caused a binary response to be provided as parameter "XMLResponse" in a multipart/form-data encoded request to DataURL. SLCommandFactory now supports unmarshalling of SL < 1.2 requests in order issue meaningful error messages. Therefore, the marshaling context for response marshaling had to be separated from the marshaling context for requests in order to avoid the marshaling of SL < 1.2 namespace prefixes in SL 1.2 responses. Target attribute in QualifiedProperties is now marshaled. (see Issue#470 https://egovlabs.gv.at/tracker/index.php?func=detail&aid=470&group_id=13&atid=134) Reporting of XML validation errors improved. git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@510 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4
Diffstat (limited to 'bkucommon/src/main/java/at/gv')
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrl.java9
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java2
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java342
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java29
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/binding/LegacyDataUrlConnectionImpl.java259
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputDecoder.java83
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputIterator.java376
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/binding/multipart/SLResultPart.java41
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidatorImpl.java24
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLog.java144
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLogFactory.java59
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java51
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLMarshallerFactory.java172
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLResult.java8
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java13
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureResultImpl.java15
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImpl.java6
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandImpl.java2
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusResultImpl.java4
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxImpl.java1
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultFileImpl.java15
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultImpl.java4
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateResultImpl.java4
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationResultImpl.java4
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java94
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java1
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java18
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLExceptionMessages.java6
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLVersionException.java28
29 files changed, 1301 insertions, 513 deletions
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrl.java
index 1db8c836..d3945253 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrl.java
@@ -16,7 +16,6 @@
*/
package at.gv.egiz.bku.binding;
-import at.gv.egiz.bku.conf.Configuration;
import at.gv.egiz.bku.conf.Configurator;
import java.net.MalformedURLException;
import java.net.URL;
@@ -89,13 +88,7 @@ public class DataUrl {
if (configuration != null) {
String className = configuration.getProperty(Configurator.DATAURLCONNECTION_CONFIG_P);
if (className != null) {
- try {
- log.info("set DataURLConnection class: " + className);
- Class c = Class.forName(className);
- connection = (DataUrlConnectionSPI) c.newInstance();
- } catch (Exception ex) {
- log.error("failed to instantiate DataURL connection " + className, ex);
- }
+ log.warn("Set DataURLConnection class not supported!");
}
}
}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java
index f954a017..384cf71c 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java
@@ -62,7 +62,7 @@ public interface DataUrlConnection {
* @param transferEncoding may be null
*/
public void setHTTPFormParameter(String name, InputStream data, String contentType, String charSet, String transferEncoding);
-
+
/**
* @pre httpHeaders != null
* @throws java.net.SocketTimeoutException
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java
index 4f2d2e00..b092ba41 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java
@@ -18,10 +18,14 @@ package at.gv.egiz.bku.binding;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.OutputStream;
+import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
+import java.net.URLEncoder;
+import java.nio.charset.Charset;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
@@ -34,6 +38,7 @@ import java.util.Set;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;
+import javax.xml.transform.stream.StreamResult;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.Part;
@@ -47,32 +52,92 @@ import at.gv.egiz.bku.conf.Configurator;
import at.gv.egiz.bku.slcommands.SLResult;
import at.gv.egiz.bku.slcommands.SLResult.SLResultType;
import at.gv.egiz.bku.slexceptions.SLRuntimeException;
+import at.gv.egiz.bku.utils.URLEncodingWriter;
import at.gv.egiz.bku.utils.binding.Protocol;
/**
- * not thread-safe thus newInsance always returns a new object
+ * An implementation of the DataUrlConnectionSPI that supports
+ * <code>multipart/form-data</code> encoding and
+ * <code>application/x-www-form-urlencoded</code> for compatibility with legacy
+ * systems.
*
*/
public class DataUrlConnectionImpl implements DataUrlConnectionSPI {
private final static Log log = LogFactory.getLog(DataUrlConnectionImpl.class);
+
+ public static final byte[] B_DEFAULT_RESPONSETYPE = DEFAULT_RESPONSETYPE.getBytes(Charset.forName("UTF-8"));
+ /**
+ * Supported protocols are HTTP and HTTPS.
+ */
public final static Protocol[] SUPPORTED_PROTOCOLS = { Protocol.HTTP,
Protocol.HTTPS };
+ /**
+ * The X509 certificate of the DataURL server.
+ */
protected X509Certificate serverCertificate;
+
+ /**
+ * The protocol of the DataURL.
+ */
protected Protocol protocol;
+
+ /**
+ * Use <code>application/x-www-form-urlencoded</code> instead of
+ * standard conform <code>application/x-www-form-urlencoded</code>.
+ */
+ protected boolean urlEncoded = true;
+
+ /**
+ * The value of the DataURL.
+ */
protected URL url;
+
+ /**
+ * The URLConnection used for communication with the DataURL server.
+ */
private HttpURLConnection connection;
+
+ /**
+ * The HTTP request headers.
+ */
protected Map<String, String> requestHttpHeaders;
- protected ArrayList<Part> formParams;
+
+ /**
+ * The HTTP form parameters.
+ */
+ protected ArrayList<HTTPFormParameter> httpFormParameter;
+
+ /**
+ * The boundary for multipart/form-data requests.
+ */
protected String boundary;
+
+ /**
+ * The configuration properties.
+ */
protected Properties config = null;
+
+ /**
+ * The SSLSocketFactory for HTTPS connections.
+ */
protected SSLSocketFactory sslSocketFactory;
+
+ /**
+ * The HostnameVerifier for HTTPS connections.
+ */
protected HostnameVerifier hostnameVerifier;
+ /**
+ * The response of the DataURL server.
+ */
protected DataUrlResponse result;
+ /* (non-Javadoc)
+ * @see at.gv.egiz.bku.binding.DataUrlConnection#getProtocol()
+ */
public String getProtocol() {
if (protocol == null) {
return null;
@@ -80,13 +145,8 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI {
return protocol.toString();
}
- /**
- * opens a connection sets the headers gets the server certificate
- *
- * @throws java.net.SocketTimeoutException
- * @throws java.io.IOException
- * @pre url != null
- * @pre httpHeaders != null
+ /* (non-Javadoc)
+ * @see at.gv.egiz.bku.binding.DataUrlConnection#connect()
*/
public void connect() throws SocketTimeoutException, IOException {
connection = (HttpURLConnection) url.openConnection();
@@ -104,9 +164,26 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI {
https.setHostnameVerifier(hostnameVerifier);
}
} else {
- log.trace("No secure connection with: "+url+ " class="+connection.getClass());
+ log.trace("No secure connection with: " + url + " class="
+ + connection.getClass());
}
connection.setDoOutput(true);
+ // Transfer-Encoding: chunked is problematic ...
+ // e.g. https://issues.apache.org/bugzilla/show_bug.cgi?id=37794
+ // ... therefore disabled.
+ // connection.setChunkedStreamingMode(5*1024);
+ if (urlEncoded) {
+ log.debug("Setting DataURL Content-Type to "
+ + HttpUtil.APPLICATION_URL_ENCODED);
+ connection.addRequestProperty(HttpUtil.HTTP_HEADER_CONTENT_TYPE,
+ HttpUtil.APPLICATION_URL_ENCODED);
+ } else {
+ log.debug("Setting DataURL Content-Type to "
+ + HttpUtil.MULTIPART_FOTMDATA_BOUNDARY);
+ connection.addRequestProperty(HttpUtil.HTTP_HEADER_CONTENT_TYPE,
+ HttpUtil.MULTIPART_FOTMDATA + HttpUtil.SEPERATOR[0]
+ + HttpUtil.MULTIPART_FOTMDATA_BOUNDARY + "=" + boundary);
+ }
Set<String> headers = requestHttpHeaders.keySet();
Iterator<String> headerIt = headers.iterator();
while (headerIt.hasNext()) {
@@ -125,51 +202,128 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI {
}
}
+ /* (non-Javadoc)
+ * @see at.gv.egiz.bku.binding.DataUrlConnection#getServerCertificate()
+ */
public X509Certificate getServerCertificate() {
return serverCertificate;
}
+ /* (non-Javadoc)
+ * @see at.gv.egiz.bku.binding.DataUrlConnection#setHTTPHeader(java.lang.String, java.lang.String)
+ */
public void setHTTPHeader(String name, String value) {
if (name != null && value != null) {
requestHttpHeaders.put(name, value);
}
}
+ /* (non-Javadoc)
+ * @see at.gv.egiz.bku.binding.DataUrlConnection#setHTTPFormParameter(java.lang.String, java.io.InputStream, java.lang.String, java.lang.String, java.lang.String)
+ */
public void setHTTPFormParameter(String name, InputStream data,
String contentType, String charSet, String transferEncoding) {
- InputStreamPartSource source = new InputStreamPartSource(null, data);
- FilePart formParam = new FilePart(name, source, contentType, charSet);
- if (transferEncoding != null) {
- formParam.setTransferEncoding(transferEncoding);
- } else {
- formParam.setTransferEncoding(null);
+ // if a content type is specified we have to switch to multipart/formdata encoding
+ if (contentType != null && contentType.length() > 0) {
+ urlEncoded = false;
}
- formParams.add(formParam);
+ httpFormParameter.add(new HTTPFormParameter(name, data, contentType,
+ charSet, transferEncoding));
}
- /**
- * send all formParameters
- *
- * @throws java.io.IOException
+
+
+ /* (non-Javadoc)
+ * @see at.gv.egiz.bku.binding.DataUrlConnection#transmit(at.gv.egiz.bku.slcommands.SLResult)
*/
public void transmit(SLResult slResult) throws IOException {
- SLResultPart slResultPart = new SLResultPart(slResult,
- XML_RESPONSE_ENCODING);
- if (slResult.getResultType() == SLResultType.XML) {
- slResultPart.setTransferEncoding(null);
- slResultPart.setContentType(slResult.getMimeType());
- slResultPart.setCharSet(XML_RESPONSE_ENCODING);
+ log.trace("Sending data");
+ if (urlEncoded) {
+ //
+ // application/x-www-form-urlencoded (legacy, SL < 1.2)
+ //
+
+ OutputStream os = connection.getOutputStream();
+ OutputStreamWriter streamWriter = new OutputStreamWriter(os, HttpUtil.DEFAULT_CHARSET);
+
+ // ResponseType
+ streamWriter.write(FORMPARAM_RESPONSETYPE);
+ streamWriter.write("=");
+ streamWriter.write(URLEncoder.encode(DEFAULT_RESPONSETYPE, "UTF-8"));
+ streamWriter.write("&");
+
+ // XMLResponse / Binary Response
+ if (slResult.getResultType() == SLResultType.XML) {
+ streamWriter.write(DataUrlConnection.FORMPARAM_XMLRESPONSE);
+ } else {
+ streamWriter.write(DataUrlConnection.FORMPARAM_BINARYRESPONSE);
+ }
+ streamWriter.write("=");
+ streamWriter.flush();
+ URLEncodingWriter urlEnc = new URLEncodingWriter(streamWriter);
+ slResult.writeTo(new StreamResult(urlEnc), false);
+ urlEnc.flush();
+
+ // transfer parameters
+ char[] cbuf = new char[512];
+ int len;
+ for (HTTPFormParameter formParameter : httpFormParameter) {
+ streamWriter.write("&");
+ streamWriter.write(URLEncoder.encode(formParameter.getName(), "UTF-8"));
+ streamWriter.write("=");
+ InputStreamReader reader = new InputStreamReader(formParameter.getData(),
+ (formParameter.getCharSet() != null)
+ ? formParameter.getCharSet()
+ : null);
+ while ((len = reader.read(cbuf)) != -1) {
+ urlEnc.write(cbuf, 0, len);
+ }
+ urlEnc.flush();
+ }
+ streamWriter.close();
+
} else {
- slResultPart.setTransferEncoding(null);
- slResultPart.setContentType(slResult.getMimeType());
- }
- formParams.add(slResultPart);
+ //
+ // multipart/form-data (conforming to SL 1.2)
+ //
- OutputStream os = connection.getOutputStream();
- log.trace("Sending data");
- Part[] parts = new Part[formParams.size()];
- Part.sendParts(os, formParams.toArray(parts), boundary.getBytes());
- os.close();
+ ArrayList<Part> parts = new ArrayList<Part>();
+
+ // ResponseType
+ StringPart responseType = new StringPart(FORMPARAM_RESPONSETYPE,
+ DEFAULT_RESPONSETYPE, "UTF-8");
+ responseType.setTransferEncoding(null);
+ parts.add(responseType);
+
+ // XMLResponse / Binary Response
+ SLResultPart slResultPart = new SLResultPart(slResult,
+ XML_RESPONSE_ENCODING);
+ if (slResult.getResultType() == SLResultType.XML) {
+ slResultPart.setTransferEncoding(null);
+ slResultPart.setContentType(slResult.getMimeType());
+ slResultPart.setCharSet(XML_RESPONSE_ENCODING);
+ } else {
+ slResultPart.setTransferEncoding(null);
+ slResultPart.setContentType(slResult.getMimeType());
+ }
+ parts.add(slResultPart);
+
+ // transfer parameters
+ for (HTTPFormParameter formParameter : httpFormParameter) {
+ InputStreamPartSource source = new InputStreamPartSource(null,
+ formParameter.getData());
+ FilePart part = new FilePart(formParameter.getName(), source,
+ formParameter.getContentType(), formParameter.getCharSet());
+ part.setTransferEncoding(formParameter.getTransferEncoding());
+ parts.add(part);
+ }
+
+ OutputStream os = connection.getOutputStream();
+ Part.sendParts(os, parts.toArray(new Part[parts.size()]), boundary.getBytes());
+ os.close();
+
+ }
+
// MultipartRequestEntity PostMethod
InputStream is = null;
try {
@@ -241,16 +395,9 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI {
.put(HttpUtil.HTTP_HEADER_USER_AGENT, Configurator.USERAGENT_DEFAULT);
}
- requestHttpHeaders.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE,
- HttpUtil.MULTIPART_FOTMDATA + HttpUtil.SEPERATOR[0]
- + HttpUtil.MULTIPART_FOTMDATA_BOUNDARY + "=" + boundary);
-
- formParams = new ArrayList<Part>();
- StringPart responseType = new StringPart(FORMPARAM_RESPONSETYPE,
- DEFAULT_RESPONSETYPE);
- responseType.setCharSet("UTF-8");
- responseType.setTransferEncoding(null);
- formParams.add(responseType);
+
+ httpFormParameter = new ArrayList<HTTPFormParameter>();
+
}
@Override
@@ -281,4 +428,107 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI {
public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {
this.hostnameVerifier = hostnameVerifier;
}
+
+ public class HTTPFormParameter {
+
+ private String name;
+
+ private InputStream data;
+
+ private String contentType;
+
+ private String charSet;
+
+ private String transferEncoding;
+
+ /**
+ * @param name
+ * @param data
+ * @param contentType
+ * @param charSet
+ * @param transferEncoding
+ */
+ public HTTPFormParameter(String name, InputStream data, String contentType,
+ String charSet, String transferEncoding) {
+ super();
+ this.name = name;
+ this.data = data;
+ this.contentType = contentType;
+ this.charSet = charSet;
+ this.transferEncoding = transferEncoding;
+ }
+
+ /**
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param name the name to set
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @return the data
+ */
+ public InputStream getData() {
+ return data;
+ }
+
+ /**
+ * @param data the data to set
+ */
+ public void setData(InputStream data) {
+ this.data = data;
+ }
+
+ /**
+ * @return the contentType
+ */
+ public String getContentType() {
+ return contentType;
+ }
+
+ /**
+ * @param contentType the contentType to set
+ */
+ public void setContentType(String contentType) {
+ this.contentType = contentType;
+ }
+
+ /**
+ * @return the charSet
+ */
+ public String getCharSet() {
+ return charSet;
+ }
+
+ /**
+ * @param charSet the charSet to set
+ */
+ public void setCharSet(String charSet) {
+ this.charSet = charSet;
+ }
+
+ /**
+ * @return the transferEncoding
+ */
+ public String getTransferEncoding() {
+ return transferEncoding;
+ }
+
+ /**
+ * @param transferEncoding the transferEncoding to set
+ */
+ public void setTransferEncoding(String transferEncoding) {
+ this.transferEncoding = transferEncoding;
+ }
+
+
+
+ }
} \ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java
index ef603fc7..a1c4d5fc 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java
@@ -22,6 +22,7 @@ import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
+import java.io.Writer;
import java.net.URL;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
@@ -46,6 +47,7 @@ import javax.xml.transform.stream.StreamSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import at.gv.egiz.bku.slcommands.ErrorResult;
import at.gv.egiz.bku.slcommands.SLCommand;
import at.gv.egiz.bku.slcommands.SLCommandContext;
import at.gv.egiz.bku.slcommands.SLCommandFactory;
@@ -635,7 +637,6 @@ public class HTTPBindingProcessor extends AbstractBindingProcessor implements
throw new SLBindingException(2006);
}
InputDecoder id = InputDecoderFactory.getDecoder(cl, is);
- id.setContentType(cl);
if (id == null) {
log.error("Cannot get inputdecoder for is");
throw new SLException(2006);
@@ -730,9 +731,20 @@ public class HTTPBindingProcessor extends AbstractBindingProcessor implements
Templates templates) throws IOException {
log.debug("Writing error as result");
ErrorResultImpl error = new ErrorResultImpl(bindingProcessorError, locale);
- error.writeTo(new StreamResult(new OutputStreamWriter(os, encoding)), templates);
+ Writer writer = writeXMLDeclarationAndProcessingInstruction(os, encoding);
+ error.writeTo(new StreamResult(writer), templates, true);
}
+ protected Writer writeXMLDeclarationAndProcessingInstruction(OutputStream os, String encoding) throws IOException {
+ if (encoding == null) {
+ encoding = HttpUtil.DEFAULT_CHARSET;
+ }
+ OutputStreamWriter writer = new OutputStreamWriter(os, encoding);
+ writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
+ writer.write("<?xml-stylesheet type=\"text/css\" href=\"errorresponse.css\"?>\n");
+ return writer;
+ }
+
@Override
public void writeResultTo(OutputStream os, String encoding)
throws IOException {
@@ -772,9 +784,16 @@ public class HTTPBindingProcessor extends AbstractBindingProcessor implements
return;
} else {
log.debug("Getting result from invoker");
- OutputStreamWriter osw = new OutputStreamWriter(os, encoding);
- slResult.writeTo(new StreamResult(osw), templates);
- osw.flush();
+ boolean fragment = false;
+ Writer writer;
+ if (slResult instanceof ErrorResult) {
+ writer = writeXMLDeclarationAndProcessingInstruction(os, encoding);
+ fragment = true;
+ } else {
+ writer = new OutputStreamWriter(os, encoding);
+ }
+ slResult.writeTo(new StreamResult(writer), templates, fragment);
+ writer.flush();
}
}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/LegacyDataUrlConnectionImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/LegacyDataUrlConnectionImpl.java
deleted file mode 100644
index cfccb7f1..00000000
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/LegacyDataUrlConnectionImpl.java
+++ /dev/null
@@ -1,259 +0,0 @@
-package at.gv.egiz.bku.binding;
-
-
-import at.gv.egiz.bku.conf.Configurator;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.StringWriter;
-import java.net.HttpURLConnection;
-import java.net.SocketTimeoutException;
-import java.net.URL;
-import java.net.URLEncoder;
-import java.security.cert.X509Certificate;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLSocketFactory;
-import javax.xml.transform.stream.StreamResult;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import at.gv.egiz.bku.slcommands.SLResult;
-import at.gv.egiz.bku.slcommands.SLResult.SLResultType;
-import at.gv.egiz.bku.slexceptions.SLRuntimeException;
-import at.gv.egiz.bku.utils.binding.Protocol;
-
-/**
- * not thread-safe thus newInsance always returns a new object
- *
- */
-public class LegacyDataUrlConnectionImpl implements DataUrlConnectionSPI {
-
- private final static Log log = LogFactory.getLog(LegacyDataUrlConnectionImpl.class);
-
- public final static Protocol[] SUPPORTED_PROTOCOLS = { Protocol.HTTP,
- Protocol.HTTPS };
- protected X509Certificate serverCertificate;
- protected Protocol protocol;
- protected URL url;
- private HttpURLConnection connection;
- protected Map<String, String> requestHttpHeaders;
- protected Map<String, String> formParams;
- protected String boundary;
- protected Properties config = null;
- protected SSLSocketFactory sslSocketFactory;
- protected HostnameVerifier hostnameVerifier;
-
- protected DataUrlResponse result;
-
- public String getProtocol() {
- if (protocol == null) {
- return null;
- }
- return protocol.toString();
- }
-
- /**
- * opens a connection sets the headers gets the server certificate
- *
- * @throws java.net.SocketTimeoutException
- * @throws java.io.IOException
- * @pre url != null
- * @pre httpHeaders != null
- */
- public void connect() throws SocketTimeoutException, IOException {
- connection = (HttpURLConnection) url.openConnection();
- if (connection instanceof HttpsURLConnection) {
- HttpsURLConnection https = (HttpsURLConnection) connection;
- if (sslSocketFactory != null) {
- log.debug("Setting custom ssl socket factory for ssl connection");
- https.setSSLSocketFactory(sslSocketFactory);
- }
- if (hostnameVerifier != null) {
- log.debug("Setting custom hostname verifier");
- https.setHostnameVerifier(hostnameVerifier);
- }
- }
- connection.setDoOutput(true);
- Set<String> headers = requestHttpHeaders.keySet();
- Iterator<String> headerIt = headers.iterator();
- while (headerIt.hasNext()) {
- String name = headerIt.next();
- connection.setRequestProperty(name, requestHttpHeaders.get(name));
- }
- log.trace("Connecting to: "+url);
- connection.connect();
- if (connection instanceof HttpsURLConnection) {
- HttpsURLConnection ssl = (HttpsURLConnection) connection;
- X509Certificate[] certs = (X509Certificate[]) ssl.getServerCertificates();
- if ((certs != null) && (certs.length >= 1)) {
- log.trace("Server certificate: "+certs[0]);
- serverCertificate = certs[0];
- }
- }
- }
-
- public X509Certificate getServerCertificate() {
- return serverCertificate;
- }
-
- public void setHTTPHeader(String name, String value) {
- if (name != null && value != null) {
- requestHttpHeaders.put(name, value);
- }
- }
-
- public void setHTTPFormParameter(String name, InputStream data,
- String contentType, String charSet, String transferEncoding) {
- StringBuilder sb = new StringBuilder();
- try {
- InputStreamReader reader = new InputStreamReader(data, (charSet != null) ? charSet : "UTF-8");
- char[] c = new char[512];
- for (int l; (l = reader.read(c)) != -1;) {
- sb.append(c, 0, l);
- }
- } catch (IOException e) {
- throw new SLRuntimeException("Failed to set HTTP form parameter.", e);
- }
- formParams.put(name, sb.toString());
- }
-
- /**
- * send all formParameters
- *
- * @throws java.io.IOException
- */
- public void transmit(SLResult slResult) throws IOException {
- StringWriter writer = new StringWriter();
- slResult.writeTo(new StreamResult(writer));
- formParams.put(
- (slResult.getResultType() == SLResultType.XML)
- ? DataUrlConnection.FORMPARAM_XMLRESPONSE
- : DataUrlConnection.FORMPARAM_BINARYRESPONSE,
- writer.toString());
-
- OutputStream os = connection.getOutputStream();
- OutputStreamWriter streamWriter = new OutputStreamWriter(os, HttpUtil.DEFAULT_CHARSET);
-
- log.trace("Sending data");
- Iterator<String> keys = formParams.keySet().iterator();
- while(keys.hasNext()) {
- String key = keys.next();
- streamWriter.write(URLEncoder.encode(key, "UTF-8"));
- streamWriter.write("=");
- streamWriter.write(URLEncoder.encode(formParams.get(key), "UTF-8"));
- if (keys.hasNext()) {
- streamWriter.write("&");
- }
- }
- streamWriter.flush();
- os.close();
-
- // MultipartRequestEntity PostMethod
- InputStream is = null;
- try {
- is = connection.getInputStream();
- } catch (IOException iox) {
- log.info(iox);
- }
- log.trace("Reading response");
- result = new DataUrlResponse(url.toString(), connection.getResponseCode(), is);
- Map<String, String> responseHttpHeaders = new HashMap<String, String>();
- Map<String, List<String>> httpHeaders = connection.getHeaderFields();
- for (Iterator<String> keyIt = httpHeaders.keySet().iterator(); keyIt
- .hasNext();) {
- String key = keyIt.next();
- StringBuffer value = new StringBuffer();
- for (String val : httpHeaders.get(key)) {
- value.append(val);
- value.append(HttpUtil.SEPERATOR[0]);
- }
- String valString = value.substring(0, value.length() - 1);
- if ((key != null) && (value.length() > 0)) {
- responseHttpHeaders.put(key, valString);
- }
- }
- result.setResponseHttpHeaders(responseHttpHeaders);
- }
-
- @Override
- public DataUrlResponse getResponse() throws IOException {
- return result;
- }
-
- /**
- * inits protocol, url, httpHeaders, formParams
- *
- * @param url
- * must not be null
- */
- @Override
- public void init(URL url) {
-
- for (int i = 0; i < SUPPORTED_PROTOCOLS.length; i++) {
- if (SUPPORTED_PROTOCOLS[i].toString().equalsIgnoreCase(url.getProtocol())) {
- protocol = SUPPORTED_PROTOCOLS[i];
- break;
- }
- }
- if (protocol == null) {
- throw new SLRuntimeException("Protocol " + url.getProtocol()
- + " not supported for data url");
- }
- this.url = url;
- requestHttpHeaders = new HashMap<String, String>();
- if ((config != null)
- && (config.getProperty(Configurator.USERAGENT_CONFIG_P) != null)) {
- log.debug("setting User-Agent header: " + config.getProperty(Configurator.USERAGENT_CONFIG_P));
- requestHttpHeaders.put(HttpUtil.HTTP_HEADER_USER_AGENT, config
- .getProperty(Configurator.USERAGENT_CONFIG_P));
- } else {
- requestHttpHeaders
- .put(HttpUtil.HTTP_HEADER_USER_AGENT, Configurator.USERAGENT_DEFAULT);
-
- }
- requestHttpHeaders.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE,
- HttpUtil.APPLICATION_URL_ENCODED);
-
- formParams = new HashMap<String, String>();
- }
-
- @Override
- public DataUrlConnectionSPI newInstance() {
- DataUrlConnectionSPI uc = new LegacyDataUrlConnectionImpl();
- uc.setConfiguration(config);
- uc.setSSLSocketFactory(sslSocketFactory);
- uc.setHostnameVerifier(hostnameVerifier);
- return uc;
- }
-
- @Override
- public URL getUrl() {
- return url;
- }
-
- @Override
- public void setConfiguration(Properties config) {
- this.config = config;
- }
-
- @Override
- public void setSSLSocketFactory(SSLSocketFactory socketFactory) {
- this.sslSocketFactory = socketFactory;
- }
-
- @Override
- public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {
- this.hostnameVerifier = hostnameVerifier;
- }
-} \ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputDecoder.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputDecoder.java
index f4ebe288..69c659e1 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputDecoder.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputDecoder.java
@@ -16,86 +16,43 @@
*/
package at.gv.egiz.bku.binding;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URLDecoder;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.commons.fileupload.ParameterParser;
-import org.apache.commons.fileupload.ParameterParser;
-
-import at.gv.egiz.bku.slexceptions.SLRuntimeException;
-import at.gv.egiz.bku.utils.StreamUtil;
-
-/**
- * Implementation based on Java's URLDecoder class
- *
- */
-// FIXME replace this code by a streaming variant
public class XWWWFormUrlInputDecoder implements InputDecoder {
-
- public final static String CHAR_SET = "charset";
- public final static String NAME_VAL_SEP = "=";
- public final static String SEP = "\\&";
-
- private String contentType;
- private InputStream dataStream;
- private String charset = "UTF-8";
-
- protected List<FormParameter> decodeInput(InputStream is) throws IOException {
- List<FormParameter> result = new LinkedList<FormParameter>();
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- StreamUtil.copyStream(is, bos);
- String inputString = new String(bos.toByteArray());
- String[] nameValuePairs = inputString.split(SEP);
- //inputString = URLDecoder.decode(inputString, charset);
- for (int i = 0; i < nameValuePairs.length; i++) {
- String[] fields = nameValuePairs[i].split(NAME_VAL_SEP, 2);
- if (fields.length != 2) {
- throw new SLRuntimeException("Invalid form encoding, missing value");
- }
- String name = URLDecoder.decode(fields[0], charset);
- String value =URLDecoder.decode(fields[1], charset);
- ByteArrayInputStream bais = new ByteArrayInputStream(value
- .getBytes(charset));
- FormParameterImpl fpi = new FormParameterImpl(contentType, name, bais, null);
- result.add(fpi);
- }
- return result;
- }
-
- @SuppressWarnings("unchecked")
+
+ /**
+ * The MIME type 'application/x-www-form-urlencoded'.
+ */
+ public static final String CONTENT_TYPE = "application/x-www-form-urlencoded";
+
+ /**
+ * The form parameter iterator.
+ */
+ protected XWWWFormUrlInputIterator iterator;
+
+ @SuppressWarnings("unchecked")
@Override
public void setContentType(String contentType) {
ParameterParser pp = new ParameterParser();
pp.setLowerCaseNames(true);
Map<String, String> params = pp.parse(contentType, new char[] { ':', ';' });
- if (!params.containsKey("application/x-www-form-urlencoded")) {
+ if (!params.containsKey(CONTENT_TYPE)) {
throw new IllegalArgumentException(
"not a url encoded content type specification: " + contentType);
}
- String cs = params.get(CHAR_SET);
- if (cs != null) {
- charset = cs;
- }
- this.contentType = contentType;
}
@Override
public Iterator<FormParameter> getFormParameterIterator() {
- try {
- return decodeInput(dataStream).iterator();
- } catch (IOException e) {
- throw new SLRuntimeException(e);
- }
+ return iterator;
}
@Override
public void setInputStream(InputStream is) {
- dataStream = is;
+ iterator = new XWWWFormUrlInputIterator(is);
}
}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputIterator.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputIterator.java
new file mode 100644
index 00000000..f052ce05
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputIterator.java
@@ -0,0 +1,376 @@
+package at.gv.egiz.bku.binding;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+public class XWWWFormUrlInputIterator implements Iterator<FormParameter> {
+
+ public static final byte NAME_VALUE_SEP = '=';
+
+ public static final byte PARAM_SEP = '&';
+
+ public static final Charset UTF_8 = Charset.forName("UTF-8");
+
+ /**
+ * The default buffer size.
+ */
+ protected static final int DEFAULT_BUFFER_SIZE = 4096;
+
+ /**
+ * Are we done with parsing the input.
+ */
+ protected boolean done = false;
+
+ /**
+ * The x-www-formdata-urlencoded input stream to be parsed.
+ */
+ protected final InputStream in;
+
+ /**
+ * The buffer size.
+ */
+ protected int bufferSize = DEFAULT_BUFFER_SIZE;
+
+ /**
+ * The read buffer.
+ */
+ protected final byte[] buf = new byte[bufferSize];
+
+ /**
+ * The read position.
+ */
+ protected int pos;
+
+ /**
+ * The number of valid bytes in the buffer;
+ */
+ protected int count;
+
+ /**
+ * The parameter returned by the last call of {@link #next()};
+ */
+ protected XWWWFormUrlEncodedParameter currentParameter;
+
+ /**
+ * An IOException that cannot be reported immediately.
+ */
+ protected IOException deferredIOException;
+
+ /**
+ * Creates a new instance of this x-www-formdata-urlencoded input iterator
+ * with the given InputStream <code>in</code> to be parsed.
+ *
+ * @param in the InputStream to be parsed
+ */
+ public XWWWFormUrlInputIterator(InputStream in) {
+ this.in = in;
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.Iterator#hasNext()
+ */
+ @Override
+ public boolean hasNext() {
+ if (done) {
+ return false;
+ }
+ if (currentParameter != null) {
+ // we have to disconnect the current parameter
+ // to look for further parameters
+ try {
+ currentParameter.formParameterValue.disconnect();
+ // fill buffer if empty
+ if (pos >= count) {
+ if ((count = in.read(buf)) == -1) {
+ // done
+ done = true;
+ return false;
+ }
+ pos = 0;
+ }
+ } catch (IOException e) {
+ deferredIOException = e;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public FormParameter next() {
+ if (hasNext()) {
+ // skip separator
+ pos++;
+ currentParameter = new XWWWFormUrlEncodedParameter();
+ return currentParameter;
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ public class XWWWFormUrlEncodedParameter implements FormParameter {
+
+ /**
+ * The list of header names.
+ */
+ // x-www-form-urlencoded parameters do not provide headers
+ protected final List<String> headers = Collections.emptyList();
+
+ /**
+ * The name of the form parameter.
+ */
+ protected String formParameterName;
+
+ /**
+ * The value of the form parameter.
+ */
+ protected URLDecodingInputStream formParameterValue;
+
+ public XWWWFormUrlEncodedParameter() {
+ // parse parameter name
+ URLDecodingInputStream urldec = new URLDecodingInputStream(in, NAME_VALUE_SEP);
+ InputStreamReader reader = new InputStreamReader(urldec, UTF_8);
+ try {
+ StringBuilder sb = new StringBuilder();
+ char[] b = new char[128];
+ for (int l = 0; (l = reader.read(b)) != -1;) {
+ sb.append(b, 0, l);
+ }
+ formParameterName = sb.toString();
+ // fill buffer if empty
+ if (pos >= count) {
+ if ((count = in.read(buf)) == -1) {
+ throw new IOException("Invalid URL encoding.");
+ }
+ pos = 0;
+ }
+ // skip separator
+ pos++;
+ } catch (IOException e) {
+ deferredIOException = e;
+ formParameterName = "";
+ }
+ formParameterValue = new URLDecodingInputStream(in, PARAM_SEP);
+ }
+
+ @Override
+ public String getFormParameterContentType() {
+ // x-www-form-urlencoded parameters do not specify a content type
+ return null;
+ }
+
+ @Override
+ public String getFormParameterName() {
+ return formParameterName;
+ }
+
+ @Override
+ public InputStream getFormParameterValue() {
+ if (deferredIOException != null) {
+ final IOException e = deferredIOException;
+ deferredIOException = null;
+ return new InputStream() {
+ @Override
+ public int read() throws IOException {
+ throw e;
+ }
+ };
+ } else {
+ return formParameterValue;
+ }
+ }
+
+ @Override
+ public Iterator<String> getHeaderNames() {
+ return headers.iterator();
+ }
+
+ @Override
+ public String getHeaderValue(String headerName) {
+ return null;
+ }
+
+ }
+
+ public class URLDecodingInputStream extends FilterInputStream {
+
+ /**
+ * Has this stream already been closed.
+ */
+ private boolean closed = false;
+
+ /**
+ * Has this stream been disconnected.
+ */
+ private boolean disconnected = false;
+
+ /**
+ * Read until this byte occurs.
+ */
+ protected final byte term;
+
+ /**
+ * Creates a new instance of this URLDecodingInputStream.
+ *
+ * @param in
+ * @param separator
+ */
+ protected URLDecodingInputStream(InputStream in, byte separator) {
+ super(in);
+ this.term = separator;
+ }
+
+ /* (non-Javadoc)
+ * @see java.io.FilterInputStream#read()
+ */
+ @Override
+ public int read() throws IOException {
+ if (closed) {
+ throw new IOException("The stream has already been closed.");
+ }
+ if (disconnected) {
+ return in.read();
+ }
+
+ if (pos >= count) {
+ if ((count = in.read(buf)) == -1) {
+ return -1;
+ }
+ pos = 0;
+ } if (buf[pos] == term) {
+ return -1;
+ } else if (buf[pos] == '+') {
+ pos++;
+ return ' ';
+ } else if (buf[pos] == '%') {
+ if (++pos == count) {
+ if ((count = in.read(buf)) == -1) {
+ throw new IOException("Invalid URL encoding.");
+ }
+ pos = 0;
+ }
+ int c1 = Character.digit(buf[pos], 16);
+ if (++pos == count) {
+ if ((count = in.read(buf)) == -1) {
+ throw new IOException("Invalid URL encoding.");
+ }
+ pos = 0;
+ }
+ int c2 = Character.digit(buf[pos], 16);
+ return ((c1 << 4) | c2);
+ } else {
+ return buf[pos++];
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see java.io.FilterInputStream#read(byte[], int, int)
+ */
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ if (closed) {
+ throw new IOException("The stream has already been closed.");
+ }
+ if (disconnected) {
+ return in.read(b, off, len);
+ }
+
+ if ((off | len | (off + len) | (b.length - (off + len))) < 0) {
+ throw new IndexOutOfBoundsException();
+ } else if (len == 0) {
+ return 0;
+ }
+
+ if (pos >= count) {
+ if ((count = in.read(buf)) == -1) {
+ return -1;
+ }
+ pos = 0;
+ }
+ if (buf[pos] == term) {
+ return -1;
+ }
+
+ int l = 0;
+ for (;;) {
+ while (pos < count) {
+ if (l == len || buf[pos] == term) {
+ return l;
+ } else if (buf[pos] == '+') {
+ b[off] = ' ';
+ } else if (buf[pos] == '%') {
+ if (++pos == count && (count = in.read(buf)) == -1) {
+ throw new IOException("Invalid URL encoding.");
+ }
+ int c1 = Character.digit(buf[pos], 16);
+ if (++pos == count && (count = in.read(buf)) == -1) {
+ throw new IOException("Invalid URL encoding.");
+ }
+ int c2 = Character.digit(buf[pos], 16);
+ b[off] = (byte) ((c1 << 4) | c2);
+ } else {
+ b[off] = buf[pos];
+ }
+ pos++;
+ off++;
+ l++;
+ }
+ if ((count = in.read(buf)) == -1) {
+ return l;
+ }
+ pos = 0;
+ }
+ }
+
+ /**
+ * Disconnect from the InputStream and buffer all remaining data.
+ *
+ * @throws IOException
+ */
+ public void disconnect() throws IOException {
+ if (!disconnected) {
+ // don't waste space for a buffer if end of stream has already been
+ // reached
+ byte[] b = new byte[1];
+ if ((read(b)) != -1) {
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ os.write(b);
+ b = new byte[1024];
+ for (int l; (l = read(b, 0, b.length)) != -1;) {
+ os.write(b, 0, l);
+ }
+ super.in = new ByteArrayInputStream(os.toByteArray());
+ }
+ disconnected = true;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see java.io.FilterInputStream#close()
+ */
+ @Override
+ public void close() throws IOException {
+ if (!hasNext()) {
+ // don't close the underlying stream until all parts are read
+ super.close();
+ }
+ disconnect();
+ closed = true;
+ }
+
+ }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/multipart/SLResultPart.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/multipart/SLResultPart.java
index 5585f02e..d896ea9f 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/multipart/SLResultPart.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/multipart/SLResultPart.java
@@ -16,37 +16,56 @@
*/
package at.gv.egiz.bku.binding.multipart;
+import at.gv.egiz.bku.binding.DataUrlConnection;
import at.gv.egiz.bku.slcommands.SLResult;
+import at.gv.egiz.bku.slcommands.SLResult.SLResultType;
+
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import javax.xml.transform.stream.StreamResult;
-import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource;
import org.apache.commons.httpclient.methods.multipart.FilePart;
+import org.apache.commons.httpclient.methods.multipart.PartSource;
-/**
- *
- * @author clemens
- */
public class SLResultPart extends FilePart {
protected SLResult slResult;
protected String encoding;
public SLResultPart(SLResult slResult, String encoding) {
- super("XMLResponse",
- new ByteArrayPartSource(null, "dummySource".getBytes()));
+ super((slResult.getResultType() == SLResultType.XML)
+ ? DataUrlConnection.FORMPARAM_XMLRESPONSE
+ : DataUrlConnection.FORMPARAM_BINARYRESPONSE,
+ new PartSource() {
+
+ @Override
+ public long getLength() {
+ // may return null, as sendData() is overridden
+ return 0;
+ }
+
+ @Override
+ public String getFileName() {
+ // return null, to prevent content-disposition header
+ return null;
+ }
+
+ @Override
+ public InputStream createInputStream() throws IOException {
+ // may return null, as sendData() is overridden below
+ return null;
+ }
+ }
+ );
this.slResult = slResult;
this.encoding = encoding;
}
@Override
protected void sendData(OutputStream out) throws IOException {
- slResult.writeTo(new StreamResult(new OutputStreamWriter(out, encoding)));
- // slResult.writeTo(new StreamResult(new OutputStreamWriter(System.out,
- // encoding)));
- // super.sendData(out);
+ slResult.writeTo(new StreamResult(new OutputStreamWriter(out, encoding)), false);
}
}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidatorImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidatorImpl.java
index 125233c1..3b2d1b99 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidatorImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidatorImpl.java
@@ -1,7 +1,9 @@
package at.gv.egiz.bku.conf;
+import iaik.logging.LogConfigurationException;
import iaik.logging.TransactionId;
import iaik.logging.impl.TransactionIdImpl;
+import iaik.logging.LoggerConfig;
import iaik.pki.DefaultPKIConfiguration;
import iaik.pki.DefaultPKIProfile;
import iaik.pki.PKIConfiguration;
@@ -18,6 +20,7 @@ import iaik.x509.X509Certificate;
import java.io.File;
import java.util.Date;
+import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -37,6 +40,27 @@ public class CertValidatorImpl implements CertValidator {
* @see at.gv.egiz.bku.conf.CertValidator#init(java.io.File, java.io.File)
*/
public void init(File certDir, File caDir) {
+ // initialize IAIK logging for PKI module
+ log.debug("Configuring logging for IAIK PKI module");
+ iaik.logging.LogFactory.configure(new LoggerConfig() {
+
+ @Override
+ public Properties getProperties() throws LogConfigurationException {
+ return null;
+ }
+
+ @Override
+ public String getNodeId() {
+ return "pki";
+ }
+
+ @Override
+ public String getFactory() {
+ return IAIKCommonsLogFactory.class.getName();
+ }
+ });
+
+
// the parameters specifying the directory certstore
CertStoreParameters[] certStoreParameters = { new DefaultDirectoryCertStoreParameters(
"CS-001", certDir.getAbsolutePath(), true, false) };
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLog.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLog.java
new file mode 100644
index 00000000..1b7dd189
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLog.java
@@ -0,0 +1,144 @@
+/**
+ *
+ */
+package at.gv.egiz.bku.conf;
+
+import iaik.logging.Log;
+import iaik.logging.TransactionId;
+
+/**
+ * @author mcentner
+ *
+ */
+public class IAIKCommonsLog implements Log {
+
+ /**
+ * The id that will be written to the log if the transactionid == null
+ */
+ public final static String NO_ID = "Null-ID";
+
+ protected org.apache.commons.logging.Log commonsLog;
+
+ protected String nodeId;
+
+ public IAIKCommonsLog(org.apache.commons.logging.Log log) {
+ this.commonsLog = log;
+ }
+
+ /* (non-Javadoc)
+ * @see iaik.logging.Log#debug(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable)
+ */
+ @Override
+ public void debug(TransactionId transactionId, Object message, Throwable t) {
+ if (commonsLog.isDebugEnabled()) {
+ commonsLog.debug(nodeId + ": "
+ + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": "
+ + message, t);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see iaik.logging.Log#info(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable)
+ */
+ @Override
+ public void info(TransactionId transactionId, Object message, Throwable t) {
+ if (commonsLog.isInfoEnabled()) {
+ commonsLog.info(nodeId + ": "
+ + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": "
+ + message, t);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see iaik.logging.Log#warn(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable)
+ */
+ @Override
+ public void warn(TransactionId transactionId, Object message, Throwable t) {
+ if (commonsLog.isWarnEnabled()) {
+ commonsLog.warn(nodeId + ": "
+ + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": "
+ + message, t);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see iaik.logging.Log#error(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable)
+ */
+ @Override
+ public void error(TransactionId transactionId, Object message, Throwable t) {
+ if (commonsLog.isErrorEnabled()) {
+ commonsLog.error(nodeId + ": "
+ + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": "
+ + message, t);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see iaik.logging.Log#fatal(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable)
+ */
+ @Override
+ public void fatal(TransactionId transactionId, Object message, Throwable t) {
+ if (commonsLog.isFatalEnabled()) {
+ commonsLog.fatal(nodeId + ": "
+ + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": "
+ + message, t);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see iaik.logging.Log#setNodeId(java.lang.String)
+ */
+ @Override
+ public void setNodeId(String nodeId) {
+ this.nodeId = nodeId;
+ }
+
+ /* (non-Javadoc)
+ * @see iaik.logging.Log#getNodeId()
+ */
+ @Override
+ public String getNodeId() {
+ return nodeId;
+ }
+
+ /* (non-Javadoc)
+ * @see iaik.logging.Log#isDebugEnabled()
+ */
+ @Override
+ public boolean isDebugEnabled() {
+ return commonsLog.isDebugEnabled();
+ }
+
+ /* (non-Javadoc)
+ * @see iaik.logging.Log#isInfoEnabled()
+ */
+ @Override
+ public boolean isInfoEnabled() {
+ return commonsLog.isInfoEnabled();
+ }
+
+ /* (non-Javadoc)
+ * @see iaik.logging.Log#isWarnEnabled()
+ */
+ @Override
+ public boolean isWarnEnabled() {
+ return commonsLog.isWarnEnabled();
+ }
+
+ /* (non-Javadoc)
+ * @see iaik.logging.Log#isErrorEnabled()
+ */
+ @Override
+ public boolean isErrorEnabled() {
+ return commonsLog.isErrorEnabled();
+ }
+
+ /* (non-Javadoc)
+ * @see iaik.logging.Log#isFatalEnabled()
+ */
+ @Override
+ public boolean isFatalEnabled() {
+ return commonsLog.isFatalEnabled();
+ }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLogFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLogFactory.java
new file mode 100644
index 00000000..14e2c757
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLogFactory.java
@@ -0,0 +1,59 @@
+/**
+ *
+ */
+package at.gv.egiz.bku.conf;
+
+import org.apache.commons.logging.impl.WeakHashtable;
+
+import iaik.logging.Log;
+import iaik.logging.LogConfigurationException;
+import iaik.logging.LogFactory;
+
+/**
+ * @author mcentner
+ *
+ */
+public class IAIKCommonsLogFactory extends LogFactory {
+
+ protected WeakHashtable instances = new WeakHashtable();
+
+ /* (non-Javadoc)
+ * @see iaik.logging.LogFactory#getInstance(java.lang.String)
+ */
+ @Override
+ public Log getInstance(String name) throws LogConfigurationException {
+ org.apache.commons.logging.Log commonsLog = org.apache.commons.logging.LogFactory.getLog(name);
+ Log log = (Log) instances.get(commonsLog);
+ if (log == null) {
+ log = new IAIKCommonsLog(commonsLog);
+ log.setNodeId(node_id_);
+ instances.put(commonsLog, log);
+ }
+ return log;
+ }
+
+ /* (non-Javadoc)
+ * @see iaik.logging.LogFactory#getInstance(java.lang.Class)
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public Log getInstance(Class clazz) throws LogConfigurationException {
+ org.apache.commons.logging.Log commonsLog = org.apache.commons.logging.LogFactory.getLog(clazz);
+ Log log = (Log) instances.get(commonsLog);
+ if (log == null) {
+ log = new IAIKCommonsLog(commonsLog);
+ log.setNodeId(node_id_);
+ instances.put(commonsLog, log);
+ }
+ return log;
+ }
+
+ /* (non-Javadoc)
+ * @see iaik.logging.LogFactory#release()
+ */
+ @Override
+ public void release() {
+ instances.clear();
+ }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java
index fe27bc54..8e3f6ece 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java
@@ -28,6 +28,7 @@ import javax.xml.bind.JAXBException;
import javax.xml.bind.UnmarshalException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.ValidationEvent;
+import javax.xml.bind.ValidationEventLocator;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
@@ -46,11 +47,11 @@ import at.gv.egiz.bku.slexceptions.SLCommandException;
import at.gv.egiz.bku.slexceptions.SLExceptionMessages;
import at.gv.egiz.bku.slexceptions.SLRequestException;
import at.gv.egiz.bku.slexceptions.SLRuntimeException;
+import at.gv.egiz.bku.slexceptions.SLVersionException;
import at.gv.egiz.bku.utils.DebugReader;
import at.gv.egiz.slbinding.RedirectEventFilter;
import at.gv.egiz.slbinding.RedirectUnmarshallerListener;
-import at.gv.egiz.validation.ValidationEventLogger;
-import javax.xml.bind.ValidationEventHandler;
+import at.gv.egiz.validation.ReportingValidationEventHandler;
public class SLCommandFactory {
@@ -60,7 +61,9 @@ public class SLCommandFactory {
public static final String[] SCHEMA_FILES = new String[]{
"at/gv/egiz/bku/slcommands/schema/xml.xsd",
"at/gv/egiz/bku/slcommands/schema/xmldsig-core-schema.xsd",
- "at/gv/egiz/bku/slcommands/schema/Core-1.2.xsd"
+ "at/gv/egiz/bku/slcommands/schema/Core-1.2.xsd",
+ "at/gv/egiz/bku/slcommands/schema/Core.20020225.xsd",
+ "at/gv/egiz/bku/slcommands/schema/Core.20020831.xsd"
};
/**
* Logging facility.
@@ -169,7 +172,10 @@ public class SLCommandFactory {
String slPkg = at.buergerkarte.namespaces.securitylayer._1.ObjectFactory.class.getPackage().getName();
String xmldsigPkg = org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName();
String cardChannelPkg = at.buergerkarte.namespaces.cardchannel.ObjectFactory.class.getPackage().getName();
- setJaxbContext(JAXBContext.newInstance(slPkg + ":" + xmldsigPkg + ":" + cardChannelPkg));
+ String slPkgLegacy1_0 = at.buergerkarte.namespaces.securitylayer._20020225_.ObjectFactory.class.getPackage().getName();
+ String slPkgLegacy1_1 = at.buergerkarte.namespaces.securitylayer._20020831_.ObjectFactory.class.getPackage().getName();
+ setJaxbContext(JAXBContext.newInstance(slPkg + ":" + xmldsigPkg + ":" + cardChannelPkg
+ + ":" + slPkgLegacy1_0 + ":" + slPkgLegacy1_1));
} catch (JAXBException e) {
log.error("Failed to setup JAXBContext security layer request.", e);
throw new SLRuntimeException(e);
@@ -248,26 +254,9 @@ public class SLCommandFactory {
SLRequestException {
Object object;
+ ReportingValidationEventHandler validationEventHandler = new ReportingValidationEventHandler();
try {
-// ValidatorHandler validator = slSchema.newValidatorHandler();
-// validator.getContentHandler();
-//
-// SAXParserFactory spf = SAXParserFactory.newInstance();
-// spf.setNamespaceAware(true);
-// XMLReader saxReader = spf.newSAXParser().getXMLReader();
-// //TODO extend validator to implement redirectContentHandler (validate+redirect)
-// saxReader.setContentHandler(validator);
-// //TODO get a InputSource
-// SAXSource saxSource = new SAXSource(saxReader, source);
-//
-// Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
-// //turn off duplicate jaxb validation
-// unmarshaller.setSchema(null);
-// unmarshaller.setListener(listener);
-// unmarshaller.unmarshal(saxSource);
-
-
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
XMLEventReader eventReader = inputFactory.createXMLEventReader(source);
RedirectEventFilter redirectEventFilter = new RedirectEventFilter();
@@ -279,7 +268,7 @@ public class SLCommandFactory {
unmarshaller.setSchema(slSchema);
}
log.trace("Before unmarshal().");
- unmarshaller.setEventHandler(new ValidationEventLogger());
+ unmarshaller.setEventHandler(validationEventHandler);
object = unmarshaller.unmarshal(filteredReader);
log.trace("After unmarshal().");
} catch (UnmarshalException e) {
@@ -288,6 +277,13 @@ public class SLCommandFactory {
} else {
log.info("Failed to unmarshall security layer request." + e.getMessage());
}
+ if (validationEventHandler.getErrorEvent() != null) {
+ // Validation Error
+ ValidationEvent errorEvent = validationEventHandler.getErrorEvent();
+ ValidationEventLocator locator = errorEvent.getLocator();
+ throw new SLRequestException(3002,
+ SLExceptionMessages.EC3002_INVALID, new Object[]{errorEvent.getMessage()});
+ }
Throwable cause = e.getCause();
if (cause instanceof SAXParseException) {
throw new SLRequestException(3000,
@@ -328,10 +324,11 @@ public class SLCommandFactory {
* if an unexpected error occurs configuring the unmarshaller, if
* unmarshalling fails with an unexpected error or if the
* corresponding <code>SLCommand</code> could not be instantiated
+ * @throws SLVersionException
*/
@SuppressWarnings("unchecked")
public SLCommand createSLCommand(Source source, SLCommandContext context)
- throws SLCommandException, SLRuntimeException, SLRequestException {
+ throws SLCommandException, SLRuntimeException, SLRequestException, SLVersionException {
DebugReader dr = null;
if (log.isTraceEnabled() && source instanceof StreamSource) {
@@ -361,6 +358,12 @@ public class SLCommandFactory {
}
QName qName = ((JAXBElement) object).getName();
+ if (!SLCommand.NAMESPACE_URI.equals(qName.getNamespaceURI())) {
+ // security layer request version not supported
+ log.info("Unsupported security layer request version : " + qName.getNamespaceURI());
+ throw new SLVersionException(qName.getNamespaceURI());
+ }
+
Class<? extends SLCommand> implClass = getImplClass(qName);
if (implClass == null) {
// command not supported
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLMarshallerFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLMarshallerFactory.java
new file mode 100644
index 00000000..e0a375cf
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLMarshallerFactory.java
@@ -0,0 +1,172 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package at.gv.egiz.bku.slcommands;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.gv.egiz.bku.slexceptions.SLRuntimeException;
+import at.gv.egiz.marshal.MarshallerFactory;
+
+public class SLMarshallerFactory {
+
+ static Log log = LogFactory.getLog(SLMarshallerFactory.class);
+
+ /**
+ * The JAXBContext used for result marshaling.
+ * <p>
+ * Note: Different contexts are used for marshaling and unmarshaling of
+ * security layer requests and responses to avoid propagation of namespace
+ * declarations of legacy namespaces into marshaled results.
+ * </p>
+ * @see #jaxbContextLegacy
+ */
+ protected static JAXBContext context;
+
+ /**
+ * The JAXBContext used for marshaling of of results in the legacy namespace.
+ */
+ protected static JAXBContext legacyContext;
+
+ // ------------------- initialization on demand idiom -------------------
+ // see http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom
+ // ----------------------------------------------------------------------
+
+ /**
+ * Private constructor called by {@link SLMarshallerFactoryInstanceHolder}.
+ */
+ private SLMarshallerFactory() {
+ // context is initialized immediately while the legacy context is initialized only on demand
+ try {
+ String slPkg = at.buergerkarte.namespaces.securitylayer._1.ObjectFactory.class.getPackage().getName();
+ String xmldsigPkg = org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName();
+ String cardChannelPkg = at.buergerkarte.namespaces.cardchannel.ObjectFactory.class.getPackage().getName();
+ context = JAXBContext.newInstance(slPkg + ":" + xmldsigPkg + ":" + cardChannelPkg);
+ } catch (JAXBException e) {
+ log.error("Failed to setup JAXBContext security layer request.", e);
+ throw new SLRuntimeException(e);
+ }
+ }
+
+ /**
+ * The lazy instance holder for this SLMarshallerFactory.
+ */
+ private static class SLMarshallerFactoryInstanceHolder {
+ /**
+ * The instance returned by {@link SLMarshallerFactory#getInstance()}
+ */
+ private static final SLMarshallerFactory instance = new SLMarshallerFactory();
+ }
+
+ /**
+ * Get an instance of the <code>SLMarshallerFactory</code>.
+ */
+ public static SLMarshallerFactory getInstance() {
+ return SLMarshallerFactoryInstanceHolder.instance;
+ }
+
+ // ----------------------------------------------------------------------
+
+ /**
+ * Initialize the JAXBContext for the legacy namespace.
+ */
+ private static synchronized void ensureLegacyContext() {
+ // legacy marshaller is initialized only on demand
+ if (legacyContext == null) {
+ try {
+ String slPkgLegacy1_0 = at.buergerkarte.namespaces.securitylayer._20020225_.ObjectFactory.class.getPackage().getName();
+ String slPkgLegacy1_1 = at.buergerkarte.namespaces.securitylayer._20020831_.ObjectFactory.class.getPackage().getName();
+ String xmldsigPkg = org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName();
+ String cardChannelPkg = at.buergerkarte.namespaces.cardchannel.ObjectFactory.class.getPackage().getName();
+ legacyContext = JAXBContext.newInstance(slPkgLegacy1_0 + ":" + slPkgLegacy1_1 + ":" + xmldsigPkg + ":" + cardChannelPkg);
+ } catch (JAXBException e) {
+ log.error("Failed to setup JAXBContext security layer request.", e);
+ throw new SLRuntimeException(e);
+ }
+ }
+ }
+
+ /**
+ * Creates an SL marshaller.
+ *
+ * @param formattedOutput
+ * <code>true</code> if the marshaller should produce formated
+ * output, <code>false</code> otherwise
+ * @return an SL marshaller
+ */
+ public Marshaller createMarshaller(boolean formattedOutput) {
+ return createMarshaller(formattedOutput, false);
+ }
+
+ /**
+ * Creates an SL marshaller.
+ *
+ * @param formattedOutput
+ * <code>true</code> if the marshaller should produce formated
+ * output, <code>false</code> otherwise
+ * @param fragment
+ * <code>true</code> if the marshaller should produce a XML fragment
+ * (omit XML declaration), <code>false</code> otherwise
+ * @return an SL marshaller
+ */
+ public Marshaller createMarshaller(boolean formattedOutput, boolean fragment) {
+ try {
+ return MarshallerFactory.createMarshaller(context, formattedOutput, fragment);
+ } catch (JAXBException e) {
+ log.fatal("Failed to marshall error response.", e);
+ throw new SLRuntimeException("Failed to marshall error response.", e);
+ }
+ }
+
+ /**
+ * Creates a legacy SL marshaller.
+ *
+ * @param formattedOutput
+ * <code>true</code> if the marshaller should produce formated
+ * output, <code>false</code> otherwise
+ * @return a legacy SL marshaller
+ */
+ public Marshaller createLegacyMarshaller(boolean formattedOutput) {
+ return createLegacyMarshaller(formattedOutput, false);
+ }
+
+ /**
+ * Creates a legacy SL marshaller.
+ *
+ * @param formattedOutput
+ * <code>true</code> if the marshaller should produce formated
+ * output, <code>false</code> otherwise
+ * @param fragment
+ * <code>true</code> if the marshaller should produce a XML fragment
+ * (omit XML declaration), <code>false</code> otherwise
+ * @return a legacy SL marshaller
+ */
+ public Marshaller createLegacyMarshaller(boolean formattedOutput, boolean fragment) {
+ try {
+ ensureLegacyContext();
+ return MarshallerFactory.createMarshaller(legacyContext, formattedOutput, fragment);
+ } catch (JAXBException e) {
+ log.fatal("Failed to marshall error response.", e);
+ throw new SLRuntimeException("Failed to marshall error response.", e);
+ }
+ }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLResult.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLResult.java
index 7989a771..e9e483c5 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLResult.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLResult.java
@@ -32,12 +32,14 @@ public interface SLResult {
*/
public String getMimeType();
- public void writeTo(Result aResult);
+ public void writeTo(Result aResult, boolean fragment);
/**
*
- * @param result
+ * @param result
+ * @param fragment TODO
* @param transformer may be null.
*/
- public void writeTo(Result result, Templates templates);
+ public void writeTo(Result result, Templates templates, boolean fragment);
+
} \ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java
index ce03dcf9..9a4536e6 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java
@@ -16,7 +16,6 @@
*/
package at.gv.egiz.bku.slcommands.impl;
-import at.gv.egiz.marshal.NamespacePrefixMapperImpl;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
import java.util.Collections;
@@ -24,7 +23,6 @@ import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
-import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
@@ -42,10 +40,8 @@ import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadParamsAssocArrayTy
import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadParamsAssocArrayType.ReadValue;
import at.gv.egiz.bku.slcommands.InfoboxReadResult;
import at.gv.egiz.bku.slcommands.SLCommandContext;
-import at.gv.egiz.bku.slcommands.SLCommandFactory;
+import at.gv.egiz.bku.slcommands.SLMarshallerFactory;
import at.gv.egiz.bku.slexceptions.SLCommandException;
-import at.gv.egiz.marshal.MarshallerFactory;
-import javax.xml.bind.PropertyException;
/**
* An abstract base class for {@link Infobox} implementations of type associative array.
@@ -255,13 +251,10 @@ public abstract class AbstractAssocArrayInfobox extends AbstractInfoboxImpl
}
protected byte[] marshallValue(Object jaxbElement) throws SLCommandException {
- SLCommandFactory commandFactory = SLCommandFactory.getInstance();
- JAXBContext jaxbContext = commandFactory.getJaxbContext();
- ByteArrayOutputStream result;
+ Marshaller marshaller = SLMarshallerFactory.getInstance().createMarshaller(false);
+ ByteArrayOutputStream result = new ByteArrayOutputStream();
try {
- Marshaller marshaller = MarshallerFactory.createMarshaller(jaxbContext);
- result = new ByteArrayOutputStream();
marshaller.marshal(jaxbElement, result);
} catch (JAXBException e) {
log.info("Failed to marshall infobox content.", e);
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureResultImpl.java
index b352a51e..19df4334 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureResultImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureResultImpl.java
@@ -16,8 +16,6 @@
*/
package at.gv.egiz.bku.slcommands.impl;
-import at.gv.egiz.marshal.NamespacePrefixMapperImpl;
-import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
@@ -33,10 +31,8 @@ import org.w3c.dom.Node;
import at.buergerkarte.namespaces.securitylayer._1.CreateXMLSignatureResponseType;
import at.buergerkarte.namespaces.securitylayer._1.ObjectFactory;
-import at.gv.egiz.bku.slcommands.SLCommandFactory;
+import at.gv.egiz.bku.slcommands.SLMarshallerFactory;
import at.gv.egiz.bku.slexceptions.SLRuntimeException;
-import at.gv.egiz.marshal.MarshallerFactory;
-import javax.xml.bind.PropertyException;
/**
* This calls implements the result of the security layer command <code>CreateXMLSignature</code>.
@@ -86,10 +82,9 @@ public class CreateXMLSignatureResultImpl extends SLResultImpl {
JAXBElement<CreateXMLSignatureResponseType> createCreateXMLSignatureResponse = factory.createCreateXMLSignatureResponse(createCreateXMLSignatureResponseType);
DocumentFragment fragment = doc.createDocumentFragment();
-
- JAXBContext jaxbContext = SLCommandFactory.getInstance().getJaxbContext();
+
+ Marshaller marshaller = SLMarshallerFactory.getInstance().createMarshaller(false);
try {
- Marshaller marshaller = MarshallerFactory.createMarshaller(jaxbContext);
marshaller.marshal(createCreateXMLSignatureResponse, fragment);
} catch (JAXBException e) {
log.error("Failed to marshall 'CreateXMLSignatureResponse'", e);
@@ -105,8 +100,8 @@ public class CreateXMLSignatureResultImpl extends SLResultImpl {
}
@Override
- public void writeTo(Result result, Templates templates) {
- writeTo(doc, result, templates);
+ public void writeTo(Result result, Templates templates, boolean fragment) {
+ writeTo(doc, result, templates, fragment);
}
}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImpl.java
index 5d0f0de0..aedde238 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImpl.java
@@ -56,11 +56,11 @@ public class ErrorResultImpl extends SLResultImpl implements ErrorResult {
}
@Override
- public void writeTo(Result result, Templates templates) {
+ public void writeTo(Result result, Templates templates, boolean fragment) {
if (locale == null) {
- writeErrorTo(slException, result, templates);
+ writeErrorTo(slException, result, templates, fragment);
} else {
- writeErrorTo(slException, result, templates, locale);
+ writeErrorTo(slException, result, templates, locale, fragment);
}
}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandImpl.java
index 46bfe18b..0c2b96f9 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandImpl.java
@@ -19,10 +19,8 @@ package at.gv.egiz.bku.slcommands.impl;
import at.buergerkarte.namespaces.securitylayer._1.GetStatusRequestType;
import at.gv.egiz.bku.slcommands.GetStatusCommand;
-import at.gv.egiz.bku.slcommands.SLCommandContext;
import at.gv.egiz.bku.slcommands.SLResult;
import at.gv.egiz.bku.slexceptions.SLCommandException;
-import at.gv.egiz.bku.slexceptions.SLException;
import at.gv.egiz.stal.ErrorResponse;
import at.gv.egiz.stal.STAL;
import at.gv.egiz.stal.STALResponse;
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusResultImpl.java
index fddd3b0b..fb1f627f 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusResultImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusResultImpl.java
@@ -45,8 +45,8 @@ public class GetStatusResultImpl extends SLResultImpl implements GetStatusResult
}
@Override
- public void writeTo(Result result, Templates templates) {
+ public void writeTo(Result result, Templates templates, boolean fragment) {
JAXBElement<GetStatusResponseType> response = of.createGetStatusResponse(responseType);
- writeTo(response, result, templates);
+ writeTo(response, result, templates, fragment);
}
}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxImpl.java
index 7a82e43f..160e9589 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxImpl.java
@@ -18,7 +18,6 @@ package at.gv.egiz.bku.slcommands.impl;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.OutputStream;
import java.net.MalformedURLException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultFileImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultFileImpl.java
index 75e44afa..422b424f 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultFileImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultFileImpl.java
@@ -16,8 +16,6 @@
*/
package at.gv.egiz.bku.slcommands.impl;
-import at.gv.egiz.marshal.NamespacePrefixMapperImpl;
-import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
@@ -39,10 +37,8 @@ import at.buergerkarte.namespaces.securitylayer._1.ObjectFactory;
import at.buergerkarte.namespaces.securitylayer._1.XMLContentType;
import at.gv.egiz.bku.slcommands.InfoboxReadResult;
import at.gv.egiz.bku.slcommands.SLCommand;
-import at.gv.egiz.bku.slcommands.SLCommandFactory;
+import at.gv.egiz.bku.slcommands.SLMarshallerFactory;
import at.gv.egiz.bku.slexceptions.SLRuntimeException;
-import at.gv.egiz.marshal.MarshallerFactory;
-import javax.xml.bind.PropertyException;
/**
* This class implements the result of the security layer command <code>InfoboxReadRequest</code>.
@@ -98,10 +94,9 @@ public class InfoboxReadResultFileImpl extends SLResultImpl implements
infoboxReadResponseType.setBinaryFileData(base64XMLContentType);
JAXBElement<InfoboxReadResponseType> infoboxReadResponse = factory.createInfoboxReadResponse(infoboxReadResponseType);
-
- JAXBContext context = SLCommandFactory.getInstance().getJaxbContext();
+
+ Marshaller marshaller = SLMarshallerFactory.getInstance().createMarshaller(false);
try {
- Marshaller marshaller = MarshallerFactory.createMarshaller(context);
marshaller.marshal(infoboxReadResponse, doc);
} catch (JAXBException e) {
log.error("Failed to marshal 'InfoboxReadResponse' document.", e);
@@ -158,8 +153,8 @@ public class InfoboxReadResultFileImpl extends SLResultImpl implements
}
@Override
- public void writeTo(Result result, Templates templates) {
- writeTo(xmlDocument, result, templates);
+ public void writeTo(Result result, Templates templates, boolean fragment) {
+ writeTo(xmlDocument, result, templates, fragment);
}
}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultImpl.java
index e508941d..271ec955 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultImpl.java
@@ -55,10 +55,10 @@ public class InfoboxReadResultImpl extends SLResultImpl implements InfoboxReadRe
}
@Override
- public void writeTo(Result result, Templates templates) {
+ public void writeTo(Result result, Templates templates, boolean fragment) {
ObjectFactory objectFactory = new ObjectFactory();
JAXBElement<InfoboxReadResponseType> response = objectFactory.createInfoboxReadResponse(infoboxReadResponse);
- writeTo(response, result, templates);
+ writeTo(response, result, templates, fragment);
}
}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateResultImpl.java
index 15064756..e12536ba 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateResultImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateResultImpl.java
@@ -36,8 +36,8 @@ public class InfoboxUpdateResultImpl extends SLResultImpl implements
}
@Override
- public void writeTo(Result result, Templates templates) {
- writeTo(RESPONSE, result, templates);
+ public void writeTo(Result result, Templates templates, boolean fragment) {
+ writeTo(RESPONSE, result, templates, fragment);
}
}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationResultImpl.java
index 05986f85..87733e39 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationResultImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationResultImpl.java
@@ -41,8 +41,8 @@ public class NullOperationResultImpl extends SLResultImpl implements NullOperati
}
@Override
- public void writeTo(Result result, Templates templates) {
- writeTo(RESPONSE, result, templates);
+ public void writeTo(Result result, Templates templates, boolean fragment) {
+ super.writeTo(RESPONSE, result, templates, fragment);
}
}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java
index 0452bddf..0077b7b2 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java
@@ -17,12 +17,14 @@
package at.gv.egiz.bku.slcommands.impl;
import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
import java.util.Locale;
-import javax.xml.bind.JAXBContext;
+import javax.xml.XMLConstants;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
+import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
@@ -41,17 +43,15 @@ import org.w3c.dom.Node;
import at.buergerkarte.namespaces.securitylayer._1.ErrorResponseType;
import at.buergerkarte.namespaces.securitylayer._1.ObjectFactory;
-import at.gv.egiz.marshal.NamespacePrefixMapperImpl;
-import at.gv.egiz.bku.slcommands.SLCommandFactory;
+import at.gv.egiz.bku.slcommands.SLMarshallerFactory;
import at.gv.egiz.bku.slcommands.SLResult;
import at.gv.egiz.bku.slexceptions.SLBindingException;
import at.gv.egiz.bku.slexceptions.SLCommandException;
import at.gv.egiz.bku.slexceptions.SLException;
import at.gv.egiz.bku.slexceptions.SLRuntimeException;
+import at.gv.egiz.bku.slexceptions.SLVersionException;
import at.gv.egiz.bku.utils.DebugOutputStream;
import at.gv.egiz.bku.utils.DebugWriter;
-import at.gv.egiz.marshal.MarshallerFactory;
-import javax.xml.bind.PropertyException;
/**
* This class serves as an abstract base class for the implementation of a
@@ -90,20 +90,18 @@ public abstract class SLResultImpl implements SLResult {
return resultingMimeType;
}
- private Marshaller getMarshaller() {
- try {
- JAXBContext context = SLCommandFactory.getInstance().getJaxbContext();
- Marshaller marshaller = MarshallerFactory.createMarshaller(context, true);
- return marshaller;
- } catch (JAXBException e) {
- log.fatal("Failed to marshall error response.", e);
- throw new SLRuntimeException("Failed to marshall error response.", e);
- }
+ @Override
+ public void writeTo(Result result, boolean fragment) {
+ writeTo(result, null, false);
}
+ @Override
+ public abstract void writeTo(Result result, Templates templates, boolean fragment);
+
private TransformerHandler getTransformerHandler(Templates templates, Result result) throws SLException {
try {
SAXTransformerFactory transformerFactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
+ transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
TransformerHandler transformerHandler = transformerFactory.newTransformerHandler(templates);
transformerHandler.setResult(result);
return transformerHandler;
@@ -119,12 +117,6 @@ public abstract class SLResultImpl implements SLResult {
}
}
- @Override
- public void writeTo(Result result) {
- writeTo(result, null);
- }
-
-
/**
* Writes the given <code>response</code> to the SAX <code>result</code> using
* the given transform <code>templates</code>.
@@ -133,7 +125,7 @@ public abstract class SLResultImpl implements SLResult {
* @param result
* @param templates
*/
- protected void writeTo(JAXBElement<?> response, Result result, Templates templates) {
+ protected void writeTo(JAXBElement<?> response, Result result, Templates templates, boolean fragment) {
DebugWriter dw = null;
DebugOutputStream ds = null;
@@ -154,11 +146,11 @@ public abstract class SLResultImpl implements SLResult {
try {
transformerHandler = getTransformerHandler(templates, result);
} catch (SLException e) {
- writeErrorTo(e, result, templates);
+ writeErrorTo(e, result, templates, fragment);
}
}
- Marshaller marshaller = getMarshaller();
+ Marshaller marshaller = SLMarshallerFactory.getInstance().createMarshaller(true);
try {
if (transformerHandler != null) {
marshaller.marshal(response, transformerHandler);
@@ -168,7 +160,7 @@ public abstract class SLResultImpl implements SLResult {
} catch (JAXBException e) {
log.info("Failed to marshall " + response.getName() + " result." , e);
SLCommandException commandException = new SLCommandException(4000);
- writeErrorTo(commandException, result, templates);
+ writeErrorTo(commandException, result, templates, fragment);
}
if (ds != null) {
@@ -185,7 +177,7 @@ public abstract class SLResultImpl implements SLResult {
}
- protected void writeTo(Node node, Result result, Templates templates) {
+ protected void writeTo(Node node, Result result, Templates templates, boolean fragment) {
DebugWriter dw = null;
DebugOutputStream ds = null;
@@ -205,24 +197,30 @@ public abstract class SLResultImpl implements SLResult {
try {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
+ if (fragment) {
+ transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+ }
transformer.transform(new DOMSource(node), result);
} catch (TransformerConfigurationException e) {
log.error("Failed to create Transformer.", e);
- writeErrorTo(new SLException(4000), result, null);
+ writeErrorTo(new SLException(4000), result, null, fragment);
} catch (TransformerException e) {
log.error("Failed to transform result.", e);
- writeErrorTo(new SLException(4000), result, null);
+ writeErrorTo(new SLException(4000), result, null, fragment);
}
} else {
try {
Transformer transformer = templates.newTransformer();
+ if (fragment) {
+ transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+ }
transformer.transform(new DOMSource(node), result);
} catch (TransformerConfigurationException e) {
log.info("Failed to create transformer.", e);
- writeErrorTo(new SLException(2008), result, templates);
+ writeErrorTo(new SLException(2008), result, templates, fragment);
} catch (TransformerException e) {
log.error("Failed to transform result.", e);
- writeErrorTo(new SLException(2008), result, templates);
+ writeErrorTo(new SLException(2008), result, templates, fragment);
}
}
@@ -240,11 +238,11 @@ public abstract class SLResultImpl implements SLResult {
}
- protected void writeErrorTo(SLException slException, Result result, Templates templates) {
- writeErrorTo(slException, result, templates, Locale.getDefault());
+ protected void writeErrorTo(SLException slException, Result result, Templates templates, boolean fragment) {
+ writeErrorTo(slException, result, templates, Locale.getDefault(), fragment);
}
- protected void writeErrorTo(SLException slException, Result result, Templates templates, Locale locale) {
+ protected void writeErrorTo(SLException slException, Result result, Templates templates, Locale locale, boolean fragment) {
TransformerHandler transformerHandler = null;
if (templates != null) {
@@ -256,13 +254,33 @@ public abstract class SLResultImpl implements SLResult {
}
}
- ObjectFactory factory = new ObjectFactory();
- ErrorResponseType responseType = factory.createErrorResponseType();
- responseType.setErrorCode(slException.getErrorCode());
- responseType.setInfo(slException.getLocalizedMessage(locale));
- JAXBElement<ErrorResponseType> response = factory.createErrorResponse(responseType);
+ Object response;
+
+ Marshaller marshaller;
+ if (slException instanceof SLVersionException
+ && ("http://www.buergerkarte.at/namespaces/securitylayer/20020225#"
+ .equals(((SLVersionException) slException).getNamespaceURI()) ||
+ "http://www.buergerkarte.at/namespaces/securitylayer/20020831#"
+ .equals(((SLVersionException) slException).getNamespaceURI()))) {
+ // issue ErrorResponse in the legacy namespace
+ at.buergerkarte.namespaces.securitylayer._20020225_.ObjectFactory factory
+ = new at.buergerkarte.namespaces.securitylayer._20020225_.ObjectFactory();
+ at.buergerkarte.namespaces.securitylayer._20020225_.ErrorResponseType errorResponseType = factory
+ .createErrorResponseType();
+ errorResponseType.setErrorCode(BigInteger.valueOf(slException
+ .getErrorCode()));
+ errorResponseType.setInfo(slException.getLocalizedMessage(locale));
+ response = factory.createErrorResponse(errorResponseType);
+ marshaller = SLMarshallerFactory.getInstance().createLegacyMarshaller(true, fragment);
+ } else {
+ ObjectFactory factory = new ObjectFactory();
+ ErrorResponseType responseType = factory.createErrorResponseType();
+ responseType.setErrorCode(slException.getErrorCode());
+ responseType.setInfo(slException.getLocalizedMessage(locale));
+ response = factory.createErrorResponse(responseType);
+ marshaller = SLMarshallerFactory.getInstance().createMarshaller(true, fragment);
+ }
- Marshaller marshaller = getMarshaller();
try {
if (transformerHandler != null) {
marshaller.marshal(response, transformerHandler);
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java
index b64306aa..2088a684 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java
@@ -81,7 +81,6 @@ import at.gv.egiz.bku.viewer.ValidationException;
import at.gv.egiz.bku.viewer.Validator;
import at.gv.egiz.bku.viewer.ValidatorFactory;
import at.gv.egiz.dom.DOMUtils;
-import at.gv.egiz.marshal.NamespacePrefix;
import at.gv.egiz.marshal.NamespacePrefixMapperImpl;
import at.gv.egiz.slbinding.impl.XMLContentType;
import javax.xml.namespace.NamespaceContext;
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java
index 9182e824..26ddb153 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java
@@ -16,7 +16,6 @@
*/
package at.gv.egiz.bku.slcommands.impl.xsect;
-import at.gv.egiz.stal.HashDataInput;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -31,9 +30,7 @@ import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
@@ -87,8 +84,6 @@ import at.gv.egiz.bku.utils.urldereferencer.StreamData;
import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext;
import at.gv.egiz.dom.DOMUtils;
-import at.gv.egiz.marshal.NamespacePrefix;
-import at.gv.egiz.marshal.NamespacePrefixMapperImpl;
import at.gv.egiz.slbinding.impl.XMLContentType;
import at.gv.egiz.stal.STAL;
import at.gv.egiz.xades.QualifyingPropertiesException;
@@ -327,6 +322,8 @@ public class Signature {
*/
public void buildXMLSignature() throws SLCommandException {
+ String signatureId = ctx.getIdValueFactory().createIdValue("Signature");
+
List<XMLObject> objects = new ArrayList<XMLObject>();
List<Reference> references = new ArrayList<Reference>();
@@ -340,7 +337,7 @@ public class Signature {
}
}
- addXAdESObjectAndReference(objects, references);
+ addXAdESObjectAndReference(objects, references, signatureId);
XMLSignatureFactory signatureFactory = ctx.getSignatureFactory();
AlgorithmMethodFactory algorithmMethodFactory = ctx.getAlgorithmMethodFactory();
@@ -369,7 +366,6 @@ public class Signature {
ki = kif.newKeyInfo(Collections.singletonList(x509Data));
}
- String signatureId = ctx.getIdValueFactory().createIdValue("Signature");
String signatureValueId = ctx.getIdValueFactory().createIdValue("SignatureValue");
xmlSignature = signatureFactory.newXMLSignature(si, ki, objects, signatureId, signatureValueId);
@@ -588,7 +584,7 @@ public class Signature {
* @param references
* the list of <code>ds:References</code> to add the created
* <code>ds:Reference</code> to
- *
+ * @param signatureId TODO
* @throws SLCommandException
* if creating and adding the XAdES
* <code>QualifyingProperties</code> fails
@@ -596,7 +592,7 @@ public class Signature {
* if <code>objects</code> or <code>references</code> is
* <code>null</code>
*/
- private void addXAdESObjectAndReference(List<XMLObject> objects, List<Reference> references) throws SLCommandException {
+ private void addXAdESObjectAndReference(List<XMLObject> objects, List<Reference> references, String signatureId) throws SLCommandException {
QualifyingPropertiesFactory factory = QualifyingPropertiesFactory.getInstance();
@@ -630,9 +626,11 @@ public class Signature {
}
}
+ String target = "#" + signatureId;
+
JAXBElement<QualifyingPropertiesType> qualifyingProperties;
try {
- qualifyingProperties = factory.createQualifyingProperties111(date, signingCertificates, idValue, dataObjectFormats);
+ qualifyingProperties = factory.createQualifyingProperties111(target, date, signingCertificates, idValue, dataObjectFormats);
} catch (QualifyingPropertiesException e) {
log.error("Failed to create QualifyingProperties.", e);
throw new SLCommandException(4000);
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLExceptionMessages.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLExceptionMessages.java
index 5ce5cba1..73ac8d1b 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLExceptionMessages.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLExceptionMessages.java
@@ -47,4 +47,10 @@ public final class SLExceptionMessages {
public static final String EC4011_NOTIMPLEMENTED = "ec4011.notimplemented";
+ //
+ // Legacy error codes
+ //
+
+ public static final String LEC2901_NOTIMPLEMENTED = "lec2901.notimplemented";
+
}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLVersionException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLVersionException.java
new file mode 100644
index 00000000..45501746
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLVersionException.java
@@ -0,0 +1,28 @@
+package at.gv.egiz.bku.slexceptions;
+
+public class SLVersionException extends SLException {
+
+ private static final long serialVersionUID = 1L;
+
+ protected String namespaceURI;
+
+ public SLVersionException(String namespaceURI) {
+ super(2901, SLExceptionMessages.LEC2901_NOTIMPLEMENTED, new Object[] {namespaceURI});
+ this.namespaceURI = namespaceURI;
+ }
+
+ public SLVersionException(int errorCode, String namespaceURI) {
+ super(errorCode);
+ this.namespaceURI = namespaceURI;
+ }
+
+ public SLVersionException(int errorCode, String namespaceURI, String message, Object[] arguments) {
+ super(errorCode, message, arguments);
+ this.namespaceURI = namespaceURI;
+ }
+
+ public String getNamespaceURI() {
+ return namespaceURI;
+ }
+
+}