summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlresende <lresende@13f79535-47bb-0310-9956-ffa450edef68>2012-02-27 19:08:28 +0000
committerlresende <lresende@13f79535-47bb-0310-9956-ffa450edef68>2012-02-27 19:08:28 +0000
commitde16ae0ca468c3d226d26cd88e3067a406c95a6e (patch)
tree9020d6913de06c1e377a536b83286d0feaf9fafe
parenta61b51a3f30deee9877d21d8594c237263ed0117 (diff)
Adding generic support for CORS (models, common-runtime, etc)
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1294278 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--sca-java-2.x/trunk/modules/common-http/META-INF/MANIFEST.MF6
-rw-r--r--sca-java-2.x/trunk/modules/common-http/pom.xml6
-rw-r--r--sca-java-2.x/trunk/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORS.java37
-rw-r--r--sca-java-2.x/trunk/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORSConfiguration.java105
-rw-r--r--sca-java-2.x/trunk/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORSConfigurationFactory.java34
-rw-r--r--sca-java-2.x/trunk/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORSHeaderProcessor.java84
-rw-r--r--sca-java-2.x/trunk/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/xml/CORSConfigurationProcessor.java256
-rw-r--r--sca-java-2.x/trunk/modules/common-http/src/main/resources/META-INF/services/org.apache.tuscany.sca.common.http.cors.CORSConfigurationFactory20
-rw-r--r--sca-java-2.x/trunk/modules/common-http/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor19
-rw-r--r--sca-java-2.x/trunk/modules/common-http/src/test/java/org/apache/tuscany/sca/common/http/cors/xml/CORSConfigurationProcessorTestCase.java95
10 files changed, 660 insertions, 2 deletions
diff --git a/sca-java-2.x/trunk/modules/common-http/META-INF/MANIFEST.MF b/sca-java-2.x/trunk/modules/common-http/META-INF/MANIFEST.MF
index 4afe089d61..72f2052149 100644
--- a/sca-java-2.x/trunk/modules/common-http/META-INF/MANIFEST.MF
+++ b/sca-java-2.x/trunk/modules/common-http/META-INF/MANIFEST.MF
@@ -8,8 +8,10 @@ Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
Bundle-Description: Apache Tuscany SCA Common HTTP
Bundle-SymbolicName: org.apache.tuscany.sca.common.http
Bundle-DocURL: http://www.apache.org/
-Export-Package: org.apache.tuscany.sca.common.http;version="2.0.0";uses:="javax.servlet.http"
-Import-Package: javax.servlet.http
+Export-Package: org.apache.tuscany.sca.common.http;version="2.0.0";uses:="javax.servlet.http",
+ org.apache.tuscany.sca.common.http.cors;version="2.0.0"
+Import-Package: javax.servlet;version="2.5.0",
+ javax.servlet.http
Bundle-RequiredExecutionEnvironment: J2SE-1.5,JavaSE-1.6
diff --git a/sca-java-2.x/trunk/modules/common-http/pom.xml b/sca-java-2.x/trunk/modules/common-http/pom.xml
index 72d5493280..ede1892d4e 100644
--- a/sca-java-2.x/trunk/modules/common-http/pom.xml
+++ b/sca-java-2.x/trunk/modules/common-http/pom.xml
@@ -29,6 +29,12 @@
<name>Apache Tuscany SCA Common HTTP</name>
<dependencies>
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-assembly-xml</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ </dependency>
+
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
diff --git a/sca-java-2.x/trunk/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORS.java b/sca-java-2.x/trunk/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORS.java
new file mode 100644
index 0000000000..15852e24c8
--- /dev/null
+++ b/sca-java-2.x/trunk/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORS.java
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+package org.apache.tuscany.sca.common.http.cors;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface CORS {
+ /**
+ *
+ * @return
+ */
+ CORSConfiguration getCORSConfiguration();
+
+ /**
+ *
+ * @param config
+ */
+ void setCORSConfiguration(CORSConfiguration config);
+}
diff --git a/sca-java-2.x/trunk/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORSConfiguration.java b/sca-java-2.x/trunk/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORSConfiguration.java
new file mode 100644
index 0000000000..0d89c5c9cb
--- /dev/null
+++ b/sca-java-2.x/trunk/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORSConfiguration.java
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+package org.apache.tuscany.sca.common.http.cors;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CORSConfiguration {
+ List<String> allowOrigins = new ArrayList<String>();
+ List<String> allowHeaders = new ArrayList<String>();
+ List<String> exposeHeaders = new ArrayList<String>();
+ List<String> allowMethods = new ArrayList<String>();
+ boolean allowCredentials;
+ int maxAge;
+
+ public CORSConfiguration() {
+
+ }
+
+ public List<String> getAllowOrigins() {
+ return allowOrigins;
+ }
+
+ public void setAllowOrigins(List<String> allowOrigins) {
+ this.allowOrigins = allowOrigins;
+ }
+
+ public List<String> getAllowHeaders() {
+ return allowHeaders;
+ }
+
+ public void setAllowHeaders(List<String> allowHeaders) {
+ this.allowHeaders = allowHeaders;
+ }
+
+ public List<String> getExposeHeaders() {
+ return exposeHeaders;
+ }
+
+ public void setExposeHeaders(List<String> exposeHeaders) {
+ this.exposeHeaders = exposeHeaders;
+ }
+
+ public List<String> getAllowMethods() {
+ return allowMethods;
+ }
+
+ public void setAllowMethods(List<String> allowMethods) {
+ this.allowMethods = allowMethods;
+ }
+
+ public boolean isAllowCredentials() {
+ return allowCredentials;
+ }
+
+ public void setAllowCredentials(boolean allowCredentials) {
+ this.allowCredentials = allowCredentials;
+ }
+
+ public int getMaxAge() {
+ return maxAge;
+ }
+
+ public void setMaxAge(int maxAge) {
+ this.maxAge = maxAge;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "CORSConfiguration [allowOrigins=" + allowOrigins
+ + ", allowHeaders="
+ + allowHeaders
+ + ", exposeHeaders="
+ + exposeHeaders
+ + ", allowMethods="
+ + allowMethods
+ + ", allowCredentials="
+ + allowCredentials
+ + ", maxAge="
+ + maxAge
+ + "]";
+ }
+
+
+}
diff --git a/sca-java-2.x/trunk/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORSConfigurationFactory.java b/sca-java-2.x/trunk/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORSConfigurationFactory.java
new file mode 100644
index 0000000000..5cbd6865a0
--- /dev/null
+++ b/sca-java-2.x/trunk/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORSConfigurationFactory.java
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+package org.apache.tuscany.sca.common.http.cors;
+
+/**
+ * Factory for the CORS Configuration
+ */
+public class CORSConfigurationFactory {
+
+ /**
+ * Create a new CORS Configuration Model
+ * @return
+ */
+ public CORSConfiguration createCORSConfiguration() {
+ return new CORSConfiguration();
+ }
+}
diff --git a/sca-java-2.x/trunk/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORSHeaderProcessor.java b/sca-java-2.x/trunk/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORSHeaderProcessor.java
new file mode 100644
index 0000000000..71afd9d09a
--- /dev/null
+++ b/sca-java-2.x/trunk/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORSHeaderProcessor.java
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+package org.apache.tuscany.sca.common.http.cors;
+
+import java.io.IOException;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class CORSHeaderProcessor {
+ public static void processCORS(CORSConfiguration config, HttpServletRequest request, HttpServletResponse response) throws IOException {
+
+ if(config == null) {
+ response.setHeader("Access-Control-Allow-Origin", "*");
+ response.setHeader("Access-Control-Allow-Headers", "X-Requested-With");
+ if (request.getMethod().equals("OPTIONS")) {
+ response.setHeader("Access-Control-Allow-Methods", "OPTIONS, HEAD, GET, POST, PUT, DELETE");
+ response.setHeader("Access-Control-Max-Age", "1728000");
+ return;
+ }
+ }
+
+ if(config.allowCredentials) {
+ response.setHeader("Access-Control-Allow-Credentials", Boolean.toString(config.isAllowCredentials()));
+ }
+
+ if(config.getMaxAge() > 0) {
+ response.setHeader("Access-Control-Max-Age", Integer.toString(config.getMaxAge()));
+ }
+
+ response.setHeader("Access-Control-Allow-Origin", getAllowOrigins(config));
+ response.setHeader("Access-Control-Allow-Methods", getAllowMethods(config));
+ response.setHeader("Access-Control-Allow-Headers", getAllowHeaders(config));
+ response.setHeader("Access-Control-Expose-Headers", getExposeHeaders(config));
+ }
+
+ private static String getAllowOrigins(CORSConfiguration config) {
+ return getListValues(config.getAllowOrigins(), "*");
+ }
+
+ private static String getAllowMethods(CORSConfiguration config) {
+ return getListValues(config.getAllowMethods(), "OPTIONS, HEAD, GET, POST, PUT, DELETE");
+ }
+
+ private static String getAllowHeaders(CORSConfiguration config) {
+ return getListValues(config.getAllowHeaders(), "X-Requested-With");
+ }
+
+ private static String getExposeHeaders(CORSConfiguration config) {
+ return getListValues(config.getExposeHeaders(), "X-Requested-With");
+ }
+
+ private static String getListValues(List<String> list, String defaultValue) {
+ StringBuffer values = new StringBuffer();
+ if(list != null && list.isEmpty() == false) {
+ for(String value : list) {
+ values.append(value).append(",");
+ }
+ values.deleteCharAt(values.length());
+ } else {
+ values.append(defaultValue);
+ }
+
+ return values.toString();
+ }
+}
diff --git a/sca-java-2.x/trunk/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/xml/CORSConfigurationProcessor.java b/sca-java-2.x/trunk/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/xml/CORSConfigurationProcessor.java
new file mode 100644
index 0000000000..d16e07ebf3
--- /dev/null
+++ b/sca-java-2.x/trunk/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/xml/CORSConfigurationProcessor.java
@@ -0,0 +1,256 @@
+/*
+ * 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.
+ */
+
+package org.apache.tuscany.sca.common.http.cors.xml;
+
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.tuscany.sca.assembly.Base;
+import org.apache.tuscany.sca.common.http.cors.CORSConfiguration;
+import org.apache.tuscany.sca.common.http.cors.CORSConfigurationFactory;
+import org.apache.tuscany.sca.contribution.processor.BaseStAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
+import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
+import org.apache.tuscany.sca.contribution.processor.ContributionWriteException;
+import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.StAXAttributeProcessor;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+
+/**
+ * CORS Configuration Artifact processor
+ * @version $Rev$ $Date$
+ */
+public class CORSConfigurationProcessor extends BaseStAXArtifactProcessor implements StAXArtifactProcessor<CORSConfiguration> {
+
+ private static final QName CORS_QNAME = new QName(Base.SCA11_TUSCANY_NS, "corsConfiguration");
+
+ private static final QName ALLOW_CREDENTIALS_QNAME = new QName(Base.SCA11_TUSCANY_NS, "allowCredentials");
+ private static final QName MAX_AGE_QNAME = new QName(Base.SCA11_TUSCANY_NS, "maxAge");
+
+ private static final QName ALLOW_ORIGINS_QNAME = new QName(Base.SCA11_TUSCANY_NS, "allowOrigins");
+ private static final QName ORIGIN_QNAME = new QName(Base.SCA11_TUSCANY_NS, "origin");
+
+ private static final QName ALLOW_METHODS_QNAME = new QName(Base.SCA11_TUSCANY_NS, "allowMethods");
+ private static final QName METHOD_QNAME = new QName(Base.SCA11_TUSCANY_NS, "method");
+
+ private static final QName ALLOW_HEADERS_QNAME = new QName(Base.SCA11_TUSCANY_NS, "allowHeaders");
+ private static final QName EXPOSE_HEADERS_QNAME = new QName(Base.SCA11_TUSCANY_NS, "exposeHeaders");
+ private static final QName HEADER_QNAME = new QName(Base.SCA11_TUSCANY_NS, "header");
+
+
+
+ private StAXArtifactProcessor<Object> extensionProcessor;
+ private CORSConfigurationFactory corsConfigurationFactory;
+
+ public CORSConfigurationProcessor(ExtensionPointRegistry extensionPoints,
+ StAXArtifactProcessor<Object> extensionProcessor,
+ StAXAttributeProcessor<Object> extensionAttributeProcessor) {
+
+ FactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class);
+ this.corsConfigurationFactory = modelFactories.getFactory(CORSConfigurationFactory.class);
+
+ this.extensionProcessor = (StAXArtifactProcessor<Object>)extensionProcessor;
+ }
+
+
+ @Override
+ public QName getArtifactType() {
+ return CORS_QNAME;
+ }
+
+ @Override
+ public Class<CORSConfiguration> getModelType() {
+ return CORSConfiguration.class;
+ }
+
+ @Override
+ public CORSConfiguration read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException, XMLStreamException {
+
+ CORSConfiguration corsConfiguration = corsConfigurationFactory.createCORSConfiguration();
+
+ /**
+ * <corsConfiguration>
+ * <allowCredentials>true</allowCredentials>
+ *
+ * <maxAge>100</maxAge>
+ *
+ * <allowOrigins>
+ * <origin>http://www.sfly.com</origin>
+ * </allowOrigins>
+ *
+ * <allowMethods>
+ * <method>PUT</method>
+ * <method>POST</method>
+ * </allowMethods>
+ *
+ * <allowHeaders>
+ * <header>X-custom-1</header>
+ * <header>X-custom-2</header>
+ * </allowHeaders>
+ *
+ * <exposeHeaders>
+ * <header>X-custom-1</header>
+ * <header>X-custom-2</header>
+ * </expose-headers>
+ *
+ * </cors-configuration>
+ **/
+
+ HeaderElementType headerType = null;
+
+ while(reader.hasNext()) {
+ QName elementName = null;
+ int event = reader.getEventType();
+ switch (event) {
+ case START_ELEMENT:
+ elementName = reader.getName();
+
+ if (ALLOW_CREDENTIALS_QNAME.equals(elementName)) {
+ String value = reader.getElementText();
+ corsConfiguration.setAllowCredentials(Boolean.parseBoolean(value));
+ } else if (MAX_AGE_QNAME.equals(elementName)) {
+ String value = reader.getElementText();
+ corsConfiguration.setMaxAge(Integer.parseInt(value));
+ } else if (ORIGIN_QNAME.equals(elementName)) {
+ String value = reader.getElementText();
+ corsConfiguration.getAllowOrigins().add(value);
+ } else if (METHOD_QNAME.equals(elementName)) {
+ String value = reader.getElementText();
+ corsConfiguration.getAllowMethods().add(value);
+ } else if (ALLOW_HEADERS_QNAME.equals(elementName)) {
+ headerType = HeaderElementType.ALLOWHEADERS;
+ } else if (EXPOSE_HEADERS_QNAME.equals(elementName)) {
+ headerType = HeaderElementType.EXPOSEHEADERS;
+ } else if (HEADER_QNAME.equals(elementName)) {
+ if(headerType != null) {
+ String value = reader.getElementText();
+ if(headerType == HeaderElementType.ALLOWHEADERS) {
+ corsConfiguration.getAllowHeaders().add(value);
+ } else {
+ corsConfiguration.getExposeHeaders().add(value);
+ }
+ }
+ }
+
+ break;
+
+ case END_ELEMENT:
+ elementName = reader.getName();
+ if(CORS_QNAME.equals(elementName)) {
+ return corsConfiguration;
+ }
+ break;
+ }
+
+
+
+ // Read the next element
+ if (reader.hasNext()) {
+ reader.next();
+ }
+ }
+
+ return corsConfiguration;
+ }
+
+ @Override
+ public void write(CORSConfiguration model, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException, XMLStreamException {
+
+ writeStart(writer, CORS_QNAME.getNamespaceURI(), CORS_QNAME.getLocalPart());
+
+ // Write allowCredentials
+ writeStart(writer, ALLOW_CREDENTIALS_QNAME.getNamespaceURI(), ALLOW_CREDENTIALS_QNAME.getLocalPart());
+ writer.writeCharacters(Boolean.toString(model.isAllowCredentials()));
+ writeEnd(writer);
+
+ // Write maxAge
+ writeStart(writer, MAX_AGE_QNAME.getNamespaceURI(), MAX_AGE_QNAME.getLocalPart());
+ writer.writeCharacters(Integer.toString(model.getMaxAge()));
+ writeEnd(writer);
+
+ // Allow origins
+ if(model.getAllowOrigins() != null && model.getAllowOrigins().isEmpty() == false) {
+ writeStart(writer, ALLOW_ORIGINS_QNAME.getNamespaceURI(), ALLOW_ORIGINS_QNAME.getLocalPart());
+ for(String origin : model.getAllowOrigins()) {
+ writeStart(writer, ORIGIN_QNAME.getNamespaceURI(), ORIGIN_QNAME.getLocalPart());
+ writer.writeCharacters(origin);
+ writeEnd(writer);
+ }
+ writeEnd(writer);
+ }
+
+ // Allow methods
+ if(model.getAllowMethods() != null && model.getAllowMethods().isEmpty() == false) {
+ writeStart(writer, ALLOW_METHODS_QNAME.getNamespaceURI(), ALLOW_METHODS_QNAME.getLocalPart());
+ for(String method : model.getAllowMethods()) {
+ writeStart(writer, METHOD_QNAME.getNamespaceURI(), METHOD_QNAME.getLocalPart());
+ writer.writeCharacters(method);
+ writeEnd(writer);
+ }
+ writeEnd(writer);
+ }
+
+
+ // Allow headers
+ if(model.getAllowHeaders() != null && model.getAllowHeaders().isEmpty() == false) {
+ writeStart(writer, ALLOW_HEADERS_QNAME.getNamespaceURI(), ALLOW_HEADERS_QNAME.getLocalPart());
+ for(String header : model.getAllowHeaders()) {
+ writeStart(writer, HEADER_QNAME.getNamespaceURI(), HEADER_QNAME.getLocalPart());
+ writer.writeCharacters(header);
+ writeEnd(writer);
+ }
+ writeEnd(writer);
+ }
+
+
+ // Exposed headers
+ if(model.getExposeHeaders() != null && model.getExposeHeaders().isEmpty() == false) {
+ writeStart(writer, EXPOSE_HEADERS_QNAME.getNamespaceURI(), EXPOSE_HEADERS_QNAME.getLocalPart());
+ for(String header : model.getExposeHeaders()) {
+ writeStart(writer, HEADER_QNAME.getNamespaceURI(), HEADER_QNAME.getLocalPart());
+ writer.writeCharacters(header);
+ writeEnd(writer);
+ }
+ writeEnd(writer);
+ }
+ writeEnd(writer);
+ }
+
+ @Override
+ public void resolve(CORSConfiguration model, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException {
+ // Should not need to do anything here for now...
+ }
+
+
+ enum HeaderElementType {
+ ALLOWHEADERS,
+ EXPOSEHEADERS
+ }
+
+
+}
diff --git a/sca-java-2.x/trunk/modules/common-http/src/main/resources/META-INF/services/org.apache.tuscany.sca.common.http.cors.CORSConfigurationFactory b/sca-java-2.x/trunk/modules/common-http/src/main/resources/META-INF/services/org.apache.tuscany.sca.common.http.cors.CORSConfigurationFactory
new file mode 100644
index 0000000000..8a8981ab12
--- /dev/null
+++ b/sca-java-2.x/trunk/modules/common-http/src/main/resources/META-INF/services/org.apache.tuscany.sca.common.http.cors.CORSConfigurationFactory
@@ -0,0 +1,20 @@
+# 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.
+
+# Implementation class for model factory
+org.apache.tuscany.sca.common.http.cors.CORSConfigurationFactory
+
diff --git a/sca-java-2.x/trunk/modules/common-http/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor b/sca-java-2.x/trunk/modules/common-http/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor
new file mode 100644
index 0000000000..c2681b0fbe
--- /dev/null
+++ b/sca-java-2.x/trunk/modules/common-http/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor
@@ -0,0 +1,19 @@
+# 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.
+
+# Implementation class for the artifact processor extension
+org.apache.tuscany.sca.common.http.cors.xml.CORSConfigurationProcessor;qname=http://tuscany.apache.org/xmlns/sca/1.1#corsConfiguration,model=org.apache.tuscany.sca.common.http.cors.CORSConfiguration,factory=org.apache.tuscany.sca.common.http.cors.CORSConfigurationFactory \ No newline at end of file
diff --git a/sca-java-2.x/trunk/modules/common-http/src/test/java/org/apache/tuscany/sca/common/http/cors/xml/CORSConfigurationProcessorTestCase.java b/sca-java-2.x/trunk/modules/common-http/src/test/java/org/apache/tuscany/sca/common/http/cors/xml/CORSConfigurationProcessorTestCase.java
new file mode 100644
index 0000000000..9aa1bc3f2a
--- /dev/null
+++ b/sca-java-2.x/trunk/modules/common-http/src/test/java/org/apache/tuscany/sca/common/http/cors/xml/CORSConfigurationProcessorTestCase.java
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+package org.apache.tuscany.sca.common.http.cors.xml;
+
+import java.io.StringReader;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+
+import junit.framework.Assert;
+
+import org.apache.tuscany.sca.common.http.cors.CORSConfiguration;
+import org.apache.tuscany.sca.contribution.processor.DefaultStAXArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class CORSConfigurationProcessorTestCase {
+
+ private static final String COMPOSITE =
+ "<?xml version=\"1.0\" encoding=\"ASCII\"?>"
+ + " <tuscany:corsConfiguration xmlns=\"http://docs.oasis-open.org/ns/opencsa/sca/200912\" xmlns:tuscany=\"http://tuscany.apache.org/xmlns/sca/1.1\" targetNamespace=\"http://cors\" >"
+ + " <tuscany:allowCredentials>true</tuscany:allowCredentials>"
+ + " <tuscany:maxAge>3600</tuscany:maxAge>"
+ + " <tuscany:allowOrigins>"
+ + " <tuscany:origin>http://www.apache.org</tuscany:origin>"
+ + " </tuscany:allowOrigins>"
+ + " <tuscany:allowMethods>"
+ + " <tuscany:method>POST</tuscany:method>"
+ + " <tuscany:method>PUT</tuscany:method>"
+ + " </tuscany:allowMethods>"
+ + " <tuscany:allowHeaders>"
+ + " <tuscany:header>X-custom-1</tuscany:header>"
+ + " <tuscany:header>X-custom-2</tuscany:header>"
+ + " </tuscany:allowHeaders>"
+ + " <tuscany:exposeHeaders>"
+ + " <tuscany:header>X-custom-1</tuscany:header>"
+ + " </tuscany:exposeHeaders>"
+ + " </tuscany:corsConfiguration>";
+
+ private static XMLInputFactory inputFactory;
+ private static StAXArtifactProcessor<Object> staxProcessor;
+ private static ProcessorContext context;
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ DefaultExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry();
+ context = new ProcessorContext(extensionPoints);
+ inputFactory = XMLInputFactory.newInstance();
+
+ StAXArtifactProcessorExtensionPoint staxProcessors = new DefaultStAXArtifactProcessorExtensionPoint(extensionPoints);
+ staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, null);
+ }
+
+ /**
+ * Test parsing valid composite definition. Valid composite populated with correct values expected.
+ * @throws Exception
+ */
+ @Test
+ public void testLoadValidComposite() throws Exception {
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(COMPOSITE));
+
+ //Composite composite = (Composite)staxProcessor.read(reader, context);
+ CORSConfiguration config = (CORSConfiguration) staxProcessor.read(reader, context);
+
+ Assert.assertNotNull(config);
+ Assert.assertTrue(config.isAllowCredentials());
+ Assert.assertEquals(3600, config.getMaxAge());
+ Assert.assertEquals(1,config.getAllowOrigins().size());
+ Assert.assertEquals(2,config.getAllowMethods().size());
+ Assert.assertEquals(2,config.getAllowHeaders().size());
+ Assert.assertEquals(1,config.getExposeHeaders().size());
+ }
+}