abdera-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jmsn...@apache.org
Subject svn commit: r1173209 [39/49] - in /abdera/abdera2: ./ .settings/ activities/ activities/src/ activities/src/main/ activities/src/main/java/ activities/src/main/java/org/ activities/src/main/java/org/apache/ activities/src/main/java/org/apache/abdera2/ ...
Date Tue, 20 Sep 2011 15:57:20 GMT
Added: abdera/abdera2/security/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedRequestFilter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/security/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedRequestFilter.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/security/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedRequestFilter.java (added)
+++ abdera/abdera2/security/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedRequestFilter.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * 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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.security.util.filters;
+
+import org.apache.abdera2.common.protocol.RequestContext.Scope;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.common.protocol.FilterChain;
+import org.apache.abdera2.security.Encryption;
+import org.apache.abdera2.security.EncryptionOptions;
+import org.apache.abdera2.security.util.Constants;
+import org.apache.abdera2.security.util.DHContext;
+
+/**
+ * A filter implementation that allows requests to be encrypted using Diffie-Hellman key negotiation. A client first
+ * uses GET/HEAD/OPTIONS to get the servers DH information, then sends an encrypted request containing it's DH
+ * information. The server can then decrypt and process the request. Note: this is currently untested.
+ */
+public class DHEncryptedRequestFilter extends AbstractEncryptedRequestFilter {
+
+    public DHEncryptedRequestFilter() {
+        super();
+    }
+
+    public DHEncryptedRequestFilter(String... methods) {
+        super(methods);
+    }
+
+    public void bootstrap(RequestContext request) {
+    }
+
+    @SuppressWarnings("unchecked")
+    public <S extends ResponseContext>S filter(RequestContext request, FilterChain chain) {
+        ResponseContext response = super.filter(request, chain);
+        String method = request.getMethod();
+        // include a Accept-Encryption header in the response to GET, HEAD and OPTIONS requests
+        // the header will specify all the information the client needs to construct
+        // it's own DH context and encrypt the request
+        if ("GET".equalsIgnoreCase(method) || "HEAD".equalsIgnoreCase(method) || "OPTIONS".equalsIgnoreCase(method)) {
+            DHContext context = (DHContext)request.getAttribute(Scope.SESSION, "dhcontext");
+            if (context == null) {
+                context = new DHContext();
+                request.setAttribute(Scope.SESSION, "dhcontext", context);
+            }
+            response.setHeader(Constants.ACCEPT_ENCRYPTION, context.getRequestString());
+        }
+        return (S)response;
+    }
+
+    protected Object initArg(RequestContext request) {
+        DHContext context = (DHContext)request.getAttribute(Scope.SESSION, "dhcontext");
+        String dh = request.getHeader(Constants.CONTENT_ENCRYPTED);
+        if (context != null && dh != null && dh.length() > 0) {
+            try {
+                context.setPublicKey(dh);
+            } catch (Exception e) {
+            }
+        }
+        return context;
+    }
+
+    protected EncryptionOptions initEncryptionOptions(RequestContext request, Encryption encryption, Object arg) {
+        EncryptionOptions options = null;
+        if (arg != null && arg instanceof DHContext) {
+            try {
+                options = ((DHContext)arg).getEncryptionOptions(encryption);
+            } catch (Exception e) {
+            }
+        }
+        return options;
+    }
+
+}

Propchange: abdera/abdera2/security/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedRequestFilter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2/security/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedResponseFilter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/security/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedResponseFilter.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/security/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedResponseFilter.java (added)
+++ abdera/abdera2/security/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedResponseFilter.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * 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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.security.util.filters;
+
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.common.protocol.FilterChain;
+import org.apache.abdera2.security.Encryption;
+import org.apache.abdera2.security.EncryptionOptions;
+import org.apache.abdera2.security.util.Constants;
+import org.apache.abdera2.security.util.DHContext;
+
+/**
+ * A Servlet Filter that uses Diffie-Hellman Key Exchange to encrypt Atom documents. The HTTP request must include an
+ * Accept-Encryption header in the form: Accept-Encryption: DH p={dh_p}, g={dh_g}, l={dh_l}, k={base64_pubkey} Example
+ * AbderaClient Code:
+ * 
+ * <pre>
+ * DHContext context = new DHContext();
+ * Abdera abdera = Abdera.getInstance();
+ * CommonsClient client = new CommonsClient(abdera);
+ * RequestOptions options = client.getDefaultRequestOptions();
+ * options.setHeader(&quot;Accept-Encryption&quot;, context.getRequestString());
+ * 
+ * ClientResponse response = client.get(&quot;http://localhost:8080/TestWeb/test&quot;, options);
+ * Document&lt;Element&gt; doc = response.getDocument();
+ * 
+ * String dh_ret = response.getHeader(&quot;Content-Encrypted&quot;);
+ * if (dh_ret != null) {
+ *     context.setPublicKey(dh_ret);
+ *     AbderaSecurity absec = new AbderaSecurity(abdera);
+ *     Encryption enc = absec.getEncryption();
+ *     EncryptionOptions encoptions = context.getEncryptionOptions(enc);
+ *     doc = enc.decrypt(doc, encoptions);
+ * }
+ * 
+ * doc.writeTo(System.out);
+ * </pre>
+ * 
+ * Webapp Deployment:
+ * 
+ * <pre>
+ * &lt;filter>
+ *   &lt;filter-name>enc filter&lt;/filter-name>
+ *   &lt;filter-class>com.test.EncryptedResponseFilter&lt;/filter-class>
+ * &lt;/filter>
+ * &lt;filter-mapping>
+ *   &lt;filter-name>enc filter&lt;/filter-name>
+ *   &lt;servlet-name>TestServlet&lt;/servlet-name>
+ * &lt;/filter-mapping>
+ * </pre>
+ */
+public class DHEncryptedResponseFilter extends AbstractEncryptedResponseFilter {
+
+    protected boolean doEncryption(RequestContext request, Object arg) {
+        return arg != null;
+    }
+
+    protected Object initArg(RequestContext request) {
+        return getDHContext(request);
+    }
+
+    protected EncryptionOptions initEncryptionOptions(RequestContext request,
+                                                      ResponseContext response,
+                                                      Encryption enc,
+                                                      Object arg) {
+        EncryptionOptions options = null;
+        try {
+            DHContext context = (DHContext)arg;
+            options = context.getEncryptionOptions(enc);
+            returnPublicKey(response, context);
+        } catch (Exception e) {
+        }
+        return options;
+
+    }
+
+    @SuppressWarnings("unchecked")
+    public <S extends ResponseContext>S filter(RequestContext request, FilterChain chain) {
+        ResponseContext response = super.filter(request, chain);
+        DHContext context = getDHContext(request);
+        response.setHeader(Constants.CONTENT_ENCRYPTED, context.getResponseString());
+        return (S)response;
+    }
+
+    private void returnPublicKey(ResponseContext response, DHContext context) {
+        response.setHeader(Constants.CONTENT_ENCRYPTED, context.getResponseString());
+    }
+
+    private DHContext getDHContext(RequestContext request) {
+        try {
+            String dh_req = request.getHeader(Constants.ACCEPT_ENCRYPTION);
+            if (dh_req == null || dh_req.length() == 0)
+                return null;
+            return new DHContext(dh_req);
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+}

Propchange: abdera/abdera2/security/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedResponseFilter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2/security/src/main/java/org/apache/abdera2/security/util/filters/SignedRequestFilter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/security/src/main/java/org/apache/abdera2/security/util/filters/SignedRequestFilter.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/security/src/main/java/org/apache/abdera2/security/util/filters/SignedRequestFilter.java (added)
+++ abdera/abdera2/security/src/main/java/org/apache/abdera2/security/util/filters/SignedRequestFilter.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * 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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.security.util.filters;
+
+import org.apache.abdera2.common.Localizer;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.common.protocol.Filter;
+import org.apache.abdera2.common.protocol.FilterChain;
+import org.apache.abdera2.common.protocol.ProviderHelper;
+import org.apache.abdera2.model.Document;
+import org.apache.abdera2.model.Element;
+import org.apache.abdera2.protocol.server.context.AtompubRequestContext;
+import org.apache.abdera2.security.Security;
+import org.apache.abdera2.security.Signature;
+
+/**
+ * Servlet Filter that verifies that an Atom document received by the server via PUT or POST contains a valid XML
+ * Digital Signature.
+ */
+public class SignedRequestFilter implements Filter {
+
+    public static final String VALID = "org.apache.abdera.security.util.servlet.SignedRequestFilter.valid";
+    public static final String CERTS = "org.apache.abdera.security.util.servlet.SignedRequestFilter.certs";
+
+    @SuppressWarnings("unchecked")
+    public <S extends ResponseContext>S filter(RequestContext request, FilterChain chain) {
+        AtompubRequestContext context = 
+          request instanceof AtompubRequestContext ? 
+            (AtompubRequestContext)request : 
+            new AtompubRequestContext(request);
+        Security security = new Security(context.getAbdera());
+        Signature sig = security.getSignature();
+        String method = request.getMethod();
+        if (method.equals("POST") || method.equals("PUT")) {
+            try {
+                Document<Element> doc = context.getDocument();
+                boolean valid = sig.verify(doc.getRoot(), null);
+                if (!valid)
+                    return (S)ProviderHelper.badrequest(request, Localizer.get("VALID.SIGNATURE.REQUIRED"));
+                request.setAttribute(VALID, valid);
+                request.setAttribute(CERTS, sig.getValidSignatureCertificates(doc.getRoot(), null));
+            } catch (Exception e) {
+            }
+        }
+        return chain.next(context);
+    }
+
+}

Propchange: abdera/abdera2/security/src/main/java/org/apache/abdera2/security/util/filters/SignedRequestFilter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2/security/src/main/java/org/apache/abdera2/security/util/filters/SignedResponseFilter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/security/src/main/java/org/apache/abdera2/security/util/filters/SignedResponseFilter.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/security/src/main/java/org/apache/abdera2/security/util/filters/SignedResponseFilter.java (added)
+++ abdera/abdera2/security/src/main/java/org/apache/abdera2/security/util/filters/SignedResponseFilter.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,254 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * 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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.security.util.filters;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.common.protocol.Filter;
+import org.apache.abdera2.common.protocol.FilterChain;
+import org.apache.abdera2.model.Document;
+import org.apache.abdera2.model.Element;
+import org.apache.abdera2.protocol.server.AtompubResponseContext;
+import org.apache.abdera2.protocol.server.context.ResponseContextWrapper;
+import org.apache.abdera2.protocol.server.impl.AbstractAtompubProvider;
+import org.apache.abdera2.security.Security;
+import org.apache.abdera2.security.SecurityException;
+import org.apache.abdera2.security.Signature;
+import org.apache.abdera2.security.SignatureOptions;
+import org.apache.abdera2.writer.Writer;
+
+/**
+ * <p>
+ * This HTTP Servlet Filter will add an XML Digital Signature to Abdera documents
+ * </p>
+ * 
+ * <pre>
+ * &lt;filter>
+ *   &lt;filter-name>signing filter&lt;/filter-name>
+ *   &lt;filter-class>org.apache.abdera.security.util.servlet.SignedResponseFilter&lt;/filter-class>
+ *   &lt;init-param>
+ *     &lt;param-name>org.apache.abdera.security.util.servlet.Keystore&lt;/param-name>
+ *     &lt;param-value>/key.jks&lt;/param-value>
+ *   &lt;/init-param>
+ *   &lt;init-param>
+ *     &lt;param-name>org.apache.abdera.security.util.servlet.KeystorePassword&lt;/param-name>
+ *     &lt;param-value>testing&lt;/param-value>
+ *   &lt;/init-param>
+ *   &lt;init-param>
+ *     &lt;param-name>org.apache.abdera.security.util.servlet.PrivateKeyAlias&lt;/param-name>
+ *     &lt;param-value>James&lt;/param-value>
+ *   &lt;/init-param>
+ *   &lt;init-param>
+ *     &lt;param-name>org.apache.abdera.security.util.servlet.PrivateKeyPassword&lt;/param-name>
+ *     &lt;param-value>testing&lt;/param-value>
+ *   &lt;/init-param>
+ *   &lt;init-param>
+ *     &lt;param-name>org.apache.abdera.security.util.servlet.CertificateAlias&lt;/param-name>
+ *     &lt;param-value>James&lt;/param-value>
+ *   &lt;/init-param>
+ *   &lt;init-param>
+ *     &lt;param-name>org.apache.abdera.security.util.servlet.SigningAlgorithm&lt;/param-name>
+ *     &lt;param-value>http://www.w3.org/2000/09/xmldsig#rsa-sha1&lt;/param-value>
+ *   &lt;/init-param>
+ * &lt;/filter>
+ * &lt;filter-mapping id="signing-filter">
+ *   &lt;filter-name>signing filter&lt;/filter-name>
+ *   &lt;servlet-name>Abdera&lt;/servlet-name>
+ * &lt;/filter-mapping>
+ * </pre>
+ */
+public class SignedResponseFilter implements Filter {
+
+    private static final String keystoreType = "JKS";
+
+    private String keystoreFile = null;
+    private String keystorePass = null;
+    private String privateKeyAlias = null;
+    private String privateKeyPass = null;
+    private String certificateAlias = null;
+    private String algorithm = null;
+    private PrivateKey signingKey = null;
+    private X509Certificate cert = null;
+
+    public SignedResponseFilter(String keystoreFile,
+                                String keystorePass,
+                                String privateKeyAlias,
+                                String privateKeyPass,
+                                String certificateAlias,
+                                String algorithm) {
+        this.keystoreFile = keystoreFile;
+        this.keystorePass = keystorePass;
+        this.privateKeyAlias = privateKeyAlias;
+        this.privateKeyPass = privateKeyPass;
+        this.certificateAlias = certificateAlias;
+        this.algorithm = algorithm;
+        try {
+            KeyStore ks = KeyStore.getInstance(keystoreType);
+            InputStream in = SignedResponseFilter.class.getResourceAsStream(keystoreFile);
+            ks.load(in, keystorePass.toCharArray());
+            signingKey = (PrivateKey)ks.getKey(privateKeyAlias, privateKeyPass.toCharArray());
+            cert = (X509Certificate)ks.getCertificate(certificateAlias);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public <S extends ResponseContext>S filter(RequestContext request, FilterChain chain) {
+        return (S)new SigningResponseContextWrapper(AbstractAtompubProvider.getAbdera(request), chain.next(request));
+    }
+
+    private Document<Element> signDocument(Abdera abdera, Document<Element> doc) throws SecurityException {
+        Security security = new Security(abdera);
+        if (signingKey == null || cert == null)
+            return doc; // pass through
+        Signature sig = security.getSignature();
+        SignatureOptions options = sig.getDefaultSignatureOptions();
+        options.setCertificate(cert);
+        options.setSigningKey(signingKey);
+        if (algorithm != null)
+            options.setSigningAlgorithm(algorithm);
+        Element element = doc.getRoot();
+        element = sig.sign(element, options);
+        return element.getDocument();
+    }
+
+    private class SigningResponseContextWrapper extends ResponseContextWrapper {
+
+        private final Abdera abdera;
+
+        public SigningResponseContextWrapper(Abdera abdera, ResponseContext response) {
+            super((AtompubResponseContext)response);
+            this.abdera = abdera;
+        }
+
+        public void writeTo(OutputStream out, Writer writer) throws IOException {
+            try {
+                sign(out, null);
+            } catch (Exception se) {
+                throw new RuntimeException(se);
+            }
+        }
+
+        public void writeTo(OutputStream out) throws IOException {
+            try {
+                sign(out, null);
+            } catch (Exception se) {
+                throw new RuntimeException(se);
+            }
+        }
+
+        private void sign(OutputStream aout, Writer writer) throws Exception {
+            Document<Element> doc = null;
+            try {
+                ByteArrayOutputStream out = new ByteArrayOutputStream();
+                if (writer == null)
+                    super.writeTo(out);
+                else
+                    super.writeTo(out, writer);
+                ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+                doc = abdera.getParser().parse(in);
+            } catch (Exception e) {
+            }
+            if (doc != null) {
+                doc = signDocument(abdera, doc);
+                doc.writeTo(aout);
+            } else {
+                super.writeTo(aout);
+            }
+        }
+    }
+
+    public String getKeystoreFile() {
+        return keystoreFile;
+    }
+
+    public void setKeystoreFile(String keystoreFile) {
+        this.keystoreFile = keystoreFile;
+    }
+
+    public String getKeystorePass() {
+        return keystorePass;
+    }
+
+    public void setKeystorePass(String keystorePass) {
+        this.keystorePass = keystorePass;
+    }
+
+    public String getPrivateKeyAlias() {
+        return privateKeyAlias;
+    }
+
+    public void setPrivateKeyAlias(String privateKeyAlias) {
+        this.privateKeyAlias = privateKeyAlias;
+    }
+
+    public String getPrivateKeyPass() {
+        return privateKeyPass;
+    }
+
+    public void setPrivateKeyPass(String privateKeyPass) {
+        this.privateKeyPass = privateKeyPass;
+    }
+
+    public String getCertificateAlias() {
+        return certificateAlias;
+    }
+
+    public void setCertificateAlias(String certificateAlias) {
+        this.certificateAlias = certificateAlias;
+    }
+
+    public String getAlgorithm() {
+        return algorithm;
+    }
+
+    public void setAlgorithm(String algorithm) {
+        this.algorithm = algorithm;
+    }
+
+    public PrivateKey getSigningKey() {
+        return signingKey;
+    }
+
+    public void setSigningKey(PrivateKey signingKey) {
+        this.signingKey = signingKey;
+    }
+
+    public X509Certificate getCert() {
+        return cert;
+    }
+
+    public void setCert(X509Certificate cert) {
+        this.cert = cert;
+    }
+
+    public static String getKeystoreType() {
+        return keystoreType;
+    }
+}

Propchange: abdera/abdera2/security/src/main/java/org/apache/abdera2/security/util/filters/SignedResponseFilter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlEncryption.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlEncryption.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlEncryption.java (added)
+++ abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlEncryption.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * 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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.security.xmlsec;
+
+import java.security.Key;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.model.Document;
+import org.apache.abdera2.model.Element;
+import org.apache.abdera2.security.EncryptionOptions;
+import org.apache.abdera2.security.SecurityException;
+import org.apache.abdera2.security.util.EncryptionBase;
+import org.apache.xml.security.encryption.EncryptedData;
+import org.apache.xml.security.encryption.EncryptedKey;
+import org.apache.xml.security.encryption.XMLCipher;
+import org.apache.xml.security.keys.KeyInfo;
+
+public class XmlEncryption extends EncryptionBase {
+
+    static {
+        if (!org.apache.xml.security.Init.isInitialized())
+            org.apache.xml.security.Init.init();
+    }
+
+    public XmlEncryption() {
+        super(Abdera.getInstance());
+    }
+
+    public XmlEncryption(Abdera abdera) {
+        super(abdera);
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T extends Element>Document<T> encrypt(Document<?> doc, EncryptionOptions options) throws SecurityException {
+        try {
+            org.w3c.dom.Document dom = fomToDom(doc, options);
+            Key dek = options.getDataEncryptionKey();
+            Key kek = options.getKeyEncryptionKey();
+            String dalg = options.getDataCipherAlgorithm();
+            String kalg = options.getKeyCipherAlgorithm();
+            boolean includeki = options.includeKeyInfo();
+            EncryptedKey enckey = null;
+            XMLCipher xmlCipher = XMLCipher.getInstance(dalg);
+            xmlCipher.init(XMLCipher.ENCRYPT_MODE, dek);
+            if (includeki && kek != null && dek != null) {
+                XMLCipher keyCipher = XMLCipher.getInstance(kalg);
+                keyCipher.init(XMLCipher.WRAP_MODE, kek);
+                enckey = keyCipher.encryptKey(dom, dek);
+                EncryptedData encdata = xmlCipher.getEncryptedData();
+                KeyInfo keyInfo = new KeyInfo(dom);
+                keyInfo.add(enckey);
+                encdata.setKeyInfo(keyInfo);
+            }
+            dom = xmlCipher.doFinal(dom, dom.getDocumentElement(), false);
+            return (Document<T>)domToFom(dom, options);
+        } catch (Exception e) {
+            throw new SecurityException(e);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T extends Element>Document<T> decrypt(Document<?> doc, EncryptionOptions options) throws SecurityException {
+        if (!isEncrypted(doc))
+            return null;
+        try {
+            org.w3c.dom.Document dom = fomToDom(doc, options);
+            Key kek = options.getKeyEncryptionKey();
+            Key dek = options.getDataEncryptionKey();
+            org.w3c.dom.Element element = dom.getDocumentElement();
+            XMLCipher xmlCipher = XMLCipher.getInstance();
+            xmlCipher.init(XMLCipher.DECRYPT_MODE, dek);
+            xmlCipher.setKEK(kek);
+            dom = xmlCipher.doFinal(dom, element);
+            return (Document<T>) domToFom(dom,options);
+        } catch (Exception e) {
+            throw new SecurityException(e);
+        }
+    }
+
+    public EncryptionOptions getDefaultEncryptionOptions() {
+        return new XmlEncryptionOptions(getAbdera());
+    }
+
+}

Propchange: abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlEncryption.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlEncryptionOptions.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlEncryptionOptions.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlEncryptionOptions.java (added)
+++ abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlEncryptionOptions.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * 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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.security.xmlsec;
+
+import java.security.Key;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.security.EncryptionOptions;
+
+public class XmlEncryptionOptions extends XmlSecurityOptions implements EncryptionOptions {
+
+    private Key dek = null;
+    private Key kek = null;
+    private String kca = "http://www.w3.org/2001/04/xmlenc#kw-aes128";
+    private String dca = "http://www.w3.org/2001/04/xmlenc#aes128-cbc";
+    private boolean setki = false;
+
+    protected XmlEncryptionOptions(Abdera abdera) {
+        super(abdera);
+    }
+
+    public Key getDataEncryptionKey() {
+        return dek;
+    }
+
+    public EncryptionOptions setDataEncryptionKey(Key key) {
+        this.dek = key;
+        return this;
+    }
+
+    public Key getKeyEncryptionKey() {
+        return kek;
+    }
+
+    public EncryptionOptions setKeyEncryptionKey(Key key) {
+        this.kek = key;
+        return this;
+    }
+
+    public String getKeyCipherAlgorithm() {
+        return kca;
+    }
+
+    public EncryptionOptions setKeyCipherAlgorithm(String alg) {
+        this.kca = alg;
+        return this;
+    }
+
+    public String getDataCipherAlgorithm() {
+        return dca;
+    }
+
+    public EncryptionOptions setDataCipherAlgorithm(String alg) {
+        this.dca = alg;
+        return this;
+    }
+
+    public boolean includeKeyInfo() {
+        return setki;
+    }
+
+    public EncryptionOptions setIncludeKeyInfo(boolean includeKeyInfo) {
+        this.setki = includeKeyInfo;
+        return this;
+    }
+}

Propchange: abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlEncryptionOptions.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlSecurityOptions.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlSecurityOptions.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlSecurityOptions.java (added)
+++ abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlSecurityOptions.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * 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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.security.xmlsec;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.parser.Parser;
+import org.apache.abdera2.security.SecurityOptions;
+
+public abstract class XmlSecurityOptions implements SecurityOptions {
+
+    protected Parser parser = null;
+    protected final Abdera abdera;
+
+    protected XmlSecurityOptions(Abdera abdera) {
+        this.abdera = abdera;
+    }
+
+    public Parser getParser() {
+        return (parser != null) ? parser : abdera.getParser();
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T extends SecurityOptions> T setParser(Parser parser) {
+        this.parser = parser;
+        return (T)this;
+    }
+
+}

Propchange: abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlSecurityOptions.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlSignature.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlSignature.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlSignature.java (added)
+++ abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlSignature.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,262 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * 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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.security.xmlsec;
+
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.model.Content;
+import org.apache.abdera2.model.Element;
+import org.apache.abdera2.model.Entry;
+import org.apache.abdera2.model.Link;
+import org.apache.abdera2.model.Source;
+import org.apache.abdera2.security.SecurityException;
+import org.apache.abdera2.security.SignatureOptions;
+import org.apache.abdera2.security.util.Constants;
+import org.apache.abdera2.security.util.SignatureBase;
+import org.apache.abdera2.common.iri.IRI;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.keys.KeyInfo;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.signature.XMLSignatureException;
+import org.apache.xml.security.transforms.Transforms;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class XmlSignature extends SignatureBase {
+
+    static {
+        if (!org.apache.xml.security.Init.isInitialized())
+            org.apache.xml.security.Init.init();
+    }
+
+    public XmlSignature() {
+        super(Abdera.getInstance());
+    }
+
+    public XmlSignature(Abdera abdera) {
+        super(abdera);
+    }
+
+    @SuppressWarnings("unchecked")
+    private <T extends Element> T _sign(T element, SignatureOptions options) throws XMLSecurityException {
+        element.setBaseUri(element.getResolvedBaseUri());
+        org.w3c.dom.Element dom = fomToDom((Element)element.clone(), options);
+        org.w3c.dom.Document domdoc = dom.getOwnerDocument();
+        PrivateKey signingKey = options.getSigningKey();
+        X509Certificate cert = options.getCertificate();
+        PublicKey pkey = options.getPublicKey();
+        IRI baseUri = element.getResolvedBaseUri();
+        XMLSignature sig =
+            new XMLSignature(domdoc, (baseUri != null) ? baseUri.toString() : "", options.getSigningAlgorithm());
+        dom.appendChild(sig.getElement());
+        Transforms transforms = new Transforms(domdoc);
+        transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
+        transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+        sig.addDocument("", transforms, org.apache.xml.security.utils.Constants.ALGO_ID_DIGEST_SHA1);
+        String[] refs = options.getReferences();
+        for (String ref : refs)
+            sig.addDocument(ref);
+
+        if (options.isSignLinks()) {
+            String[] rels = options.getSignLinkRels();
+            List<Link> links = null;
+            Content content = null;
+            if (element instanceof Source) {
+                links = (rels == null) ? ((Source)element).getLinks() : ((Source)element).getLinks(rels);
+            } else if (element instanceof Entry) {
+                links = (rels == null) ? ((Entry)element).getLinks() : ((Entry)element).getLinks(rels);
+                content = ((Entry)element).getContentElement();
+            }
+            if (links != null) {
+                for (Link link : links) {
+                    sig.addDocument(link.getResolvedHref().toASCIIString());
+                }
+            }
+            if (content != null && content.getResolvedSrc() != null)
+                sig.addDocument(content.getResolvedSrc().toASCIIString());
+        }
+
+        if (cert != null)
+            sig.addKeyInfo(cert);
+        if (pkey != null)
+            sig.addKeyInfo(pkey);
+        sig.sign(signingKey);
+        return (T)domToFom(dom, options);
+    }
+
+    public <T extends Element> T sign(T entry, SignatureOptions options) throws SecurityException {
+        try {
+            return (T)_sign(entry, options);
+        } catch (Exception e) {
+            throw new SecurityException(e);
+        }
+    }
+
+    private boolean is_valid_signature(XMLSignature sig, SignatureOptions options) throws XMLSignatureException,
+        XMLSecurityException {
+        KeyInfo ki = sig.getKeyInfo();
+        if (ki != null) {
+            X509Certificate cert = ki.getX509Certificate();
+            if (cert != null) {
+                return sig.checkSignatureValue(cert);
+            } else {
+                PublicKey key = ki.getPublicKey();
+                if (key != null) {
+                    return sig.checkSignatureValue(key);
+                }
+            }
+        } else if (options != null) {
+            PublicKey key = options.getPublicKey();
+            X509Certificate cert = options.getCertificate();
+            if (key != null)
+                return sig.checkSignatureValue(key);
+            if (cert != null)
+                return sig.checkSignatureValue(cert);
+        }
+        return false;
+    }
+
+    private <T extends Element> X509Certificate[] _getcerts(T element, SignatureOptions options)
+        throws XMLSignatureException, XMLSecurityException {
+        List<X509Certificate> certs = new ArrayList<X509Certificate>();
+        org.w3c.dom.Element dom = fomToDom((Element)element, options);
+        NodeList children = dom.getChildNodes();
+        for (int n = 0; n < children.getLength(); n++) {
+            try {
+                Node node = children.item(n);
+                if (node.getNodeType() == Node.ELEMENT_NODE) {
+                    org.w3c.dom.Element el = (org.w3c.dom.Element)node;
+                    if (Constants.DSIG_NS.equals(el.getNamespaceURI()) && Constants.LN_SIGNATURE.equals(el
+                        .getLocalName())) {
+                        IRI baseUri = element.getResolvedBaseUri();
+                        XMLSignature sig = new XMLSignature(el, (baseUri != null) ? baseUri.toString() : "");
+                        if (is_valid_signature(sig, options)) {
+                            KeyInfo ki = sig.getKeyInfo();
+                            if (ki != null) {
+                                X509Certificate cert = ki.getX509Certificate();
+                                if (cert != null)
+                                    certs.add(cert);
+                            }
+                        }
+                    }
+                }
+            } catch (Exception e) {
+            }
+        }
+        return certs.toArray(new X509Certificate[certs.size()]);
+    }
+
+    public X509Certificate[] getValidSignatureCertificates(Element element, SignatureOptions options)
+        throws SecurityException {
+        try {
+            return _getcerts(element, options);
+        } catch (Exception e) {
+        }
+        return null;
+    }
+
+    public KeyInfo getSignatureKeyInfo(Element element, SignatureOptions options)
+        throws SecurityException {
+        KeyInfo ki = null;
+        org.w3c.dom.Element dom = fomToDom((Element)element, options);
+        NodeList children = dom.getChildNodes();
+        for (int n = 0; n < children.getLength(); n++) {
+            try {
+                Node node = children.item(n);
+                if (node.getNodeType() == Node.ELEMENT_NODE) {
+                    org.w3c.dom.Element el = (org.w3c.dom.Element)node;
+                    if (Constants.DSIG_NS.equals(el.getNamespaceURI()) && Constants.LN_SIGNATURE.equals(el
+                        .getLocalName())) {
+                        IRI baseUri = element.getResolvedBaseUri();
+                        XMLSignature sig = new XMLSignature(el, (baseUri != null) ? baseUri.toString() : "");
+                        ki = sig.getKeyInfo();
+                    }
+                }
+            } catch (Exception e) {
+            }
+        }
+        return ki;
+    }
+
+    private boolean _verify(Element element, SignatureOptions options) throws XMLSignatureException,
+        XMLSecurityException {
+        boolean answer = false;
+        org.w3c.dom.Element dom = fomToDom((Element)element, options);
+        NodeList children = dom.getChildNodes();
+        for (int n = 0; n < children.getLength(); n++) {
+            Node node = children.item(n);
+            if (node.getNodeType() == Node.ELEMENT_NODE) {
+                org.w3c.dom.Element el = (org.w3c.dom.Element)node;
+                if (Constants.DSIG_NS.equals(el.getNamespaceURI()) && Constants.LN_SIGNATURE.equals(el.getLocalName())) {
+                    IRI baseUri = element.getResolvedBaseUri();
+                    XMLSignature sig = new XMLSignature(el, (baseUri != null) ? baseUri.toString() : "");
+                    answer = is_valid_signature(sig, options);
+                }
+            }
+        }
+
+        return answer;
+    }
+
+    public boolean verify(Element entry, SignatureOptions options) throws SecurityException {
+        if (!isSigned(entry))
+            return false;
+        try {
+            return _verify(entry, options);
+        } catch (Exception e) {
+            throw new SecurityException(e);
+        }
+    }
+
+    public SignatureOptions getDefaultSignatureOptions() throws SecurityException {
+        return new XmlSignatureOptions(getAbdera());
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T extends Element> T removeInvalidSignatures(T element, SignatureOptions options) throws SecurityException {
+        List<org.w3c.dom.Element> remove = new ArrayList<org.w3c.dom.Element>();
+        org.w3c.dom.Element dom = fomToDom((Element)element, options);
+        NodeList children = dom.getChildNodes();
+        for (int n = 0; n < children.getLength(); n++) {
+            try {
+                Node node = children.item(n);
+                if (node.getNodeType() == Node.ELEMENT_NODE) {
+                    org.w3c.dom.Element el = (org.w3c.dom.Element)node;
+                    if (Constants.DSIG_NS.equals(el.getNamespaceURI()) && Constants.LN_SIGNATURE.equals(el
+                        .getLocalName())) {
+                        IRI baseUri = element.getResolvedBaseUri();
+                        XMLSignature sig = new XMLSignature(el, (baseUri != null) ? baseUri.toString() : "");
+                        if (!is_valid_signature(sig, options)) {
+                            remove.add(el);
+                        }
+                    }
+                }
+            } catch (Exception e) {
+            }
+        }
+        for (org.w3c.dom.Element el : remove)
+            dom.removeChild(el);
+        return (T)domToFom(dom, options);
+    }
+
+}

Propchange: abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlSignature.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlSignatureOptions.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlSignatureOptions.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlSignatureOptions.java (added)
+++ abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlSignatureOptions.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * 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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.security.xmlsec;
+
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.security.SignatureOptions;
+
+public class XmlSignatureOptions extends XmlSecurityOptions implements SignatureOptions {
+
+    private PrivateKey signingKey = null;
+    private PublicKey publickey = null;
+    private X509Certificate cert = null;
+    private String[] linkrels = null;
+    private boolean signlinks = false;
+    private List<String> references = null;
+    private String algo = "http://www.w3.org/2000/09/xmldsig#dsa-sha1";
+
+    public String getSigningAlgorithm() {
+        return algo;
+    }
+
+    public SignatureOptions setSigningAlgorithm(String algorithm) {
+        this.algo = algorithm;
+        return this;
+    }
+
+    protected XmlSignatureOptions(Abdera abdera) {
+        super(abdera);
+        references = new ArrayList<String>();
+    }
+
+    public PrivateKey getSigningKey() {
+        return signingKey;
+    }
+
+    public SignatureOptions setSigningKey(PrivateKey privateKey) {
+        this.signingKey = privateKey;
+        return this;
+    }
+
+    public X509Certificate getCertificate() {
+        return cert;
+    }
+
+    public SignatureOptions setCertificate(X509Certificate cert) {
+        this.cert = cert;
+        return this;
+    }
+
+    public SignatureOptions addReference(String href) {
+        if (!references.contains(href))
+            references.add(href);
+        return this;
+    }
+
+    public String[] getReferences() {
+        return references.toArray(new String[references.size()]);
+    }
+
+    public PublicKey getPublicKey() {
+        return publickey;
+    }
+
+    public SignatureOptions setPublicKey(PublicKey publickey) {
+        this.publickey = publickey;
+        return this;
+    }
+
+    public boolean isSignLinks() {
+        return signlinks;
+    }
+
+    public SignatureOptions setSignLinks(boolean signlinks) {
+        this.signlinks = signlinks;
+        return this;
+    }
+
+    public String[] getSignLinkRels() {
+        return this.linkrels;
+    }
+
+    public SignatureOptions setSignedLinkRels(String... rel) {
+        this.linkrels = rel;
+        return this;
+    }
+
+}

Propchange: abdera/abdera2/security/src/main/java/org/apache/abdera2/security/xmlsec/XmlSignatureOptions.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2/server/pom.xml
URL: http://svn.apache.org/viewvc/abdera/abdera2/server/pom.xml?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/server/pom.xml (added)
+++ abdera/abdera2/server/pom.xml Tue Sep 20 15:56:46 2011
@@ -0,0 +1,62 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" 
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.abdera2</groupId>
+    <artifactId>abdera2</artifactId>
+    <version>2.0-SNAPSHOT</version>  
+  </parent>  
+
+  <artifactId>abdera2-server</artifactId>
+  <packaging>bundle</packaging>
+  <name>Abdera2 Server</name>
+  <version>2.0-SNAPSHOT</version>  
+  <description>Atom Publishing Protocol Server Implementation</description>
+
+  <properties>
+    <topDir>${basedir}/..</topDir>
+    <!-- 
+    <abdera.osgi.default.exports>
+		org.apache.abdera.protocol.client.*
+	</abdera.osgi.default.exports>
+    <abdera.osgi.default.imports>
+      org.apache.commons.codec*;version="[1.3,2)",
+      *
+    </abdera.osgi.default.imports>
+   -->
+  </properties>
+  
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.abdera2</groupId>
+      <artifactId>abdera2-core</artifactId>
+      <version>2.0-SNAPSHOT</version>  
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.abdera2</groupId>
+      <artifactId>abdera2-common</artifactId>
+      <version>2.0-SNAPSHOT</version>  
+      <scope>compile</scope>
+    </dependency>
+  </dependencies>
+</project>

Propchange: abdera/abdera2/server/pom.xml
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubCollectionAdapter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubCollectionAdapter.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubCollectionAdapter.java (added)
+++ abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubCollectionAdapter.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * 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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server;
+
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.common.protocol.CollectionAdapter;
+
+/**
+ * The CollectionAdapter interface is the component that provides the business logic of an Atompub server. The Provider
+ * will use it's WorkspaceManager to determine which CollectionAdapter to dispatch a request to. Once an adapter is
+ * selected, the Provider will determine what kind of request is being made and will forward the request on to the
+ * appropriate CollectionAdapter method.
+ */
+public interface AtompubCollectionAdapter 
+  extends CollectionAdapter {
+
+    /**
+     * Get an Atompub Categories document
+     */
+    <S extends ResponseContext>S getCategories(RequestContext request);
+
+}

Propchange: abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubCollectionAdapter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubMediaCollectionAdapter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubMediaCollectionAdapter.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubMediaCollectionAdapter.java (added)
+++ abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubMediaCollectionAdapter.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * 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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server;
+
+import org.apache.abdera2.common.protocol.MediaCollectionAdapter;
+
+/**
+ * Extends CollectionAdapter with methods specific to the handling of Atompub Media Link Entries
+ */
+public interface AtompubMediaCollectionAdapter 
+  extends AtompubCollectionAdapter, 
+          MediaCollectionAdapter {
+
+}

Propchange: abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubMediaCollectionAdapter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubProvider.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubProvider.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubProvider.java (added)
+++ abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubProvider.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * 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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server;
+
+import java.util.Map;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.common.protocol.Provider;
+import org.apache.abdera2.common.protocol.TargetType;
+
+/**
+ * Providers are responsible for processing all requests to the Atompub server.<br>
+ * Actual request processing is delegated to {@link AtompubRequestProcessor} implementations, depending on the request
+ * {@link TargetType}.
+ */
+public interface AtompubProvider extends Provider {
+
+    /**
+     * Initialize the Provider.
+     */
+    void init(Abdera abdera, Map<String, String> properties);
+
+    /**
+     * Retrieve the Abdera instance associated with this provider
+     */
+    Abdera getAbdera();
+
+}

Propchange: abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubProvider.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubResponseContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubResponseContext.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubResponseContext.java (added)
+++ abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubResponseContext.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * 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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.writer.Writer;
+
+/**
+ * The ResponseContext encapsulates a server response
+ */
+public interface AtompubResponseContext extends ResponseContext {
+
+    /**
+     * Write the response out to the specified OutputStream
+     */
+    void writeTo(OutputStream out, Writer writer) throws IOException;
+
+    /**
+     * Write the response out to the specified Writer
+     */
+    void writeTo(java.io.Writer javaWriter, Writer abderaWriter) throws IOException;
+
+    /**
+     * Set the Abdera Writer for this response. This can be used to customize the serialization of the response
+     */
+    AtompubResponseContext setWriter(Writer writer);
+
+}

Propchange: abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubResponseContext.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubServiceManager.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubServiceManager.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubServiceManager.java (added)
+++ abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubServiceManager.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * 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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server;
+
+import java.util.Map;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.common.Discover;
+import org.apache.abdera2.common.Localizer;
+import org.apache.abdera2.common.protocol.AbstractServiceManager;
+import org.apache.abdera2.protocol.server.impl.DefaultAtompubProvider;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * The ServiceManager is used by the AbderaServlet to bootstrap the server instance. There should be little to no reason
+ * why an end user would need to use this class directly.
+ */
+public class AtompubServiceManager 
+  extends AbstractServiceManager<AtompubProvider> {
+
+    private final static Log log = LogFactory.getLog(AtompubServiceManager.class);
+
+    private final Abdera abdera = Abdera.getInstance();
+
+    public AtompubServiceManager() {}
+
+    public Abdera getAbdera() {
+        return abdera;
+    }
+
+    public AtompubProvider newProvider(Map<String, String> properties) {
+        Abdera abdera = getAbdera();
+        String instance = properties.get(PROVIDER);
+        if (instance == null)
+            instance = DefaultAtompubProvider.class.getName();
+        log.debug(Localizer.sprintf("CREATING.NEW.INSTANCE", "Provider"));
+        AtompubProvider provider = (AtompubProvider)Discover.locate(AtompubProvider.class, instance);
+        log.debug(Localizer.sprintf("INITIALIZING.INSTANCE", "Provider"));
+        provider.init(abdera, properties);
+        return provider;
+    }    
+}

Propchange: abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/AtompubServiceManager.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/AtompubRequestContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/AtompubRequestContext.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/AtompubRequestContext.java (added)
+++ abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/AtompubRequestContext.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * 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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server.context;
+
+import java.io.IOException;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.model.Document;
+import org.apache.abdera2.model.Element;
+import org.apache.abdera2.parser.ParseException;
+import org.apache.abdera2.parser.Parser;
+import org.apache.abdera2.parser.ParserOptions;
+import org.apache.abdera2.protocol.server.AtompubProvider;
+import org.apache.abdera2.common.Localizer;
+import org.apache.abdera2.common.mediatype.MimeTypeHelper;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.BaseRequestContextWrapper;
+import org.apache.abdera2.common.protocol.Provider;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+@SuppressWarnings("unchecked")
+public class AtompubRequestContext 
+  extends BaseRequestContextWrapper {
+
+    private final static Log log = LogFactory.getLog(AtompubRequestContext.class);
+
+    protected Document<?> document;
+    
+    public AtompubRequestContext(RequestContext parent) {
+      super(parent);
+    }
+
+    public Abdera getAbdera() {
+      Provider provider = getProvider();
+      return provider instanceof AtompubProvider ? 
+        ((AtompubProvider)provider).getAbdera() : 
+        Abdera.getInstance();
+    }
+
+    public synchronized <T extends Element> Document<T> getDocument() throws ParseException, IOException {
+        log.debug(Localizer.get("PARSING.REQUEST.DOCUMENT"));
+        if (document == null)
+            document = getDocument(getAbdera().getParser());
+        return (Document<T>)document;
+    }
+
+    public synchronized <T extends Element> Document<T> getDocument(Parser parser) throws ParseException, IOException {
+        log.debug(Localizer.get("PARSING.REQUEST.DOCUMENT"));
+        if (parser == null)
+            parser = getAbdera().getParser();
+        if (parser == null)
+            throw new IllegalArgumentException("No Parser implementation was provided");
+        if (document == null)
+            document = getDocument(parser, parser.getDefaultParserOptions());
+        return (Document<T>)document;
+    }
+
+    public synchronized <T extends Element> Document<T> getDocument(ParserOptions options) throws ParseException,
+        IOException {
+        log.debug(Localizer.get("PARSING.REQUEST.DOCUMENT"));
+        if (document == null)
+            document = getDocument(getAbdera().getParser(), options);
+        return (Document<T>)document;
+    }
+
+    public synchronized <T extends Element> Document<T> getDocument(Parser parser, ParserOptions options)
+        throws ParseException, IOException {
+        log.debug(Localizer.get("PARSING.REQUEST.DOCUMENT"));
+        if (parser == null)
+            parser = getAbdera().getParser();
+        if (parser == null)
+            throw new IllegalArgumentException("No Parser implementation was provided");
+        if (document == null) {
+            document = parser.parse(getInputStream(), getResolvedUri().toString(), options);
+        }
+        return (Document<T>)document;
+    }
+
+    public boolean isAtom() {
+        try {
+            return MimeTypeHelper.isAtom(getContentType().toString());
+        } catch (Exception e) {
+            return false;
+        }
+    }
+    
+}

Propchange: abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/AtompubRequestContext.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/EntityProviderResponseContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/EntityProviderResponseContext.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/EntityProviderResponseContext.java (added)
+++ abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/EntityProviderResponseContext.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * 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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server.context;
+
+import java.io.IOException;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.protocol.EntityProvider;
+import org.apache.abdera2.writer.StreamWriter;
+
+/**
+ * StreamWriterResponseContext implementation based on the EntityProvider interface
+ */
+public class EntityProviderResponseContext extends StreamWriterResponseContext {
+
+    private final EntityProvider provider;
+
+    public EntityProviderResponseContext(EntityProvider provider, Abdera abdera, String encoding, String sw) {
+        super(abdera, encoding, sw);
+        this.provider = provider;
+        init();
+    }
+
+    public EntityProviderResponseContext(EntityProvider provider, Abdera abdera, String encoding) {
+        super(abdera, encoding);
+        this.provider = provider;
+        init();
+    }
+
+    public EntityProviderResponseContext(EntityProvider provider, Abdera abdera) {
+        super(abdera);
+        this.provider = provider;
+        init();
+    }
+
+    private void init() {
+        setContentType(provider.getContentType());
+        setEntityTag(provider.getEntityTag());
+        setLastModified(provider.getLastModified());
+    }
+
+    @Override
+    protected void writeTo(StreamWriter sw) throws IOException {
+        provider.writeTo(sw);
+    }
+
+}

Propchange: abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/EntityProviderResponseContext.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/FOMResponseContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/FOMResponseContext.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/FOMResponseContext.java (added)
+++ abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/FOMResponseContext.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * 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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server.context;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.activation.MimeType;
+
+import org.apache.abdera2.model.Base;
+import org.apache.abdera2.model.Document;
+import org.apache.abdera2.model.Element;
+import org.apache.abdera2.model.Element.Helper;
+import org.apache.abdera2.protocol.server.AtompubResponseContext;
+import org.apache.abdera2.common.protocol.AbstractResponseContext;
+import org.apache.abdera2.writer.Writer;
+
+public class FOMResponseContext<T extends Base> 
+    extends AbstractResponseContext 
+            implements AtompubResponseContext {
+
+    private final T base;
+    private final boolean chunked;
+
+    protected Writer writer;
+    
+    public FOMResponseContext(T base) {
+        this(base, true);
+    }
+
+    public FOMResponseContext(T base, boolean chunked) {
+        this.base = base;
+        setStatus(200);
+        setStatusText("OK");
+        this.chunked = chunked;
+        try {
+            MimeType type = getContentType();
+            String charset = type.getParameter("charset");
+            if (charset == null)
+                charset = getCharsetFromBase(base);
+            if (charset == null)
+                charset = "UTF-8";
+            type.setParameter("charset", charset);
+            setContentType(type.toString());
+        } catch (Exception e) {
+        }
+    }
+
+    private String getCharsetFromBase(Base base) {
+        if (base == null)
+            return null;
+        if (base instanceof Document) {
+            return ((Document<?>)base).getCharset();
+        } else if (base instanceof Element) {
+            return getCharsetFromBase(((Element)base).getDocument());
+        }
+        return null;
+    }
+
+    public T getBase() {
+        return base;
+    }
+
+    public boolean hasEntity() {
+        return (base != null);
+    }
+
+    public void writeTo(java.io.Writer javaWriter) throws IOException {
+        if (hasEntity()) {
+            if (writer == null)
+                base.writeTo(javaWriter);
+            else
+                writeTo(javaWriter, writer);
+        }
+    }
+
+    public void writeTo(OutputStream out) throws IOException {
+        if (hasEntity()) {
+            if (writer == null)
+                base.writeTo(out);
+            else
+                writeTo(out, writer);
+        }
+    }
+
+    @Override
+    public MimeType getContentType() {
+        try {
+            MimeType t = super.getContentType();
+            if (t == null) {
+                String type = Helper.getMimeType(base);
+                if (type != null)
+                    t = new MimeType(type);
+            }
+            return t;
+        } catch (javax.activation.MimeTypeParseException e) {
+            throw new org.apache.abdera2.common.mediatype.MimeTypeParseException(e);
+        }
+    }
+
+    @Override
+    public long getContentLength() {
+        long len = super.getContentLength();
+        if (hasEntity() && len == -1 && !chunked) {
+            try {
+                ByteArrayOutputStream out = new ByteArrayOutputStream();
+                base.writeTo(out);
+                len = out.size();
+                super.setContentLength(len);
+            } catch (Exception e) {
+            }
+        }
+        return len;
+    }
+
+    public void writeTo(OutputStream out, Writer writer) throws IOException {
+        writer.writeTo(base, out);
+    }
+
+    public void writeTo(java.io.Writer javaWriter, Writer abderaWriter) throws IOException {
+        abderaWriter.writeTo(base, javaWriter);
+    }
+    
+    public AtompubResponseContext setWriter(Writer writer) {
+      this.writer = writer;
+      return this;
+  }
+}

Propchange: abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/FOMResponseContext.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/ResponseContextWrapper.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/ResponseContextWrapper.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/ResponseContextWrapper.java (added)
+++ abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/ResponseContextWrapper.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * 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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server.context;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import org.apache.abdera2.common.protocol.BaseResponseContextWrapper;
+import org.apache.abdera2.protocol.server.AtompubResponseContext;
+import org.apache.abdera2.writer.Writer;
+
+public class ResponseContextWrapper 
+  extends BaseResponseContextWrapper implements AtompubResponseContext {
+
+    public ResponseContextWrapper(AtompubResponseContext response) {
+        super(response);
+    }
+
+    private AtompubResponseContext getResponse() {
+      return (AtompubResponseContext)response;
+    }
+    
+    public AtompubResponseContext setWriter(Writer writer) {
+        getResponse().setWriter(writer);
+        return this;
+    }
+
+    public void writeTo(OutputStream out, Writer writer) throws IOException {
+        getResponse().writeTo(out, writer);
+    }
+
+    public void writeTo(java.io.Writer javaWriter, Writer abderaWriter) throws IOException {
+        getResponse().writeTo(javaWriter, abderaWriter);
+    }
+}

Propchange: abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/ResponseContextWrapper.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/StreamWriterResponseContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/StreamWriterResponseContext.java?rev=1173209&view=auto
==============================================================================
--- abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/StreamWriterResponseContext.java (added)
+++ abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/StreamWriterResponseContext.java Tue Sep 20 15:56:46 2011
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * 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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server.context;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.common.protocol.SimpleResponseContext;
+import org.apache.abdera2.protocol.server.AtompubResponseContext;
+import org.apache.abdera2.writer.StreamWriter;
+
+/**
+ * Abstract base class for creating ResponseContext implementations that use the StreamWriter interface. Using the
+ * StreamWriter to write out documents is significantly faster than using the object model but requires developers to
+ * know more about proper Atom syntax.
+ */
+public abstract class StreamWriterResponseContext 
+  extends SimpleResponseContext
+  implements AtompubResponseContext {
+
+    private final Abdera abdera;
+    private final String sw;
+    private boolean autoindent;
+
+    /**
+     * Create a new StreamWriterResponseContext
+     * 
+     * @param abdera The Abdera instance
+     */
+    protected StreamWriterResponseContext(Abdera abdera) {
+        this(abdera, null, null);
+    }
+
+    /**
+     * Create a new StreamWriterResponseContext
+     * 
+     * @param abdera The Abdera instance
+     * @param encoding The charset encoding
+     */
+    protected StreamWriterResponseContext(Abdera abdera, String encoding) {
+        this(abdera, encoding, null);
+    }
+
+    /**
+     * Create a new StreamWriterResponseContext
+     * 
+     * @param abdera The Abdera instance
+     * @param encoding The charset encoding
+     * @param sw The name of the Named StreamWriter to use
+     */
+    protected StreamWriterResponseContext(Abdera abdera, String encoding, String sw) {
+        super(encoding);
+        this.abdera = abdera!=null?abdera:Abdera.getInstance();
+        this.sw = sw;
+    }
+
+    /**
+     * Get the Abdera instance
+     */
+    protected final Abdera getAbdera() {
+        return abdera;
+    }
+
+    /**
+     * Create a new StreamWriter instance. If the sw property was set, the specified Named StreamWriter will be returned
+     */
+    protected StreamWriter newStreamWriter() {
+        return sw == null ? abdera.create(StreamWriter.class) : 
+          abdera.getWriterFactory().newStreamWriter(sw);
+    }
+
+    protected void writeEntity(Writer writer) throws IOException {
+        writeTo(newStreamWriter().setWriter(writer).setAutoIndent(autoindent));
+    }
+
+    /**
+     * Write to the specified StreamWriter. Subclasses of this class must implement this method.
+     */
+    protected abstract void writeTo(StreamWriter sw) throws IOException;
+
+    /**
+     * True to enable automatic indenting on the StreamWriter
+     */
+    public StreamWriterResponseContext setAutoIndent(boolean autoindent) {
+        this.autoindent = autoindent;
+        return this;
+    }
+
+    /**
+     * True if automatic indenting is enabled on the StreamWriter
+     */
+    public boolean getAutoIndent() {
+        return this.autoindent;
+    }
+
+    public boolean hasEntity() {
+        return true;
+    }
+
+    public AtompubResponseContext setWriter(
+        org.apache.abdera2.writer.Writer writer) {
+      throw new UnsupportedOperationException();
+    }
+
+  public void writeTo(OutputStream out, org.apache.abdera2.writer.Writer writer) throws IOException {
+  throw new UnsupportedOperationException();
+}
+
+public void writeTo(Writer javaWriter, org.apache.abdera2.writer.Writer abderaWriter) throws IOException {
+  throw new UnsupportedOperationException();
+}
+}

Propchange: abdera/abdera2/server/src/main/java/org/apache/abdera2/protocol/server/context/StreamWriterResponseContext.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



Mime
View raw message