summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common')
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPCacheContext.java280
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPConstants.java36
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPContentTypeMapper.java58
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPContext.java46
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPHeader.java78
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPUtils.java110
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/ThreadHTTPContext.java42
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORS.java37
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORSConfiguration.java105
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORSConfigurationFactory.java34
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORSHeaderProcessor.java104
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/xml/CORSConfigurationProcessor.java256
12 files changed, 1186 insertions, 0 deletions
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPCacheContext.java b/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPCacheContext.java
new file mode 100644
index 0000000000..08faf6a14b
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPCacheContext.java
@@ -0,0 +1,280 @@
+/*
+ * 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;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * A class to store cache settings for Atom and HTTP requests and responses.
+ *
+ * Predicates are statements that work in conjunction with
+ * ETags and LastModified dates to determine if a precondition
+ * or postcondition is satisfied.
+ * See HTTP specification for how predicates wrk:
+ * http://tools.ietf.org/html/rfc2616
+ * Example predicates in HTTP include If-Match, If-None-Match,
+ * If-Modified-Since, If-Unmodified-Since, If-Range.
+ *
+ * @version $Rev$ $Date$
+ */
+public class HTTPCacheContext {
+ public static final SimpleDateFormat RFC822DateFormat = new SimpleDateFormat( "EEE, dd MMM yyyy HH:mm:ss Z" ); // RFC 822 date time
+
+ public boolean enabled;
+ public String eTag;
+ public String lastModified;
+ public Date lastModifiedDate;
+ public boolean ifModifiedSince;
+ public boolean ifUnmodifiedSince;
+ public boolean ifMatch;
+ public boolean ifNoneMatch;
+ public boolean ifRange;
+
+
+ /**
+ * Enabled is true whenever ETag, LastModified, or predicate is set.
+ * @return the enabled
+ */
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ /**
+ * @param enabled the enabled to set
+ */
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ /**
+ * An ETag is a unique ID for an item. It changes when
+ * a field in the item or the update date changes.
+ * See HTTP specification for how ETags work:
+ * http://tools.ietf.org/html/rfc2616
+ * @return the eTag
+ */
+ public String getETag() {
+ return eTag;
+ }
+
+ /**
+ * @param tag the eTag to set
+ */
+ public void setETag(String tag) {
+ eTag = tag;
+ enabled = true;
+ }
+
+ /**
+ * The LastModified date is the time the item was last
+ * changed. See HTTP specification for how ETags work:
+ * http://tools.ietf.org/html/rfc2616
+ * @return the lastModified
+ */
+ public String getLastModified() {
+ return lastModified;
+ }
+
+ /**
+ * The LastModified date is the time the item was last
+ * changed. See HTTP specification for how ETags work:
+ * http://tools.ietf.org/html/rfc2616
+ * @return the lastModified
+ */
+ public Date getLastModifiedAsDate() {
+ return lastModifiedDate;
+ }
+
+ /**
+ * @param lastModified the lastModified to set
+ */
+ public void setLastModified(String lastModified) throws java.text.ParseException {
+ this.lastModified = lastModified;
+ // Catch date formatting on input to help debugging.
+ lastModifiedDate = RFC822DateFormat.parse( lastModified );
+ enabled = true;
+ }
+
+ /**
+ * @param lastModified the lastModified to set
+ */
+ public void setLastModified(Date updated) {
+ this.lastModified = RFC822DateFormat.format( updated );
+ lastModifiedDate = updated;
+ enabled = true;
+ }
+
+ /**
+ * @return the ifModifedSince
+ */
+ public boolean isIfModifiedSince() {
+ return ifModifiedSince;
+ }
+
+ /**
+ * @param ifModifedSince the ifModifedSince to set
+ */
+ public void setIfModifiedSince(boolean ifModifiedSince) {
+ this.ifModifiedSince = ifModifiedSince;
+ if ( ifModifiedSince ) {
+ enabled = true;
+ }
+ }
+
+ /**
+ * @return the ifUnModifiedSince
+ */
+ public boolean isIfUnmodifiedSince() {
+ return ifUnmodifiedSince;
+ }
+
+ /**
+ * @param ifUnModifiedSince the ifUnModifiedSince to set
+ */
+ public void setIfUnmodifiedSince(boolean ifUnmodifiedSince) {
+ this.ifUnmodifiedSince = ifUnmodifiedSince;
+ if ( ifUnmodifiedSince ) {
+ enabled = true;
+ }
+ }
+
+ /**
+ * @return the ifMatch
+ */
+ public boolean isIfMatch() {
+ return ifMatch;
+ }
+
+ /**
+ * @param ifMatch the ifMatch to set
+ */
+ public void setIfMatch(boolean ifMatch) {
+ this.ifMatch = ifMatch;
+ if ( ifMatch ) {
+ enabled = true;
+ }
+ }
+
+ /**
+ * @return the ifNoneMatch
+ */
+ public boolean isIfNoneMatch() {
+ return ifNoneMatch;
+ }
+
+ /**
+ * @param ifNoneMatch the ifNoneMatch to set
+ */
+ public void setIfNoneMatch(boolean ifNoneMatch) {
+ this.ifNoneMatch = ifNoneMatch;
+ if ( ifNoneMatch ) {
+ enabled = true;
+ }
+ }
+
+ /**
+ * @return the ifRange
+ */
+ public boolean isIfRange() {
+ return ifRange;
+ }
+
+ /**
+ * @param ifRange the ifRange to set
+ */
+ public void setIfRange(boolean ifRange) {
+ this.ifRange = ifRange;
+ if ( ifRange ) {
+ enabled = true;
+ }
+ }
+
+ /**
+ * Gets the cache context information (ETag, LastModified, predicates) from the Http request.
+ * @param request
+ * @return
+ */
+ public static HTTPCacheContext createCacheContextFromRequest( HttpServletRequest request ) throws java.text.ParseException {
+ HTTPCacheContext context = new HTTPCacheContext();
+
+ String eTag = request.getHeader( "If-Match" );
+ if ( eTag != null ) {
+ context.setETag( eTag );
+ context.setIfMatch( true );
+ }
+ eTag = request.getHeader( "If-None-Match" );
+ if ( eTag != null ) {
+ context.setETag( eTag );
+ context.setIfNoneMatch( true );
+ }
+ String lastModifiedString = request.getHeader( "If-Modified-Since" );
+ if ( lastModifiedString != null ) {
+ context.setLastModified( lastModifiedString );
+ context.setIfModifiedSince( true );
+ }
+ lastModifiedString = request.getHeader( "If-Unmodified-Since" );
+ if ( lastModifiedString != null ) {
+ context.setLastModified( lastModifiedString );
+ context.setIfUnmodifiedSince( true );
+ }
+ lastModifiedString = request.getHeader( "If-Range" );
+ if ( lastModifiedString != null ) {
+ context.setLastModified( lastModifiedString );
+ context.setIfRange( true );
+ }
+ return context;
+ }
+
+ public String toString() {
+ final String PREDPREFIX = ", predicates=";
+ StringBuffer sb = new StringBuffer(PREDPREFIX);
+ if ( ifMatch || ifNoneMatch || ifModifiedSince || ifUnmodifiedSince || ifRange ) {
+ if ( ifMatch ) {
+ if ( sb.length() > PREDPREFIX.length() ) sb.append( ", ");
+ sb.append("If-Match");
+ }
+ if ( ifNoneMatch ) {
+ if ( sb.length() > PREDPREFIX.length() ) sb.append( ", ");
+ sb.append("If-None-Match");
+ }
+ if ( ifModifiedSince ) {
+ if ( sb.length() > PREDPREFIX.length() ) sb.append( ", ");
+ sb.append("If-Modified-Since");
+ }
+ if ( ifUnmodifiedSince ) {
+ if ( sb.length() > PREDPREFIX.length() ) sb.append( ", ");
+ sb.append("If-UnModified-Since");
+ }
+ if ( ifRange ) {
+ if ( sb.length() > PREDPREFIX.length() ) sb.append( ", ");
+ sb.append("If-Range");
+ }
+ } else {
+ sb.append("null");
+ }
+
+ return "eTag=" + eTag + ", lastModified=" + lastModified
+ + sb.toString();
+ }
+
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPConstants.java b/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPConstants.java
new file mode 100644
index 0000000000..056e7f5f54
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPConstants.java
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+/**
+ * HTTP generic constants
+ *
+ * @version $Rev$ $Date$
+ */
+public interface HTTPConstants {
+ public static final String CHARACTER_ENCODING_UTF8 = "UTF-8";
+
+ public static final String HTM = "htm";
+ public static final String HTML = "html";
+ public static final String JAVASCRIPT = "js";
+
+ public static final String HTML_CONTENT_TYPE = "text/html";
+ public static final String JAVASCRIPT_CONTENT_TYPE = "text/javascript";
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPContentTypeMapper.java b/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPContentTypeMapper.java
new file mode 100644
index 0000000000..035e7c0fa6
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPContentTypeMapper.java
@@ -0,0 +1,58 @@
+/*
+ * 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;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Utility class to provide default HTTP Content-Type header
+ * based on resource type
+ *
+ * @version $Rev$ $Date$
+ */
+public class HTTPContentTypeMapper implements HTTPConstants{
+ private static Map<String, String> contentTypeTable = new HashMap<String, String>();
+
+ static {
+ contentTypeTable.put(HTM, HTML_CONTENT_TYPE);
+ contentTypeTable.put(HTML, HTML_CONTENT_TYPE);
+ contentTypeTable.put(JAVASCRIPT, JAVASCRIPT_CONTENT_TYPE);
+ }
+
+ /**
+ * Provided a resource path, identify default content-type based on the resource extension
+ * @param resourcePath
+ * @return
+ */
+ public static String getContentType(String resourcePath) {
+ return contentTypeTable.get(getResourceType(resourcePath));
+ }
+
+ /**
+ * Utility function to calculate file type based on its extension
+ * Useful to map HTTP content-type based on file extension
+ * @param resource the resource/file name
+ * @return the resource type/extension
+ */
+ private static String getResourceType(String resource) {
+ return resource.substring(resource.lastIndexOf(".") + 1);
+ }
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPContext.java b/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPContext.java
new file mode 100644
index 0000000000..3324be6ef1
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPContext.java
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * HTTP Context used as binding context in HTTP related bindings
+ *
+ * @version $Rev$ $Date$
+ */
+public class HTTPContext {
+ private HttpServletRequest request;
+ private HttpServletResponse response;
+
+ public HttpServletRequest getHttpRequest() {
+ return request;
+ }
+ public void setHttpRequest(HttpServletRequest request) {
+ this.request = request;
+ }
+ public HttpServletResponse getHttpResponse() {
+ return response;
+ }
+ public void setHttpResponse(HttpServletResponse response) {
+ this.response = response;
+ }
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPHeader.java b/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPHeader.java
new file mode 100644
index 0000000000..63f62d1e5c
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPHeader.java
@@ -0,0 +1,78 @@
+/*
+ * 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;
+
+/**
+ * Wrapper for HTTP header name/value pair
+ *
+ * @version $Rev$ $Date$
+ */
+
+public class HTTPHeader {
+ private String name;
+ private String value;
+
+ public HTTPHeader() {
+ super();
+ }
+
+ public HTTPHeader(String name, String value) {
+ super();
+ this.name = name;
+ this.value = value;
+ }
+
+ /**
+ * Get header name
+ * @return the header name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Set header value
+ * @param name the header name
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Get header value
+ * @return the header value
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * Set header value
+ * @param value the header value
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return "HTTPHeader [name=" + name + ", value=" + value + "]";
+ }
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPUtils.java b/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPUtils.java
new file mode 100644
index 0000000000..6ab6216522
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPUtils.java
@@ -0,0 +1,110 @@
+/*
+ * 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;
+
+import java.math.BigInteger;
+import java.security.MessageDigest;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ *
+ * @tuscany.spi.extension.asclient
+ *
+ */
+public class HTTPUtils {
+
+ /**
+ * Utility method to set common http headers and other stuff in a
+ * default http response. Applications / Extensions can then override and
+ * tweak as they see fit.
+ *
+ * @param response
+ */
+ public static void prepareHTTPResponse(HttpServletResponse response) {
+ response.setDateHeader("Date", System.currentTimeMillis());
+ }
+
+ /**
+ * Calculate the relative request path taking in consideration if
+ * the application is running in a embedded webContatiner or from
+ * within a web application server host environment
+ *
+ * @param request The http request
+ * @return the relative path
+ */
+ public static String getRequestPath(HttpServletRequest request) {
+ // Get the request path
+ String contextPath = request.getContextPath();
+ String servletPath = request.getServletPath();
+ String requestURI = request.getRequestURI();
+
+ int contextPathLength = contextPath.length();
+ int servletPathLenght = servletPath.contains(contextPath) ? servletPath.length() - contextPath.length() : servletPath.length();
+
+ String requestPath = requestURI.substring(contextPathLength + servletPathLenght);
+
+ return requestPath;
+ }
+
+ /**
+ * Calculate the context root for an application taking in consideration if
+ * the application is running in a embedded webContatiner or from
+ * within a web application server host environment.
+ *
+ * In the case of webContainer the contextRoot will always be a empty string.
+ *
+ * @param request The http request
+ * @return the contextRoot
+ */
+ public static String getContextRoot(HttpServletRequest request) {
+ // Get the request path
+ String contextPath = request.getContextPath();
+ String requestURI = request.getRequestURI();
+
+ int contextPathLength = contextPath.length();
+
+ String contextRoot = requestURI.substring(0, contextPathLength);
+
+ return contextRoot;
+ }
+
+ /**
+ * Calculate the ETag using MD5 Hash Algorithm
+ * @param content the content to hash
+ * @return
+ */
+ public static String calculateHashETag(byte[] content) {
+ String eTag = "invalid";
+ try {
+ MessageDigest messageDigest = MessageDigest.getInstance("MD5");
+ byte[] digest = messageDigest.digest(content);
+ BigInteger number = new BigInteger(1, digest);
+ StringBuffer sb = new StringBuffer('0');
+ sb.append(number.toString(16));
+ eTag = sb.toString();
+ } catch(Exception e) {
+ //ignore, we will return random etag
+ eTag = Integer.toString((new java.util.Random()).nextInt(Integer.MAX_VALUE));
+ }
+ return eTag;
+ }
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/ThreadHTTPContext.java b/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/ThreadHTTPContext.java
new file mode 100644
index 0000000000..fb1206f005
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/ThreadHTTPContext.java
@@ -0,0 +1,42 @@
+/*
+ * 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;
+
+public class ThreadHTTPContext {
+
+ private static final ThreadLocal<HTTPContext> CONTEXT = new ThreadLocal<HTTPContext>();
+
+ private ThreadHTTPContext() {
+ }
+
+ public static HTTPContext setHTTPContext(HTTPContext context) {
+ HTTPContext old = CONTEXT.get();
+ CONTEXT.set(context);
+ return old;
+ }
+
+ public static HTTPContext getHTTPContext() {
+ return CONTEXT.get();
+ }
+
+ public static void removeHTTPContext() {
+ CONTEXT.remove();
+ }
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORS.java b/sca-java-2.x/tags/2.0.1-RC1/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/tags/2.0.1-RC1/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/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORSConfiguration.java b/sca-java-2.x/tags/2.0.1-RC1/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/tags/2.0.1-RC1/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/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORSConfigurationFactory.java b/sca-java-2.x/tags/2.0.1-RC1/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/tags/2.0.1-RC1/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/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORSHeaderProcessor.java b/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORSHeaderProcessor.java
new file mode 100644
index 0000000000..ffb92f520f
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/CORSHeaderProcessor.java
@@ -0,0 +1,104 @@
+/*
+ * 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) {
+ String allowHeaders = request.getHeader("Access-Control-Request-Headers");
+ if (allowHeaders == null) {
+ allowHeaders = "Content-Type, Accept, Origin, X-Requested-With";
+ }
+ String allowMethods = request.getHeader("Access-Control-Request-Method");
+ if (allowMethods == null) {
+ allowHeaders = "OPTIONS, HEAD, GET, POST, PUT, DELETE";
+ }
+
+ String allowOrigins = request.getHeader("Origin");
+ if (allowOrigins == null) {
+ allowOrigins = "*";
+ }
+
+ response.setHeader("Access-Control-Allow-Origin", allowOrigins);
+ response.setHeader("Access-Control-Allow-Headers", allowHeaders);
+ response.setHeader("Access-Control-Allow-Credentials", "true");
+ if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
+ response.setHeader("Access-Control-Allow-Methods", allowMethods);
+ response.setHeader("Access-Control-Max-Age", "1728000");
+ }
+ return;
+ }
+
+ if (config.isAllowCredentials()) {
+ response.setHeader("Access-Control-Allow-Credentials", "true");
+ }
+
+ if (config.getMaxAge() > 0) {
+ response.setHeader("Access-Control-Max-Age", Integer.toString(config.getMaxAge()));
+ }
+
+ response.setHeader("Access-Control-Allow-Origin", getAllowOrigins(config, request));
+ 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, HttpServletRequest request) {
+ String allowOrigins = request.getHeader("Origin");
+ if (allowOrigins == null) {
+ allowOrigins = "*";
+ }
+ return getListValues(config.getAllowOrigins(), allowOrigins);
+ }
+
+ 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, Content-Type, Accept, Origin");
+ }
+
+ private static String getExposeHeaders(CORSConfiguration config) {
+ return getListValues(config.getExposeHeaders(), "X-Requested-With, Content-Type");
+ }
+
+ 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/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/xml/CORSConfigurationProcessor.java b/sca-java-2.x/tags/2.0.1-RC1/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/cors/xml/CORSConfigurationProcessor.java
new file mode 100644
index 0000000000..bc396d66f3
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/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>
+ * </exposeHeaders>
+ *
+ * </corsConfiguration>
+ **/
+
+ 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
+ }
+
+
+}