summaryrefslogtreecommitdiffstats
path: root/java/sca
diff options
context:
space:
mode:
authorantelder <antelder@13f79535-47bb-0310-9956-ffa450edef68>2008-08-27 14:24:14 +0000
committerantelder <antelder@13f79535-47bb-0310-9956-ffa450edef68>2008-08-27 14:24:14 +0000
commitbfa022e51868d981c7219eb7e67b65d94b7c8623 (patch)
treed8893b137f0ad1e4c22b1c5332be458f41d89eea /java/sca
parent2c189e0a7d056a9d76b2244f5dcc1a2804b7d9aa (diff)
TUSCANY-2516: Apply pacth from Dan Becker for HTTP binding should support etag and if-modified headers
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@689492 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to '')
-rw-r--r--java/sca/modules/binding-atom-abdera/pom.xml6
-rw-r--r--java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingListenerServlet.java39
-rw-r--r--java/sca/modules/binding-atom/src/main/java/org/apache/tuscany/sca/binding/atom/CacheContext.java117
-rw-r--r--java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingListenerServlet.java432
-rw-r--r--java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java42
-rw-r--r--java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceListenerServlet.java5
-rw-r--r--java/sca/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HTTPBindingTestCase.java9
-rw-r--r--java/sca/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/TestGetImpl.java6
-rw-r--r--java/sca/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/TestServiceImpl.java3
-rw-r--r--java/sca/modules/binding-http/src/main/java/org/apache/tuscany/sca/binding/http/CacheContext.java257
10 files changed, 746 insertions, 170 deletions
diff --git a/java/sca/modules/binding-atom-abdera/pom.xml b/java/sca/modules/binding-atom-abdera/pom.xml
index cfd2e60849..f10497c9c5 100644
--- a/java/sca/modules/binding-atom-abdera/pom.xml
+++ b/java/sca/modules/binding-atom-abdera/pom.xml
@@ -73,6 +73,12 @@
</dependency>
<dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-binding-http</artifactId>
+ <version>1.4-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.0.1</version>
diff --git a/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingListenerServlet.java b/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingListenerServlet.java
index bcd0d6a9bf..d31247d3ae 100644
--- a/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingListenerServlet.java
+++ b/java/sca/modules/binding-atom-abdera/src/main/java/org/apache/tuscany/sca/binding/atom/provider/AtomBindingListenerServlet.java
@@ -53,7 +53,7 @@ import org.apache.abdera.parser.Parser;
import org.apache.abdera.writer.WriterFactory;
import org.apache.commons.codec.binary.Base64;
-import org.apache.tuscany.sca.binding.atom.CacheContext;
+import org.apache.tuscany.sca.binding.http.CacheContext;
import org.apache.tuscany.sca.data.collection.Entry;
import org.apache.tuscany.sca.databinding.Mediator;
import org.apache.tuscany.sca.interfacedef.DataType;
@@ -163,7 +163,7 @@ class AtomBindingListenerServlet extends HttpServlet {
// Test for any cache info in the request
CacheContext cacheContext = null;
try {
- cacheContext = getCacheContextFromRequest( request );
+ cacheContext = CacheContext.getCacheContextFromRequest( request );
} catch ( java.text.ParseException e ) {
}
// System.out.println( "AtomBindingListener.doGet cache context=" + cacheContext );
@@ -843,39 +843,4 @@ class AtomBindingListenerServlet extends HttpServlet {
return "application/atom+xml";
}
- /**
- * Gets the cache context information (ETag, LastModified, predicates) from the Http request.
- * @param request
- * @return
- */
- public CacheContext getCacheContextFromRequest( HttpServletRequest request ) throws java.text.ParseException {
- CacheContext context = new CacheContext();
- List<String> predicates = new ArrayList<String>();
-
- String eTag = request.getHeader( "If-Match" );
- if ( eTag != null ) {
- context.setETag( eTag );
- predicates.add( "If-Match" );
- }
- eTag = request.getHeader( "If-None-Match" );
- if ( eTag != null ) {
- context.setETag( eTag );
- predicates.add( "If-None-Match" );
- }
- String lastModifiedString = request.getHeader( "If-Modified-Since" );
- if ( lastModifiedString != null ) {
- context.setLastModified( lastModifiedString );
- predicates.add( "If-Modified-Since" );
- }
- lastModifiedString = request.getHeader( "If-Unmodified-Since" );
- if ( lastModifiedString != null ) {
- context.setLastModified( lastModifiedString );
- predicates.add( "If-Unmodified-Since" );
- }
- if ( predicates.size() > 0 ) {
- context.setPredicates( predicates.toArray( new String[ 0 ] ) );
- }
- return context;
- }
-
}
diff --git a/java/sca/modules/binding-atom/src/main/java/org/apache/tuscany/sca/binding/atom/CacheContext.java b/java/sca/modules/binding-atom/src/main/java/org/apache/tuscany/sca/binding/atom/CacheContext.java
deleted file mode 100644
index 204cca963c..0000000000
--- a/java/sca/modules/binding-atom/src/main/java/org/apache/tuscany/sca/binding/atom/CacheContext.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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.binding.atom;
-
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-/**
- * A class to store cache settings for Atom and HTTP requests and responses.
- */
-public class CacheContext {
- private static final SimpleDateFormat RFC822DateFormat = new SimpleDateFormat( "EEE, dd MMM yyyy HH:mm:ss Z" ); // RFC 822 date time
- public String eTag;
- public String lastModified;
- public Date lastModifiedDate;
- public String [] predicates;
-
- /**
- * 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;
- }
- /**
- * 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 );
- }
-
- /**
- * 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 predicats in HTTP include If-Match, If-None-Match,
- * If-Modified-Since, If-Unmodified-Since, If-Range.
- * @return the predicates
- */
- public String[] getPredicates() {
- return predicates;
- }
- /**
- * @param predicates the predicates to set
- */
- public void setPredicates(String[] predicates) {
- this.predicates = predicates;
- }
-
- public String toString() {
- StringBuffer sb = new StringBuffer(", predicates=");
- if (predicates == null) {
- sb.append("null");
- } else if ( predicates.length == 0 ){
- sb.append("length=0");
- } else {
- for (int i = 0; i < predicates.length; i++) {
- if (i > 0)
- sb.append(", ");
- sb.append(predicates[i]);
- }
- }
-
- return "eTag=" + eTag + ", lastModified=" + lastModified
- + sb.toString();
- }
-}
diff --git a/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingListenerServlet.java b/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingListenerServlet.java
new file mode 100644
index 0000000000..582742bd3f
--- /dev/null
+++ b/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingListenerServlet.java
@@ -0,0 +1,432 @@
+/*
+ * 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.binding.http.provider;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URLDecoder;
+import java.text.ParseException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.tuscany.sca.binding.http.CacheContext;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.invocation.MessageFactory;
+
+/**
+ * Servlet responsible for dispatching HTTP requests to the
+ * target component implementation.
+ *
+ * @version $Rev$ $Date$
+ */
+public class HTTPBindingListenerServlet extends HttpServlet {
+ private static final long serialVersionUID = 2865466417329430610L;
+
+ private MessageFactory messageFactory;
+ private Invoker getInvoker;
+ private Invoker conditionalGetInvoker;
+ private Invoker putInvoker;
+ private Invoker conditionalPutInvoker;
+ private Invoker postInvoker;
+ private Invoker conditionalPostInvoker;
+ private Invoker deleteInvoker;
+ private Invoker conditionalDeleteInvoker;
+
+ /**
+ * Constructs a new HTTPServiceListenerServlet.
+ */
+ public HTTPBindingListenerServlet(MessageFactory messageFactory) {
+ this.messageFactory = messageFactory;
+ }
+
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ // Get the request path
+ String path = URLDecoder.decode(request.getRequestURI().substring(request.getServletPath().length()), "UTF-8");
+ if (path.length() ==0) {
+ // Redirect to a URL ending with / to make relative hrefs work
+ // relative to the served resource.
+ response.sendRedirect(request.getRequestURL().append('/').toString());
+ return;
+ }
+
+ // Invoke the get operation on the service implementation
+ Message requestMessage = messageFactory.createMessage();
+ String id = path.substring(1);
+
+ Message responseMessage = null;
+ CacheContext cacheContext = null;
+ try {
+ cacheContext = CacheContext.getCacheContextFromRequest(request);
+ } catch (ParseException e) {
+ }
+
+ // Route message based on availability of cache info and cache methods
+ if (( cacheContext != null ) && (cacheContext.isEnabled()) && (conditionalGetInvoker != null )) {
+ requestMessage.setBody(new Object[] {id, cacheContext});
+ responseMessage = conditionalGetInvoker.invoke(requestMessage);
+ } else {
+ requestMessage.setBody(new Object[] {id});
+ responseMessage = getInvoker.invoke(requestMessage);
+ }
+ if (responseMessage.isFault()) {
+ Object body = responseMessage.getBody();
+
+ int index = -1;
+ if ( -1 < (index = body.getClass().getName().indexOf( "NotModifiedException")) ) {
+ if ( index > -1 )
+ response.sendError( HttpServletResponse.SC_NOT_MODIFIED, body.toString().substring( index ));
+ else
+ response.sendError( HttpServletResponse.SC_NOT_MODIFIED );
+ return;
+ } else if ( -1 < (index = body.getClass().getName().indexOf( "PreconditionFailedException")) ) {
+ if ( index > -1 )
+ response.sendError( HttpServletResponse.SC_PRECONDITION_FAILED, body.toString().substring( index ));
+ else
+ response.sendError( HttpServletResponse.SC_PRECONDITION_FAILED );
+ return;
+ }
+
+ throw new ServletException((Throwable)responseMessage.getBody());
+ }
+
+ // Write the response from the service implementation to the response
+ // output stream
+ InputStream is = (InputStream)responseMessage.getBody();
+ OutputStream os = response.getOutputStream();
+ byte[] buffer = new byte[2048];
+ for (;;) {
+ int n = is.read(buffer);
+ if (n <= 0)
+ break;
+ os.write(buffer, 0, n);
+ }
+ os.flush();
+ os.close();
+ }
+
+ @Override
+ protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ // Get the request path
+ String path = URLDecoder.decode(request.getRequestURI().substring(request.getServletPath().length()), "UTF-8");
+ if (path.length() ==0) {
+ // Redirect to a URL ending with / to make relative hrefs work
+ // relative to the served resource.
+ response.sendRedirect(request.getRequestURL().append('/').toString());
+ return;
+ }
+
+ // Invoke the get operation on the service implementation
+ Message requestMessage = messageFactory.createMessage();
+ String id = path.substring(1);
+
+ Message responseMessage = null;
+ CacheContext cacheContext = null;
+ try {
+ cacheContext = CacheContext.getCacheContextFromRequest(request);
+ } catch (ParseException e) {
+ }
+
+ // Route message based on availability of cache info and cache methods
+ if (( cacheContext != null ) && (cacheContext.isEnabled()) && (conditionalDeleteInvoker != null )) {
+ requestMessage.setBody(new Object[] {id, cacheContext});
+ responseMessage = conditionalDeleteInvoker.invoke(requestMessage);
+ } else {
+ requestMessage.setBody(new Object[] {id});
+ responseMessage = deleteInvoker.invoke(requestMessage);
+ }
+ if (responseMessage.isFault()) {
+ Object body = responseMessage.getBody();
+
+ int index = -1;
+ if ( -1 < (index = body.getClass().getName().indexOf( "NotModifiedException")) ) {
+ if ( index > -1 )
+ response.sendError( HttpServletResponse.SC_NOT_MODIFIED, body.toString().substring( index ));
+ else
+ response.sendError( HttpServletResponse.SC_NOT_MODIFIED );
+ return;
+ } else if ( -1 < (index = body.getClass().getName().indexOf( "PreconditionFailedException")) ) {
+ if ( index > -1 )
+ response.sendError( HttpServletResponse.SC_PRECONDITION_FAILED, body.toString().substring( index ));
+ else
+ response.sendError( HttpServletResponse.SC_PRECONDITION_FAILED );
+ return;
+ }
+
+ throw new ServletException((Throwable)responseMessage.getBody());
+ }
+
+ // Write the response from the service implementation to the response
+ // output stream
+ InputStream is = (InputStream)responseMessage.getBody();
+ OutputStream os = response.getOutputStream();
+ byte[] buffer = new byte[2048];
+ for (;;) {
+ int n = is.read(buffer);
+ if (n <= 0)
+ break;
+ os.write(buffer, 0, n);
+ }
+ os.flush();
+ os.close();
+ }
+
+ @Override
+ protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ // Get the request path
+ String path = URLDecoder.decode(request.getRequestURI().substring(request.getServletPath().length()), "UTF-8");
+ if (path.length() ==0) {
+ // Redirect to a URL ending with / to make relative hrefs work
+ // relative to the served resource.
+ response.sendRedirect(request.getRequestURL().append('/').toString());
+ return;
+ }
+
+ // Invoke the get operation on the service implementation
+ Message requestMessage = messageFactory.createMessage();
+ String id = path.substring(1);
+
+ Message responseMessage = null;
+ CacheContext cacheContext = null;
+ try {
+ cacheContext = CacheContext.getCacheContextFromRequest(request);
+ } catch (ParseException e) {
+ }
+
+ // Route message based on availability of cache info and cache methods
+ if (( cacheContext != null ) && (cacheContext.isEnabled()) && (conditionalPutInvoker != null )) {
+ requestMessage.setBody(new Object[] {id, cacheContext});
+ responseMessage = conditionalPutInvoker.invoke(requestMessage);
+ } else {
+ requestMessage.setBody(new Object[] {id});
+ responseMessage = putInvoker.invoke(requestMessage);
+ }
+ if (responseMessage.isFault()) {
+ Object body = responseMessage.getBody();
+
+ int index = -1;
+ if ( -1 < (index = body.getClass().getName().indexOf( "NotModifiedException")) ) {
+ if ( index > -1 )
+ response.sendError( HttpServletResponse.SC_NOT_MODIFIED, body.toString().substring( index ));
+ else
+ response.sendError( HttpServletResponse.SC_NOT_MODIFIED );
+ return;
+ } else if ( -1 < (index = body.getClass().getName().indexOf( "PreconditionFailedException")) ) {
+ if ( index > -1 )
+ response.sendError( HttpServletResponse.SC_PRECONDITION_FAILED, body.toString().substring( index ));
+ else
+ response.sendError( HttpServletResponse.SC_PRECONDITION_FAILED );
+ return;
+ }
+
+ throw new ServletException((Throwable)responseMessage.getBody());
+ }
+
+ // Write the response from the service implementation to the response
+ // output stream
+ InputStream is = (InputStream)responseMessage.getBody();
+ OutputStream os = response.getOutputStream();
+ byte[] buffer = new byte[2048];
+ for (;;) {
+ int n = is.read(buffer);
+ if (n <= 0)
+ break;
+ os.write(buffer, 0, n);
+ }
+ os.flush();
+ os.close();
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ // Get the request path
+ String path = URLDecoder.decode(request.getRequestURI().substring(request.getServletPath().length()), "UTF-8");
+ if (path.length() ==0) {
+ // Redirect to a URL ending with / to make relative hrefs work
+ // relative to the served resource.
+ response.sendRedirect(request.getRequestURL().append('/').toString());
+ return;
+ }
+
+ // Invoke the get operation on the service implementation
+ Message requestMessage = messageFactory.createMessage();
+ // String id = path.substring(1);
+
+ Message responseMessage = null;
+ CacheContext cacheContext = null;
+ try {
+ cacheContext = CacheContext.getCacheContextFromRequest(request);
+ } catch (ParseException e) {
+ }
+
+ // Route message based on availability of cache info and cache methods
+ if (( cacheContext != null ) && (cacheContext.isEnabled()) && (conditionalPostInvoker != null )) {
+ requestMessage.setBody(new Object[] {cacheContext});
+ responseMessage = conditionalPostInvoker.invoke(requestMessage);
+ } else {
+ requestMessage.setBody(new Object[] {});
+ responseMessage = postInvoker.invoke(requestMessage);
+ }
+ if (responseMessage.isFault()) {
+ Object body = responseMessage.getBody();
+
+ int index = -1;
+ if ( -1 < (index = body.getClass().getName().indexOf( "NotModifiedException")) ) {
+ if ( index > -1 )
+ response.sendError( HttpServletResponse.SC_NOT_MODIFIED, body.toString().substring( index ));
+ else
+ response.sendError( HttpServletResponse.SC_NOT_MODIFIED );
+ return;
+ } else if ( -1 < (index = body.getClass().getName().indexOf( "PreconditionFailedException")) ) {
+ if ( index > -1 )
+ response.sendError( HttpServletResponse.SC_PRECONDITION_FAILED, body.toString().substring( index ));
+ else
+ response.sendError( HttpServletResponse.SC_PRECONDITION_FAILED );
+ return;
+ }
+
+ throw new ServletException((Throwable)responseMessage.getBody());
+ }
+
+ // Put ETag and LastModified in response.
+ CacheContext cc = (CacheContext)responseMessage.getBody();
+ response.setHeader( "ETag", cc.getETag() );
+ response.setHeader( "LastModified", cc.getLastModified() );
+ }
+
+ /**
+ * @return the getInvoker
+ */
+ public Invoker getGetInvoker() {
+ return getInvoker;
+ }
+
+ /**
+ * @param getInvoker the getInvoker to set
+ */
+ public void setGetInvoker(Invoker getInvoker) {
+ this.getInvoker = getInvoker;
+ }
+
+ /**
+ * @return the conditionalGetInvoker
+ */
+ public Invoker getConditionalGetInvoker() {
+ return conditionalGetInvoker;
+ }
+
+ /**
+ * @param conditionalGetInvoker the conditionalGetInvoker to set
+ */
+ public void setConditionalGetInvoker(Invoker conditionalGetInvoker) {
+ this.conditionalGetInvoker = conditionalGetInvoker;
+ }
+
+ /**
+ * @return the putInvoker
+ */
+ public Invoker getPutInvoker() {
+ return putInvoker;
+ }
+
+ /**
+ * @param putInvoker the putInvoker to set
+ */
+ public void setPutInvoker(Invoker putInvoker) {
+ this.putInvoker = putInvoker;
+ }
+
+ /**
+ * @return the conditionalPutInvoker
+ */
+ public Invoker getConditionalPutInvoker() {
+ return conditionalPutInvoker;
+ }
+
+ /**
+ * @param conditionalPutInvoker the conditionalPutInvoker to set
+ */
+ public void setConditionalPutInvoker(Invoker conditionalPutInvoker) {
+ this.conditionalPutInvoker = conditionalPutInvoker;
+ }
+
+ /**
+ * @return the postInvoker
+ */
+ public Invoker getPostInvoker() {
+ return postInvoker;
+ }
+
+ /**
+ * @param postInvoker the postInvoker to set
+ */
+ public void setPostInvoker(Invoker postInvoker) {
+ this.postInvoker = postInvoker;
+ }
+
+ /**
+ * @return the conditionalPostInvoker
+ */
+ public Invoker getConditionalPostInvoker() {
+ return conditionalPostInvoker;
+ }
+
+ /**
+ * @param conditionalPostInvoker the conditionalPostInvoker to set
+ */
+ public void setConditionalPostInvoker(Invoker conditionalPostInvoker) {
+ this.conditionalPostInvoker = conditionalPostInvoker;
+ }
+
+ /**
+ * @return the deleteInvoker
+ */
+ public Invoker getDeleteInvoker() {
+ return deleteInvoker;
+ }
+
+ /**
+ * @param deleteInvoker the deleteInvoker to set
+ */
+ public void setDeleteInvoker(Invoker deleteInvoker) {
+ this.deleteInvoker = deleteInvoker;
+ }
+
+ /**
+ * @return the conditionalDeleteInvoker
+ */
+ public Invoker getConditionalDeleteInvoker() {
+ return conditionalDeleteInvoker;
+ }
+
+ /**
+ * @param conditionalDeleteInvoker the conditionalDeleteInvoker to set
+ */
+ public void setConditionalDeleteInvoker(Invoker conditionalDeleteInvoker) {
+ this.conditionalDeleteInvoker = conditionalDeleteInvoker;
+ }
+
+}
diff --git a/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java b/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java
index 4584a479b3..0a8f74edca 100644
--- a/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java
+++ b/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java
@@ -45,7 +45,8 @@ public class HTTPServiceBindingProvider implements ServiceBindingProvider {
private MessageFactory messageFactory;
private ServletHost servletHost;
private String servletMapping;
-
+ private HTTPBindingListenerServlet bindingListenerServlet;
+
public HTTPServiceBindingProvider(RuntimeComponent component,
RuntimeComponentService service,
HTTPBinding binding,
@@ -58,18 +59,46 @@ public class HTTPServiceBindingProvider implements ServiceBindingProvider {
}
public void start() {
-
// Get the invokers for the supported operations
RuntimeComponentService componentService = (RuntimeComponentService) service;
RuntimeWire wire = componentService.getRuntimeWire(binding);
Servlet servlet = null;
+ bindingListenerServlet = new HTTPBindingListenerServlet( messageFactory );
for (InvocationChain invocationChain : wire.getInvocationChains()) {
Operation operation = invocationChain.getTargetOperation();
String operationName = operation.getName();
- if (operationName.equals("get")) {
+ if (operationName.equals("get")) {
Invoker getInvoker = invocationChain.getHeadInvoker();
- servlet = new HTTPGetListenerServlet(getInvoker, messageFactory);
- break;
+ bindingListenerServlet.setGetInvoker(getInvoker);
+ servlet = bindingListenerServlet;
+ } else if (operationName.equals("conditionalGet")) {
+ Invoker conditionalGetInvoker = invocationChain.getHeadInvoker();
+ bindingListenerServlet.setConditionalGetInvoker(conditionalGetInvoker);
+ servlet = bindingListenerServlet;
+ } else if (operationName.equals("delete")) {
+ Invoker deleteInvoker = invocationChain.getHeadInvoker();
+ bindingListenerServlet.setDeleteInvoker(deleteInvoker);
+ servlet = bindingListenerServlet;
+ } else if (operationName.equals("conditionalDelete")) {
+ Invoker conditionalDeleteInvoker = invocationChain.getHeadInvoker();
+ bindingListenerServlet.setConditionalDeleteInvoker(conditionalDeleteInvoker);
+ servlet = bindingListenerServlet;
+ } else if (operationName.equals("put")) {
+ Invoker putInvoker = invocationChain.getHeadInvoker();
+ bindingListenerServlet.setPutInvoker(putInvoker);
+ servlet = bindingListenerServlet;
+ } else if (operationName.equals("conditionalPut")) {
+ Invoker conditionalPutInvoker = invocationChain.getHeadInvoker();
+ bindingListenerServlet.setConditionalPutInvoker(conditionalPutInvoker);
+ servlet = bindingListenerServlet;
+ } else if (operationName.equals("post")) {
+ Invoker postInvoker = invocationChain.getHeadInvoker();
+ bindingListenerServlet.setPostInvoker(postInvoker);
+ servlet = bindingListenerServlet;
+ } else if (operationName.equals("conditionalPost")) {
+ Invoker conditionalPostInvoker = invocationChain.getHeadInvoker();
+ bindingListenerServlet.setConditionalPostInvoker(conditionalPostInvoker);
+ servlet = bindingListenerServlet;
} else if (operationName.equals("service")) {
Invoker serviceInvoker = invocationChain.getHeadInvoker();
servlet = new HTTPServiceListenerServlet(serviceInvoker, messageFactory);
@@ -92,8 +121,7 @@ public class HTTPServiceBindingProvider implements ServiceBindingProvider {
servletHost.addServletMapping(servletMapping, servlet);
}
- public void stop() {
-
+ public void stop() {
// Unregister the Servlet from the Servlet host
servletHost.removeServletMapping(servletMapping);
}
diff --git a/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceListenerServlet.java b/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceListenerServlet.java
index f3da2367f0..3dee67b1ba 100644
--- a/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceListenerServlet.java
+++ b/java/sca/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceListenerServlet.java
@@ -48,6 +48,7 @@ public class HTTPServiceListenerServlet implements Servlet {
* Constructs a new HTTPServiceListenerServlet.
*/
public HTTPServiceListenerServlet(Invoker serviceInvoker, MessageFactory messageFactory) {
+ System.out.println( "DOB: HTTPServiceListenerServlet.service cons");
this.serviceInvoker = serviceInvoker;
this.messageFactory = messageFactory;
}
@@ -68,13 +69,13 @@ public class HTTPServiceListenerServlet implements Servlet {
}
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
+ System.out.println( "DOB: HTTPServiceListenerServlet.service entry");
// Dispatch the service interaction to the service invoker
Message requestMessage = messageFactory.createMessage();
requestMessage.setBody(new Object[]{request, response});
Message responseMessage = serviceInvoker.invoke(requestMessage);
- if (responseMessage.isFault()) {
-
+ if (responseMessage.isFault()) {
// Turn a fault into an exception
//throw new ServletException((Throwable)responseMessage.getBody());
Throwable e = (Throwable)responseMessage.getBody();
diff --git a/java/sca/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HTTPBindingTestCase.java b/java/sca/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HTTPBindingTestCase.java
index bc87dd2f93..e5cad080a6 100644
--- a/java/sca/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HTTPBindingTestCase.java
+++ b/java/sca/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HTTPBindingTestCase.java
@@ -23,6 +23,7 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
+import java.text.MessageFormat;
import junit.framework.TestCase;
@@ -54,7 +55,7 @@ public class HTTPBindingTestCase extends TestCase {
REQUEST2_HEADER + REQUEST2_CONTENT.getBytes().length + "\n\n" + REQUEST2_CONTENT;
private static final String REQUEST3_HEADER =
- "GET /httpget/test HTTP/1.0\n" + "Host: localhost\n"
+ "GET /httpget/{0} HTTP/1.0\n" + "Host: localhost\n"
+ "Content-Type: text/xml\n"
+ "Connection: close\n"
+ "Content-Length: ";
@@ -97,11 +98,13 @@ public class HTTPBindingTestCase extends TestCase {
public void testGetImplementation() throws Exception {
Socket client = new Socket("127.0.0.1", HTTP_PORT);
OutputStream os = client.getOutputStream();
- os.write(REQUEST3.getBytes());
+ int index = 0;
+ String request = MessageFormat.format( REQUEST3, index );
+ os.write( request.getBytes());
os.flush();
String document = read(client);
- assertTrue(document.indexOf("<body><p>uh oh</body>") != -1);
+ assertTrue(document.indexOf("<body><p>item=" + index) != -1);
}
/**
diff --git a/java/sca/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/TestGetImpl.java b/java/sca/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/TestGetImpl.java
index 0e0360d821..0df279dedd 100644
--- a/java/sca/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/TestGetImpl.java
+++ b/java/sca/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/TestGetImpl.java
@@ -30,9 +30,9 @@ import java.io.InputStream;
public class TestGetImpl {
public InputStream get(String id) {
-
- return new ByteArrayInputStream("<html><body><p>uh oh</body></html>".getBytes());
-
+ System.out.println( "DOB: TestGetImpl id=" + id );
+ return new ByteArrayInputStream(("<html><body><p>item=" + id + "</body></html>").getBytes());
+
}
}
diff --git a/java/sca/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/TestServiceImpl.java b/java/sca/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/TestServiceImpl.java
index 1cfc02a473..11945c8cd1 100644
--- a/java/sca/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/TestServiceImpl.java
+++ b/java/sca/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/TestServiceImpl.java
@@ -23,6 +23,7 @@ import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
@@ -42,7 +43,7 @@ public class TestServiceImpl implements Servlet {
}
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
- //HttpServletResponse httpResponse = (HttpServletResponse)response;
+ //HttpServletResponse httpResponse = (HttpServletResponse)response;
response.getOutputStream().print("<html><body><p>hey</body></html>");
}
diff --git a/java/sca/modules/binding-http/src/main/java/org/apache/tuscany/sca/binding/http/CacheContext.java b/java/sca/modules/binding-http/src/main/java/org/apache/tuscany/sca/binding/http/CacheContext.java
new file mode 100644
index 0000000000..aa80b7a40b
--- /dev/null
+++ b/java/sca/modules/binding-http/src/main/java/org/apache/tuscany/sca/binding/http/CacheContext.java
@@ -0,0 +1,257 @@
+/*
+ * 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.binding.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.
+
+ */
+public class CacheContext {
+ 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;
+
+ /**
+ * 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;
+ }
+
+ 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();
+ }
+
+ /**
+ * Gets the cache context information (ETag, LastModified, predicates) from the Http request.
+ * @param request
+ * @return
+ */
+ public static CacheContext getCacheContextFromRequest( HttpServletRequest request ) throws java.text.ParseException {
+ CacheContext context = new CacheContext();
+
+ 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;
+ }
+ /**
+ * 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;
+ }
+}