From 32d17447a258188b2d534bcb0bf65a659ba7b7d0 Mon Sep 17 00:00:00 2001
From: mcentner
Date: Fri, 29 Aug 2008 12:11:34 +0000
Subject: Initial import.
git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@1 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4
---
bkucommon/src/main/java/META-INF/MANIFEST.MF | 3 +
.../egiz/bku/binding/AbstractBindingProcessor.java | 86 ++
.../at/gv/egiz/bku/binding/BindingProcessor.java | 75 ++
.../egiz/bku/binding/BindingProcessorManager.java | 102 ++
.../bku/binding/BindingProcessorManagerImpl.java | 258 +++++
.../main/java/at/gv/egiz/bku/binding/DataUrl.java | 62 ++
.../at/gv/egiz/bku/binding/DataUrlConnection.java | 79 ++
.../gv/egiz/bku/binding/DataUrlConnectionImpl.java | 216 +++++
.../gv/egiz/bku/binding/DataUrlConnectionSPI.java | 42 +
.../at/gv/egiz/bku/binding/DataUrlResponse.java | 98 ++
.../java/at/gv/egiz/bku/binding/ExpiryRemover.java | 67 ++
.../gv/egiz/bku/binding/FixedFormParameters.java | 28 +
.../java/at/gv/egiz/bku/binding/FormParameter.java | 39 +
.../at/gv/egiz/bku/binding/FormParameterImpl.java | 93 ++
.../at/gv/egiz/bku/binding/FormParameterStore.java | 146 +++
.../gv/egiz/bku/binding/HTTPBindingProcessor.java | 820 ++++++++++++++++
.../main/java/at/gv/egiz/bku/binding/HttpUtil.java | 78 ++
.../src/main/java/at/gv/egiz/bku/binding/Id.java | 27 +
.../java/at/gv/egiz/bku/binding/IdFactory.java | 106 +++
.../main/java/at/gv/egiz/bku/binding/IdImpl.java | 80 ++
.../java/at/gv/egiz/bku/binding/InputDecoder.java | 41 +
.../gv/egiz/bku/binding/InputDecoderFactory.java | 89 ++
.../bku/binding/MultiPartFormDataInputDecoder.java | 133 +++
.../at/gv/egiz/bku/binding/RemovalStrategy.java | 26 +
.../gv/egiz/bku/binding/SLCommandInvokerImpl.java | 66 ++
.../egiz/bku/binding/XWWWFormUrlInputDecoder.java | 101 ++
.../binding/multipart/InputStreamPartSource.java | 66 ++
.../egiz/bku/binding/multipart/SLResultPart.java | 57 ++
.../bku/slcommands/AccessControlInvocation.java | 21 +
.../bku/slcommands/CreateXMLSignatureCommand.java | 25 +
.../bku/slcommands/CreateXMLSignatureResult.java | 20 +
.../at/gv/egiz/bku/slcommands/ErrorResult.java | 20 +
.../gv/egiz/bku/slcommands/InfoboxReadCommand.java | 20 +
.../gv/egiz/bku/slcommands/InfoboxReadResult.java | 20 +
.../gv/egiz/bku/slcommands/InvocationStrategy.java | 20 +
.../egiz/bku/slcommands/NullOperationCommand.java | 20 +
.../egiz/bku/slcommands/NullOperationResult.java | 20 +
.../java/at/gv/egiz/bku/slcommands/SLCommand.java | 31 +
.../gv/egiz/bku/slcommands/SLCommandContext.java | 42 +
.../gv/egiz/bku/slcommands/SLCommandFactory.java | 370 +++++++
.../gv/egiz/bku/slcommands/SLCommandInvoker.java | 45 +
.../java/at/gv/egiz/bku/slcommands/SLResult.java | 44 +
.../at/gv/egiz/bku/slcommands/SLSourceContext.java | 63 ++
.../at/gv/egiz/bku/slcommands/SLTargetContext.java | 50 +
.../impl/CreateXMLSignatureCommandImpl.java | 229 +++++
.../impl/CreateXMLSignatureResultImpl.java | 138 +++
.../egiz/bku/slcommands/impl/ErrorResultImpl.java | 60 ++
.../slcommands/impl/InfoboxReadCommandImpl.java | 409 ++++++++
.../bku/slcommands/impl/InfoboxReadResultImpl.java | 171 ++++
.../slcommands/impl/NullOperationCommandImpl.java | 43 +
.../slcommands/impl/NullOperationResultImpl.java | 47 +
.../gv/egiz/bku/slcommands/impl/SLCommandImpl.java | 162 ++++
.../gv/egiz/bku/slcommands/impl/SLResultImpl.java | 117 +++
.../impl/xsect/AlgorithmMethodFactory.java | 79 ++
.../impl/xsect/AlgorithmMethodFactoryImpl.java | 125 +++
.../impl/xsect/ByteArrayDereferencer.java | 65 ++
.../egiz/bku/slcommands/impl/xsect/DataObject.java | 1006 ++++++++++++++++++++
.../bku/slcommands/impl/xsect/IdValueFactory.java | 37 +
.../slcommands/impl/xsect/IdValueFactoryImpl.java | 127 +++
.../slcommands/impl/xsect/LocRefDereferencer.java | 113 +++
.../bku/slcommands/impl/xsect/STALPrivateKey.java | 122 +++
.../bku/slcommands/impl/xsect/STALProvider.java | 64 ++
.../bku/slcommands/impl/xsect/STALSignature.java | 165 ++++
.../impl/xsect/STALSignatureException.java | 92 ++
.../egiz/bku/slcommands/impl/xsect/Signature.java | 935 ++++++++++++++++++
.../slcommands/impl/xsect/SignatureContext.java | 129 +++
.../slcommands/impl/xsect/SignatureLocation.java | 235 +++++
.../impl/xsect/SimpleDOMErrorHandler.java | 98 ++
.../impl/xsect/URIDereferncerAdapter.java | 103 ++
.../bku/slcommands/impl/xsect/XSECTReference.java | 112 +++
.../bku/slcommands/impl/xsect/XSECTTransforms.java | 124 +++
.../egiz/bku/slexceptions/SLBindingException.java | 31 +
.../egiz/bku/slexceptions/SLCanceledException.java | 26 +
.../egiz/bku/slexceptions/SLCommandException.java | 30 +
.../at/gv/egiz/bku/slexceptions/SLException.java | 88 ++
.../egiz/bku/slexceptions/SLExceptionMessages.java | 50 +
.../egiz/bku/slexceptions/SLRequestException.java | 30 +
.../egiz/bku/slexceptions/SLRuntimeException.java | 37 +
.../egiz/bku/slexceptions/SLViewerException.java | 25 +
.../at/gv/egiz/bku/slcommands/schema/Core-1.2.xsd | 877 +++++++++++++++++
.../at/gv/egiz/bku/slcommands/schema/xml.xsd | 145 +++
.../bku/slcommands/schema/xmldsig-core-schema.xsd | 308 ++++++
.../bku/slcommands/schema/xmldsig-transforms.xsd | 41 +
.../slexceptions/SLExceptionMessages.properties | 97 ++
.../slexceptions/SLExceptionMessages_de.properties | 98 ++
85 files changed, 10905 insertions(+)
create mode 100644 bkucommon/src/main/java/META-INF/MANIFEST.MF
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/AbstractBindingProcessor.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessor.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManager.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManagerImpl.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrl.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionSPI.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlResponse.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/ExpiryRemover.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/FixedFormParameters.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/FormParameter.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/FormParameterImpl.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/FormParameterStore.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpUtil.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/Id.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/IdFactory.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/IdImpl.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/InputDecoder.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/InputDecoderFactory.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/MultiPartFormDataInputDecoder.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/RemovalStrategy.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/SLCommandInvokerImpl.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputDecoder.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/multipart/InputStreamPartSource.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/multipart/SLResultPart.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/AccessControlInvocation.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureCommand.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureResult.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/ErrorResult.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxReadCommand.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxReadResult.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InvocationStrategy.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/NullOperationCommand.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/NullOperationResult.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommand.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandContext.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandInvoker.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLResult.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLSourceContext.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLTargetContext.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureResultImpl.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImpl.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultImpl.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationCommandImpl.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationResultImpl.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLCommandImpl.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactory.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/ByteArrayDereferencer.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/IdValueFactory.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/IdValueFactoryImpl.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/LocRefDereferencer.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALPrivateKey.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALProvider.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignature.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureException.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureContext.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureLocation.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SimpleDOMErrorHandler.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/URIDereferncerAdapter.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/XSECTReference.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/XSECTTransforms.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLBindingException.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLCanceledException.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLCommandException.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLException.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLExceptionMessages.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRequestException.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRuntimeException.java
create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLViewerException.java
create mode 100644 bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/Core-1.2.xsd
create mode 100644 bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/xml.xsd
create mode 100644 bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/xmldsig-core-schema.xsd
create mode 100644 bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/xmldsig-transforms.xsd
create mode 100644 bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties
create mode 100644 bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_de.properties
(limited to 'bkucommon/src/main')
diff --git a/bkucommon/src/main/java/META-INF/MANIFEST.MF b/bkucommon/src/main/java/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..5e949512
--- /dev/null
+++ b/bkucommon/src/main/java/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path:
+
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/AbstractBindingProcessor.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/AbstractBindingProcessor.java
new file mode 100644
index 00000000..17ce29ce
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/AbstractBindingProcessor.java
@@ -0,0 +1,86 @@
+/*
+* Copyright 2008 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.binding;
+
+import java.io.InputStream;
+import java.util.Date;
+
+import at.gv.egiz.bku.slcommands.SLCommandInvoker;
+import at.gv.egiz.stal.STAL;
+
+public abstract class AbstractBindingProcessor implements BindingProcessor {
+ protected Id id;
+ protected STAL stal;
+ protected SLCommandInvoker commandInvoker;
+ protected long lastAccessedTime = System.currentTimeMillis();
+
+ public AbstractBindingProcessor(String idString) {
+ this.id = IdFactory.getInstance().createId(idString);
+ }
+
+ /**
+ * @see java.lang.Thread#run()
+ */
+ public abstract void run();
+
+ /**
+ * The caller is advised to check the result in case an error occurred.
+ *
+ * @see #getResult()
+ */
+ public abstract void consumeRequestStream(InputStream aIs);
+
+ public Id getId() {
+ return id;
+ }
+
+ public STAL getSTAL() {
+ return stal;
+ }
+
+ public SLCommandInvoker getCommandInvoker() {
+ return commandInvoker;
+ }
+
+ public void updateLastAccessTime() {
+ lastAccessedTime = System.currentTimeMillis();
+ }
+
+ public Date getLastAccessTime() {
+ return new Date(lastAccessedTime);
+ }
+
+ /**
+ * To be called after object creation.
+ *
+ * @param aStal
+ * must not be null
+ * @param aCommandInvoker
+ * must not be null
+ */
+ public void init(STAL aStal, SLCommandInvoker aCommandInvoker) {
+ if (aStal == null) {
+ throw new NullPointerException("STAL must not be set to null");
+ }
+ if (aCommandInvoker == null) {
+ throw new NullPointerException("Commandinvoker must not be set to null");
+ }
+ stal = aStal;
+ commandInvoker = aCommandInvoker;
+ Thread.currentThread().setName("BPID#"+getId().toString());
+ }
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessor.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessor.java
new file mode 100644
index 00000000..c386508d
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessor.java
@@ -0,0 +1,75 @@
+/*
+* Copyright 2008 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.binding;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.Locale;
+
+import at.gv.egiz.bku.slcommands.SLCommandInvoker;
+import at.gv.egiz.stal.STAL;
+
+/**
+ * Represents an single instance of a SL HTTP binding.
+ *
+ * @author wbauer
+ *
+ */
+public interface BindingProcessor extends Runnable {
+
+ /**
+ * The stream must be read completely within this method.
+ *
+ * The caller is advised to check the result in case an error occurred.
+ *
+ * @see #getResult()
+ */
+ public void consumeRequestStream(InputStream aIs);
+
+ /**
+ * The unique Id of this http binding instance.
+ * @return
+ */
+ public Id getId();
+
+ /**
+ * The used underlying STAL instance
+ * @return
+ */
+ public STAL getSTAL();
+
+ public SLCommandInvoker getCommandInvoker();
+
+ public Date getLastAccessTime();
+
+ public void updateLastAccessTime();
+
+ public String getResultContentType();
+
+ public void writeResultTo(OutputStream os, String encoding) throws IOException;
+
+ public void init(STAL aStal, SLCommandInvoker aCommandInvoker);
+
+ /**
+ * Sets the preferred locale for userinteraction.
+ * If the locale is not set the default locale will be used.
+ * @param locale must not be null.
+ */
+ public void setLocale(Locale locale);
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManager.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManager.java
new file mode 100644
index 00000000..a4e5bd90
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManager.java
@@ -0,0 +1,102 @@
+/*
+* Copyright 2008 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.binding;
+
+import java.util.Locale;
+import java.util.Set;
+
+import at.gv.egiz.bku.slcommands.SLCommandInvoker;
+import at.gv.egiz.stal.STALFactory;
+
+/**
+ * Central player that handles the protocol binding.
+ *
+ * @author wbauer
+ *
+ */
+public interface BindingProcessorManager {
+
+ /**
+ * FactoryMethod creating a new BindingProcessor object.
+ * The created binding processor must be passed to the process method to execute.
+ *
+ * @param protcol
+ * the transport binding protocol
+ * @param aSessionId
+ * optional an external sessionId (e.g. http session) could be
+ * provided. This parameter may be null.
+ * @param locale the locale used for user interaction, may be null
+ */
+ public BindingProcessor createBindingProcessor(String protcol,
+ String aSessionId, Locale locale);
+
+ /**
+ * FactoryMethod creating a new BindingProcessor object.
+ * The created binding processor must be passed to the process method to execute.
+ *
+ * @param protcol
+ * the transport binding protocol
+ * @param aSessionId
+ * optional an external sessionId (e.g. http session) could be
+ * provided. This parameter may be null.
+ */
+ public BindingProcessor createBindingProcessor(String protcol,
+ String aSessionId);
+
+
+ /**
+ * Gets the binding processor with a certain id. The binding processor must be passed to the
+ * process method before it is managed and thus returned by this method.
+ * @param aId must not be null
+ * @return null if the binding processor was not "processed" before.
+ */
+ public BindingProcessor getBindingProcessor(Id aId);
+
+ /**
+ * Sets the STAL factory that is used for creating STAL objects that are used by BindingProcessor objects.
+ * For each new BindingProcessor a new STAL object is created.
+ * @param aStalFactory the factory to be used. Must not be null.
+ */
+ public void setSTALFactory(STALFactory aStalFactory);
+
+ /**
+ * Sets the invoker to be used.
+ * @param invoker
+ */
+ public void setSLCommandInvoker(SLCommandInvoker invoker);
+
+ /**
+ * Schedules the provided binding processor for processing and immediately returns.
+ *
+ * @param aBindingProcessor
+ */
+ public void process(BindingProcessor aBindingProcessor);
+
+ /**
+ * Removes a formerly added (by calling the process method) binding processor.
+ * @param bindingProcessor must not be null
+ */
+ public void removeBindingProcessor(Id sessionId);
+
+ /**
+ * A set of all managed binding processors.
+ * @return
+ */
+ public Set getManagedIds();
+
+ public void shutdown();
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManagerImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManagerImpl.java
new file mode 100644
index 00000000..7a3b1bb9
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManagerImpl.java
@@ -0,0 +1,258 @@
+/*
+* Copyright 2008 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.binding;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.gv.egiz.bku.slcommands.SLCommandInvoker;
+import at.gv.egiz.bku.slexceptions.SLRuntimeException;
+import at.gv.egiz.bku.utils.binding.Protocol;
+import at.gv.egiz.stal.STAL;
+import at.gv.egiz.stal.STALFactory;
+
+/**
+ * This class maintains all active BindingProcessor Objects. Currently, only
+ * HTTPBinding is supported.
+ */
+public class BindingProcessorManagerImpl implements BindingProcessorManager {
+
+ public final static Protocol[] SUPPORTED_PROTOCOLS = { Protocol.HTTP,
+ Protocol.HTTPS };
+
+ private static Log log = LogFactory.getLog(BindingProcessorManagerImpl.class);
+
+ private RemovalStrategy removalStrategy;
+ private STALFactory stalFactory;
+ private SLCommandInvoker commandInvokerClass;
+ private ExecutorService executorService;
+ private Map bindingProcessorMap = Collections
+ .synchronizedMap(new HashMap());
+
+ /**
+ * Container to hold a Future and Bindingprocessor object as map value.
+ * @author wbauer
+ * @see BindingProcessorManagerImpl#bindingProcessorMap
+ */
+ static class MapEntityWrapper {
+ private Future> future;
+ private BindingProcessor bindingProcessor;
+
+ public MapEntityWrapper(Future> future, BindingProcessor bindingProcessor) {
+ if ((bindingProcessor == null) || (future == null)) {
+ throw new NullPointerException("Argument must not be null");
+ }
+ this.bindingProcessor = bindingProcessor;
+ this.future = future;
+ }
+
+ public Future> getFuture() {
+ return future;
+ }
+
+ public BindingProcessor getBindingProcessor() {
+ return bindingProcessor;
+ }
+
+ public int hashCode() {
+ return bindingProcessor.getId().hashCode();
+ }
+
+ public boolean equals(Object other) {
+ if (other instanceof MapEntityWrapper) {
+ MapEntityWrapper o = (MapEntityWrapper) other;
+ return (o.bindingProcessor.getId().equals(bindingProcessor.getId()));
+ } else {
+ return false;
+ }
+ }
+ }
+
+ /**
+ *
+ * @param fab
+ * must not be null
+ * @param ci
+ * must not be null (prototype to generate new instances)
+ */
+ public BindingProcessorManagerImpl(STALFactory fab, SLCommandInvoker ci) {
+ if (fab == null) {
+ throw new NullPointerException("STALFactory must not be null");
+ }
+ stalFactory = fab;
+ if (ci == null) {
+ throw new NullPointerException("SLCommandInvoker must not be null");
+ }
+ commandInvokerClass = ci;
+ executorService = Executors.newCachedThreadPool();
+ }
+
+ /**
+ *
+ * @return the STALFactory currently used.
+ */
+ public STALFactory getStalFactory() {
+ return stalFactory;
+ }
+
+ /**
+ * Sets the STALFactory to be used.
+ * @param stalFactory
+ */
+ public void setStalFactory(STALFactory stalFactory) {
+ this.stalFactory = stalFactory;
+ }
+
+ /**
+ * Could be used to setup a new executor service during application stratup.
+ * @param executorService
+ */
+ public void setExecutorService(ExecutorService executorService) {
+ this.executorService = executorService;
+ }
+
+ public void setRemovalStrategy(RemovalStrategy aStrategy) {
+ removalStrategy = aStrategy;
+ }
+
+ public RemovalStrategy getRemovlaStrategy() {
+ return removalStrategy;
+ }
+
+ public void shutdown() {
+ log.info("Shutting down the BindingProcessorManager");
+ executorService.shutdown();
+ }
+
+ /**
+ * Uses the default locale
+ */
+ public BindingProcessor createBindingProcessor(String protocol,
+ String aSessionId) {
+ return createBindingProcessor(protocol, aSessionId, null);
+ }
+
+ /**
+ * FactoryMethod creating a new BindingProcessor object.
+ *
+ * @param protocol
+ * must not be null
+ */
+ public BindingProcessor createBindingProcessor(String protocol,
+ String aSessionId, Locale locale) {
+ String low = protocol.toLowerCase();
+ Protocol proto = null;
+ for (int i = 0; i < SUPPORTED_PROTOCOLS.length; i++) {
+ if (SUPPORTED_PROTOCOLS[i].toString().equals(low)) {
+ proto = SUPPORTED_PROTOCOLS[i];
+ break;
+ }
+ }
+ if (proto == null) {
+ throw new UnsupportedOperationException();
+ }
+ BindingProcessor bindingProcessor = new HTTPBindingProcessor(aSessionId,
+ commandInvokerClass.newInstance(), proto);
+ STAL stal = stalFactory.createSTAL();
+ bindingProcessor.init(stal, commandInvokerClass.newInstance());
+ if (locale != null) {
+ bindingProcessor.setLocale(locale);
+ stal.setLocale(locale);
+ }
+ return bindingProcessor;
+ }
+
+ /**
+ * @return the bindingprocessor object for this id or null if no bindingprocessor was found.
+ */
+ public BindingProcessor getBindingProcessor(Id aId) {
+ if (bindingProcessorMap.get(aId) != null) {
+ return bindingProcessorMap.get(aId).getBindingProcessor();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ *
+ */
+ public void setSTALFactory(STALFactory aStalFactory) {
+ if (aStalFactory == null) {
+ throw new NullPointerException("Cannot set STALFactory to null");
+ }
+ stalFactory = aStalFactory;
+ }
+
+ /**
+ * Causes the BindingProcessorManager to manage the provided BindingProcessor
+ * @param aBindingProcessor must not be null
+ */
+ public void process(BindingProcessor aBindingProcessor) {
+ if (bindingProcessorMap.containsKey(aBindingProcessor.getId())) {
+ log.fatal("Clashing ids, cannot process bindingprocessor with id:"
+ + aBindingProcessor.getId());
+ throw new SLRuntimeException(
+ "Clashing ids, cannot process bindingprocessor with id:"
+ + aBindingProcessor.getId());
+ }
+ Future> f = executorService.submit(aBindingProcessor);
+ bindingProcessorMap.put(aBindingProcessor.getId(), new MapEntityWrapper(f,
+ aBindingProcessor));
+ }
+
+ @Override
+ public void setSLCommandInvoker(SLCommandInvoker invoker) {
+ commandInvokerClass = invoker;
+ }
+
+ @Override
+ public void removeBindingProcessor(Id sessionId) {
+ MapEntityWrapper wrapper = bindingProcessorMap
+ .get(sessionId);
+ if (wrapper == null) {
+ return;
+ }
+ Future> f = wrapper.getFuture();
+ if (!f.isDone()) {
+ f.cancel(true);
+ }
+ bindingProcessorMap.remove(sessionId);
+ }
+
+ @Override
+ public Set getManagedIds() {
+ Set result = new HashSet();
+ synchronized (bindingProcessorMap) {
+ for (Iterator it = bindingProcessorMap.keySet().iterator(); it
+ .hasNext();) {
+ result.add(it.next());
+ }
+ }
+ return result;
+ }
+}
\ No newline at end of file
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
new file mode 100644
index 00000000..8eaeacbd
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrl.java
@@ -0,0 +1,62 @@
+/*
+* Copyright 2008 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.binding;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.gv.egiz.bku.slexceptions.SLRuntimeException;
+
+/**
+ * Used to handle DataUrl connections as specified in the CCE's HTTP protocol binding.
+ *
+ */
+public class DataUrl {
+ private static DataUrlConnectionSPI defaultDataUrlConnection = new DataUrlConnectionImpl();
+ private static Log log = LogFactory.getLog(DataUrl.class);
+
+ private URL url;
+
+ /**
+ * Sets the default DataUrlConnection implementation
+ * @param aClass must not be null
+ */
+ public static void setDataUrlConnectionClass(DataUrlConnectionSPI dataUrlConnection) {
+ if (dataUrlConnection == null) {
+ throw new NullPointerException("Default dataurlconnection must not be set to null");
+ }
+ defaultDataUrlConnection = dataUrlConnection;
+ }
+
+ public DataUrl(String aUrlString) throws MalformedURLException {
+ url = new URL(aUrlString);
+ }
+
+ public DataUrlConnection openConnection() {
+ try {
+ DataUrlConnectionSPI retVal = defaultDataUrlConnection.newInstance();
+ retVal.init(url);
+ return retVal;
+ } catch (Exception e) {
+ log.error(e);
+ throw new SLRuntimeException("Cannot instantiate a dataurlconnection:",e);
+ }
+ }
+}
\ No newline at end of file
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
new file mode 100644
index 00000000..e6d5e075
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2008 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.binding;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.SocketTimeoutException;
+import java.security.cert.X509Certificate;
+
+import at.gv.egiz.bku.slcommands.SLResult;
+
+/**
+ * Transmit a security layer result to DataURL via HTTP POST, encoded as multipart/form-data.
+ * The HTTP header user-agent is set to citizen-card-environment/1.2 BKU2 1.0.
+ * The form-parameter ResponseType is set to HTTP-Security-Layer-RESPONSE.
+ * All other headers/parameters are set by the caller.
+ *
+ * @author clemens
+ */
+public interface DataUrlConnection {
+
+ public static final String DEFAULT_USERAGENT = "citizen-card-environment/1.2 BKU2 1.0";
+ public static final String FORMPARAM_RESPONSETYPE = "ResponseType";
+ public static final String DEFAULT_RESPONSETYPE = "HTTP-Security-Layer-RESPONSE";
+ public static final String FORMPARAM_XMLRESPONSE = "XMLResponse";
+ public static final String FORMPARAM_BINARYRESPONSE = "BinaryResponse";
+
+ public static final String XML_RESPONSE_ENCODING = "UTF-8";
+
+ public String getProtocol();
+
+ /**
+ * Set a HTTP Header.
+ * @param key
+ * @param value multiple values are assumed to have the correct formatting (comma-separated list)
+ */
+ public void setHTTPHeader(String key, String value);
+
+ /**
+ * Set a form-parameter.
+ * @param name
+ * @param data
+ * @param contentType may be null
+ * @param charSet may be null
+ * @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
+ * @throws java.io.IOException
+ */
+ public void connect() throws SocketTimeoutException, IOException;
+
+ public X509Certificate getServerCertificate();
+
+ /**
+ * @pre connection != null
+ * @throws java.io.IOException
+ */
+ public void transmit(SLResult slResult) throws IOException;
+
+ public DataUrlResponse getResponse() throws IOException;
+}
\ No newline at end of file
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
new file mode 100644
index 00000000..134d765e
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java
@@ -0,0 +1,216 @@
+/*
+* Copyright 2008 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.binding;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.SocketTimeoutException;
+import java.net.URL;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.net.ssl.HttpsURLConnection;
+
+import org.apache.commons.httpclient.methods.multipart.FilePart;
+import org.apache.commons.httpclient.methods.multipart.Part;
+import org.apache.commons.httpclient.methods.multipart.StringPart;
+
+import at.gv.egiz.bku.binding.multipart.InputStreamPartSource;
+import at.gv.egiz.bku.binding.multipart.SLResultPart;
+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.StreamUtil;
+import at.gv.egiz.bku.utils.binding.Protocol;
+
+/**
+ * not thread-safe thus newInsance always returns a new object
+ *
+ */
+public class DataUrlConnectionImpl implements DataUrlConnectionSPI {
+
+ public final static Protocol[] SUPPORTED_PROTOCOLS = { Protocol.HTTP,
+ Protocol.HTTPS };
+ protected X509Certificate serverCertificate;
+ protected Protocol protocol;
+ protected URL url;
+ private HttpURLConnection connection;
+ protected Map requestHttpHeaders;
+ protected ArrayList formParams;
+ protected String boundary;
+
+ 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();
+
+ // FIXXME move this to config.
+ HttpURLConnection.setFollowRedirects(false);
+
+
+ connection.setDoOutput(true);
+ Set headers = requestHttpHeaders.keySet();
+ Iterator headerIt = headers.iterator();
+ while (headerIt.hasNext()) {
+ String name = headerIt.next();
+ connection.setRequestProperty(name, requestHttpHeaders.get(name));
+ }
+ connection.connect();
+ if (connection instanceof HttpsURLConnection) {
+ HttpsURLConnection ssl = (HttpsURLConnection) connection;
+ X509Certificate[] certs = (X509Certificate[]) ssl.getServerCertificates();
+ if ((certs != null) && (certs.length >= 1)) {
+ 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) {
+ InputStreamPartSource source = new InputStreamPartSource(null, data);
+ FilePart formParam = new FilePart(name, source, contentType, charSet);
+ if (transferEncoding != null) {
+ formParam.setTransferEncoding(transferEncoding);
+ } else {
+ formParam.setTransferEncoding(null);
+ }
+ formParams.add(formParam);
+ }
+
+ /**
+ * send all formParameters
+ *
+ * @throws java.io.IOException
+ */
+ 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);
+ } else {
+ slResultPart.setTransferEncoding(null);
+ slResultPart.setContentType(slResult.getMimeType());
+ }
+ formParams.add(slResultPart);
+
+ OutputStream os = connection.getOutputStream();
+
+ Part[] parts = new Part[formParams.size()];
+ Part.sendParts(os, formParams.toArray(parts), boundary.getBytes());
+ os.close();
+ // MultipartRequestEntity PostMethod
+ result = new DataUrlResponse(url.toString(), connection.getResponseCode(),
+ connection.getInputStream());
+
+ Map responseHttpHeaders = new HashMap();
+ Map> httpHeaders = connection.getHeaderFields();
+ for (Iterator 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;
+ boundary = "--" + IdFactory.getInstance().createId().toString();
+ requestHttpHeaders = new HashMap();
+ requestHttpHeaders.put(HttpUtil.HTTP_HEADER_USER_AGENT, DEFAULT_USERAGENT);
+ requestHttpHeaders.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE,
+ HttpUtil.MULTIPART_FOTMDATA + HttpUtil.SEPERATOR[0]
+ + HttpUtil.MULTIPART_FOTMDATA_BOUNDARY + "=" + boundary);
+
+ formParams = new ArrayList();
+ StringPart responseType = new StringPart(FORMPARAM_RESPONSETYPE,
+ DEFAULT_RESPONSETYPE);
+ responseType.setCharSet("UTF-8");
+ responseType.setTransferEncoding(null);
+ formParams.add(responseType);
+ }
+
+ @Override
+ public DataUrlConnectionSPI newInstance() {
+ return new DataUrlConnectionImpl();
+ }
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionSPI.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionSPI.java
new file mode 100644
index 00000000..9e5a66f8
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionSPI.java
@@ -0,0 +1,42 @@
+/*
+* Copyright 2008 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.binding;
+
+import java.net.URL;
+
+/**
+ * Prototype of a DataurlconnectionSPI
+ * @author wbauer
+ *
+ */
+public interface DataUrlConnectionSPI extends DataUrlConnection {
+
+ /**
+ * Returns a new instance of this class to handle a dataurl.
+ * Called by the factory each time the openConnection method is called.
+ * @return
+ */
+ public DataUrlConnectionSPI newInstance();
+
+ /**
+ * Initializes the DataUrlConnection
+ * @param url
+ */
+ public void init(URL url);
+
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlResponse.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlResponse.java
new file mode 100644
index 00000000..b75cb0f3
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlResponse.java
@@ -0,0 +1,98 @@
+/*
+* Copyright 2008 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.binding;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import java.util.Iterator;
+import java.util.Map;
+
+import at.gv.egiz.bku.utils.urldereferencer.StreamData;
+
+/**
+ * The response of a dataurl server.
+ * Additionally holds return code and response headers.
+ */
+public class DataUrlResponse extends StreamData {
+
+ public final static String OK = "";
+
+ protected Map responseHttpHeaders;
+
+ protected int responseCode = -1;
+
+ public DataUrlResponse(String url, int responseCode, InputStream stream) {
+ super(url, null, new PushbackInputStream(stream, 10));
+ this.responseCode = responseCode;
+ }
+
+ public String getContentType() {
+ if (contentType != null) {
+ return contentType;
+ }
+ if (responseHttpHeaders == null) {
+ return null;
+ }
+ for (Iterator keyIt = responseHttpHeaders.keySet().iterator(); keyIt
+ .hasNext();) {
+ String key = keyIt.next();
+ if (HttpUtil.HTTP_HEADER_CONTENT_TYPE.equalsIgnoreCase(key)) {
+ contentType = responseHttpHeaders.get(key);
+ return contentType;
+ }
+ }
+ return contentType;
+ }
+
+ public void setResponseHttpHeaders(Map responseHttpHeaders) {
+ this.responseHttpHeaders = responseHttpHeaders;
+ }
+
+ public Map getResponseHeaders() {
+ return responseHttpHeaders;
+ }
+
+ public int getResponseCode() {
+ return responseCode;
+ }
+
+ /**
+ * Checks if the http response equals ""
+ *
+ * @throws IOException
+ */
+ public boolean isHttpResponseXMLOK() throws IOException {
+ String charset = HttpUtil.getCharset(contentType, true);
+ byte[] buffer = new byte[10];
+ int i = 0;
+ int read = 0;
+ while ((i < 10) && (read != -1)) {
+ read = inputStream.read(buffer, i, 10 - i);
+ if (read != -1) {
+ i += read;
+ }
+ }
+ PushbackInputStream pbis = (PushbackInputStream) inputStream;
+ pbis.unread(buffer, 0, i);
+ if (i < 5) {
+ return false;
+ }
+ String ok = new String(buffer, 0, i, charset);
+ return (OK.equals(ok));
+ }
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/ExpiryRemover.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/ExpiryRemover.java
new file mode 100644
index 00000000..d17a27c2
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/ExpiryRemover.java
@@ -0,0 +1,67 @@
+/*
+* Copyright 2008 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.binding;
+
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * This class can be used to check the BindingProcessorManager for expired entries and remove them.
+ * Should be run periodically.
+ *
+ */
+public class ExpiryRemover implements RemovalStrategy {
+
+ private static Log log = LogFactory.getLog(ExpiryRemover.class);
+
+ protected BindingProcessorManager bindingProcessorManager;
+ // keep max 5 min.
+ protected long maxAcceptedAge = 1000 * 60 * 5;
+
+ @Override
+ public void execute() {
+ log.debug("Triggered Expiry Remover");
+ if (bindingProcessorManager == null) {
+ log.warn("Bindingprocessor not set, skipping removal");
+ return;
+ }
+ Set managedIds = bindingProcessorManager.getManagedIds();
+ for (Iterator it = managedIds.iterator(); it.hasNext();) {
+ Id bindId = it.next();
+ BindingProcessor bp = bindingProcessorManager.getBindingProcessor(bindId);
+ if (bp != null) {
+ if (bp.getLastAccessTime().getTime() < (System.currentTimeMillis() - maxAcceptedAge)) {
+ log.debug("Removing binding processor: " + bp.getId());
+ bindingProcessorManager.removeBindingProcessor(bp.getId());
+ }
+ }
+ }
+ }
+
+ public void setMaxAcceptedAge(long maxAcceptedAge) {
+ this.maxAcceptedAge = maxAcceptedAge;
+ }
+
+ @Override
+ public void setBindingProcessorManager(BindingProcessorManager bp) {
+ bindingProcessorManager = bp;
+ }
+
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/FixedFormParameters.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/FixedFormParameters.java
new file mode 100644
index 00000000..cce3d720
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/FixedFormParameters.java
@@ -0,0 +1,28 @@
+/*
+* Copyright 2008 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.binding;
+
+/**
+ * Form parameters with special meaning as defined in the CCE's http binding.
+ *
+ */
+public interface FixedFormParameters {
+ String XMLREQUEST = "XMLRequest";
+ String REDIRECTURL = "RedirectURL";
+ String DATAURL = "DataURL";
+ String STYLESHEETURL = "StylesheetURL";
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormParameter.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormParameter.java
new file mode 100644
index 00000000..93339451
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormParameter.java
@@ -0,0 +1,39 @@
+/*
+* Copyright 2008 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.binding;
+
+import java.io.InputStream;
+import java.util.Iterator;
+
+/**
+ * Interface to access form control contents from the http request.
+ * It's designed to be used for URL encoded and multipart-formdata requests.
+ * @author wbauer
+ *
+ */
+public interface FormParameter {
+
+ String getFormParameterName();
+
+ InputStream getFormParameterValue();
+
+ String getFormParameterContentType();
+
+ Iterator getHeaderNames();
+
+ String getHeaderValue(String headerName);
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormParameterImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormParameterImpl.java
new file mode 100644
index 00000000..45aa9be6
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormParameterImpl.java
@@ -0,0 +1,93 @@
+/*
+* Copyright 2008 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.binding;
+
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.Iterator;
+
+import org.apache.commons.fileupload.FileItemHeaders;
+
+/**
+ * Simple wrapper to read data while consuming an stream within the http
+ * processor.
+ *
+ *
+ */
+public class FormParameterImpl implements FormParameter {
+
+ protected InputStream dataStream;
+ protected String contentType;
+ protected String formName;
+ protected FileItemHeaders headers;
+
+ public FormParameterImpl(String contentType, String formName, InputStream is,
+ FileItemHeaders header) {
+ this.contentType = contentType;
+ this.formName = formName;
+ this.dataStream = is;
+ this.headers = header;
+ }
+
+ @Override
+ public String getFormParameterContentType() {
+ return contentType;
+ }
+
+ @Override
+ public String getFormParameterName() {
+ return formName;
+ }
+
+ @Override
+ public InputStream getFormParameterValue() {
+ return dataStream;
+ }
+
+ @Override
+ public String getHeaderValue(String headerName) {
+ if (headers == null) {
+ return null;
+ }
+ return headers.getHeader(headerName);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Iterator getHeaderNames() {
+ if (headers == null) {
+ return Collections.EMPTY_LIST.iterator();
+ }
+ return headers.getHeaderNames();
+ }
+
+ public FileItemHeaders getHeaders() {
+ return headers;
+ }
+
+ public boolean equals(Object other) {
+ if (other instanceof FormParameter) {
+ FormParameter fp = (FormParameter) other;
+ return fp.getFormParameterName().equals(getFormParameterName());
+ }
+ return false;
+ }
+
+ public int hashCode() {
+ return getFormParameterName().hashCode();
+ }
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormParameterStore.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormParameterStore.java
new file mode 100644
index 00000000..8b6cd4b2
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/FormParameterStore.java
@@ -0,0 +1,146 @@
+/*
+* Copyright 2008 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.binding;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.Iterator;
+
+import org.apache.commons.fileupload.FileItemHeaders;
+import org.apache.commons.fileupload.util.FileItemHeadersImpl;
+
+import at.gv.egiz.bku.slexceptions.SLRuntimeException;
+import at.gv.egiz.bku.utils.StreamUtil;
+
+/**
+ * Simple store for form parameters based on a byte[]
+ *
+ * @author wbauer
+ *
+ */
+public class FormParameterStore implements FormParameter {
+
+ private byte[] dataBuffer;
+ private String contentType;
+ private String parameterName;
+ private boolean initialized = false;
+ protected FileItemHeaders headers;
+
+ /**
+ * Make sure to call init after creating a new instance.
+ */
+ public FormParameterStore() {
+ }
+
+ public void init(InputStream dataSource, String paramName,
+ String contentType, FileItemHeaders header) throws IOException {
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ StreamUtil.copyStream(dataSource, os);
+ this.dataBuffer = os.toByteArray();
+ this.parameterName = paramName;
+ this.contentType = contentType;
+ initialized = true;
+ this.headers = header;
+ }
+
+ public void init(byte[] dataSource, String paramName,
+ String contentType, FileItemHeaders header) throws IOException {
+ this.dataBuffer = dataSource;
+ this.parameterName = paramName;
+ this.contentType = contentType;
+ initialized = true;
+ this.headers = header;
+ }
+
+ public void init(FormParameter fp) throws IOException {
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ StreamUtil.copyStream(fp.getFormParameterValue(), os);
+ this.dataBuffer = os.toByteArray();
+ this.parameterName = fp.getFormParameterName();
+ this.contentType = fp.getFormParameterContentType();
+ if (fp instanceof FormParameterImpl) {
+ headers = ((FormParameterImpl) fp).getHeaders();
+ } else {
+ FileItemHeadersImpl headersImpl = new FileItemHeadersImpl();
+ for (Iterator i = fp.getHeaderNames(); i.hasNext();) {
+ String headerName = i.next();
+ headersImpl.addHeader(headerName, fp.getHeaderValue(headerName));
+ }
+ }
+ initialized = true;
+ }
+
+ protected void ensureInitialized() {
+ if (!initialized) {
+ throw new SLRuntimeException("FormParameterStore not initialized");
+ }
+ }
+
+ /**
+ * Reads all data from the stream and stores it internally. The stream will
+ * not be closed.
+ *
+ * @param datSource
+ * @param formName
+ * @param contentType
+ */
+ @Override
+ public String getFormParameterContentType() {
+ ensureInitialized();
+ return contentType;
+ }
+
+ @Override
+ public String getFormParameterName() {
+ ensureInitialized();
+ return parameterName;
+ }
+
+ /**
+ * May be called more than once.
+ */
+ @Override
+ public InputStream getFormParameterValue() {
+ return new ByteArrayInputStream(dataBuffer);
+ }
+
+ @Override
+ public String getHeaderValue(String name) {
+ if (headers == null) {
+ return null;
+ }
+ return headers.getHeader(name);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Iterator getHeaderNames() {
+ if (headers == null) {
+ return Collections.EMPTY_LIST.iterator();
+ }
+ return headers.getHeaderNames();
+ }
+
+ public boolean isEmpty() {
+ ensureInitialized();
+ return dataBuffer.length == 0;
+ }
+
+}
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
new file mode 100644
index 00000000..b79f7d55
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java
@@ -0,0 +1,820 @@
+/*
+* Copyright 2008 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.binding;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.net.ssl.SSLHandshakeException;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.gv.egiz.bku.slcommands.SLCommand;
+import at.gv.egiz.bku.slcommands.SLCommandContext;
+import at.gv.egiz.bku.slcommands.SLCommandFactory;
+import at.gv.egiz.bku.slcommands.SLCommandInvoker;
+import at.gv.egiz.bku.slcommands.SLResult;
+import at.gv.egiz.bku.slcommands.SLSourceContext;
+import at.gv.egiz.bku.slcommands.SLTargetContext;
+import at.gv.egiz.bku.slcommands.impl.ErrorResultImpl;
+import at.gv.egiz.bku.slexceptions.SLBindingException;
+import at.gv.egiz.bku.slexceptions.SLCanceledException;
+import at.gv.egiz.bku.slexceptions.SLException;
+import at.gv.egiz.bku.slexceptions.SLRuntimeException;
+import at.gv.egiz.bku.utils.StreamUtil;
+import at.gv.egiz.bku.utils.binding.Protocol;
+import at.gv.egiz.bku.utils.urldereferencer.FormDataURLSupplier;
+import at.gv.egiz.bku.utils.urldereferencer.SimpleFormDataContextImpl;
+import at.gv.egiz.bku.utils.urldereferencer.StreamData;
+import at.gv.egiz.bku.utils.urldereferencer.URIResolverAdapter;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext;
+import at.gv.egiz.stal.QuitRequest;
+import at.gv.egiz.stal.STALRequest;
+
+/**
+ * Class performing the HTTP binding as defined by the CCE specification.
+ * Currently a huge monolithic class.
+ * @TODO refactor
+ */
+@SuppressWarnings("unchecked")
+public class HTTPBindingProcessor extends AbstractBindingProcessor implements
+ FormDataURLSupplier {
+
+ private static Log log = LogFactory.getLog(HTTPBindingProcessor.class);
+
+ private static enum State {
+ INIT, PROCESS, DATAURL, TRANSFORM, FINISHED
+ };
+
+ public final static Collection XML_REQ_TRANSFER_ENCODING = Arrays
+ .asList(new String[] { "binary" });
+
+ /**
+ * Defines the maximum number of dataurl connects that are allowed within a
+ * single SL Request processing.
+ */
+ protected static int MAX_DATAURL_HOPS = 10;
+
+ protected static String XML_MIME_TYPE = "text/xml";
+ protected static String BINARY_MIME_TYPE = "application/octet-stream";
+
+ /**
+ * If null everything is ok and the result is taken from the command invoker.
+ */
+ protected SLException bindingProcessorError;
+ protected SLCommandInvoker commandInvoker;
+ protected DataUrlResponse dataUrlResponse;
+ protected Map headerMap = Collections.EMPTY_MAP;
+ protected SLCommand slCommand;
+ protected Map formParameterMap = new HashMap();
+ protected SLSourceContext srcContex = new SLSourceContext();
+ protected SLTargetContext targetContext = new SLTargetContext();
+ protected Protocol protocol;
+ protected State currentState = State.INIT;
+ protected Transformer transformer = null;
+ protected String resultContentType = null;
+ protected SLResult slResult = null;
+ protected int responseCode = 200;
+ protected Map responseHeaders = Collections.EMPTY_MAP;
+ protected Locale locale = Locale.getDefault();
+
+ /**
+ *
+ * @param id
+ * may be null. In this case a new session id will be created.
+ * @param cmdInvoker
+ * must not be null;
+ */
+ public HTTPBindingProcessor(String id, SLCommandInvoker cmdInvoker,
+ Protocol protocol) {
+ super(id);
+ if ((protocol != Protocol.HTTP) && (protocol != Protocol.HTTPS)) {
+ throw new SLRuntimeException("Protocol not supported: " + protocol);
+ }
+ if (cmdInvoker == null) {
+ throw new NullPointerException("Commandinvoker cannot be set to null");
+ }
+ commandInvoker = cmdInvoker;
+ this.protocol = protocol;
+ srcContex.setSourceProtocol(protocol);
+ srcContex.setSourceIsDataURL(false);
+ }
+
+ //----------------------------------------------------------------------------
+ // ----------- BEGIN CONVENIENCE METHODS -----------
+
+ protected void sendSTALQuit() {
+ log.info("Sending QUIT command to STAL");
+ List quit = new ArrayList(1);
+ quit.add(new QuitRequest());
+ getSTAL().handleRequest(quit);
+ }
+
+ protected String getFormParameterAsString(String formParameterName) {
+ FormParameter fp = formParameterMap.get(formParameterName);
+ return getFormParameterAsString(fp);
+ }
+
+ protected String getFormParameterAsString(FormParameter fp) {
+ if (fp == null) {
+ return null;
+ }
+ try {
+ return StreamUtil.asString(fp.getFormParameterValue(), HttpUtil
+ .getCharset(fp.getFormParameterContentType(), true));
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ protected String getDataUrl() {
+ return getFormParameterAsString(FixedFormParameters.DATAURL);
+ }
+
+ protected String getStyleSheetUrl() {
+ return getFormParameterAsString(FixedFormParameters.STYLESHEETURL);
+ }
+
+ protected List getFormParameters(String parameterNamePostfix) {
+ List resultList = new ArrayList();
+ for (Iterator fpi = formParameterMap.keySet().iterator(); fpi
+ .hasNext();) {
+ String paramName = fpi.next();
+ if (paramName.endsWith(parameterNamePostfix)) {
+ resultList.add(formParameterMap.get(paramName));
+ }
+ }
+ return resultList;
+ }
+
+ protected List getTransferHeaders() {
+ return getFormParameters("__");
+ }
+
+ protected List getTransferForms() {
+ List resultList = new ArrayList();
+ for (Iterator fpi = formParameterMap.keySet().iterator(); fpi
+ .hasNext();) {
+ String paramName = fpi.next();
+ if ((paramName.endsWith("_")) && (!paramName.endsWith("__"))) {
+ resultList.add(formParameterMap.get(paramName));
+ }
+ }
+ return resultList;
+ }
+
+ protected void closeDataUrlConnection() {
+ log.debug("Closing data url input stream");
+ if (dataUrlResponse == null) {
+ return;
+ }
+ InputStream is = dataUrlResponse.getStream();
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ log.info("Error closing input stream to dataurl server:" + e);
+ }
+ }
+ }
+
+ //----------------------------------------------------------------------------
+ // ----------- END CONVENIENCE METHODS -----------
+
+ //----------------------------------------------------------------------------
+ // -- BEGIN Methods that handle the http binding activities as defined in the
+ // activity diagram --
+
+ protected void init() {
+ log.info("Starting Bindingprocessor in Thread: "
+ + Thread.currentThread().getId());
+ if (bindingProcessorError != null) {
+ log.debug("Detected binding processor error, sending quit command");
+ // sendSTALQuit();
+ currentState = State.FINISHED;
+ } else if (slCommand == null) {
+ log.error("SLCommand not set (consumeRequest not called ??)");
+ bindingProcessorError = new SLException(2000);
+ // sendSTALQuit();
+ currentState = State.FINISHED;
+ } else {
+ currentState = State.PROCESS;
+ }
+ }
+
+ protected void processRequest() {
+ log.debug("Entered State: " + State.PROCESS);
+ log.debug("Processing command: " + slCommand);
+ commandInvoker.setCommand(slCommand);
+ responseCode = 200;
+ responseHeaders = Collections.EMPTY_MAP;
+ try {
+ commandInvoker.invoke(srcContex);
+ } catch (SLCanceledException e) {
+ log.info("Caught exception: " + e);
+ bindingProcessorError = e;
+ currentState = State.TRANSFORM;
+ }
+ dataUrlResponse = null;
+ if (getDataUrl() != null) {
+ log.debug("Data Url set to: " + getDataUrl());
+ currentState = State.DATAURL;
+ } else {
+ log.debug("No data url set");
+ currentState = State.TRANSFORM;
+ }
+ }
+
+ protected void handleDataUrl() {
+ log.debug("Entered State: " + State.DATAURL);
+ try {
+ DataUrl dataUrl = new DataUrl(getDataUrl());
+ DataUrlConnection conn = dataUrl.openConnection();
+
+ // set transfer headers
+ for (FormParameter fp : getTransferHeaders()) {
+ String paramString = getFormParameterAsString(fp);
+ if (paramString == null) {
+ log.error("Got empty transfer header, ignoring this");
+ } else {
+ String[] keyVal = paramString.split(":", 2);
+ String key = keyVal[0];
+ String val = null;
+ if (keyVal.length == 2) {
+ val = keyVal[1];
+ }
+ val = val.trim();
+ log.debug("Setting header " + key + " to value " + val);
+ conn.setHTTPHeader(key, val);
+ }
+ }
+
+ // set transfer form parameters
+ for (FormParameter fp : getTransferForms()) {
+ String contentTransferEncoding = null;
+ String contentType = fp.getFormParameterContentType();
+ String charSet = HttpUtil.getCharset(contentType, false);
+ if (charSet != null) {
+ contentType = contentType.substring(0, contentType
+ .lastIndexOf(HttpUtil.SEPERATOR[0]));
+ }
+ for (Iterator header = fp.getHeaderNames(); header.hasNext();) {
+ if (HttpUtil.CONTENT_TRANSFER_ENCODING
+ .equalsIgnoreCase(header.next())) {
+ contentTransferEncoding = getFormParameterAsString(fp);
+ }
+ }
+ log.debug("Setting form: " + fp.getFormParameterName()
+ + " contentType: " + contentType + " charset: " + charSet
+ + " contentTransferEncoding: " + contentTransferEncoding);
+ conn.setHTTPFormParameter(fp.getFormParameterName(), fp
+ .getFormParameterValue(), contentType, charSet,
+ contentTransferEncoding);
+ }
+
+ // connect
+ conn.connect();
+ // fetch and set SL result
+ targetContext.setTargetIsDataURL(true);
+ targetContext.setTargetCertificate(conn.getServerCertificate());
+ targetContext.setTargetProtocol(conn.getProtocol());
+ SLResult result = commandInvoker.getResult(targetContext);
+
+ // transfer result
+ conn.transmit(result);
+
+ // process Dataurl response
+ dataUrlResponse = conn.getResponse();
+ log.debug("Received data url response code: "
+ + dataUrlResponse.getResponseCode());
+ protocol = Protocol.fromString(conn.getProtocol());
+
+ switch (dataUrlResponse.getResponseCode()) {
+ case 200:
+ String contentType = dataUrlResponse.getContentType();
+ log.debug("Got dataurl response content type: " + contentType);
+ if (contentType != null) {
+ if ((contentType.startsWith(HttpUtil.APPLICATION_URL_ENCODED))
+ || (contentType.startsWith(HttpUtil.MULTIPART_FOTMDATA))) {
+ log.debug("Detected SL Request in dataurl response");
+ // process headers and request
+ setHTTPHeaders(dataUrlResponse.getResponseHeaders());
+ consumeRequestStream(dataUrlResponse.getStream());
+ closeDataUrlConnection();
+ srcContex.setSourceCertificate(conn.getServerCertificate());
+ srcContex.setSourceIsDataURL(true);
+ srcContex
+ .setSourceProtocol(Protocol.fromString(conn.getProtocol()));
+ currentState = State.PROCESS;
+ } else if (((contentType.startsWith(HttpUtil.TXT_HTML))
+ || (contentType.startsWith(HttpUtil.TXT_PLAIN)) || (contentType
+ .startsWith(HttpUtil.TXT_XML)))
+ && (dataUrlResponse.isHttpResponseXMLOK())) {
+ log.info("Dataurl response matches with content type: "
+ + contentType);
+ currentState = State.TRANSFORM;
+
+ } else if ((contentType.startsWith(HttpUtil.TXT_XML))
+ && (!dataUrlResponse.isHttpResponseXMLOK())) {
+ log
+ .debug("Detected text/xml dataurl response with content != ");
+ headerMap.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE, contentType);
+ assignXMLRequest(dataUrlResponse.getStream(), HttpUtil.getCharset(
+ contentType, true));
+ closeDataUrlConnection();
+ srcContex.setSourceCertificate(conn.getServerCertificate());
+ srcContex.setSourceIsDataURL(true);
+ srcContex
+ .setSourceProtocol(Protocol.fromString(conn.getProtocol()));
+ currentState = State.PROCESS;
+ // just to be complete, actually not used
+ srcContex.setSourceHTTPReferer(dataUrlResponse.getResponseHeaders()
+ .get(HttpUtil.HTTP_HEADER_REFERER));
+ } else {
+ resultContentType = contentType;
+ responseHeaders = dataUrlResponse.getResponseHeaders();
+ responseCode = dataUrlResponse.getResponseCode();
+ currentState = State.FINISHED;
+ }
+ } else {
+ log.debug("Content type not set in dataurl response");
+ closeDataUrlConnection();
+ throw new SLBindingException(2007);
+ }
+
+ break;
+ case 307:
+ contentType = dataUrlResponse.getContentType();
+ if ((contentType != null) && (contentType.startsWith(HttpUtil.TXT_XML))) {
+ log.debug("Received dataurl response code 307 with XML content");
+ String location = dataUrlResponse.getResponseHeaders().get(
+ HttpUtil.HTTP_HEADER_LOCATION);
+ if (location == null) {
+ log
+ .error("Did not get a location header for a 307 data url response");
+ throw new SLBindingException(2003);
+ }
+ // consumeRequestStream(dataUrlResponse.getStream());
+ FormParameterStore fp = new FormParameterStore();
+ fp.init(location.getBytes(HttpUtil.DEFAULT_CHARSET),
+ FixedFormParameters.DATAURL, null, null);
+ formParameterMap.put(FixedFormParameters.DATAURL, fp);
+ headerMap.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE, contentType);
+ assignXMLRequest(dataUrlResponse.getStream(), HttpUtil.getCharset(
+ dataUrlResponse.getContentType(), true));
+ closeDataUrlConnection();
+ srcContex.setSourceCertificate(conn.getServerCertificate());
+ srcContex.setSourceIsDataURL(true);
+ srcContex.setSourceProtocol(Protocol.fromString(conn.getProtocol()));
+ currentState = State.PROCESS;
+ // just to be complete, actually not used
+ srcContex.setSourceHTTPReferer(dataUrlResponse.getResponseHeaders()
+ .get(HttpUtil.HTTP_HEADER_REFERER));
+
+ } else {
+ log.debug("Received dataurl response code 307 non XML content: "
+ + dataUrlResponse.getContentType());
+ resultContentType = dataUrlResponse.getContentType();
+ currentState = State.FINISHED;
+ }
+ responseHeaders = dataUrlResponse.getResponseHeaders();
+ responseCode = dataUrlResponse.getResponseCode();
+ break;
+
+ case 301:
+ case 302:
+ case 303:
+ responseHeaders = dataUrlResponse.getResponseHeaders();
+ responseCode = dataUrlResponse.getResponseCode();
+ resultContentType = dataUrlResponse.getContentType();
+ currentState = State.FINISHED;
+ break;
+
+ default:
+ // issue error
+ log.info("Unexpected response code from dataurl server: "
+ + dataUrlResponse.getResponseCode());
+ throw new SLBindingException(2007);
+ }
+
+ } catch (SLException slx) {
+ bindingProcessorError = slx;
+ log.error("Error during dataurl communication");
+ resultContentType = HttpUtil.TXT_XML;
+ currentState = State.TRANSFORM;
+ } catch (SSLHandshakeException hx) {
+ bindingProcessorError = new SLException(2010);
+ log.info("Error during dataurl communication", hx);
+ resultContentType = HttpUtil.TXT_XML;
+ currentState = State.TRANSFORM;
+ } catch (IOException e) {
+ bindingProcessorError = new SLBindingException(2001);
+ log.error("Error while data url handling", e);
+ resultContentType = HttpUtil.TXT_XML;
+ currentState = State.TRANSFORM;
+ return;
+ }
+ }
+
+ protected void transformResult() {
+ log.debug("Entered State: " + State.TRANSFORM);
+ if (bindingProcessorError != null) {
+ resultContentType = HttpUtil.TXT_XML;
+ } else if (dataUrlResponse != null) {
+ resultContentType = dataUrlResponse.getContentType();
+ } else {
+ targetContext.setTargetIsDataURL(false);
+ targetContext.setTargetProtocol(protocol.toString());
+ try {
+ slResult = commandInvoker.getResult(targetContext);
+ resultContentType = slResult.getMimeType();
+ log
+ .debug("Successfully got SLResult from commandinvoker, setting mimetype to: "
+ + resultContentType);
+ } catch (SLCanceledException e) {
+ log.info("Cannot get result from invoker:", e);
+ bindingProcessorError = new SLException(6002);
+ resultContentType = HttpUtil.TXT_XML;
+ }
+ }
+ transformer = getTransformer(getStyleSheetUrl());
+ if (transformer != null) {
+ log.debug("Output transformation required");
+ resultContentType = transformer.getOutputProperty("media-type");
+ log.debug("Got media type from stylesheet: " + resultContentType);
+ if (resultContentType == null) {
+ log.debug("Setting to default text/xml result conent type");
+ resultContentType = "text/xml";
+ }
+ log.debug("Deferring sytylesheet processing");
+ }
+ currentState = State.FINISHED;
+ }
+
+ protected void finished() {
+ log.debug("Entered State: " + State.FINISHED);
+ if (bindingProcessorError != null) {
+ log.debug("Binding processor error, sending quit command");
+ resultContentType = HttpUtil.TXT_XML;
+ }
+ sendSTALQuit();
+ log.info("Terminating Bindingprocessor; Thread: "
+ + Thread.currentThread().getId());
+ }
+
+ // -- END Methods that handle the http binding activities as defined in the
+ // activity diagram --
+ //----------------------------------------------------------------------------
+
+ /**
+ * Sets the headers of the SL Request. IMPORTANT: make sure to set all headers
+ * before invoking {@link #consumeRequestStream(InputStream)}
+ *
+ * @param aHeaderMap
+ * if null all header will be cleared.
+ */
+ public void setHTTPHeaders(Map aHeaderMap) {
+ headerMap = new HashMap();
+ // ensure lowercase keys
+ if (aHeaderMap != null) {
+ for (String s : aHeaderMap.keySet()) {
+ if (s != null) {
+ headerMap.put(s.toLowerCase(), aHeaderMap.get(s));
+ if (s.equalsIgnoreCase(HttpUtil.HTTP_HEADER_REFERER)) {
+ String referer = aHeaderMap.get(s);
+ log.debug("Got referer header: " + referer);
+ srcContex.setSourceHTTPReferer(referer);
+ }
+ }
+ }
+ }
+ }
+
+ public void setSourceCertificate(X509Certificate aCert) {
+ srcContex.setSourceCertificate(aCert);
+ }
+
+ /**
+ * The HTTPBindingProcessor does not handle redirect URLs. It only provides
+ * the parameter.
+ *
+ * @return null if redirect url is not set.
+ */
+ public String getRedirectURL() {
+ return getFormParameterAsString(FixedFormParameters.REDIRECTURL);
+ }
+
+ public String getFormDataContentType(String aParameterName) {
+ FormParameter fp = formParameterMap.get(aParameterName);
+ if (fp != null) {
+ return fp.getFormParameterContentType();
+ }
+ return null;
+ }
+
+ public InputStream getFormData(String aParameterName) {
+ FormParameter fp = formParameterMap.get(aParameterName);
+ if (fp != null) {
+ return fp.getFormParameterValue();
+ }
+ return null;
+ }
+
+ protected void assignXMLRequest(InputStream is, String charset)
+ throws IOException, SLException {
+ Reader r = new InputStreamReader(is, charset);
+ StreamSource source = new StreamSource(r);
+ SLCommandContext commandCtx = new SLCommandContext();
+ commandCtx.setSTAL(getSTAL());
+ commandCtx.setURLDereferencerContext(new SimpleFormDataContextImpl(this));
+ slCommand = SLCommandFactory.getInstance().createSLCommand(source,
+ commandCtx);
+ log.debug("Created new command: " + slCommand);
+ }
+
+ @Override
+ public void run() {
+ boolean done = false;
+ int hopcounter = 0;
+ if (bindingProcessorError != null) {
+ currentState = State.FINISHED;
+ }
+ try {
+ while (!done) {
+ try {
+ switch (currentState) {
+ case INIT:
+ init();
+ break;
+ case PROCESS:
+ processRequest();
+ break;
+ case DATAURL:
+ handleDataUrl();
+ if (++hopcounter > MAX_DATAURL_HOPS) {
+ log.error("Maximum number of dataurl hops reached");
+ bindingProcessorError = new SLBindingException(2000);
+ currentState = State.FINISHED;
+ }
+ break;
+ case TRANSFORM:
+ transformResult();
+ break;
+ case FINISHED:
+ done = true;
+ finished();
+ break;
+ }
+ } catch (RuntimeException rte) {
+ throw rte;
+ } catch (Exception t) {
+ log.error("Caught unexpected exception", t);
+ responseCode = 200;
+ resultContentType = HttpUtil.TXT_XML;
+ responseHeaders = Collections.EMPTY_MAP;
+ bindingProcessorError = new SLException(2000);
+ currentState = State.FINISHED;
+ }
+ }
+ } catch (Throwable t) {
+ log.error("Caught unexpected exception", t);
+ responseCode = 200;
+ resultContentType = HttpUtil.TXT_XML;
+ responseHeaders = Collections.EMPTY_MAP;
+ bindingProcessorError = new SLException(2000);
+ currentState = State.FINISHED;
+ }
+ log.debug("Terminated http binding processor");
+ }
+
+ @Override
+ public void consumeRequestStream(InputStream is) {
+ try {
+ log.debug("Start consuming request stream");
+ formParameterMap.clear();
+ String cl = headerMap
+ .get(HttpUtil.HTTP_HEADER_CONTENT_TYPE.toLowerCase());
+ if (cl == null) {
+ log.info("No content type set in http header");
+ 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);
+ }
+ for (Iterator fpi = id.getFormParameterIterator(); fpi
+ .hasNext();) {
+ FormParameter fp = fpi.next();
+ log.debug("Got request parameter with name: "
+ + fp.getFormParameterName());
+ if (fp.getFormParameterName().equals(FixedFormParameters.XMLREQUEST)) {
+ log.debug("Creating XML Request");
+ for (Iterator headerIterator = fp.getHeaderNames(); headerIterator
+ .hasNext();) {
+ String headerName = headerIterator.next();
+ if (HttpUtil.CONTENT_TRANSFER_ENCODING.equalsIgnoreCase(headerName)) {
+ String transferEncoding = fp.getHeaderValue(headerName);
+ log.debug("Got transfer encoding for xmlrequest: "
+ + transferEncoding);
+ if (XML_REQ_TRANSFER_ENCODING.contains(transferEncoding)) {
+ log.debug("Supported transfer encoding: " + transferEncoding);
+ } else {
+ log
+ .error("Transferencoding not supported: "
+ + transferEncoding);
+ throw new SLBindingException(2005);
+ }
+ }
+ }
+ String charset = HttpUtil.getCharset(cl, true);
+ assignXMLRequest(fp.getFormParameterValue(), charset);
+ } else {
+ FormParameterStore fps = new FormParameterStore();
+ fps.init(fp);
+ if (!fps.isEmpty()) {
+ log.debug("Setting from parameter: " + fps.getFormParameterName());
+ formParameterMap.put(fps.getFormParameterName(), fps);
+ }
+ }
+ }
+ if (slCommand == null) {
+ throw new SLBindingException(2004);
+ }
+ if (is.read() != -1) {
+ log.error("Request input stream not completely read");
+ // consume rest of stream, should never occur
+ throw new SLRuntimeException(
+ "request input stream not consumed till end");
+ }
+ } catch (SLException slx) {
+ log.info("Error while consuming input stream " + slx);
+ bindingProcessorError = slx;
+ } catch (Throwable t) {
+ log.info("Error while consuming input stream " + t, t);
+ bindingProcessorError = new SLException(2000);
+ } finally {
+ try {
+ while (is.read() != -1)
+ ;
+ } catch (IOException e) {
+ log.error(e);
+ }
+ }
+ }
+
+ @Override
+ public String getResultContentType() {
+ return resultContentType;
+ }
+
+ protected Transformer getTransformer(String styleSheetURL) {
+ if (styleSheetURL == null) {
+ log.debug("Stylesheet URL not set");
+ return null;
+ }
+ try {
+ URLDereferencerContext urlCtx = new SimpleFormDataContextImpl(this);
+ URIResolver resolver = new URIResolverAdapter(URLDereferencer
+ .getInstance(), urlCtx);
+ TransformerFactory factory = TransformerFactory.newInstance();
+ StreamData sd = URLDereferencer.getInstance().dereference(styleSheetURL,
+ urlCtx);
+ Transformer t = factory.newTransformer(new StreamSource(sd.getStream()));
+ t.setURIResolver(resolver);
+ return t;
+ } catch (Exception ex) {
+ log.info("Cannot instantiate transformer", ex);
+ bindingProcessorError = new SLException(2002);
+ return null;
+ }
+ }
+
+ protected void handleBindingProcessorError(OutputStream os, String encoding,
+ Transformer transformer) throws IOException {
+ log.debug("Writing error as result");
+ ErrorResultImpl error = new ErrorResultImpl(bindingProcessorError);
+ try {
+ error.writeTo(new StreamResult(new OutputStreamWriter(os, encoding)),
+ transformer);
+ } catch (TransformerException e) {
+ log.fatal("Cannot write error result to stream", e);
+ }
+ }
+
+ @Override
+ public void writeResultTo(OutputStream os, String encoding)
+ throws IOException {
+ if (encoding == null) {
+ encoding = HttpUtil.DEFAULT_CHARSET;
+ }
+ if (bindingProcessorError != null) {
+ log.debug("Detected error in binding processor, writing error as result");
+ handleBindingProcessorError(os, encoding, transformer);
+ return;
+ } else if (dataUrlResponse != null) {
+ log.debug("Writing data url response as result");
+ String charEnc = HttpUtil.getCharset(dataUrlResponse.getContentType(),
+ true);
+ InputStreamReader isr = new InputStreamReader(
+ dataUrlResponse.getStream(), charEnc);
+ OutputStreamWriter osw = new OutputStreamWriter(os, encoding);
+ if (transformer == null) {
+ StreamUtil.copyStream(isr, osw);
+ } else {
+ try {
+ transformer.transform(new StreamSource(isr), new StreamResult(osw));
+ } catch (TransformerException e) {
+ log.fatal("Exception occured during result transformation", e);
+ // bindingProcessorError = new SLException(2008);
+ // handleBindingProcessorError(os, encoding, null);
+ return;
+ }
+ }
+ osw.flush();
+ isr.close();
+ } else if (slResult == null) {
+ // result not yet assigned -> must be a cancel
+ bindingProcessorError = new SLException(6001);
+ handleBindingProcessorError(os, encoding, transformer);
+ return;
+ } else {
+ log.debug("Getting result from invoker");
+ OutputStreamWriter osw = new OutputStreamWriter(os, encoding);
+ try {
+ slResult.writeTo(new StreamResult(osw), transformer);
+ } catch (TransformerException e) {
+ log.fatal("Cannot write result to stream", e);
+ // bindingProcessorError = new SLException(2008);
+ // handleBindingProcessorError(os, encoding, transformer);
+ }
+ osw.flush();
+ }
+ }
+
+ /**
+ * The response code from the dataurl server or 200 if no dataurl server
+ * created the result
+ *
+ * @return
+ */
+ public int getResponseCode() {
+ return responseCode;
+ }
+
+ /**
+ * All headers from the data url server in case of a direct forward from the
+ * dataurl server.
+ *
+ * @return
+ */
+ public Map getResponseHeaders() {
+ return responseHeaders;
+ }
+
+ @Override
+ public void setLocale(Locale locale) {
+ if (locale == null) {
+ throw new NullPointerException("Locale must not be set to null");
+ }
+ this.locale = locale;
+ }
+
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpUtil.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpUtil.java
new file mode 100644
index 00000000..b11a4d85
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HttpUtil.java
@@ -0,0 +1,78 @@
+/*
+* Copyright 2008 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.binding;
+
+import java.util.Map;
+
+import org.apache.commons.fileupload.ParameterParser;
+
+/**
+ * Placeholder for some HTTP related constants and helper method to extract the charset for a request.
+ *
+ */
+public class HttpUtil {
+
+ public final static String CHAR_SET = "charset";
+ public final static String DEFAULT_CHARSET = "ISO-8859-1";
+ public final static String HTTP_HEADER_CONTENT_TYPE = "Content-Type";
+ public static final String HTTP_HEADER_USER_AGENT = "User-Agent";
+ public final static String HTTP_HEADER_REFERER = "Referer";
+ public final static String CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding";
+ public final static String MULTIPART_FOTMDATA = "multipart/form-data";
+ public final static String MULTIPART_FOTMDATA_BOUNDARY = "boundary";
+ public final static String TXT_XML = "text/xml";
+ public final static String TXT_PLAIN = "text/plain";
+ public final static String TXT_HTML = "text/html";
+ public final static String APPLICATION_URL_ENCODED = "application/x-www-form-urlencoded";
+ public final static String HTTP_HEADER_LOCATION = "Location";
+
+ public final static char[] SEPERATOR = { ';' };
+
+ /**
+ * Extracts charset from a content type header.
+ *
+ * @param contentType
+ * @param replaceNullWithDefault
+ * if true the method return the default charset if not set
+ * @return charset String or null if not present
+ */
+ @SuppressWarnings("unchecked")
+ public static String getCharset(String contentType,
+ boolean replaceNullWithDefault) {
+ ParameterParser pf = new ParameterParser();
+ pf.setLowerCaseNames(true);
+ Map map = pf.parse(contentType, SEPERATOR);
+ String retVal = (String) map.get(CHAR_SET);
+ if ((retVal == null) && (replaceNullWithDefault)) {
+ if (map.containsKey(APPLICATION_URL_ENCODED)) {
+ // default charset for url encoded data
+ return "UTF-8";
+ }
+ retVal = getDefaultCharset();
+ }
+ return retVal;
+ }
+
+ /**
+ *
+ * Not to be used for url encoded requests.
+ */
+ public static String getDefaultCharset() {
+ return DEFAULT_CHARSET;
+ }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/Id.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/Id.java
new file mode 100644
index 00000000..93ab2e8b
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/Id.java
@@ -0,0 +1,27 @@
+/*
+* Copyright 2008 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.binding;
+
+/**
+ * The unique identifier for a BindingProcessor
+ * @author wbauer
+ *
+ */
+public interface Id {
+
+ public String toString();
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdFactory.java
new file mode 100644
index 00000000..60bf69a4
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdFactory.java
@@ -0,0 +1,106 @@
+/*
+* Copyright 2008 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.binding;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Creates or converts Ids for BindingProcessors.
+ * @author wbauer
+ *
+ */
+public class IdFactory {
+
+ public static int DEFAULT_NUMBER_OF_BITS = 168;
+
+ private static Log log = LogFactory.getLog(IdFactory.class);
+
+ private static IdFactory instance = new IdFactory();
+
+ private SecureRandom random;
+ private int numberOfBits = DEFAULT_NUMBER_OF_BITS;
+
+ private IdFactory() {
+ try {
+ random = SecureRandom.getInstance("SHA1PRNG");
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Cannot instantiate secure random" + e);
+ }
+ }
+
+ public static IdFactory getInstance() {
+ return instance;
+ }
+
+
+ /**
+ * set the secure random number generator to create secure ids.
+ *
+ * @param random
+ * must not be null
+ */
+ public void setSecureRandom(SecureRandom random) {
+ if (random == null) {
+ throw new NullPointerException("Cannot set secure random to null");
+ }
+ this.random = random;
+ }
+
+ /**
+ * Don't use this method unless you know exactly what you do !
+ * Be sure to use a sufficient large entropy
+ * @param numberOfBits >=1 (although this small entropy does not make sense)
+ */
+ public void setNumberOfBits(int numberOfBits) {
+ if (numberOfBits <1) {
+ throw new IllegalArgumentException("Cannot set number of bits < 1");
+ }
+ this.numberOfBits = numberOfBits;
+ }
+
+ public int getNumberOfBits() {
+ return numberOfBits;
+ }
+
+ /**
+ * Creates a new Id object with the factory's secure RNG and the set number of
+ * bits.
+ *
+ * @return
+ */
+ public Id createId() {
+ return new IdImpl(numberOfBits, random);
+ }
+
+ /**
+ * Creates an Id object for the provided String
+ *
+ * @param idString
+ * may be null in this case the method call creates a new Id.
+ * @return
+ */
+ public Id createId(String idString) {
+ if (idString == null) {
+ return createId();
+ }
+ return new IdImpl(idString);
+ }
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdImpl.java
new file mode 100644
index 00000000..5523992a
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/IdImpl.java
@@ -0,0 +1,80 @@
+/*
+* Copyright 2008 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.binding;
+
+import iaik.utils.Base64OutputStream;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.SecureRandom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Implementation that uses a Base64 representation for self generated Ids.
+ * @author wbauer
+ *
+ */
+public class IdImpl implements at.gv.egiz.bku.binding.Id {
+ private static Log log = LogFactory.getLog(IdImpl.class);
+
+ private String idString;
+
+ public IdImpl(int bitNumber, SecureRandom random) {
+ int byteSize = bitNumber/8;
+ if (bitNumber % 8 != 0) {
+ byteSize++;
+ }
+ byte[] randomBytes = new byte[byteSize];
+ random.nextBytes(randomBytes);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Base64OutputStream b64 = new Base64OutputStream(baos);
+ try {
+ b64.write(randomBytes);
+ b64.flush();
+ b64.close();
+ idString = new String(baos.toByteArray());
+ } catch (IOException e) {
+ log.error("Cannot create secure id: "+e);
+ }
+ }
+
+ public IdImpl(String idString) {
+ if (idString == null) {
+ throw new NullPointerException("Provided idstring must not be null");
+ }
+ this.idString = idString;
+ }
+
+ public String toString() {
+ return idString;
+ }
+
+ public int hashCode() {
+ return idString.hashCode();
+ }
+
+ public boolean equals(Object other) {
+ if (other instanceof Id) {
+ Id otherId = (Id)other;
+ return otherId.toString().equals(idString);
+ } else {
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/InputDecoder.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/InputDecoder.java
new file mode 100644
index 00000000..e22e54f2
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/InputDecoder.java
@@ -0,0 +1,41 @@
+/*
+* Copyright 2008 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.binding;
+
+import java.io.InputStream;
+import java.util.Iterator;
+
+/**
+ * Decodes http input stream (either url encoded or multipart formdata)
+ * @author wbauer
+ *
+ */
+public interface InputDecoder {
+ /**
+ * Called from Factory.
+ * @param contentType
+ */
+ void setContentType(String contentType);
+
+ /**
+ * Called from Factory.
+ * @param is the input must not be null
+ */
+ void setInputStream(InputStream is);
+
+ Iterator getFormParameterIterator();
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/InputDecoderFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/InputDecoderFactory.java
new file mode 100644
index 00000000..211deee7
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/InputDecoderFactory.java
@@ -0,0 +1,89 @@
+/*
+* Copyright 2008 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.binding;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Factory to get a matching instance for a encoded input stream when reading a http request.
+ *
+ */
+public class InputDecoderFactory {
+
+ public final static String MULTIPART_FORMDATA = "multipart/form-data";
+ public final static String URL_ENCODED = "application/x-www-form-urlencoded";
+
+ private static InputDecoderFactory instance = new InputDecoderFactory();
+ private static Log log = LogFactory.getLog(InputDecoderFactory.class);
+
+ private String defaultEncoding = URL_ENCODED;
+ private Map> decoderMap = new HashMap>();
+
+ private InputDecoderFactory() {
+ decoderMap.put(MULTIPART_FORMDATA, MultiPartFormDataInputDecoder.class);
+ decoderMap.put(URL_ENCODED, XWWWFormUrlInputDecoder.class);
+ }
+
+ public static InputDecoder getDefaultDecoder(InputStream is) {
+ return getDecoder(instance.defaultEncoding, is);
+ }
+
+ /**
+ *
+ * @param contentType
+ * @param is
+ * @return null if the content type is not supported
+ */
+ public static InputDecoder getDecoder(String contentType, InputStream is) {
+ String prefix = contentType.split(";")[0].trim().toLowerCase();
+ Class extends InputDecoder> dec = instance.decoderMap.get(prefix);
+ if (dec == null) {
+ log.info("Unknown encoding prefix " + contentType);
+ return null;
+ }
+ InputDecoder id;
+ try {
+ id = dec.newInstance();
+ id.setContentType(contentType);
+ id.setInputStream(is);
+ return id;
+ } catch (InstantiationException e) {
+ log.error(e);
+ throw new IllegalArgumentException(
+ "Cannot get an input decoder for content type: " + contentType);
+ } catch (IllegalAccessException e) {
+ log.error(e);
+ throw new IllegalArgumentException(
+ "Cannot get an input decoder for content type: " + contentType);
+ }
+ }
+
+ /**
+ * Allows to register decoders for special mime types.
+ * @param mimeType
+ * @param decoder
+ */
+ public static void registerDecoder(String mimeType,
+ Class extends InputDecoder> decoder) {
+ instance.decoderMap.put(mimeType.toLowerCase(), decoder);
+ }
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/MultiPartFormDataInputDecoder.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/MultiPartFormDataInputDecoder.java
new file mode 100644
index 00000000..f8b13553
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/MultiPartFormDataInputDecoder.java
@@ -0,0 +1,133 @@
+/*
+* Copyright 2008 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.binding;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+
+import org.apache.commons.fileupload.FileItemIterator;
+import org.apache.commons.fileupload.FileItemStream;
+import org.apache.commons.fileupload.FileUpload;
+import org.apache.commons.fileupload.FileUploadException;
+import org.apache.commons.fileupload.RequestContext;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.gv.egiz.bku.slexceptions.SLRuntimeException;
+
+/**
+ * The code to detect the multipart boundary is based on
+ * org.apache.commons.fileupload.FileUploadBase of
+ * http://commons.apache.org/fileupload/
+ *
+ * @author wbauer
+ *
+ */
+public class MultiPartFormDataInputDecoder implements InputDecoder,
+ RequestContext {
+
+ private static Log log = LogFactory
+ .getLog(MultiPartFormDataInputDecoder.class);
+
+ private String contentType;
+ private InputStream stream;
+
+ @Override
+ public void setContentType(String contentType) {
+ this.contentType = contentType;
+ }
+
+ @Override
+ public String getCharacterEncoding() {
+ return null;
+ }
+
+ @Override
+ public int getContentLength() {
+ return 0;
+ }
+
+ @Override
+ public String getContentType() {
+ return contentType;
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return stream;
+ }
+
+ @Override
+ public Iterator getFormParameterIterator() {
+ try {
+ FileUpload fup = new FileUpload();
+ FileItemIterator fit = fup.getItemIterator(this);
+ return new IteratorDelegator(fit);
+ } catch (Exception iox) {
+ log.error("Cannot decode multipart form data stream " + iox);
+ throw new SLRuntimeException(iox);
+ }
+ }
+
+ @Override
+ public void setInputStream(InputStream is) {
+ stream = is;
+ }
+
+ static class IteratorDelegator implements Iterator {
+
+ private FileItemIterator fileItemIterator;
+
+ public IteratorDelegator(FileItemIterator fit) {
+ fileItemIterator = fit;
+ }
+
+ @Override
+ public boolean hasNext() {
+ try {
+ return fileItemIterator.hasNext();
+ } catch (FileUploadException e) {
+ log.error(e);
+ throw new SLRuntimeException(e);
+ } catch (IOException e) {
+ log.error(e);
+ throw new SLRuntimeException(e);
+ }
+ }
+
+ @Override
+ public FormParameter next() {
+ try {
+ FileItemStream item = fileItemIterator.next();
+ return new FormParameterImpl(item.getContentType(),
+ item.getFieldName(), item.openStream(), item.getHeaders());
+ } catch (FileUploadException e) {
+ log.error(e);
+ throw new SLRuntimeException(e);
+ } catch (IOException e) {
+ log.error(e);
+ throw new SLRuntimeException(e);
+ }
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("Remove not supported");
+ }
+ }
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/RemovalStrategy.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/RemovalStrategy.java
new file mode 100644
index 00000000..6c2dcb9f
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/RemovalStrategy.java
@@ -0,0 +1,26 @@
+/*
+* Copyright 2008 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.binding;
+
+/**
+ * Could be used to remove expired BindingProcessor objects from a BindingProcessorManager.
+ *
+ */
+public interface RemovalStrategy {
+ public void execute();
+ public void setBindingProcessorManager(BindingProcessorManager bp);
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/SLCommandInvokerImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/SLCommandInvokerImpl.java
new file mode 100644
index 00000000..ef2affd1
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/SLCommandInvokerImpl.java
@@ -0,0 +1,66 @@
+/*
+* Copyright 2008 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.binding;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.gv.egiz.bku.slcommands.SLCommand;
+import at.gv.egiz.bku.slcommands.SLCommandInvoker;
+import at.gv.egiz.bku.slcommands.SLResult;
+import at.gv.egiz.bku.slcommands.SLSourceContext;
+import at.gv.egiz.bku.slcommands.SLTargetContext;
+
+/**
+ * This class implements the entry point for the CCEs security management.
+ *
+ * TODO the secuirty management is currently not implemented.
+ */
+public class SLCommandInvokerImpl implements SLCommandInvoker {
+
+ private static Log log = LogFactory.getLog(SLCommandInvokerImpl.class);
+
+ protected SLCommand command;
+ protected SLResult result;
+
+ /**
+ * Invokes a sl command.
+ */
+ public void invoke(SLSourceContext aContext) {
+ // FIXXME add security policy here.
+ log.warn("Security policy not implemented yet, invoking command: "+command);
+ result = command.execute();
+ }
+
+ public SLResult getResult(SLTargetContext aContext) {
+ // FIXXME
+ log.warn("Security policy not implemented yet, getting result of command: "+command);
+ return result;
+ }
+
+ public void setCommand(SLCommand aCmd) {
+ command = aCmd;
+ }
+
+ @Override
+ public SLCommandInvoker newInstance() {
+ SLCommandInvokerImpl cmdInv = new SLCommandInvokerImpl();
+ return cmdInv;
+ }
+
+
+}
\ 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
new file mode 100644
index 00000000..f4ebe288
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputDecoder.java
@@ -0,0 +1,101 @@
+/*
+* Copyright 2008 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.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 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 decodeInput(InputStream is) throws IOException {
+ List result = new LinkedList();
+ 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")
+ @Override
+ public void setContentType(String contentType) {
+ ParameterParser pp = new ParameterParser();
+ pp.setLowerCaseNames(true);
+ Map params = pp.parse(contentType, new char[] { ':', ';' });
+ if (!params.containsKey("application/x-www-form-urlencoded")) {
+ 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 getFormParameterIterator() {
+ try {
+ return decodeInput(dataStream).iterator();
+ } catch (IOException e) {
+ throw new SLRuntimeException(e);
+ }
+ }
+
+ @Override
+ public void setInputStream(InputStream is) {
+ dataStream = is;
+ }
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/multipart/InputStreamPartSource.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/multipart/InputStreamPartSource.java
new file mode 100644
index 00000000..253f8ff5
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/multipart/InputStreamPartSource.java
@@ -0,0 +1,66 @@
+/*
+* Copyright 2008 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.
+*/
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package at.gv.egiz.bku.binding.multipart;
+
+import java.io.IOException;
+import java.io.InputStream;
+import org.apache.commons.httpclient.methods.multipart.PartSource;
+
+/**
+ * InputStream source for FilePart.
+ * DOES NOT RETURN A CORRECT LENGTH OF THE INPUT DATA. (but we don't care, since we use chunked encoding)
+ *
+ * @author clemens
+ */
+public class InputStreamPartSource implements PartSource {
+
+ protected String name;
+ protected InputStream data;
+
+ public InputStreamPartSource(String name, InputStream data) {
+ this.name = name;
+ this.data = data;
+ }
+
+ /**
+ * Just a dummy value to make Part work
+ * @return 42
+ */
+ @Override
+ public long getLength() {
+ //System.out.println("***********GETLENGTH");
+ return 42;
+ }
+
+ @Override
+ public String getFileName() {
+ return name;
+ }
+
+ @Override
+ public InputStream createInputStream() throws IOException {
+ if (data == null)
+ throw new IOException("Failed to get stream for part: no data was set.");
+ return data;
+ }
+
+}
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
new file mode 100644
index 00000000..566b77b3
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/multipart/SLResultPart.java
@@ -0,0 +1,57 @@
+/*
+* Copyright 2008 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.
+*/
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package at.gv.egiz.bku.binding.multipart;
+
+import at.gv.egiz.bku.slcommands.SLResult;
+import java.io.IOException;
+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;
+
+/**
+ *
+ * @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()));
+ 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);
+ }
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/AccessControlInvocation.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/AccessControlInvocation.java
new file mode 100644
index 00000000..014b7fd7
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/AccessControlInvocation.java
@@ -0,0 +1,21 @@
+/*
+* Copyright 2008 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;
+
+public class AccessControlInvocation implements
+ at.gv.egiz.bku.slcommands.InvocationStrategy {
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureCommand.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureCommand.java
new file mode 100644
index 00000000..2d87c39f
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureCommand.java
@@ -0,0 +1,25 @@
+/*
+* Copyright 2008 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 at.gv.egiz.bku.slexceptions.SLCommandException;
+import at.gv.egiz.bku.slexceptions.SLRequestException;
+
+public interface CreateXMLSignatureCommand extends SLCommand {
+
+ public void prepareXMLSignature() throws SLCommandException, SLRequestException;
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureResult.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureResult.java
new file mode 100644
index 00000000..4bc2820b
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/CreateXMLSignatureResult.java
@@ -0,0 +1,20 @@
+/*
+* Copyright 2008 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;
+
+public interface CreateXMLSignatureResult extends SLResult {
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/ErrorResult.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/ErrorResult.java
new file mode 100644
index 00000000..5d52c0ea
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/ErrorResult.java
@@ -0,0 +1,20 @@
+/*
+* Copyright 2008 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;
+
+public interface ErrorResult extends SLResult {
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxReadCommand.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxReadCommand.java
new file mode 100644
index 00000000..77529a36
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxReadCommand.java
@@ -0,0 +1,20 @@
+/*
+* Copyright 2008 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;
+
+public interface InfoboxReadCommand extends SLCommand {
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxReadResult.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxReadResult.java
new file mode 100644
index 00000000..c6a51362
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxReadResult.java
@@ -0,0 +1,20 @@
+/*
+* Copyright 2008 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;
+
+public interface InfoboxReadResult extends SLResult {
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InvocationStrategy.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InvocationStrategy.java
new file mode 100644
index 00000000..6b410fac
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InvocationStrategy.java
@@ -0,0 +1,20 @@
+/*
+* Copyright 2008 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;
+
+public interface InvocationStrategy {
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/NullOperationCommand.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/NullOperationCommand.java
new file mode 100644
index 00000000..0651f882
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/NullOperationCommand.java
@@ -0,0 +1,20 @@
+/*
+* Copyright 2008 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;
+
+public interface NullOperationCommand extends SLCommand {
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/NullOperationResult.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/NullOperationResult.java
new file mode 100644
index 00000000..c36c879e
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/NullOperationResult.java
@@ -0,0 +1,20 @@
+/*
+* Copyright 2008 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;
+
+public interface NullOperationResult extends SLResult {
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommand.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommand.java
new file mode 100644
index 00000000..a8625946
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommand.java
@@ -0,0 +1,31 @@
+/*
+* Copyright 2008 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 at.gv.egiz.bku.slexceptions.SLCommandException;
+
+public interface SLCommand {
+
+ public final String NAMESPACE_URI = "http://www.buergerkarte.at/namespaces/securitylayer/1.2#";
+
+ public String getName();
+
+ public void init(SLCommandContext aCtx, Object aUnmarshalledRequest) throws SLCommandException;
+
+ public SLResult execute();
+
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandContext.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandContext.java
new file mode 100644
index 00000000..c95736bd
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandContext.java
@@ -0,0 +1,42 @@
+/*
+* Copyright 2008 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 at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext;
+import at.gv.egiz.stal.STAL;
+
+public class SLCommandContext {
+
+ private STAL stal;
+ private URLDereferencerContext urlDerefCtx;
+
+ public void setSTAL(STAL aStal) {
+ this.stal = aStal;
+ }
+
+ public void setURLDereferencerContext(URLDereferencerContext aCtx) {
+ this.urlDerefCtx = aCtx;
+ }
+
+ public STAL getSTAL() {
+ return stal;
+ }
+
+ public URLDereferencerContext getURLDereferencerContext() {
+ return urlDerefCtx;
+ }
+}
\ No newline at end of file
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
new file mode 100644
index 00000000..e13b29a1
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java
@@ -0,0 +1,370 @@
+/*
+* Copyright 2008 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 java.io.IOException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.UnmarshalException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import at.gv.egiz.bku.slcommands.impl.CreateXMLSignatureCommandImpl;
+import at.gv.egiz.bku.slcommands.impl.InfoboxReadCommandImpl;
+import at.gv.egiz.bku.slcommands.impl.NullOperationCommandImpl;
+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.slbinding.RedirectEventFilter;
+import at.gv.egiz.slbinding.RedirectUnmarshallerListener;
+
+public class SLCommandFactory {
+
+ /**
+ * Schema files required for Security Layer command validation.
+ */
+ 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"
+ };
+ /**
+ * Logging facility.
+ */
+ static Log log = LogFactory.getLog(SLCommandFactory.class);
+ /**
+ * The instance returned by {@link #getInstance()}.
+ */
+ private static SLCommandFactory instance;
+ /**
+ * Schema for Security Layer command validation.
+ */
+ private static Schema slSchema;
+ /**
+ * The JAXBContext.
+ */
+ private static JAXBContext jaxbContext;
+ /**
+ * The map of : to implementation class of the
+ * corresponding {@link SLCommand}.
+ */
+ private static Map> slRequestTypeMap = new HashMap>();
+
+
+ static {
+
+ // TODO: implement dynamic registration
+
+ // register all known implementation classes
+ putImplClass(SLCommand.NAMESPACE_URI, "NullOperationRequest",
+ NullOperationCommandImpl.class);
+ putImplClass(SLCommand.NAMESPACE_URI, "InfoboxReadRequest",
+ InfoboxReadCommandImpl.class);
+ putImplClass(SLCommand.NAMESPACE_URI, "CreateXMLSignatureRequest",
+ CreateXMLSignatureCommandImpl.class);
+ }
+
+ /**
+ * Register an {@link SLCommand} implementation class of a Security Layer
+ * command with the given namespaceUri and localname
+ * .
+ *
+ * @param namespaceUri
+ * the namespace URI of the Security Layer command
+ * @param localname
+ * the localname of the Security Layer command
+ * @param slCommandClass
+ * the implementation class, or null to deregister a
+ * currently registered class
+ */
+ public static void putImplClass(String namespaceUri, String localname,
+ Class extends SLCommand> slCommandClass) {
+ if (slCommandClass != null) {
+ slRequestTypeMap.put(namespaceUri + ":" + localname, slCommandClass);
+ } else {
+ slRequestTypeMap.remove(namespaceUri + ":" + localname);
+ }
+ }
+
+ /**
+ * Returns the implementation class of an {@link SLCommand} with the given
+ * name, or null if no such class is registered.
+ *
+ * @param name
+ * the QName of the Security Layer command
+ * @return the implementation class, or null if no class is
+ * registered for the given name
+ */
+ public static Class extends SLCommand> getImplClass(QName name) {
+ String namespaceURI = name.getNamespaceURI();
+ String localPart = name.getLocalPart();
+ return slRequestTypeMap.get(namespaceURI + ":" + localPart);
+ }
+
+ /**
+ * Sets the schema to validate Security Layer commands with.
+ *
+ * @param slSchema the schema to validate Security Layer commands with
+ */
+ public static void setSLSchema(Schema slSchema) {
+ SLCommandFactory.slSchema = slSchema;
+ }
+
+ /**
+ * @return the jaxbContext
+ */
+ public static JAXBContext getJaxbContext() {
+ ensureJaxbContext();
+ return jaxbContext;
+ }
+
+ /**
+ * @param jaxbContext the jaxbContext to set
+ */
+ public static void setJaxbContext(JAXBContext jaxbContext) {
+ SLCommandFactory.jaxbContext = jaxbContext;
+ }
+
+ /**
+ * Initialize the JAXBContext.
+ */
+ private synchronized static void ensureJaxbContext() {
+ if (jaxbContext == null) {
+ try {
+ String slPkg = at.buergerkarte.namespaces.securitylayer._1.ObjectFactory.class.getPackage().getName();
+ String xmldsigPkg = org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName();
+ setJaxbContext(JAXBContext.newInstance(slPkg + ":" + xmldsigPkg));
+ } catch (JAXBException e) {
+ log.error("Failed to setup JAXBContext security layer request.", e);
+ throw new SLRuntimeException(e);
+ }
+ }
+ }
+
+ /**
+ * Initialize the security layer schema.
+ */
+ private synchronized static void ensureSchema() {
+ if (slSchema == null) {
+ try {
+ SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ ClassLoader cl = SLCommandFactory.class.getClassLoader();
+ Source[] sources = new Source[SCHEMA_FILES.length];
+ for (int i = 0; i < SCHEMA_FILES.length; i++) {
+ String schemaFile = SCHEMA_FILES[i];
+ URL schemaURL = cl.getResource(schemaFile);
+ if (schemaURL == null) {
+ throw new SLRuntimeException("Failed to load schema file " + schemaFile + ".");
+ }
+ log.debug("Schema location: " + schemaURL);
+ sources[i] = new StreamSource(schemaURL.openStream());
+ }
+ Schema schema = schemaFactory.newSchema(sources);
+ log.debug("Schema successfully created.");
+ SLCommandFactory.setSLSchema(schema);
+ } catch (SAXException e) {
+ log.error("Failed to load security layer schema.", e);
+ throw new SLRuntimeException("Failed to load security layer schema.", e);
+ } catch (IOException e) {
+ log.error("Failed to load security layer schema.", e);
+ throw new SLRuntimeException("Failed to load security layer schema.", e);
+ }
+
+ }
+ }
+
+ /**
+ * Get an instance of the SLCommandFactory.
+ */
+ public synchronized static SLCommandFactory getInstance() {
+ if (instance == null) {
+ ensureJaxbContext();
+ ensureSchema();
+ instance = new SLCommandFactory();
+ }
+ return instance;
+ }
+
+ /**
+ * Private constructor used by {@link #getInstance()}.
+ */
+ private SLCommandFactory() {
+ }
+
+ /**
+ * Unmarshalls from the given source.
+ *
+ * @see Unmarshaller#unmarshal(Source)
+ *
+ * Note:Could replace JAXB's unmarshal-time validation engine (see commented code), however,
+ * we need a redirect filter.
+ *
+ * @param source
+ * the source to unmarshal from
+ * @return the object returned by {@link Unmarshaller#unmarshal(Source)}
+ * @throws SLRequestException
+ * if unmarshalling fails
+ * @throws SLRuntimeException
+ * if an unexpected error occurs configuring the unmarshaller or if
+ * unmarshalling fails with an unexpected error
+ */
+ protected Object unmarshal(Source source) throws SLRuntimeException,
+ SLRequestException {
+
+ Object object;
+ 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();
+ XMLEventReader filteredReader = inputFactory.createFilteredReader(eventReader, redirectEventFilter);
+
+ Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+ unmarshaller.setListener(new RedirectUnmarshallerListener(redirectEventFilter));
+ if (slSchema != null) {
+ unmarshaller.setSchema(slSchema);
+ }
+ log.trace("Before unmarshal().");
+ object = unmarshaller.unmarshal(filteredReader);
+ log.trace("After unmarshal().");
+ } catch (UnmarshalException e) {
+ if (log.isDebugEnabled()) {
+ log.debug("Failed to unmarshall security layer request.", e);
+ } else {
+ log.info("Failed to unmarshall security layer request." + e.getMessage());
+ }
+ Throwable cause = e.getCause();
+ if (cause instanceof SAXParseException) {
+ throw new SLRequestException(3000,
+ SLExceptionMessages.EC3000_UNCLASSIFIED, new Object[]{cause.getMessage()});
+ } else {
+ throw new SLRequestException(3000,
+ SLExceptionMessages.EC3000_UNCLASSIFIED, new Object[]{e});
+ }
+ } catch (JAXBException e) {
+ // unexpected error
+ log.error("Failed to unmarshall security layer request.", e);
+ throw new SLRuntimeException(e);
+ } catch (XMLStreamException e) {
+ // unexpected error
+ log.error("Failed to unmarshall security layer request.", e);
+ throw new SLRuntimeException(e);
+ }
+
+ return object;
+
+ }
+
+ /**
+ * Creates a new SLCommand from the given source and
+ * context.
+ *
+ * @param source
+ * the Source to unmarshall from
+ * @param context
+ * the context for the created SLCommand
+ * @return the SLCommand unmarshalled from the given
+ * source
+ * @throws SLRequestException
+ * if unmarshalling fails
+ * @throws SLCommandException
+ * if command ist not supported
+ * @throws SLRuntimeException
+ * if an unexpected error occurs configuring the unmarshaller, if
+ * unmarshalling fails with an unexpected error or if the
+ * corresponding SLCommand could not be instantiated
+ */
+ @SuppressWarnings("unchecked")
+ public SLCommand createSLCommand(Source source, SLCommandContext context)
+ throws SLCommandException, SLRuntimeException, SLRequestException {
+
+ Object object = unmarshal(source);
+ if (!(object instanceof JAXBElement)) {
+ // invalid request
+ log.info("Invalid security layer request. " + object.toString());
+ throw new SLRequestException(3002, SLExceptionMessages.EC3002_INVALID,
+ new Object[]{object.toString()});
+ }
+
+ QName qName = ((JAXBElement) object).getName();
+ Class extends SLCommand> implClass = getImplClass(qName);
+ if (implClass == null) {
+ // command not supported
+ log.info("Unsupported command received: " + qName.toString());
+ throw new SLCommandException(4011,
+ SLExceptionMessages.EC4011_NOTIMPLEMENTED, new Object[]{qName.toString()});
+ }
+
+ // try to instantiate
+ SLCommand slCommand;
+ try {
+ slCommand = implClass.newInstance();
+ log.debug("SLCommand " + slCommand.getName() + " created.");
+ } catch (InstantiationException e) {
+ // unexpected error
+ log.error("Failed to instantiate security layer command implementation.",
+ e);
+ throw new SLRuntimeException(e);
+ } catch (IllegalAccessException e) {
+ // unexpected error
+ log.error("Failed to instantiate security layer command implementation.",
+ e);
+ throw new SLRuntimeException(e);
+ }
+ slCommand.init(context, (JAXBElement) object);
+
+ return slCommand;
+
+ }
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandInvoker.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandInvoker.java
new file mode 100644
index 00000000..30c6b68f
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandInvoker.java
@@ -0,0 +1,45 @@
+/*
+* Copyright 2008 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 at.gv.egiz.bku.slexceptions.SLCanceledException;
+
+public interface SLCommandInvoker {
+
+ /**
+ *
+ * @param aContext
+ * @throws SLCanceledException if the security management prevents execution of this command
+ */
+ public void invoke(SLSourceContext aContext) throws SLCanceledException;
+
+ /**
+ *
+ * @param aContext
+ * @return
+ * @throws SLCanceledException if the security management prevents execution of this command
+ */
+ public SLResult getResult(SLTargetContext aContext) throws SLCanceledException;
+
+ public void setCommand(at.gv.egiz.bku.slcommands.SLCommand aCmd);
+
+ /**
+ * Prototype creation
+ * @return
+ */
+ public SLCommandInvoker newInstance();
+}
\ No newline at end of file
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
new file mode 100644
index 00000000..7cf43fda
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLResult.java
@@ -0,0 +1,44 @@
+/*
+* Copyright 2008 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.transform.Result;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+
+public interface SLResult {
+
+ public static enum SLResultType {BINARY, XML};
+
+ public SLResultType getResultType();
+
+ /**
+ * The MIME Type of the Result.
+ *
+ * @return may result null if unknown.
+ */
+ public String getMimeType();
+
+ public void writeTo(Result aResult);
+
+ /**
+ *
+ * @param result
+ * @param transformer may be null.
+ */
+ public void writeTo(Result result, Transformer transformer) throws TransformerException;
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLSourceContext.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLSourceContext.java
new file mode 100644
index 00000000..ded55b2a
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLSourceContext.java
@@ -0,0 +1,63 @@
+/*
+* Copyright 2008 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 java.security.cert.X509Certificate;
+
+import at.gv.egiz.bku.utils.binding.Protocol;
+
+
+public class SLSourceContext {
+
+ private Protocol sourceProtocol;
+ private boolean sourceIsDataURL;
+ private X509Certificate sourceCertificate;
+ private String sourceHTTPReferer;
+
+ public Protocol getSourceProtocol() {
+ return sourceProtocol;
+ }
+
+ public void setSourceProtocol(Protocol sourceProtocol) {
+ this.sourceProtocol = sourceProtocol;
+ }
+
+ public boolean isSourceIsDataURL() {
+ return sourceIsDataURL;
+ }
+
+ public void setSourceIsDataURL(boolean sourceIsDataURL) {
+ this.sourceIsDataURL = sourceIsDataURL;
+ }
+
+ public X509Certificate getSourceCertificate() {
+ return sourceCertificate;
+ }
+
+ public void setSourceCertificate(X509Certificate sourceCertificate) {
+ this.sourceCertificate = sourceCertificate;
+ }
+
+ public String getSourceHTTPReferer() {
+ return sourceHTTPReferer;
+ }
+
+ public void setSourceHTTPReferer(String sourceHTTPReferer) {
+ this.sourceHTTPReferer = sourceHTTPReferer;
+ }
+
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLTargetContext.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLTargetContext.java
new file mode 100644
index 00000000..cf800406
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLTargetContext.java
@@ -0,0 +1,50 @@
+/*
+* Copyright 2008 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 java.security.cert.X509Certificate;
+
+public class SLTargetContext {
+ private String targetProtocol;
+ private boolean targetIsDataURL;
+ private X509Certificate targetCertificate;
+
+ public String getTargetProtocol() {
+ return targetProtocol;
+ }
+
+ public void setTargetProtocol(String targetProtocol) {
+ this.targetProtocol = targetProtocol;
+ }
+
+ public boolean isTargetIsDataURL() {
+ return targetIsDataURL;
+ }
+
+ public void setTargetIsDataURL(boolean targetIsDataURL) {
+ this.targetIsDataURL = targetIsDataURL;
+ }
+
+ public X509Certificate getTargetCertificate() {
+ return targetCertificate;
+ }
+
+ public void setTargetCertificate(X509Certificate targetCertificate) {
+ this.targetCertificate = targetCertificate;
+ }
+
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java
new file mode 100644
index 00000000..136fa6f3
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java
@@ -0,0 +1,229 @@
+/*
+* Copyright 2008 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.impl;
+
+import java.io.ByteArrayInputStream;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.Date;
+
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.URIReferenceException;
+import javax.xml.crypto.dsig.XMLSignatureException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSSerializer;
+
+import at.buergerkarte.namespaces.securitylayer._1.CreateXMLSignatureRequestType;
+import at.buergerkarte.namespaces.securitylayer._1.DataObjectInfoType;
+import at.gv.egiz.bku.slcommands.CreateXMLSignatureCommand;
+import at.gv.egiz.bku.slcommands.SLCommandContext;
+import at.gv.egiz.bku.slcommands.SLResult;
+import at.gv.egiz.bku.slcommands.impl.xsect.AlgorithmMethodFactory;
+import at.gv.egiz.bku.slcommands.impl.xsect.AlgorithmMethodFactoryImpl;
+import at.gv.egiz.bku.slcommands.impl.xsect.IdValueFactory;
+import at.gv.egiz.bku.slcommands.impl.xsect.IdValueFactoryImpl;
+import at.gv.egiz.bku.slcommands.impl.xsect.Signature;
+import at.gv.egiz.bku.slexceptions.SLCommandException;
+import at.gv.egiz.bku.slexceptions.SLRequestException;
+import at.gv.egiz.dom.DOMUtils;
+import at.gv.egiz.stal.InfoboxReadRequest;
+import at.gv.egiz.stal.InfoboxReadResponse;
+import at.gv.egiz.stal.STALRequest;
+import at.gv.egiz.stal.STALResponse;
+
+/**
+ * This class implements the security layer command CreateXMLSignatureRequest.
+ *
+ * @author mcentner
+ */
+public class CreateXMLSignatureCommandImpl extends SLCommandImpl implements
+ CreateXMLSignatureCommand {
+
+ /**
+ * Logging facility.
+ */
+ protected static Log log = LogFactory.getLog(CreateXMLSignatureCommandImpl.class);
+
+ /**
+ * The signing certificate.
+ */
+ protected X509Certificate signingCertificate;
+
+ /**
+ * The keybox identifier of the key used for signing.
+ */
+ protected String keyboxIdentifier;
+
+ /**
+ * The to-be signed signature.
+ */
+ protected Signature signature;
+
+ @Override
+ public void init(SLCommandContext ctx, Object unmarshalledRequest)
+ throws SLCommandException {
+ super.init(ctx, unmarshalledRequest);
+ }
+
+ @Override
+ public void prepareXMLSignature() throws SLCommandException, SLRequestException {
+
+ CreateXMLSignatureRequestType request = getRequestValue();
+
+ // TODO: make configurable?
+ IdValueFactory idValueFactory = new IdValueFactoryImpl();
+
+ // TODO: make configurable?
+ AlgorithmMethodFactory algorithmMethodFactory;
+ try {
+ algorithmMethodFactory = new AlgorithmMethodFactoryImpl(signingCertificate);
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Failed to get DigestMethod.", e);
+ throw new SLCommandException(4006);
+ }
+
+ signature = new Signature(getCmdCtx().getURLDereferencerContext(), idValueFactory, algorithmMethodFactory);
+
+ // SigningTime
+ signature.setSigningTime(new Date());
+
+ // SigningCertificate
+ signature.setSignerCeritifcate(signingCertificate);
+
+ // SignatureInfo
+ if (request.getSignatureInfo() != null) {
+ signature.setSignatureInfo(request.getSignatureInfo());
+ }
+
+ // DataObjects
+ for (DataObjectInfoType dataObjectInfo : request.getDataObjectInfo()) {
+ signature.addDataObject(dataObjectInfo);
+ }
+
+ signature.buildXMLSignature();
+
+ }
+
+ /**
+ * Gets the signing certificate from STAL.
+ *
+ * @throws SLCommandException
+ * if getting the singing certificate fails
+ */
+ private void getSigningCertificate() throws SLCommandException {
+
+ CreateXMLSignatureRequestType request = getRequestValue();
+ keyboxIdentifier = request.getKeyboxIdentifier();
+
+ InfoboxReadRequest stalRequest = new InfoboxReadRequest();
+ stalRequest.setInfoboxIdentifier(keyboxIdentifier);
+
+ requestSTAL(Collections.singletonList((STALRequest) stalRequest));
+
+ STALResponse stalResponse = stalResponses.next();
+
+ if (stalResponse instanceof InfoboxReadResponse) {
+ byte[] infobox = ((InfoboxReadResponse) stalResponse).getInfoboxValue();
+
+ try {
+ CertificateFactory certFactory = CertificateFactory.getInstance("X509");
+ signingCertificate = (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(infobox));
+ } catch (CertificateException e) {
+ log.info("Failed to decode signing certificate.", e);
+ // TODO: issue appropriate error
+ throw new SLCommandException(4000);
+ }
+
+ } else {
+ log.info("Failed to get signing certificate.");
+ // TODO: issue appropriate error
+ throw new SLCommandException(4000);
+ }
+
+ }
+
+ /**
+ * Signs the signature.
+ *
+ * @throws SLCommandException
+ * if signing the signature fails
+ */
+ private void signXMLSignature() throws SLCommandException {
+
+ try {
+ signature.sign(getCmdCtx().getSTAL(), keyboxIdentifier);
+ } catch (MarshalException e) {
+ log.error("Failed to marshall XMLSignature.", e);
+ throw new SLCommandException(4000);
+ } catch (XMLSignatureException e) {
+ if (e.getCause() instanceof URIReferenceException) {
+ URIReferenceException uriReferenceException = (URIReferenceException) e.getCause();
+ if (uriReferenceException.getCause() instanceof SLCommandException) {
+ throw (SLCommandException) uriReferenceException.getCause();
+ }
+ }
+ log.error("Failed to sign XMLSignature.", e);
+ throw new SLCommandException(4000);
+ }
+
+ }
+
+ @Override
+ public SLResult execute() {
+ try {
+
+ // get certificate in order to select appropriate algorithms for hashing and signing
+ getSigningCertificate();
+
+ // prepare the XMLSignature for signing
+ prepareXMLSignature();
+
+ // sign the XMLSignature
+ signXMLSignature();
+
+ if (log.isTraceEnabled()) {
+
+ DOMImplementationLS domImplLS = DOMUtils.getDOMImplementationLS();
+ LSSerializer serializer = domImplLS.createLSSerializer();
+ String debugString = serializer.writeToString(signature.getDocument());
+
+ log.trace(debugString);
+
+ }
+
+ return new CreateXMLSignatureResultImpl(signature.getDocument());
+
+ } catch (SLCommandException e) {
+ return new ErrorResultImpl(e);
+ } catch (SLRequestException e) {
+ return new ErrorResultImpl(e);
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "CreateXMLSignatureRequest";
+ }
+
+
+}
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
new file mode 100644
index 00000000..d2d2e678
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureResultImpl.java
@@ -0,0 +1,138 @@
+/*
+* Copyright 2008 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.impl;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.transform.Result;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Element;
+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.slexceptions.SLRuntimeException;
+
+/**
+ * This calls implements the result of the security layer command CreateXMLSignature.
+ *
+ * @author mcentner
+ */
+public class CreateXMLSignatureResultImpl extends SLResultImpl {
+
+ /**
+ * Logging facility.
+ */
+ private static Log log = LogFactory.getLog(CreateXMLSignatureResultImpl.class);
+
+ /**
+ * The document containing the XMLSignature.
+ */
+ protected Document doc;
+
+ /**
+ * Creates a new instance of this CreateXMLSignatureResultImpl with the given
+ * signature document.
+ *
+ * @param document the signature document
+ *
+ * @throws NullPointerException if document is null
+ */
+ public CreateXMLSignatureResultImpl(Document document) {
+ super();
+
+ if (document == null) {
+ throw new NullPointerException("Argument 'document' must not be null.");
+ }
+
+ this.doc = document;
+
+ marshallCreateXMLSignatureResponse();
+ }
+
+ /**
+ * Marshalls the CreateXMLSignatureResponse.
+ */
+ private void marshallCreateXMLSignatureResponse() {
+
+ ObjectFactory factory = new ObjectFactory();
+
+ CreateXMLSignatureResponseType createCreateXMLSignatureResponseType = factory.createCreateXMLSignatureResponseType();
+ JAXBElement createCreateXMLSignatureResponse = factory.createCreateXMLSignatureResponse(createCreateXMLSignatureResponseType);
+
+ DocumentFragment fragment = doc.createDocumentFragment();
+
+ JAXBContext jaxbContext = SLCommandFactory.getJaxbContext();
+ try {
+ Marshaller marshaller = jaxbContext.createMarshaller();
+ marshaller.marshal(createCreateXMLSignatureResponse, fragment);
+ } catch (JAXBException e) {
+ log.error("Failed to marshall 'CreateXMLSignatureResponse'", e);
+ throw new SLRuntimeException(e);
+ }
+
+ Node child = fragment.getFirstChild();
+ if (child instanceof Element) {
+ Node node = doc.replaceChild(child, doc.getDocumentElement());
+ child.appendChild(node);
+ }
+
+ }
+
+ @Override
+ public void writeTo(Result result) {
+
+ try {
+ writeTo(result, null);
+ } catch (TransformerException e) {
+ log.error(e);
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egiz.bku.slcommands.impl.SLResultImpl#writeTo(javax.xml.transform.Result, javax.xml.transform.Transformer)
+ */
+ @Override
+ public void writeTo(Result result, Transformer transformer) throws TransformerException {
+
+ if (transformer == null) {
+ TransformerFactory transformerFactory = TransformerFactory.newInstance();
+ try {
+ transformer = transformerFactory.newTransformer();
+ } catch (TransformerConfigurationException e) {
+ log.error("Failed to create Transformer.", e);
+ throw new SLRuntimeException(e);
+ }
+ }
+ transformer.transform(new DOMSource(doc), result);
+
+ }
+
+}
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
new file mode 100644
index 00000000..555f83bd
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImpl.java
@@ -0,0 +1,60 @@
+/*
+* Copyright 2008 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.impl;
+
+import at.buergerkarte.namespaces.securitylayer._1.ErrorResponseType;
+import at.buergerkarte.namespaces.securitylayer._1.ObjectFactory;
+import at.gv.egiz.bku.slcommands.ErrorResult;
+import at.gv.egiz.bku.slexceptions.SLException;
+
+import javax.xml.transform.Result;
+
+/**
+ * This class implements the security layer result ErrorResponse.
+ *
+ * @author mcentner
+ */
+public class ErrorResultImpl extends SLResultImpl implements ErrorResult {
+
+ /**
+ * The exception containing information provided in the ErrorResponse.
+ */
+ protected SLException slException;
+
+ /**
+ * Creates a new instance of this ErrorResultImpl with the given
+ * slException containing information provided in the
+ * ErrorResponse.
+ *
+ * @param slException the exception
+ */
+ public ErrorResultImpl(SLException slException) {
+ this.slException = slException;
+ }
+
+ @Override
+ public void writeTo(Result result) {
+
+ ObjectFactory factory = new ObjectFactory();
+ ErrorResponseType responseType = factory.createErrorResponseType();
+ responseType.setErrorCode(slException.getErrorCode());
+ responseType.setInfo(slException.getDetailedMsg());
+
+ writeTo(factory.createErrorResponse(responseType), result);
+
+ }
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java
new file mode 100644
index 00000000..93131cf4
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java
@@ -0,0 +1,409 @@
+/*
+* Copyright 2008 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.impl;
+
+import iaik.asn1.CodingException;
+import iaik.asn1.DerCoder;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Result;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+import at.buergerkarte.namespaces.personenbindung._20020506_.CompressedIdentityLinkType;
+import at.buergerkarte.namespaces.securitylayer._1.AnyChildrenType;
+import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadParamsBinaryFileType;
+import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadRequestType;
+import at.gv.egiz.bku.slcommands.InfoboxReadCommand;
+import at.gv.egiz.bku.slcommands.SLCommand;
+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.SLExceptionMessages;
+import at.gv.egiz.bku.slexceptions.SLRuntimeException;
+import at.gv.egiz.idlink.CompressedIdentityLinkFactory;
+import at.gv.egiz.idlink.IdentityLinkTransformer;
+import at.gv.egiz.idlink.ans1.IdentityLink;
+import at.gv.egiz.stal.InfoboxReadRequest;
+import at.gv.egiz.stal.InfoboxReadResponse;
+import at.gv.egiz.stal.STALRequest;
+
+/**
+ * This class implements the security layer command
+ * InfoboxReadRequest.
+ *
+ * NOTE: Currently the only supported infobox identifier is '
+ * IdentityLink'.
+ *
+ *
+ * @author mcentner
+ */
+public class InfoboxReadCommandImpl extends SLCommandImpl implements
+ InfoboxReadCommand {
+
+ /**
+ * Logging facility.
+ */
+ protected static Log log = LogFactory.getLog(InfoboxReadCommandImpl.class);
+
+ public static final String INFOBOX_IDENTIFIER_CERTIFICATES = "Certificates";
+
+ public static final String BOX_SPECIFIC_PARAMETER_IDENTITY_LINK_DOMAIN_IDENTIFIER = "IdentityLinkDomainIdentifier";
+
+ public static final String INFOBOX_IDENTIFIER_IDENTITY_LINK = "IdentityLink";
+
+ /**
+ * The InfoboxIdentifier
+ */
+ protected String infoboxIdentifier;
+
+ /**
+ * The IdentityLinkDomainIdentifier value of an IdentyLink infobox.
+ */
+ protected String identityLinkDomainIdentifier;
+
+ /**
+ * Is content XML entity?
+ */
+ protected boolean isXMLEntity;
+
+ @Override
+ public String getName() {
+ return "InfoboxReadRequest";
+ }
+
+ /**
+ * @return the infoboxIdentifier
+ */
+ public String getInfoboxIdentifier() {
+ return infoboxIdentifier;
+ }
+
+ @Override
+ public void init(SLCommandContext ctx, Object request) throws SLCommandException {
+ super.init(ctx, request);
+
+ InfoboxReadRequestType req = getRequestValue();
+
+ infoboxIdentifier = req.getInfoboxIdentifier();
+
+ InfoboxReadParamsBinaryFileType binaryFileParameters = req.getBinaryFileParameters();
+ if (binaryFileParameters != null) {
+ isXMLEntity = binaryFileParameters.isContentIsXMLEntity();
+ log.debug("Got ContentIsXMLEntity=" + isXMLEntity + ".");
+ }
+
+ if (INFOBOX_IDENTIFIER_IDENTITY_LINK.equals(infoboxIdentifier)) {
+
+ if (req.getAssocArrayParameters() != null) {
+ log.info("Got AssocArrayParameters but Infobox type is BinaryFile.");
+ throw new SLCommandException(4010);
+ }
+
+
+ AnyChildrenType boxSpecificParameters = req.getBoxSpecificParameters();
+
+ if (boxSpecificParameters != null) {
+ // check BoxSpecificParameters
+ List
+ *
+ * @author mcentner
+ */
+public class IdValueFactoryImpl implements IdValueFactory {
+
+ /**
+ * A generator for xsd:Id-attribute values.
+ *
+ * @author mcentner
+ */
+ private class IdGenerator {
+
+ /**
+ * The salt.
+ */
+ private String salt;
+
+ /**
+ * The element name.
+ */
+ private String elementName;
+
+ /**
+ * The sequence number.
+ */
+ private int i = 0;
+
+ /**
+ * Creates a new instance of this IdGenerator with the given
+ * elementName and salt value.
+ *
+ * @param elementName the element name
+ * @param salt the salt valeu
+ */
+ private IdGenerator(String elementName, String salt) {
+ super();
+ this.elementName = elementName;
+ this.salt = salt;
+ }
+
+ /**
+ * @return returns the next xsd:Id-attribute value.
+ */
+ public String getNextId() {
+ return elementName + "-" + salt + "-" + Integer.toString(++i);
+ }
+
+ }
+
+ /**
+ * A map of element names to xsd:Id-value generators.
+ */
+ private Map generators = new HashMap();
+
+ /**
+ * The seed value.
+ */
+ private String seed;
+
+ /**
+ * Creates a new instance of this IdValueFactory.
+ */
+ public IdValueFactoryImpl() {
+
+ Random random = new Random();
+ int rand = random.nextInt();
+ seed = Integer.toHexString(rand);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.gv.egiz.bku.slcommands.impl.IdValueFactory#createIdValue(java.lang.String
+ * )
+ */
+ public String createIdValue(String elementName) {
+
+ IdGenerator generator = generators.get(elementName);
+ if (generator == null) {
+ generator = new IdGenerator(elementName, seed);
+ generators.put(elementName, generator);
+ }
+ return generator.getNextId();
+
+ }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/LocRefDereferencer.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/LocRefDereferencer.java
new file mode 100644
index 00000000..a6399c9b
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/LocRefDereferencer.java
@@ -0,0 +1,113 @@
+/*
+* Copyright 2008 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.impl.xsect;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import javax.xml.crypto.Data;
+import javax.xml.crypto.OctetStreamData;
+import javax.xml.crypto.URIDereferencer;
+import javax.xml.crypto.URIReference;
+import javax.xml.crypto.URIReferenceException;
+import javax.xml.crypto.XMLCryptoContext;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.gv.egiz.bku.utils.urldereferencer.StreamData;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext;
+
+/**
+ * An URIDereferencer implementation that dereferences LocRef
+ * references.
+ *
+ * @author mcentner
+ */
+public class LocRefDereferencer implements URIDereferencer {
+
+ /**
+ * Logging facility.
+ */
+ private static Log log = LogFactory.getLog(LocRefDereferencer.class);
+
+ /**
+ * The LocRef-reference to be dereferenced by
+ * {@link #dereference(URIReference, XMLCryptoContext)}.
+ */
+ protected String locRef;
+
+ /**
+ * The context to be used for dereferencing.
+ */
+ protected URLDereferencerContext dereferencerContext;
+
+ /**
+ * Creates a new instance of this LocRefDereferencer with the given
+ * dereferencerContext and locRef reference.
+ *
+ * @param dereferencerContext
+ * the context to be used for dereferencing
+ * @param locRef
+ * the LocRef-reference (must be an absolute URI)
+ *
+ * @throws URISyntaxException
+ * if LocRef is not an absolute URI
+ */
+ public LocRefDereferencer(URLDereferencerContext dereferencerContext,
+ String locRef) throws URISyntaxException {
+
+ this.dereferencerContext = dereferencerContext;
+
+ URI locRefUri = new URI(locRef);
+ if (locRefUri.isAbsolute()) {
+ this.locRef = locRef;
+ } else {
+ throw new IllegalArgumentException(
+ "Parameter 'locRef' must be an absolut URI.");
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * javax.xml.crypto.URIDereferencer#dereference(javax.xml.crypto.URIReference,
+ * javax.xml.crypto.XMLCryptoContext)
+ */
+ @Override
+ public Data dereference(URIReference uriReference, XMLCryptoContext context)
+ throws URIReferenceException {
+
+ URLDereferencer dereferencer = URLDereferencer.getInstance();
+ StreamData streamData;
+ try {
+ streamData = dereferencer.dereference(locRef, dereferencerContext);
+ } catch (IOException e) {
+ log.info("Failed to dereference URI'" + locRef + "'. " + e.getMessage(),
+ e);
+ throw new URIReferenceException("Failed to dereference URI '" + locRef
+ + "'. " + e.getMessage(), e);
+ }
+
+ return new OctetStreamData(streamData.getStream(), locRef, streamData
+ .getContentType());
+ }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALPrivateKey.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALPrivateKey.java
new file mode 100644
index 00000000..64c758c9
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALPrivateKey.java
@@ -0,0 +1,122 @@
+/*
+* Copyright 2008 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.impl.xsect;
+
+import java.security.PrivateKey;
+
+import at.gv.egiz.stal.STAL;
+import at.gv.egiz.stal.HashDataInputCallback;
+
+/**
+ * This class implements a private key used by the {@link STALSignature} class.
+ *
+ * @author mcentner
+ */
+public class STALPrivateKey implements PrivateKey {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The STAL implementation.
+ */
+ private STAL stal;
+
+ /**
+ * The callback interface for obtaining the hash input data.
+ */
+ private HashDataInputCallback hashDataInputCallback;
+
+ /**
+ * The keybox identifier.
+ */
+ private String keyboxIdentifier;
+
+ /**
+ * The signature algorithm.
+ */
+ private String algorithm;
+
+ /**
+ * Creates a new instance of this STALPrivateKey with the given
+ * stal implementation, signature algorithm,
+ * keyboxIdentifier and hashDataInputCallback
+ * interface.
+ *
+ * @param stal
+ * the STAL implementation
+ * @param algorithm
+ * the signature algorithm
+ * @param keyboxIdentifier
+ * the keybox identifier
+ * @param hashDataInputCallback
+ * the interface for obtaining the has input data
+ */
+ public STALPrivateKey(STAL stal,
+ String algorithm, String keyboxIdentifier, HashDataInputCallback hashDataInputCallback) {
+ super();
+ this.keyboxIdentifier = keyboxIdentifier;
+ this.hashDataInputCallback = hashDataInputCallback;
+ this.stal = stal;
+ this.algorithm = algorithm;
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.Key#getAlgorithm()
+ */
+ @Override
+ public String getAlgorithm() {
+ return algorithm;
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.Key#getEncoded()
+ */
+ @Override
+ public byte[] getEncoded() {
+ throw new UnsupportedOperationException("STALPrivateKey does not support the getEncoded() method.");
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.Key#getFormat()
+ */
+ @Override
+ public String getFormat() {
+ return null;
+ }
+
+ /**
+ * @return the STAL implementation
+ */
+ public STAL getStal() {
+ return stal;
+ }
+
+ /**
+ * @return the interface for obtaining the hash data input
+ */
+ public HashDataInputCallback getHashDataInputCallback() {
+ return hashDataInputCallback;
+ }
+
+ /**
+ * @return the keybox identifier
+ */
+ public String getKeyboxIdentifier() {
+ return keyboxIdentifier;
+ }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALProvider.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALProvider.java
new file mode 100644
index 00000000..0ab30530
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALProvider.java
@@ -0,0 +1,64 @@
+/*
+* Copyright 2008 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.impl.xsect;
+
+import iaik.xml.crypto.XmldsigMore;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.Provider;
+import java.security.Signature;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.crypto.dsig.SignatureMethod;
+
+/**
+ * A security provider implementation that provides {@link Signature} implementations
+ * based on STAL.
+ *
+ * @author mcentner
+ */
+public class STALProvider extends Provider {
+
+ private static final long serialVersionUID = 1L;
+
+ private static String IMPL_PACKAGE_NAME = "at.gv.egiz.bku.slcommands.impl.xsect";
+
+ public STALProvider() {
+
+ super("STAL", 1.0, "Security Token Abstraction Layer Provider");
+
+ final Map map = new HashMap();
+
+ // TODO: register further algorithms
+ map.put("Signature." + SignatureMethod.RSA_SHA1,
+ IMPL_PACKAGE_NAME + ".STALSignature");
+ map.put("Signature." + XmldsigMore.SIGNATURE_ECDSA_SHA1,
+ IMPL_PACKAGE_NAME + ".STALSignature");
+
+ AccessController.doPrivileged(new PrivilegedAction() {
+ @Override
+ public Void run() {
+ putAll(map);
+ return null;
+ }
+ });
+
+ }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignature.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignature.java
new file mode 100644
index 00000000..f0fcb891
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignature.java
@@ -0,0 +1,165 @@
+/*
+* Copyright 2008 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.impl.xsect;
+
+import java.io.ByteArrayOutputStream;
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.SignatureSpi;
+import java.util.Collections;
+import java.util.List;
+
+import at.gv.egiz.stal.ErrorResponse;
+import at.gv.egiz.stal.STAL;
+import at.gv.egiz.stal.STALRequest;
+import at.gv.egiz.stal.STALResponse;
+import at.gv.egiz.stal.SignRequest;
+import at.gv.egiz.stal.SignResponse;
+import at.gv.egiz.stal.HashDataInputCallback;
+
+/**
+ * A signature service provider implementation that uses STAL to sign.
+ *
+ * @author mcentner
+ */
+public class STALSignature extends SignatureSpi {
+
+ /**
+ * The private key.
+ */
+ protected STALPrivateKey privateKey;
+
+ /**
+ * The to-be signed data.
+ */
+ protected ByteArrayOutputStream data = new ByteArrayOutputStream();
+
+ /* (non-Javadoc)
+ * @see java.security.SignatureSpi#engineGetParameter(java.lang.String)
+ */
+ @Override
+ protected Object engineGetParameter(String param)
+ throws InvalidParameterException {
+ throw new InvalidParameterException();
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.SignatureSpi#engineInitSign(java.security.PrivateKey)
+ */
+ @Override
+ protected void engineInitSign(PrivateKey privateKey)
+ throws InvalidKeyException {
+
+ if (!(privateKey instanceof STALPrivateKey)) {
+ throw new InvalidKeyException("STALSignature supports STALKeys only.");
+ }
+
+ this.privateKey = (STALPrivateKey) privateKey;
+
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.SignatureSpi#engineInitVerify(java.security.PublicKey)
+ */
+ @Override
+ protected void engineInitVerify(PublicKey publicKey)
+ throws InvalidKeyException {
+
+ throw new UnsupportedOperationException("STALSignature does not support signature verification.");
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.SignatureSpi#engineSetParameter(java.lang.String, java.lang.Object)
+ */
+ @Override
+ protected void engineSetParameter(String param, Object value)
+ throws InvalidParameterException {
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.SignatureSpi#engineSign()
+ */
+ @Override
+ protected byte[] engineSign() throws SignatureException {
+
+ STAL stal = privateKey.getStal();
+
+ if (stal == null) {
+ throw new SignatureException("STALSignature requires the STALPrivateKey " +
+ "to provide a STAL implementation reference.");
+ }
+
+ HashDataInputCallback signRefDataSupplier = privateKey.getHashDataInputCallback();
+
+ String keyboxIdentifier = privateKey.getKeyboxIdentifier();
+
+ if (keyboxIdentifier == null) {
+ throw new SignatureException("STALSignature requires the STALPrivateKey " +
+ "to provide a KeyboxIdentifier.");
+ }
+
+ SignRequest signRequest = new SignRequest();
+ signRequest.setKeyIdentifier(keyboxIdentifier);
+ signRequest.setSignedInfo(data.toByteArray());
+ signRequest.setHashDataInput(signRefDataSupplier);
+
+ List responses = stal.handleRequest(Collections.singletonList((STALRequest) signRequest));
+
+ if (responses == null || responses.size() != 1) {
+ throw new SignatureException("Failed to access STAL.");
+ }
+
+ STALResponse response = responses.get(0);
+ if (response instanceof SignResponse) {
+ return ((SignResponse) response).getSignatureValue();
+ } else if (response instanceof ErrorResponse) {
+ throw new STALSignatureException(((ErrorResponse) response).getErrorCode());
+ } else {
+ throw new SignatureException("Failed to access STAL.");
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.SignatureSpi#engineUpdate(byte)
+ */
+ @Override
+ protected void engineUpdate(byte b) throws SignatureException {
+ data.write(b);
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.SignatureSpi#engineUpdate(byte[], int, int)
+ */
+ @Override
+ protected void engineUpdate(byte[] b, int off, int len)
+ throws SignatureException {
+ data.write(b, off, len);
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.SignatureSpi#engineVerify(byte[])
+ */
+ @Override
+ protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
+ throw new UnsupportedOperationException("STALSignature des not support signature verification.");
+ }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureException.java
new file mode 100644
index 00000000..4e86b07c
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALSignatureException.java
@@ -0,0 +1,92 @@
+/*
+* Copyright 2008 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.impl.xsect;
+
+import java.security.SignatureException;
+
+/**
+ * A SignatureException thrown by the {@link STALSignature}.
+ *
+ * @author mcentner
+ */
+public class STALSignatureException extends SignatureException {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The STAL error code.
+ */
+ private int errorCode;
+
+ /**
+ * Creates a new instance of this STALSignatureException.
+ */
+ public STALSignatureException() {
+ }
+
+ /**
+ * Creates a new instance of this STALSigantureException with
+ * the given errorCode.
+ *
+ * @param errorCode the error code
+ */
+ public STALSignatureException(int errorCode) {
+ this.errorCode = errorCode;
+ }
+
+ /**
+ * Creates a new instance of this STALSignatureException with
+ * the given error msg.
+ *
+ * @param msg the error message
+ * @see SignatureException#SignatureException(String)
+ */
+ public STALSignatureException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * Creates a new instance of this STALSignatureException with
+ * the given root cause.
+ *
+ * @param cause the cause
+ * @see SignatureException#SignatureException(Throwable)
+ */
+ public STALSignatureException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Creates a new instance of this STALSignautureException with
+ * the given error message and root cause.
+ *
+ * @param message the error message
+ * @param cause the cause
+ * @see SignatureException#SignatureException(String, Throwable)
+ */
+ public STALSignatureException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * @return the error code
+ */
+ public int getErrorCode() {
+ return errorCode;
+ }
+
+}
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
new file mode 100644
index 00000000..94a4a066
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java
@@ -0,0 +1,935 @@
+/*
+* Copyright 2008 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.impl.xsect;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+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;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.dom.DOMStructure;
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.DigestMethod;
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.SignatureMethod;
+import javax.xml.crypto.dsig.SignedInfo;
+import javax.xml.crypto.dsig.XMLObject;
+import javax.xml.crypto.dsig.XMLSignature;
+import javax.xml.crypto.dsig.XMLSignatureException;
+import javax.xml.crypto.dsig.XMLSignatureFactory;
+import javax.xml.crypto.dsig.dom.DOMSignContext;
+import javax.xml.crypto.dsig.keyinfo.KeyInfo;
+import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
+import javax.xml.crypto.dsig.keyinfo.X509Data;
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.etsi.uri._01903.v1_1.DataObjectFormatType;
+import org.etsi.uri._01903.v1_1.QualifyingPropertiesType;
+import org.w3c.dom.DOMConfiguration;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSException;
+import org.w3c.dom.ls.LSInput;
+import org.w3c.dom.ls.LSOutput;
+import org.w3c.dom.ls.LSParser;
+import org.w3c.dom.ls.LSResourceResolver;
+import org.w3c.dom.ls.LSSerializer;
+
+import at.buergerkarte.namespaces.securitylayer._1.Base64XMLLocRefReqRefContentType;
+import at.buergerkarte.namespaces.securitylayer._1.Base64XMLOptRefContentType;
+import at.buergerkarte.namespaces.securitylayer._1.DataObjectAssociationType;
+import at.buergerkarte.namespaces.securitylayer._1.DataObjectInfoType;
+import at.buergerkarte.namespaces.securitylayer._1.SignatureInfoCreationType;
+import at.gv.egiz.bku.binding.HttpUtil;
+import at.gv.egiz.bku.slexceptions.SLCommandException;
+import at.gv.egiz.bku.slexceptions.SLRequestException;
+import at.gv.egiz.bku.utils.HexDump;
+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.slbinding.impl.XMLContentType;
+import at.gv.egiz.stal.HashDataInputCallback;
+import at.gv.egiz.stal.STAL;
+import at.gv.egiz.xades.QualifyingPropertiesException;
+import at.gv.egiz.xades.QualifyingPropertiesFactory;
+
+/**
+ * This class represents an XML-Signature as to be created by the
+ * security layer command CreateXMLSignatureRequest.
+ *
+ * @author mcentner
+ */
+public class Signature implements HashDataInputCallback {
+
+ /**
+ * Logging facility.
+ */
+ private static Log log = LogFactory.getLog(Signature.class);
+
+ /**
+ * The DOM implementation used.
+ */
+ private DOMImplementationLS domImplLS;
+
+ /**
+ * The SignatureContext for the XMLSignature.
+ */
+ private SignatureContext ctx;
+
+ /**
+ * The list of {@link DataObject}s for this signature.
+ */
+ private List dataObjects = new ArrayList();
+
+ /**
+ * A mapping from the Id-attribute values of this signature's
+ * ds:References to the corresponding {@link DataObject}s.
+ */
+ private Map dataObjectReferencIds = new HashMap();
+
+ /**
+ * The SignatureEnvironment for this signature.
+ */
+ private SignatureLocation signatureLocation;
+
+ /**
+ * The XML signature.
+ */
+ private XMLSignature xmlSignature;
+
+ /**
+ * A list of attributes of type xsd:ID to be registered in the {@link DOMSignContext}.
+ */
+ private List idAttributes = new ArrayList();
+
+ /**
+ * The signer's X509 certificate.
+ */
+ private X509Certificate signerCertificate;
+
+ /**
+ * The signing time.
+ */
+ private Date signingTime;
+
+ /**
+ * Creates a new SLXMLSignature instance.
+ */
+ public Signature(URLDereferencerContext dereferencerContext,
+ IdValueFactory idValueFactory,
+ AlgorithmMethodFactory algorithmMethodFactory) {
+
+ domImplLS = DOMUtils.getDOMImplementationLS();
+
+ ctx = new SignatureContext();
+
+ ctx.setSignatureFactory(XMLSignatureFactory.getInstance());
+
+ ctx.setDereferencerContext(dereferencerContext);
+ ctx.setIdValueFactory(idValueFactory);
+ ctx.setAlgorithmMethodFactory(algorithmMethodFactory);
+
+ }
+
+ /**
+ * @return the Document containing this Signature
+ */
+ public Document getDocument() {
+ return ctx.getDocument();
+ }
+
+ /**
+ * @return the parent Node for this Signature
+ */
+ public Node getParent() {
+ return (signatureLocation != null) ? signatureLocation.getParent() : null;
+ }
+
+ /**
+ * @return the next sibling Node for this Signature
+ */
+ public Node getNextSibling() {
+ return (signatureLocation != null) ? signatureLocation.getNextSibling() : null;
+ }
+
+ /**
+ * @return the XMLSignature
+ */
+ public XMLSignature getXMLSignature() {
+ return xmlSignature;
+ }
+
+ /**
+ * @return the list of {@link Reference}s of this Signature
+ */
+ @SuppressWarnings("unchecked")
+ public List getReferences() {
+ return (xmlSignature != null) ? xmlSignature.getSignedInfo().getReferences() : null;
+ }
+
+ /**
+ * @return the list of {@link XMLObject}s of this Signature
+ */
+ @SuppressWarnings("unchecked")
+ public List getXMLObjects() {
+ return (xmlSignature != null) ? xmlSignature.getObjects() : null;
+ }
+
+ /**
+ * Prepares the signature document with the information given by the
+ * signatureInfo provided.
+ *
+ * @param signatureInfo
+ * the SignatureInfo
+ *
+ * @throws SLCommandException
+ * if processing fails for any reason
+ * @throws IllegalStateException
+ * if the parent node has already been set
+ * @throws NullPointerException
+ * if signatureInfo is null
+ */
+ public void setSignatureInfo(SignatureInfoCreationType signatureInfo) throws SLCommandException {
+
+ if (signatureLocation != null) {
+ throw new IllegalStateException("SignatureEnvironment already set.");
+ }
+
+ Base64XMLOptRefContentType signatureEnvironment = signatureInfo.getSignatureEnvironment();
+
+ if (signatureEnvironment == null) {
+
+ // no SignatureEnvironment, so we use an empty document and the document as parent
+ ensureSignatureLocation();
+
+ } else {
+
+ // parse SignatureEnvrionment and use as document
+ Document document = parseSignatureEnvironment(signatureEnvironment, signatureInfo.getSupplement());
+ ctx.setDocument(document);
+
+ signatureLocation = new SignatureLocation(ctx);
+ signatureLocation.setSignatureInfo(signatureInfo);
+
+ }
+
+ }
+
+ /**
+ * Ensures a SignatureLocation for this Signature.
+ */
+ private void ensureSignatureLocation() {
+
+ if (signatureLocation == null) {
+ Document document = DOMUtils.createDocument();
+ ctx.setDocument(document);
+
+ signatureLocation = new SignatureLocation(ctx);
+ signatureLocation.setParent(document);
+ }
+
+ }
+
+ /**
+ * Adds a DataObject with the information given by the
+ * dataObjectInfo provided to this Signature.
+ *
+ * @param dataObjectInfo
+ * the DataObjectInfo element
+ *
+ * @throws SLCommandException
+ * if adding the DataObject fails
+ * @throws SLRequestException
+ * if the information provided by the given
+ * dataObjectInfo does not conform to the security
+ * layer specification
+ * @throws NullPointerException
+ * if dataObjectInfo is null
+ */
+ public void addDataObject(DataObjectInfoType dataObjectInfo) throws SLCommandException, SLRequestException {
+
+ ensureSignatureLocation();
+
+ DataObject dataObject = new DataObject(ctx);
+ dataObject.setDataObjectInfo(dataObjectInfo);
+
+ dataObjects.add(dataObject);
+
+ dataObjectReferencIds.put(dataObject.getReference().getId(), dataObject);
+
+ }
+
+ /**
+ * Sets the SigningTime qualifying property of this Signature.
+ *
+ * @param signingTime the signing time to set
+ */
+ public void setSigningTime(Date signingTime) {
+ this.signingTime = signingTime;
+ }
+
+ /**
+ * Sets the SignerCertificate qualifying property of this Signature.
+ *
+ * @param certificate the signer's certificate
+ */
+ public void setSignerCeritifcate(X509Certificate certificate) {
+ this.signerCertificate = certificate;
+ }
+
+ /**
+ * Builds the XMLSignature data structure of this Signature as configured by
+ * the various setter methods.
+ *
+ * @throws SLCommandException if building this signature fails
+ */
+ public void buildXMLSignature() throws SLCommandException {
+
+ List objects = new ArrayList();
+ List references = new ArrayList();
+
+ // add all data objects
+ for (DataObject dataObject : dataObjects) {
+ if (dataObject.getXmlObject() != null) {
+ objects.add(dataObject.getXmlObject());
+ }
+ if (dataObject.getReference() != null) {
+ references.add(dataObject.getReference());
+ }
+ }
+
+ addXAdESObjectAndReference(objects, references);
+
+ XMLSignatureFactory signatureFactory = ctx.getSignatureFactory();
+ AlgorithmMethodFactory algorithmMethodFactory = ctx.getAlgorithmMethodFactory();
+
+ CanonicalizationMethod cm;
+ SignatureMethod sm;
+ try {
+ cm = algorithmMethodFactory.createCanonicalizationMethod(ctx);
+ sm = algorithmMethodFactory.createSignatureMethod(ctx);
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Failed to get Canonicalization or Signature algorithm.", e);
+ throw new SLCommandException(4006);
+ } catch (InvalidAlgorithmParameterException e) {
+ log.error("Failed to get Canonicalization or Signature algorithm.", e);
+ throw new SLCommandException(4006);
+ }
+
+ String siId = ctx.getIdValueFactory().createIdValue("SignedInfo");
+
+ SignedInfo si = signatureFactory.newSignedInfo(cm, sm, references, siId);
+
+ KeyInfo ki = null;
+ if (signerCertificate != null) {
+ KeyInfoFactory kif = KeyInfoFactory.getInstance();
+ X509Data x509Data = kif.newX509Data(Collections.singletonList(signerCertificate));
+ 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);
+
+ }
+
+ /**
+ * Sign this Signature using the given signContext.
+ *
+ * Call's {@link #buildXMLSignature()} if it has not been called yet.
+ *
+ *
+ * @param signContext
+ * the signing context
+ *
+ * @throws MarshalException
+ * if marshalling the XMLSignature fails
+ * @throws XMLSignatureException
+ * if signing the XMLSignature fails
+ * @throws SLCommandException
+ * if building the XMLSignature fails
+ * @throws NullPointerException
+ * if signContext is null
+ */
+ public void sign(DOMSignContext signContext) throws MarshalException, XMLSignatureException, SLCommandException {
+
+ if (xmlSignature == null) {
+ buildXMLSignature();
+ }
+
+ for (IdAttribute idAttribute : idAttributes) {
+ signContext.setIdAttributeNS(idAttribute.element, idAttribute.namespaceURI, idAttribute.localName);
+ }
+
+ // DO NOT USE:
+ // signContext.setProperty("iaik.xml.crypto.dsig.sign-over", Boolean.TRUE);
+
+ signContext.setProperty("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE);
+
+ signContext.putNamespacePrefix(XMLSignature.XMLNS, "dsig");
+
+ signContext.setURIDereferencer(new URIDereferncerAdapter(ctx.getDereferencerContext()));
+
+ try {
+ xmlSignature.sign(signContext);
+ } catch (XMLSignatureException e) {
+ Throwable cause = e.getCause();
+ while (cause != null) {
+ if (cause instanceof STALSignatureException) {
+ int errorCode = ((STALSignatureException) cause).getErrorCode();
+ SLCommandException commandException = new SLCommandException(errorCode);
+ log.info("Failed to sign signature.", commandException);
+ throw commandException;
+ } else {
+ cause = cause.getCause();
+ }
+ }
+ throw e;
+ }
+
+ // debug
+ if (log.isTraceEnabled()) {
+ for (DataObject dataObject : dataObjects) {
+ Reference reference = dataObject.getReference();
+ InputStream digestInputStream = reference.getDigestInputStream();
+ if (digestInputStream != null) {
+ String mimeType = dataObject.getMimeType();
+ StringBuilder sb = new StringBuilder();
+ sb.append("DigestInput for Reference with id='");
+ sb.append(reference.getId());
+ sb.append("' (MIME-Type=");
+ sb.append(dataObject.getMimeType());
+ sb.append("):\n");
+ try {
+ if (mimeType != null && (
+ mimeType.startsWith("text") ||
+ "application/xhtml+xml".equals(mimeType))) {
+ byte[] b = new byte[512];
+ for (int l; (l = digestInputStream.read(b)) != -1;) {
+ sb.append(new String(b, 0, l));
+ }
+ } else {
+ sb.append(HexDump.hexDump(digestInputStream));
+ }
+ } catch (IOException e) {
+ log.error(e);
+ }
+ log.trace(sb.toString());
+ } else {
+ log.trace("Reference caching is not enabled.");
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Sign this Signature using the given stal implementation and
+ * keyboxIdentifier.
+ *
+ * This method configures an appropriate {@link DOMSignContext} and calls
+ * {@link #sign(DOMSignContext)}. If {@link #buildXMLSignature()} has not been
+ * called yet, it is called by this method.
+ *
+ *
+ * @param stal
+ * the STAL implementation to use
+ * @param keyboxIdentifier
+ * the KeyboxIdentifier to use
+ *
+ * @throws MarshalException
+ * if marshalling this Signature fails
+ * @throws XMLSignatureException
+ * if signing this Signature fails
+ * @throws SLCommandException
+ * if building this Signature fails
+ * @throws NullPointerException
+ * if stal or keyboxIdentifier is
+ * null
+ */
+ public void sign(STAL stal, String keyboxIdentifier) throws MarshalException, XMLSignatureException, SLCommandException {
+
+ if (stal == null) {
+ throw new NullPointerException("Argument 'stal' must not be null.");
+ }
+
+ if (keyboxIdentifier == null) {
+ throw new NullPointerException("Argument 'keyboxIdentifier' must not be null.");
+ }
+
+ if (xmlSignature == null) {
+ buildXMLSignature();
+ }
+
+ SignatureMethod signatureMethod = xmlSignature.getSignedInfo().getSignatureMethod();
+ String algorithm = signatureMethod.getAlgorithm();
+
+ PrivateKey privateKey = new STALPrivateKey(stal, algorithm, keyboxIdentifier, this);
+
+ DOMSignContext signContext;
+ if (getNextSibling() == null) {
+ signContext = new DOMSignContext(privateKey, getParent());
+ } else {
+ signContext = new DOMSignContext(privateKey, getParent(), getNextSibling());
+ }
+
+ sign(signContext);
+ }
+
+ @Override
+ public InputStream getHashDataInput(String referenceId) {
+
+ DataObject dataObject = dataObjectReferencIds.get(referenceId);
+ if (dataObject != null) {
+ return dataObject.getReference().getDigestInputStream();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Adds the XAdES QualifyingProperties as an
+ * ds:Object and a corresponding ds:Reference to
+ * it's SignedProperties element to this Signature.
+ *
+ * @param objects
+ * the list of ds:Objects to add the created
+ * ds:Object to
+ * @param references
+ * the list of ds:References to add the created
+ * ds:Reference to
+ *
+ * @throws SLCommandException
+ * if creating and adding the XAdES
+ * QualifyingProperties fails
+ * @throws NullPointerException
+ * if objects or references is
+ * null
+ */
+ private void addXAdESObjectAndReference(List objects, List references) throws SLCommandException {
+
+ QualifyingPropertiesFactory factory = QualifyingPropertiesFactory.getInstance();
+
+ String idValue = ctx.getIdValueFactory().createIdValue("SignedProperties");
+
+ Date date = (signingTime != null) ? signingTime : new Date();
+
+ List signingCertificates;
+ if (signerCertificate != null) {
+ signingCertificates = Collections.singletonList(signerCertificate);
+ } else {
+ signingCertificates = Collections.emptyList();
+ }
+
+ // TODO: report MOA-SP bug
+ //
+ // The security layer specification mandates the use of version 1.2.2. of the
+ // XAdES QualifyingProperties. However MOA-SP supports only version 1.1.1. Therefore,
+ // the version 1.1.1 is used in order to be compatible with current MOA-SP versions.
+
+ List dataObjectFormats = new ArrayList();
+ for (DataObject dataObject : dataObjects) {
+ if (dataObject.getMimeType() != null && dataObject.getReference() != null) {
+ Reference reference = dataObject.getReference();
+ if (reference.getId() != null) {
+ String objectReference = "#" + reference.getId();
+ dataObjectFormats.add(factory.createDataObjectFormatType(
+ objectReference, dataObject.getMimeType(), dataObject
+ .getDescription()));
+ }
+ }
+ }
+
+ JAXBElement qualifyingProperties;
+ try {
+ qualifyingProperties = factory.createQualifyingProperties111(date, signingCertificates, idValue, dataObjectFormats);
+ } catch (QualifyingPropertiesException e) {
+ log.error("Failed to create QualifyingProperties.", e);
+ throw new SLCommandException(4000);
+ }
+
+ DocumentFragment fragment = ctx.getDocument().createDocumentFragment();
+
+ try {
+ factory.marshallQualifyingProperties(qualifyingProperties, fragment);
+ } catch (JAXBException e) {
+ log.error("Failed to marshal QualifyingProperties.", e);
+ throw new SLCommandException(4000);
+ }
+
+ List content = Collections.singletonList(new DOMStructure(fragment.getFirstChild()));
+
+ String objectIdValue = ctx.getIdValueFactory().createIdValue("Object");
+
+ XMLObject object = ctx.getSignatureFactory().newXMLObject(content, objectIdValue, null, null);
+
+ objects.add(object);
+
+ // TODO: Report MOA-SP Bug
+ //
+ // Direct referencing of the SignedPorperties Id-attribute is not supported by MOA-SP
+ // because the QualifyingProperties are parsed without the XAdES schema. Therefore,
+ // the shorthand XPointer could not be resolved.
+ //
+ // The following workaround uses an XPointer to select the SignedProperties in order
+ // to allow the signature to be verified with MOA-SP.
+
+ String referenceURI = "#xmlns(xades=http://uri.etsi.org/01903/v1.1.1%23)%20xpointer(id('"
+ + objectIdValue
+ + "')/child::xades:QualifyingProperties/child::xades:SignedProperties)";
+ DigestMethod dm;
+ try {
+ dm = ctx.getAlgorithmMethodFactory().createDigestMethod(ctx);
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Failed to get DigestMethod algorithm.", e);
+ throw new SLCommandException(4006);
+ } catch (InvalidAlgorithmParameterException e) {
+ log.error("Failed to get DigestMethod algorithm.", e);
+ throw new SLCommandException(4006);
+ }
+
+ String referenceIdValue = ctx.getIdValueFactory().createIdValue("Reference");
+ String referenceType = QualifyingPropertiesFactory.SIGNED_PROPERTIES_REFERENCE_TYPE_V1_1_1;
+
+ Reference reference = ctx.getSignatureFactory().newReference(referenceURI, dm, null, referenceType, referenceIdValue);
+
+ references.add(reference);
+
+ Node child = fragment.getFirstChild();
+ if (child instanceof Element) {
+ NodeList nodes = ((Element) child).getElementsByTagNameNS(QualifyingPropertiesFactory.NS_URI_V1_1_1, "SignedProperties");
+ if (nodes.getLength() > 0) {
+ IdAttribute idAttribute = new IdAttribute();
+ idAttribute.element = (Element) nodes.item(0);
+ idAttribute.namespaceURI = null;
+ idAttribute.localName = "Id";
+ idAttributes.add(idAttribute);
+ }
+ }
+
+ }
+
+ /**
+ * Parse the SignatureEnvironment.
+ *
+ * @param signatureEnvironment
+ * the SignatureEnvironment element
+ * @param supplements
+ * an optional list of Supplements (may be
+ * null)
+ *
+ * @return the parsed SignatureEnvironment document
+ *
+ * @throws SLCommandException
+ * if parsing the SignatureEnvironment fails
+ * @throws NullPointerException
+ * if signatureEnvironment is null
+ */
+ private Document parseSignatureEnvironment(
+ Base64XMLOptRefContentType signatureEnvironment,
+ List supplements) throws SLCommandException {
+
+ if (signatureEnvironment == null) {
+ throw new NullPointerException("Argument 'signatureEnvironment' must not be null.");
+ }
+
+ LSInput input;
+ try {
+ if (signatureEnvironment.getReference() != null) {
+ log.debug("SignatureEnvironment contains Reference " + signatureEnvironment.getReference() + ".");
+ input = createLSInput(signatureEnvironment.getReference());
+ } else if (signatureEnvironment.getBase64Content() != null) {
+ log.debug("SignatureEnvironment contains Base64Content.");
+ input = createLSInput(signatureEnvironment.getBase64Content());
+ } else if (signatureEnvironment.getXMLContent() != null) {
+ log.debug("SignatureEnvironment contains XMLContent.");
+ input = createLSInput((XMLContentType) signatureEnvironment.getXMLContent());
+ } else {
+ // the schema does not allow us to reach this point
+ throw new SLCommandException(4000);
+ }
+ } catch (IOException e) {
+ log.info("XML document in which the signature is to be integrated cannot be resolved.", e);
+ throw new SLCommandException(4100);
+ } catch (XMLStreamException e) {
+ log.info("XML document in which the signature is to be integrated cannot be resolved.", e);
+ throw new SLCommandException(4100);
+ }
+
+ LSParser parser = domImplLS.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
+ DOMConfiguration domConfig = parser.getDomConfig();
+ SimpleDOMErrorHandler errorHandler = new SimpleDOMErrorHandler();
+ domConfig.setParameter("error-handler", errorHandler);
+ LSResourceResolverAdapter resourceResolver = new LSResourceResolverAdapter(supplements);
+ domConfig.setParameter("resource-resolver", resourceResolver);
+ domConfig.setParameter("validate", Boolean.TRUE);
+
+ Document doc;
+ try {
+ doc = parser.parse(input);
+ } catch (DOMException e) {
+ log.info("XML document in which the signature is to be integrated cannot be parsed.", e);
+ throw new SLCommandException(4101);
+ } catch (LSException e) {
+ log.info("XML document in which the signature is to be integrated cannot be parsed.", e);
+ throw new SLCommandException(4101);
+ }
+
+ if (resourceResolver.getError() != null) {
+ log.info("Failed to resolve resource while parsing SignatureEnvironment document.", resourceResolver.getError());
+ // we don't stop here, as we only _try_ to parse validating
+ }
+
+ if (errorHandler.hasFatalErrors()) {
+ // log fatal errors
+ if (log.isInfoEnabled()) {
+ List errorMessages = errorHandler.getErrorMessages();
+ StringBuffer sb = new StringBuffer();
+ for (String errorMessage : errorMessages) {
+ sb.append(" ");
+ sb.append(errorMessage);
+ }
+ log.info("XML document in which the signature is to be integrated cannot be parsed." + sb.toString());
+ }
+ throw new SLCommandException(4101);
+ }
+
+ // log parsed document
+ if (log.isTraceEnabled()) {
+
+ StringWriter writer = new StringWriter();
+
+ writer.write("SignatureEnvironment:\n");
+
+ LSOutput output = domImplLS.createLSOutput();
+ output.setCharacterStream(writer);
+ output.setEncoding("UTF-8");
+ LSSerializer serializer = domImplLS.createLSSerializer();
+ serializer.write(doc, output);
+
+ log.trace(writer.toString());
+ }
+
+ return doc;
+
+ }
+
+ /**
+ * Creates an LSInput from the given reference URI.
+ *
+ * @param reference
+ * the reference URL
+ *
+ * @return an LSInput from the given reference URI
+ *
+ * @throws IOException
+ * if dereferencing the given reference fails
+ */
+ private LSInput createLSInput(String reference) throws IOException {
+
+ URLDereferencer urlDereferencer = URLDereferencer.getInstance();
+ StreamData streamData = urlDereferencer.dereference(reference, ctx.getDereferencerContext());
+
+ String contentType = streamData.getContentType();
+ String charset = HttpUtil.getCharset(contentType, true);
+ InputStreamReader streamReader;
+ try {
+ streamReader = new InputStreamReader(streamData.getStream(), charset);
+ } catch (UnsupportedEncodingException e) {
+ log.info("Charset " + charset + " not supported. Using default.");
+ streamReader = new InputStreamReader(streamData.getStream());
+ }
+
+ LSInput input = domImplLS.createLSInput();
+ input = domImplLS.createLSInput();
+ input.setCharacterStream(streamReader);
+
+ return input;
+
+ }
+
+ /**
+ * Creates an LSInput from the given content bytes.
+ *
+ * @param content
+ * the content bytes
+ *
+ * @return an LSInput from the givne content bytes
+ */
+ private LSInput createLSInput(byte[] content) {
+
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(content);
+ LSInput input = domImplLS.createLSInput();
+ input.setByteStream(inputStream);
+
+ return input;
+
+ }
+
+ /**
+ * Creates an LSInput from the given XML content.
+ *
+ * @param content
+ * the XML content
+ * @return an LSInput from the given XML content
+ *
+ * @throws XMLStreamException
+ * if reading the XMLStream from the given XML content fails
+ */
+ private LSInput createLSInput(XMLContentType content) throws XMLStreamException {
+
+ ByteArrayOutputStream redirectedStream = content.getRedirectedStream();
+ if (redirectedStream != null) {
+ LSInput input = domImplLS.createLSInput();
+ input.setByteStream(new ByteArrayInputStream(redirectedStream.toByteArray()));
+ return input;
+ } else {
+ return null;
+ }
+
+ }
+
+ /**
+ * Represents an xsd:Id-attribute value.
+ *
+ * @author mcentner
+ */
+ private class IdAttribute {
+
+ private Element element;
+
+ private String namespaceURI;
+
+ private String localName;
+
+ }
+
+ /**
+ * An implementation of the LSResourceResolver that uses a list of supplements
+ * to resolve resources.
+ *
+ * @author mcentner
+ */
+ private class LSResourceResolverAdapter implements LSResourceResolver {
+
+ List supplements;
+
+ private LSResourceResolverAdapter(
+ List supplements) {
+ this.supplements = supplements;
+ }
+
+ private Exception error;
+
+ /**
+ * @return the error
+ */
+ public Exception getError() {
+ return error;
+ }
+
+ @Override
+ public LSInput resolveResource(String type, String namespaceURI,
+ String publicId, String systemId, String baseURI) {
+
+ if (log.isTraceEnabled()) {
+ log.trace("Resolve resource :" +
+ "\n type=" + type +
+ "\n namespaceURI=" + namespaceURI +
+ "\n publicId=" + publicId +
+ "\n systemId=" + systemId +
+ "\n baseURI=" + baseURI);
+ }
+
+ if (systemId != null) {
+
+ log.debug("Resolve resource '" + systemId + "'.");
+
+ for (DataObjectAssociationType supplement : supplements) {
+
+ Base64XMLLocRefReqRefContentType content = supplement.getContent();
+ if (content != null) {
+
+ String reference = content.getReference();
+ if (systemId.equals(reference)) {
+
+ try {
+ if (content.getLocRefContent() != null) {
+ log.trace("Resolved resource '" + reference + "' to supplement with LocRefContent.");
+ return createLSInput(content.getLocRefContent());
+ } else if (content.getBase64Content() != null) {
+ log.trace("Resolved resource '" + reference + "' to supplement with Base64Content.");
+ return createLSInput(content.getBase64Content());
+ } else if (content.getXMLContent() != null) {
+ log.trace("Resolved resource '" + reference + "' to supplement with XMLContent.");
+ return createLSInput((XMLContentType) content.getXMLContent());
+ } else {
+ return null;
+ }
+ } catch (IOException e) {
+ log.info("Failed to resolve resource '" + systemId + "' to supplement.", e);
+ error = e;
+ return null;
+ } catch (XMLStreamException e) {
+ log.info("Failed to resolve resource '" + systemId + "' to supplement.", e);
+ error = e;
+ return null;
+ }
+
+ }
+
+ }
+
+ }
+
+ log.info("Failed to resolve resource '" + systemId + "' to supplement. No such supplement.");
+
+ }
+
+ return null;
+
+ }
+
+
+ }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureContext.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureContext.java
new file mode 100644
index 00000000..0925f2fd
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureContext.java
@@ -0,0 +1,129 @@
+/*
+* Copyright 2008 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.impl.xsect;
+
+import javax.xml.crypto.dsig.DigestMethod;
+import javax.xml.crypto.dsig.XMLSignatureFactory;
+
+import org.w3c.dom.Document;
+
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext;
+
+/**
+ * An instance of this class carries context information for a XML-Signature
+ * created by the security layer command CreateXMLSignature.
+ *
+ * @author mcentner
+ */
+public class SignatureContext {
+
+ /**
+ * The document going to contain the XML signature.
+ */
+ private Document document;
+
+ /**
+ * The IdValueFactory used to create xsd:ID-attribute values.
+ */
+ private IdValueFactory idValueFactory;
+
+ /**
+ * The XMLSignatureFactory to create XML signature objects.
+ */
+ private XMLSignatureFactory signatureFactory;
+
+ /**
+ * The URLDereferencerContext for dereferencing URLs.
+ */
+ private URLDereferencerContext dereferencerContext;
+
+ /**
+ * The DigestMethodFactory to create {@link DigestMethod} objects.
+ */
+ private AlgorithmMethodFactory digestMethodFactory;
+
+ /**
+ * @return the document
+ */
+ public Document getDocument() {
+ return document;
+ }
+
+ /**
+ * @param document the document to set
+ */
+ public void setDocument(Document document) {
+ this.document = document;
+ }
+
+ /**
+ * @return the idValueFactory
+ */
+ public IdValueFactory getIdValueFactory() {
+ return idValueFactory;
+ }
+
+ /**
+ * @param idValueFactory the idValueFactory to set
+ */
+ public void setIdValueFactory(IdValueFactory idValueFactory) {
+ this.idValueFactory = idValueFactory;
+ }
+
+ /**
+ * @return the signatureFactory
+ */
+ public XMLSignatureFactory getSignatureFactory() {
+ return signatureFactory;
+ }
+
+ /**
+ * @param signatureFactory the signatureFactory to set
+ */
+ public void setSignatureFactory(XMLSignatureFactory signatureFactory) {
+ this.signatureFactory = signatureFactory;
+ }
+
+ /**
+ * @return the dereferencerContext
+ */
+ public URLDereferencerContext getDereferencerContext() {
+ return dereferencerContext;
+ }
+
+ /**
+ * @param dereferencerContext the dereferencerContext to set
+ */
+ public void setDereferencerContext(URLDereferencerContext dereferencerContext) {
+ this.dereferencerContext = dereferencerContext;
+ }
+
+ /**
+ * @return the digestMethodFactory
+ */
+ public AlgorithmMethodFactory getAlgorithmMethodFactory() {
+ return digestMethodFactory;
+ }
+
+ /**
+ * @param digestMethodFactory the digestMethodFactory to set
+ */
+ public void setAlgorithmMethodFactory(AlgorithmMethodFactory digestMethodFactory) {
+ this.digestMethodFactory = digestMethodFactory;
+ }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureLocation.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureLocation.java
new file mode 100644
index 00000000..5ec02893
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureLocation.java
@@ -0,0 +1,235 @@
+/*
+* Copyright 2008 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.impl.xsect;
+
+import java.util.Iterator;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import at.buergerkarte.namespaces.securitylayer._1.SignatureInfoCreationType;
+import at.gv.egiz.bku.slexceptions.SLCommandException;
+import at.gv.egiz.slbinding.impl.SignatureLocationType;
+
+/**
+ * This class implements the SignatureLocation of an XML-Signature
+ * to be created by the security layer command CreateXMLSignature.
+ *
+ * @author mcentner
+ */
+public class SignatureLocation {
+
+ /**
+ * Logging facility.
+ */
+ private static Log log = LogFactory.getLog(SignatureLocation.class);
+
+ /**
+ * The SignatureContext for the XML signature
+ */
+ private SignatureContext ctx;
+
+ /**
+ * The parent node for the XML signature.
+ */
+ private Node parent;
+
+ /**
+ * The next sibling node for the XML signature.
+ */
+ private Node nextSibling;
+
+ /**
+ * Creates a new SignatureLocation with the given signatureContext
+ *
+ * @param signatureContext the context for the XML signature creation
+ */
+ public SignatureLocation(SignatureContext signatureContext) {
+ this.ctx = signatureContext;
+ }
+
+ /**
+ * @return the parent node for the XML signature
+ */
+ public Node getParent() {
+ return parent;
+ }
+
+ /**
+ * @param parent the parent for the XML signature
+ */
+ public void setParent(Node parent) {
+ this.parent = parent;
+ }
+
+ /**
+ * @return the next sibling node for the XML signature
+ */
+ public Node getNextSibling() {
+ return nextSibling;
+ }
+
+ /**
+ * @param nextSibling the next sibling node for the XML signature
+ */
+ public void setNextSibling(Node nextSibling) {
+ this.nextSibling = nextSibling;
+ }
+
+ /**
+ * Configures this SignatureLocation with the information provided by the
+ * given SignatureInfo element.
+ *
+ * @param signatureInfo
+ * the SignatureInfo element
+ *
+ * @throws SLCommandException
+ * if configuring this SignatureLocation with given
+ * signatureInfofails
+ */
+ public void setSignatureInfo(SignatureInfoCreationType signatureInfo)
+ throws SLCommandException {
+
+ // evaluate signature location XPath ...
+ SignatureLocationType signatureLocation = (SignatureLocationType) signatureInfo
+ .getSignatureLocation();
+
+ NamespaceContext namespaceContext = new MOAIDWorkaroundNamespaceContext(
+ signatureLocation.getNamespaceContext());
+
+ parent = evaluateSignatureLocation(signatureInfo.getSignatureLocation()
+ .getValue(), namespaceContext, ctx.getDocument().getDocumentElement());
+
+ // ... and index
+ nextSibling = findNextSibling(parent, signatureInfo.getSignatureLocation()
+ .getIndex().intValue());
+
+ }
+
+ /**
+ * Evaluates the given xpath with the document element as context node
+ * and returns the resulting node.
+ *
+ * @param xpath the XPath expression
+ * @param nsContext the namespace context of the XPath expression
+ * @param contextNode the context node for the XPath evaluation
+ *
+ * @return the result of evaluating the XPath expression
+ *
+ * @throws SLCommandException
+ */
+ private Node evaluateSignatureLocation(String xpath, NamespaceContext nsContext, Node contextNode) throws SLCommandException {
+
+ Node node = null;
+ try {
+ XPathFactory xpathFactory = XPathFactory.newInstance();
+ XPath xPath = xpathFactory.newXPath();
+ xPath.setNamespaceContext(nsContext);
+ XPathExpression xpathExpr = xPath.compile(xpath);
+ node = (Node) xpathExpr.evaluate(contextNode, XPathConstants.NODE);
+ } catch (XPathExpressionException e) {
+ log.info("Failed to evaluate SignatureLocation XPath expression '" + xpath + "' on context node.", e);
+ throw new SLCommandException(4102);
+ }
+
+ if (node == null) {
+ log.info("Failed to evaluate SignatureLocation XPath expression '" + xpath + "'. Result is empty.");
+ throw new SLCommandException(4102);
+ }
+
+ return node;
+
+ }
+
+ /**
+ * Finds the next sibling node of the parent's n-th child node
+ * or null if there is no next sibling.
+ *
+ * @param parent the parent node
+ * @param n the index of the child node
+ *
+ * @return the next sibling node of the node specified by parent and index n,
+ * or null if there is no next sibling node.
+ *
+ * @throws SLCommandException if the n-th child of parent does not exist
+ */
+ private Node findNextSibling(Node parent, int n) throws SLCommandException {
+
+ NodeList childNodes = parent.getChildNodes();
+ Node childNode = childNodes.item(n);
+ if (childNode == null) {
+ log.info("SingatureLocation Index '" + n + "' not found in document.");
+ throw new SLCommandException(4102);
+ } else {
+ return childNode.getNextSibling();
+ }
+
+ }
+
+ /**
+ * Workaround for a missing namespace prefix declaration in MOA-ID.
+ *
+ * @author mcentner
+ */
+ private class MOAIDWorkaroundNamespaceContext implements NamespaceContext {
+
+ private NamespaceContext namespaceContext;
+
+ public MOAIDWorkaroundNamespaceContext(NamespaceContext namespaceContext) {
+ super();
+ this.namespaceContext = namespaceContext;
+ }
+
+ @Override
+ public String getNamespaceURI(String prefix) {
+
+ String namespaceURI = namespaceContext.getNamespaceURI(prefix);
+
+ if ((namespaceURI == null || XMLConstants.NULL_NS_URI.equals(namespaceURI)) && "saml".equals(prefix)) {
+ namespaceURI = "urn:oasis:names:tc:SAML:1.0:assertion";
+ log.debug("Namespace prefix '" + prefix + "' resolved to '" + namespaceURI + "' (MOA-ID Workaround).");
+ } else {
+ log.trace("Namespace prefix '" + prefix + "' resolved to '" + namespaceURI + "'.");
+ }
+
+ return namespaceURI;
+ }
+
+ @Override
+ public String getPrefix(String namespaceURI) {
+ return namespaceContext.getPrefix(namespaceURI);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Iterator getPrefixes(String namespaceURI) {
+ return namespaceContext.getPrefixes(namespaceURI);
+ }
+
+ }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SimpleDOMErrorHandler.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SimpleDOMErrorHandler.java
new file mode 100644
index 00000000..0d54adce
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/SimpleDOMErrorHandler.java
@@ -0,0 +1,98 @@
+/*
+* Copyright 2008 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.impl.xsect;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.DOMError;
+import org.w3c.dom.DOMErrorHandler;
+
+/**
+ * A simple DOMErrorHandler implementation.
+ *
+ * @author mcentner
+ */
+public class SimpleDOMErrorHandler implements DOMErrorHandler {
+
+ /**
+ * Have there been errors reported?
+ */
+ private boolean errors = false;
+
+ /**
+ * Have there been fatal error reported?
+ */
+ private boolean fatalErrors = false;
+
+ /**
+ * The list of error messages of reported errors.
+ */
+ private List errorMessages = new ArrayList();
+
+ /**
+ * @return true if errors have been reported, or false otherwise
+ */
+ public boolean hasErrors() {
+ return errors;
+ }
+
+ /**
+ * @return true if fatal errors have been reported, or false otherwise
+ */
+ public boolean hasFatalErrors() {
+ return fatalErrors;
+ }
+
+ /**
+ * @return a list of error messages that have been reported
+ */
+ public List getErrorMessages() {
+ return errorMessages;
+ }
+
+ /* (non-Javadoc)
+ * @see org.w3c.dom.DOMErrorHandler#handleError(org.w3c.dom.DOMError)
+ */
+ @Override
+ public boolean handleError(DOMError error) {
+
+ switch (error.getSeverity()) {
+
+ case DOMError.SEVERITY_WARNING :
+// log.debug("[warning] " + error.getMessage());
+ return true;
+
+ case DOMError.SEVERITY_ERROR :
+// log.debug("[error] " + error.getMessage());
+ errorMessages.add(error.getMessage());
+ errors = true;
+ return false;
+
+ case DOMError.SEVERITY_FATAL_ERROR :
+// log.debug("[fatal error] " + error.getMessage());
+ errorMessages.add(error.getMessage());
+ fatalErrors = true;
+ return false;
+
+ default:
+ return false;
+ }
+
+ }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/URIDereferncerAdapter.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/URIDereferncerAdapter.java
new file mode 100644
index 00000000..c94937be
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/URIDereferncerAdapter.java
@@ -0,0 +1,103 @@
+/*
+* Copyright 2008 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.impl.xsect;
+
+import iaik.xml.crypto.utils.URIDereferencerImpl;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import javax.xml.crypto.Data;
+import javax.xml.crypto.OctetStreamData;
+import javax.xml.crypto.URIDereferencer;
+import javax.xml.crypto.URIReference;
+import javax.xml.crypto.URIReferenceException;
+import javax.xml.crypto.XMLCryptoContext;
+
+import at.gv.egiz.bku.utils.urldereferencer.StreamData;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext;
+
+/**
+ * An URIDereferencer implementation that uses an {@link URLDereferencer} to
+ * dereference.
+ *
+ * @author mcentner
+ */
+public class URIDereferncerAdapter implements URIDereferencer {
+
+ /**
+ * The context for dereferencing.
+ */
+ protected URLDereferencerContext urlDereferencerContext;
+
+ /**
+ * Creates a new URIDereferencerAdapter instance with the given
+ * urlDereferencerContext.
+ *
+ * @param urlDereferencerContext the context to be used for dereferencing
+ */
+ public URIDereferncerAdapter(URLDereferencerContext urlDereferencerContext) {
+ super();
+ this.urlDereferencerContext = urlDereferencerContext;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.xml.crypto.URIDereferencer#dereference(javax.xml.crypto.URIReference, javax.xml.crypto.XMLCryptoContext)
+ */
+ @Override
+ public Data dereference(URIReference uriReference, XMLCryptoContext context)
+ throws URIReferenceException {
+
+ String uriString = uriReference.getURI();
+ if (uriString == null) {
+ return null;
+ }
+
+ URI uri;
+ try {
+ uri = new URI(uriString);
+ } catch (URISyntaxException e) {
+ throw new URIReferenceException(e.getMessage(), e);
+ }
+
+ if (uri.isAbsolute()) {
+
+ URLDereferencer dereferencer = URLDereferencer.getInstance();
+ StreamData streamData;
+ try {
+ streamData = dereferencer.dereference(uriString, urlDereferencerContext);
+ } catch (IOException e) {
+ throw new URIReferenceException(e.getMessage(), e);
+ }
+ return new OctetStreamData(streamData.getStream(), uriString, streamData.getContentType());
+
+ } else {
+
+ URIDereferencer uriDereferencer = context.getURIDereferencer();
+ if (uriDereferencer == null || uriDereferencer == this) {
+ uriDereferencer = new URIDereferencerImpl();
+ }
+
+ return uriDereferencer.dereference(uriReference, context);
+
+ }
+
+ }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/XSECTReference.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/XSECTReference.java
new file mode 100644
index 00000000..6b388f2a
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/XSECTReference.java
@@ -0,0 +1,112 @@
+/*
+* Copyright 2008 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.impl.xsect;
+
+import iaik.xml.crypto.dsig.DigestMethodImpl;
+import iaik.xml.crypto.dsig.DigestValueImpl;
+import iaik.xml.crypto.dsig.ReferenceImpl;
+import iaik.xml.crypto.dsig.TransformImpl;
+import iaik.xml.crypto.dsig.TransformsImpl;
+
+import javax.xml.crypto.Data;
+import javax.xml.crypto.URIDereferencer;
+import javax.xml.crypto.URIReferenceException;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.dsig.DigestMethod;
+import javax.xml.crypto.dsig.TransformException;
+
+import at.gv.egiz.bku.slexceptions.SLCommandException;
+import at.gv.egiz.bku.slexceptions.SLExceptionMessages;
+
+/**
+ * This class extends the XSECT ReferenceImpl to allow for the use
+ * of already marshalled ds:Transforms elements for initialization.
+ *
+ * @author mcentner
+ */
+public class XSECTReference extends ReferenceImpl {
+
+ /**
+ * The URIDereferencer to be used for dereferencing.
+ */
+ protected URIDereferencer dereferencer;
+
+ /**
+ * Creates a new instance of this XSECTReference with the given
+ * uri, digest method, transforms, type
+ * and id value.
+ *
+ * @param uri
+ * the URI-attribute value (may be null)
+ * @param dm
+ * the digest method
+ * @param transforms
+ * a TransformsImpl element (may be null)
+ * @param type
+ * the Type-attribute value (may be null)
+ * @param id
+ * the Id-attribute value (may be null)
+ *
+ * @throws NullPointerException
+ * if digestMethod is null
+ * @throws IllegalArgumentException
+ * if uri is not RFC 2396 compliant
+ * @throws ClassCastException
+ * if any of the transforms is not of type
+ * {@link TransformImpl}
+ */
+ public XSECTReference(String uri, DigestMethod dm, TransformsImpl transforms, String type,
+ String id) {
+ super(uri, transforms, type, id);
+ digestMethod_ = (DigestMethodImpl) dm;
+ digestValue_ = new DigestValueImpl();
+ }
+
+ /* (non-Javadoc)
+ * @see iaik.xml.crypto.dsig.ReferenceType#dereference(javax.xml.crypto.XMLCryptoContext)
+ */
+ @Override
+ public Data dereference(XMLCryptoContext context) throws TransformException,
+ URIReferenceException {
+ if (dereferencer != null) {
+ return dereferencer.dereference(this, context);
+ } else {
+ try {
+ return super.dereference(context);
+ } catch (URIReferenceException e) {
+ SLCommandException commandException = new SLCommandException(4003,
+ SLExceptionMessages.EC4003_NOT_RESOLVED, new Object[] { getURI() });
+ throw new URIReferenceException("Failed to dereference data to-be signed.", commandException);
+ }
+ }
+ }
+
+ /**
+ * @return the dereferencer to be used for dereferencing this reference
+ */
+ public URIDereferencer getDereferencer() {
+ return dereferencer;
+ }
+
+ /**
+ * @param dereferencer the dereferencer to be used for dereferencing this reference
+ */
+ public void setDereferencer(URIDereferencer dereferencer) {
+ this.dereferencer = dereferencer;
+ }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/XSECTTransforms.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/XSECTTransforms.java
new file mode 100644
index 00000000..a98e4236
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/XSECTTransforms.java
@@ -0,0 +1,124 @@
+/*
+* Copyright 2008 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.impl.xsect;
+
+import iaik.xml.crypto.dsig.TransformImpl;
+import iaik.xml.crypto.dsig.TransformsImpl;
+
+import java.util.List;
+
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.dom.DOMCryptoContext;
+import javax.xml.crypto.dsig.Transform;
+
+import org.w3c.dom.Node;
+
+/**
+ * This class extends the XSECT TransformsImpl to allow for the use of an
+ * unmarshalled ds:Transforms element for initalization.
+ *
+ * @author mcentner
+ */
+public class XSECTTransforms extends TransformsImpl {
+
+ /**
+ * Creates a new XSECTTransforms with the given list of transforms.
+ *
+ * @param transforms a list of {@link TransformImpl}s
+ * @see TransformsImpl#TransformsImpl(List)
+ */
+ @SuppressWarnings("unchecked")
+ public XSECTTransforms(List transforms) {
+ super(transforms);
+ }
+
+ /**
+ * Creates a new XSECTTransforms and initializes it from the given
+ * ds:Transforms node.
+ *
+ * @param context the context used for unmarshalling
+ * @param node the ds:Transforms node
+ *
+ * @throws MarshalException if unmarshalling the ds:Transforms fails
+ */
+ public XSECTTransforms(DOMCryptoContext context, Node node)
+ throws MarshalException {
+ super(context, node);
+ }
+
+ /**
+ * Inserts the given transform at the top of the
+ * transform list.
+ *
+ * @param transform the ds:Transform to instert
+ */
+ @SuppressWarnings("unchecked")
+ public void insertTransform(Transform transform) {
+ if (transform == null) {
+ throw new NullPointerException("Parameter 'transform' must not be null.");
+ }
+ if (!(transform instanceof TransformImpl)) {
+ throw new ClassCastException("Transform 'transform' must be of type '" + TransformImpl.class.getName() + "'.");
+ }
+ transforms_.add(0, transform);
+ }
+
+ /**
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ private List getTransformImpls() {
+ return transforms_;
+ }
+
+ /* (non-Javadoc)
+ * @see iaik.xml.crypto.dsig.TransformsType#marshal(javax.xml.crypto.dom.DOMCryptoContext, org.w3c.dom.Node, org.w3c.dom.Node)
+ */
+ @Override
+ public Node marshal(DOMCryptoContext context, Node parent, Node nextSibling)
+ throws MarshalException {
+
+ if (getNode() != null) {
+ // If this TransformsImpl has been unmarshalled from exiting nodes,
+ // we don't want to re-marshal ...
+ state_ = STATE_MARSHALED;
+
+ // ... but append the existing node to the parent ...
+ Node transformsNode = parent.insertBefore(getNode(), nextSibling);
+
+ // ... and marshal any Transforms not yet marshalled (e.g. that
+ // have been added via insertTransform().
+ Node transformNextSibling = transformsNode.getFirstChild();
+ List transforms = getTransformImpls();
+ for (int i = 0; i < transforms.size(); i++) {
+ TransformImpl transform = transforms.get(i);
+ Node transformNode = transform.getNode();
+ if (transformNode == null) {
+ // marshall TransformImpl
+ transformNode = transform.marshal(context, transformsNode, transformNextSibling);
+ }
+ transformNextSibling = transformNode.getNextSibling();
+ }
+
+ return transformsNode;
+ } else {
+ return super.marshal(context, parent, nextSibling);
+ }
+
+ }
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLBindingException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLBindingException.java
new file mode 100644
index 00000000..3f1732ba
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLBindingException.java
@@ -0,0 +1,31 @@
+/*
+* Copyright 2008 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.slexceptions;
+
+/**
+ * Error in the binding to the transport protocol (2xxx)
+ */
+public class SLBindingException extends SLException {
+
+ public SLBindingException(int errorCode) {
+ super(errorCode);
+ }
+
+ public SLBindingException(int errorCode, String msg, Object[] args) {
+ super(errorCode, msg, args);
+ }
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLCanceledException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLCanceledException.java
new file mode 100644
index 00000000..8136a093
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLCanceledException.java
@@ -0,0 +1,26 @@
+/*
+* Copyright 2008 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.slexceptions;
+
+public class SLCanceledException extends
+ at.gv.egiz.bku.slexceptions.SLException {
+
+ public SLCanceledException(int errorCode, String msg, Object[] args) {
+ super(errorCode, msg, args);
+ // TODO Auto-generated constructor stub
+ }
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLCommandException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLCommandException.java
new file mode 100644
index 00000000..73ae3325
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLCommandException.java
@@ -0,0 +1,30 @@
+/*
+* Copyright 2008 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.slexceptions;
+
+public class SLCommandException extends at.gv.egiz.bku.slexceptions.SLException {
+
+ private static final long serialVersionUID = 1L;
+
+ public SLCommandException(int errorCode) {
+ super(errorCode);
+ }
+
+ public SLCommandException(int errorCode, String msg, Object[] args) {
+ super(errorCode, msg, args);
+ }
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLException.java
new file mode 100644
index 00000000..4b541deb
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLException.java
@@ -0,0 +1,88 @@
+/*
+* Copyright 2008 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.slexceptions;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class SLException extends Exception {
+
+ private static String RESOURCE_BUNDLE_BASE_NAME = "at.gv.egiz.bku.slexceptions.SLExceptionMessages";
+
+ private static String MISSING_RESOURCE_PATTERN = "MISSING RESOURCE FOR ERROR MESSAGE: {0} ({1})";
+
+ private static String ILLEGAL_ARGUMENT_MESSAGE = "MESSAGE FORMAT FAILED";
+
+ private static final long serialVersionUID = 1L;
+
+ private int errorCode;
+
+ private String message;
+
+ private Object[] arguments;
+
+ public SLException(int errorCode) {
+ this.errorCode = errorCode;
+ this.message = SLExceptionMessages.STANDARD_PREFIX + Integer.toString(errorCode);
+ }
+
+ public SLException(int errorCode, String message, Object[] arguments) {
+ this.errorCode = errorCode;
+ this.message = message;
+ this.arguments = arguments;
+ }
+
+ public int getErrorCode() {
+ return errorCode;
+ }
+
+ public String getDetailedMsg() {
+ return getLocalizedMessage();
+ }
+
+ @Override
+ public String getLocalizedMessage() {
+ return getLocalizedMessage(Locale.getDefault());
+ }
+
+ public String getLocalizedMessage(Locale locale) {
+
+ String pattern;
+ Object[] arguments = this.arguments;
+ try {
+ ResourceBundle bundle = ResourceBundle.getBundle(RESOURCE_BUNDLE_BASE_NAME, locale);
+ pattern = bundle.getString(message);
+ } catch (MissingResourceException e) {
+ pattern = MISSING_RESOURCE_PATTERN;
+ arguments = new Object[]{message, e.getMessage()};
+ }
+
+ String localizedMessage;
+ try {
+ localizedMessage = MessageFormat.format(pattern, arguments);
+ } catch (IllegalArgumentException e) {
+ localizedMessage = ILLEGAL_ARGUMENT_MESSAGE + ": " + pattern;
+ }
+
+ return localizedMessage;
+
+ }
+
+
+}
\ No newline at end of file
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
new file mode 100644
index 00000000..5ce5cba1
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLExceptionMessages.java
@@ -0,0 +1,50 @@
+/*
+* Copyright 2008 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.slexceptions;
+
+public final class SLExceptionMessages {
+
+ private SLExceptionMessages() {
+ }
+
+ public static final String STANDARD_PREFIX = "ec";
+
+ //
+ // 3xxx
+ //
+ // Error in the XML structure of the command request
+
+ public static final String EC3000_UNCLASSIFIED = "ec3000.unclassified";
+
+ public static final String EC3002_INVALID = "ec3002.invalid";
+
+ //
+ // 4xxx
+ //
+ // Error during command execution
+
+ public static final String EC4000_UNCLASSIFIED_INFOBOX_INVALID = "ec4000.infobox.invalid";
+
+ public static final String EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED = "ec4000.idlink.transfomation.failed";
+
+ public static final String EC4002_INFOBOX_UNKNOWN = "ec4002.infobox.unknown";
+
+ public static final String EC4003_NOT_RESOLVED = "ec4003.not.resolved";
+
+ public static final String EC4011_NOTIMPLEMENTED = "ec4011.notimplemented";
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRequestException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRequestException.java
new file mode 100644
index 00000000..548732e6
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRequestException.java
@@ -0,0 +1,30 @@
+/*
+* Copyright 2008 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.slexceptions;
+
+public class SLRequestException extends SLException {
+
+ public SLRequestException(int errorCode) {
+ super(errorCode);
+ // TODO Auto-generated constructor stub
+ }
+
+ public SLRequestException(int errorCode, String msg, Object[] args) {
+ super(errorCode, msg, args);
+ // TODO Auto-generated constructor stub
+ }
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRuntimeException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRuntimeException.java
new file mode 100644
index 00000000..d09ca418
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLRuntimeException.java
@@ -0,0 +1,37 @@
+/*
+* Copyright 2008 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.slexceptions;
+
+public class SLRuntimeException extends RuntimeException {
+
+ public SLRuntimeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public SLRuntimeException(String message) {
+ super(message);
+ }
+
+ public SLRuntimeException(Throwable cause) {
+ super(cause);
+ }
+
+ public SLRuntimeException() {
+ }
+
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLViewerException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLViewerException.java
new file mode 100644
index 00000000..1d128a00
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLViewerException.java
@@ -0,0 +1,25 @@
+/*
+* Copyright 2008 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.slexceptions;
+
+public class SLViewerException extends SLException {
+
+ public SLViewerException(int errorCode, String msg, Object[] args) {
+ super(errorCode, msg, args);
+ // TODO Auto-generated constructor stub
+ }
+}
\ No newline at end of file
diff --git a/bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/Core-1.2.xsd b/bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/Core-1.2.xsd
new file mode 100644
index 00000000..594e4415
--- /dev/null
+++ b/bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/Core-1.2.xsd
@@ -0,0 +1,877 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/xml.xsd b/bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/xml.xsd
new file mode 100644
index 00000000..eeb9db56
--- /dev/null
+++ b/bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/xml.xsd
@@ -0,0 +1,145 @@
+
+
+
+
+
+ See http://www.w3.org/XML/1998/namespace.html and
+ http://www.w3.org/TR/REC-xml for information about this namespace.
+
+ This schema document describes the XML namespace, in a form
+ suitable for import by other schema documents.
+
+ Note that local names in this namespace are intended to be defined
+ only by the World Wide Web Consortium or its subgroups. The
+ following names are currently defined in this namespace and should
+ not be used with conflicting semantics by any Working Group,
+ specification, or document instance:
+
+ base (as an attribute name): denotes an attribute whose value
+ provides a URI to be used as the base for interpreting any
+ relative URIs in the scope of the element on which it
+ appears; its value is inherited. This name is reserved
+ by virtue of its definition in the XML Base specification.
+
+ id (as an attribute name): denotes an attribute whose value
+ should be interpreted as if declared to be of type ID.
+ This name is reserved by virtue of its definition in the
+ xml:id specification.
+
+ lang (as an attribute name): denotes an attribute whose value
+ is a language code for the natural language of the content of
+ any element; its value is inherited. This name is reserved
+ by virtue of its definition in the XML specification.
+
+ space (as an attribute name): denotes an attribute whose
+ value is a keyword indicating what whitespace processing
+ discipline is intended for the content of the element; its
+ value is inherited. This name is reserved by virtue of its
+ definition in the XML specification.
+
+ Father (in any context at all): denotes Jon Bosak, the chair of
+ the original XML Working Group. This name is reserved by
+ the following decision of the W3C XML Plenary and
+ XML Coordination groups:
+
+ In appreciation for his vision, leadership and dedication
+ the W3C XML Plenary on this 10th day of February, 2000
+ reserves for Jon Bosak in perpetuity the XML name
+ xml:Father
+
+
+
+
+ This schema defines attributes and an attribute group
+ suitable for use by
+ schemas wishing to allow xml:base, xml:lang, xml:space or xml:id
+ attributes on elements they define.
+
+ To enable this, such a schema must import this schema
+ for the XML namespace, e.g. as follows:
+ <schema . . .>
+ . . .
+ <import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+
+ Subsequently, qualified reference to any of the attributes
+ or the group defined below will have the desired effect, e.g.
+
+ <type . . .>
+ . . .
+ <attributeGroup ref="xml:specialAttrs"/>
+
+ will define a type which will schema-validate an instance
+ element with any of those attributes
+
+
+
+ In keeping with the XML Schema WG's standard versioning
+ policy, this schema document will persist at
+ http://www.w3.org/2007/08/xml.xsd.
+ At the date of issue it can also be found at
+ http://www.w3.org/2001/xml.xsd.
+ The schema document at that URI may however change in the future,
+ in order to remain compatible with the latest version of XML Schema
+ itself, or with the XML namespace itself. In other words, if the XML
+ Schema or XML namespaces change, the version of this document at
+ http://www.w3.org/2001/xml.xsd will change
+ accordingly; the version at
+ http://www.w3.org/2007/08/xml.xsd will not change.
+
+
+
+
+
+ Attempting to install the relevant ISO 2- and 3-letter
+ codes as the enumerated possible values is probably never
+ going to be a realistic possibility. See
+ RFC 3066 at http://www.ietf.org/rfc/rfc3066.txt and the IANA registry
+ at http://www.iana.org/assignments/lang-tag-apps.htm for
+ further information.
+
+ The union allows for the 'un-declaration' of xml:lang with
+ the empty string.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ See http://www.w3.org/TR/xmlbase/ for
+ information about this attribute.
+
+
+
+
+
+ See http://www.w3.org/TR/xml-id/ for
+ information about this attribute.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/xmldsig-core-schema.xsd b/bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/xmldsig-core-schema.xsd
new file mode 100644
index 00000000..8422fdfa
--- /dev/null
+++ b/bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/xmldsig-core-schema.xsd
@@ -0,0 +1,308 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/xmldsig-transforms.xsd b/bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/xmldsig-transforms.xsd
new file mode 100644
index 00000000..25fdec88
--- /dev/null
+++ b/bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/xmldsig-transforms.xsd
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties b/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties
new file mode 100644
index 00000000..8e0a09bc
--- /dev/null
+++ b/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties
@@ -0,0 +1,97 @@
+# Copyright 2008 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.
+
+test.noerror=This is a test error-message. No error occurred.
+
+ec1000=Unclassified error.
+ec2000=Unclassified error in the transport binding.
+ec2001=HTTP/HTTPS binding: DataURL cannot be resolved.
+ec2002=HTTP/HTTPS binding: StylesheetURL cannot be resolved.
+ec2003=HTTP/HTTPS binding: RedirectURL cannot be resolved.
+ec2004=HTTP/HTTPS binding: XMLRequest parameter missing.
+ec2005=HTTP/HTTPS binding: Unknown parameter encoding.
+ec2006=HTTP/HTTPS binding: Incorrect parameter encoding.
+ec2007=HTTP/HTTPS binding: DataURL server transmits error or unexpected response.
+ec2008=HTTP/HTTPS binding: Error in stylesheet obtained from the StylesheetURL.
+ec2009=HTTP/HTTPS binding: HTTP request to local CCE directed to unauthorised URL.
+ec2010=HTTPS binding: Error while establishing the TLS connection.
+ec3000=Unclassified error in the XML structure of the command request.
+ec3001=XML structure of the command request is not well formed.
+ec3002=XML structure of the command request does not comply with the Security Layer schema.
+ec3003=XML structure of the command request contains an invalid combination of optional elements or attributes.
+ec3004=XML structure contains an element or attribute whose syntax does not match the Security Layer specification.
+ec3005=Protocol version of Security Layer not supported.
+ec4000=Unclassified error while processing command.
+ec4001=Unknown key box identifier.
+ec4002=Unknown info box identifier.
+ec4003=Date to be signed cannot be resolved.
+ec4004=Supplementary object cannot be resolved.
+ec4005=Date to be encrypted cannot be resolved.
+ec4006=Algorithm (signature, encryption, digest, canonicalisation, transformation) not supported.
+ec4007=Error while executing algorithm (signature, encryption, digest, canonicalisation, transformation).
+ec4008=Error while parsing CMS message
+ec4009=No matching decryption key.
+ec4010=Info box command parameters do not match info box type.
+ec4011=Command not implemented.
+ec4100=XML document in which the signature is to be integrated cannot be resolved.
+ec4101=XML document in which the signature is to be integrated cannot be parsed.
+ec4102=Signature cannot be integrated in the existing XML document at the specified location.
+ec4103=Signature certificate not contained in the CMS signature.
+ec4104=Signed data not contained in the CMS signature or XML request.
+ec4105=XML document containing the signature to be verified cannot be resolved.
+ec4106=XML document containing the signature to be verified cannot be parsed.
+ec4107=There is no XML signature at the specified location within the XML document.
+ec4108=Encrypted date cannot be inserted in the existing XML document at the specified location.
+ec4109=Existing XML document is required but missing.
+ec4110=Existing XML document cannot be resolved.
+ec4111=Existing XML document cannot be parsed.
+ec4112=Encrypted data encryption keys cannot be inserted in the existing XML document at the specified location.
+ec4113=Data to be decrypted not contained in either the CMS message or XML request.
+ec4114=XML document to be decrypted cannot be resolved.
+ec4115=XML document to be decrypted cannot be parsed.
+ec4116=At least one specified encryption element cannot be found in the XML document to be decrypted.
+ec4117=No encryption element for binary response.
+ec4118=Date to be hashed cannot be resolved.
+ec4119=Date for which the hash value is to be verified cannot be resolved.
+ec4120=Selected info box identifier already allocated.
+ec4121=Info box with specified identifier does not exist.
+ec4122=Contents of the selected info box cannot be displayed as XML.
+ec4123=Associative array: No entry for the specified key.
+ec5000=Unclassified error in the viewer component.
+ec5001=Display of data of the mime type specified in the command request not supported.
+ec5002=Character encoding of the data to be displayed is invalid or not supported.
+ec5003=Data to be displayed contains unsupported characters.
+ec5004=Standard display format: HTML does not conform to specification.
+ec5005=Standard display format: CSS does not conform to specification.
+ec5006=Standard display format: Format of an embedded image does not conform to specification.
+ec5007=Standard display format: Signature for embedded images missing or does not conform to specification.
+ec6000=Unclassified cancelling by the citizen.
+ec6001=Cancelled by the citizen via the user interface.
+ec6002=Cancelled because of insufficient rights to execute command.
+
+# 3xxx
+#
+
+ec3000.unclassified=Error in the XML structure of the command request. {0}
+ec3002.invalid=XML structure of the command request does not comply with the Security Layer schema. {0}
+
+# 4xxx
+#
+
+ec4000.infobox.invalid=The infobox '{0}' contains invalid content.
+ec4000.idlink.transfomation.failed=Failed to transform CompressedIdentityLink with Stylesheet {0}.
+ec4002.infobox.unknown=Unknown info box identifier {0}.
+ec4003.not.resolved=Data to be signed cannot be resolved from URI={0}.
+ec4011.notimplemented=Command {0} not implemented.
diff --git a/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_de.properties b/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_de.properties
new file mode 100644
index 00000000..cf52a4c3
--- /dev/null
+++ b/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_de.properties
@@ -0,0 +1,98 @@
+# Copyright 2008 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.
+
+test.noerror=Das ist eine Test-Fehlermeldung. Es ist kein Fehler aufgetreten.
+
+ec1000=Unklassifizierter Fehler.
+ec2000=Unklassifizierter Fehler in der Transportbindung.
+ec2001=HTTP/HTTPS-Bindung: DataURL kann nicht aufgelöst werden.
+ec2002=HTTP/HTTPS-Bindung: StylesheetURL kann nicht aufgelöst werden.
+ec2003=HTTP/HTTPS-Bindung: RedirectURL kann nicht aufgelöst werden.
+ec2004=HTTP/HTTPS-Bindung: Parameter XMLRequest fehlt.
+ec2005=HTTP/HTTPS-Bindung: Unbekannte Kodierung der Parameter.
+ec2006=HTTP/HTTPS-Bindung: Fehlerhafte Kodierung der Parameter.
+ec2007=HTTP/HTTPS-Bindung: DataURL-Server sendet Fehler oder unerwartete Antwort.
+ec2008=HTTP/HTTPS-Bindung: Fehler im Stylesheet, der von der StylesheetURL bezogen wurde.
+ec2009=HTTP/HTTPS-Bindung: HTTP-Anfrage an lokale BKU wurde an unerlaubte URL gerichtet.
+ec2010=HTTPS-Bindung: Fehler beim Aufbau der TLS-Verbindung.
+ec3000=Unklassifizierter Fehler in der XML-Struktur der Befehlsanfrage.
+ec3001=XML-Struktur der Befehlsanfrage ist nicht wohlgeformt.
+ec3002=XML-Struktur der Befehlsanfrage entspricht nicht dem Schema des Security-Layers.
+ec3003=XML-Struktur der Befehlsanfrage enthält eine unerlaubte Kombination aus optionalen Elementen oder Attributen.
+ec3004=XML-Struktur enthält ein Element oder Attribut, dessen Syntax nicht der Spezifikation des Security-Layer entspricht.
+ec3005=Protokollversion des Security-Layer wird nicht unterstützt.
+ec4000=Unklassifizierter Fehler in der Befehlsabarbeitung.
+ec4001=Unbekannter Keyboxbezeichner.
+ec4002=Unbekannter Infoboxbezeichner.
+ec4003=Zu signierendes Datum kann nicht aufgelöst werden.
+ec4004=Ergänzungsobjekt kann nicht aufgelöst werden.
+ec4005=Zu verschlüsselndes Datum kann nicht aufgelöst werden.
+ec4006=Algorithmus (Signatur, Verschlüsselung, Digest, Kanonisierung, Transformation) wird nicht unterstützt.
+ec4007=Fehler bei der Algorithmusausführung (Signatur, Verschlüsselung, Digest, Kanonisierung, Transformation).
+ec4008=Fehler beim Parsen der CMS-Nachricht.
+ec4009=Kein passender Entschlüsselungsschlüssel vorhanden.
+ec4010=Parameter des Infobox-Befehls passen nicht zum Typ der Infobox.
+ec4011=Befehl ist nicht implementiert.
+ec4100=XML-Dokument, in das die Signatur integriert werden soll, kann nicht aufgelöst werden.
+ec4101=XML-Dokument, in das die Signatur integriert werden soll, kann nicht geparst werden.
+ec4102=Signatur kann nicht am spezifizierten Ort in das bestehende XML-Dokument integriert werden.
+ec4103=Signatorzertifikat ist nicht in der CMS-Signatur enthalten.
+ec4104=Signierte Daten sind weder in der CMS-Signatur noch im XML-Request enthalten.
+ec4105=XML-Dokument, das die zu prüfende Signatur enthält, kann nicht aufgelöst werden.
+ec4106=XML-Dokument, das die zu prüfende Signatur enthält, kann nicht geparst werden.
+ec4107=Am spezifizierten Ort innerhalb des XML-Dokuments befindet sich keine XML-Signatur.
+ec4108=Verschlüsseltes Datum kann nicht am spezifizierten Ort in das bestehende XML-Dokument eingefügt werden.
+ec4109=Bestehendes XML-Dokument ist notwendig, aber nicht vorhanden.
+ec4110=Bestehendes XML-Dokument kann nicht aufgelöst werden.
+ec4111=Bestehendes XML-Dokument kann nicht geparst werden.
+ec4112=Verschlüsselte Datenverschlüsselungsschlüssel können nicht am spezifizierten Ort in das bestehende XML-Dokument eingefügt werden.
+ec4113=Zu entschlüsselnde Daten sind weder in der CMS-Nachricht noch im XML-Request enthalten.
+ec4114=Zu entschlüsselndes XML-Dokument kann nicht aufgelöst werden.
+ec4115=Zu entschlüsselndes XML-Dokument kann nicht geparst werden.
+ec4116=Zumindest ein spezifiziertes Verschlüsselungselement kann nicht im zu entschlüsselnden XML-Dokument gefunden werden.
+ec4117=Kein Verschlüsselungselement für Binärantwort vorhanden.
+ec4118=Zu hashendes Datum kann nicht aufgelöst werden.
+ec4119=Datum, für das der Hashwert zu prüfen ist, kann nicht aufgelöst werden.
+ec4120=Gewählter Infoboxbezeichner bereits vergeben.
+ec4121=Infobox mit spezifiziertem Bezeichner existiert nicht.
+ec4122=Inhalt der ausgewählten Infobox kann nicht als XML dargestellt werden.
+ec4123=Assoziatives Array: Zum spezifizierten Schlüssel existiert kein Eintrag.
+ec5000=Unklassifizierter Fehler in der Anzeigekomponente.
+ec5001=Anzeige von Daten des in der Befehlsanfrage angegebenen Mime-Types wird nicht unterstützt.
+ec5002=Zeichenkodierung der anzuzeigenden Daten ist fehlerhaft oder wird nicht unterstützt.
+ec5003=Anzuzeigende Daten enhalten nicht unterstützte Zeichen.
+ec5004=Standardanzeigeformat: HTML ist nicht spezifikationskonform.
+ec5005=Standardanzeigeformat: CSS ist nicht spezifikationskonform.
+ec5006=Standardanzeigeformat: Format eines eingebundenen Bildes ist nicht spezifikationskonform.
+ec5007=Standardanzeigeformat: Signatur über eingebundene Bilder fehlt oder ist nicht spezifikationskonform.
+ec6000=Unklassifizierter Abbruch durch den Bürger.
+ec6001=Abbruch durch den Bürger über die Benutzerschnittstelle.
+ec6002=Abbruch auf Grund mangelnder Rechte zur Befehlsausführung.
+
+# 3xxx
+#
+
+ec3000.unclassified=Unklassifizierter Fehler in der XML-Struktur der Befehlsanfrage. {0}
+ec3002.invalid=XML-Struktur der Befehlsanfrage entspricht nicht dem Schema des Security-Layers. {0}
+
+# 4xxx
+#
+
+ec4000.infobox.invalid=Die Infobox '{0}' enthält ungültige Daten.
+ec4000.idlink.transfomation.failed=Die komprimierte Personenbindung konnte mit dem Stylesheet {0} nicht transformiert werden.
+ec4002.infobox.unknown=Unbekannter Infoboxbezeichner {0}.
+ec4003.not.resolved=Zu signierendes Datum kann nicht aufgelöst werden (URI={0}).
+ec4011.notimplemented=Befehl {0} ist nicht implementiert.
+
--
cgit v1.2.3