You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by an...@apache.org on 2010/08/30 09:34:20 UTC

svn commit: r990712 - in /tuscany/sca-java-2.x/trunk/modules/binding-http-runtime: ./ src/main/java/org/apache/tuscany/sca/binding/http/format/ src/main/java/org/apache/tuscany/sca/binding/http/provider/ src/main/resources/META-INF/services/ src/test/j...

Author: antelder
Date: Mon Aug 30 07:34:19 2010
New Revision: 990712

URL: http://svn.apache.org/viewvc?rev=990712&view=rev
Log:
Update the http binding to use default wireFormat and operationSelector that work as being discussed on the ML to expose arbitrary sca services as http endpoints. See http://apache.markmail.org/message/ix3vvyomronellmi

Added:
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultOperationSelectorProviderFactory.java
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultServiceOperationSelectorInterceptor.java
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultWireFormatProviderFactory.java
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultWireFormatServiceInterceptor.java
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingServiceServlet.java
      - copied, changed from r988392, tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingListenerServlet.java
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPContext.java
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.OperationSelectorProviderFactory
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.WireFormatProviderFactory
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/Helloworld.java
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HelloworldImpl.java
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HelloworldTestCase.java
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/resources/helloworld.composite
Removed:
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPGetListenerServlet.java
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceListenerServlet.java
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HTTPBindingCacheTestCase.java
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HTTPBindingTestCase.java
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/NotModifiedException.java
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/PreconditionFailedException.java
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/TestBindingCacheImpl.java
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/TestGetImpl.java
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/TestServiceImpl.java
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/resources/content/
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/resources/test.composite
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/resources/testCache.composite
Modified:
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/pom.xml
    tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java

Modified: tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/pom.xml
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/pom.xml?rev=990712&r1=990711&r2=990712&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/pom.xml (original)
+++ tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/pom.xml Mon Aug 30 07:34:19 2010
@@ -81,6 +81,13 @@
             <version>2.0-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
+        
+        <dependency>
+            <groupId>org.apache.tuscany.sca</groupId>
+            <artifactId>tuscany-databinding-json</artifactId>
+            <version>2.0-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
 
         <dependency>
             <groupId>junit</groupId>

Added: tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultOperationSelectorProviderFactory.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultOperationSelectorProviderFactory.java?rev=990712&view=auto
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultOperationSelectorProviderFactory.java (added)
+++ tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultOperationSelectorProviderFactory.java Mon Aug 30 07:34:19 2010
@@ -0,0 +1,60 @@
+/*
+ * 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.format;
+
+import org.apache.tuscany.sca.binding.http.HTTPDefaultOperationSelector;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.invocation.Interceptor;
+import org.apache.tuscany.sca.invocation.Phase;
+import org.apache.tuscany.sca.provider.OperationSelectorProvider;
+import org.apache.tuscany.sca.provider.OperationSelectorProviderFactory;
+import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
+import org.apache.tuscany.sca.runtime.RuntimeEndpointReference;
+
+public class HTTPDefaultOperationSelectorProviderFactory implements OperationSelectorProviderFactory<HTTPDefaultOperationSelector>{
+
+    public HTTPDefaultOperationSelectorProviderFactory(ExtensionPointRegistry extensionPoints) {
+    }
+    
+    @Override
+    public Class<HTTPDefaultOperationSelector> getModelType() {
+        return null;
+    }
+
+    @Override
+    public OperationSelectorProvider createReferenceOperationSelectorProvider(RuntimeEndpointReference endpointReference) {
+        return null;
+    }
+
+    @Override
+    public OperationSelectorProvider createServiceOperationSelectorProvider(final RuntimeEndpoint endpoint) {
+        return new OperationSelectorProvider(){
+            @Override
+            public Interceptor createInterceptor() {
+                return new HTTPDefaultServiceOperationSelectorInterceptor(endpoint);
+            }
+
+            @Override
+            public String getPhase() {
+                return Phase.SERVICE_BINDING_OPERATION_SELECTOR;
+            }};
+    }
+
+}

Added: tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultServiceOperationSelectorInterceptor.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultServiceOperationSelectorInterceptor.java?rev=990712&view=auto
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultServiceOperationSelectorInterceptor.java (added)
+++ tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultServiceOperationSelectorInterceptor.java Mon Aug 30 07:34:19 2010
@@ -0,0 +1,85 @@
+/*
+ * 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.format;
+
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.tuscany.sca.binding.http.provider.HTTPContext;
+import org.apache.tuscany.sca.interfacedef.Interface;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.invocation.Interceptor;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
+import org.oasisopen.sca.ServiceRuntimeException;
+
+/**
+ * Sets the operation based on the request path.
+ * 
+ * From a url: http://localhost:8080/HelloworldComponent/Helloworld/sayHello?name=Petra
+ * where the component is HelloworldComponent and the service is Helloworld
+ * the path will be "/sayHello" so the operation is "sayHello".
+ * 
+ * TODO: we could also do something similar to how the JMS binding supports
+ *       a single "onMessage" method to get all requests, so perhaps this could
+ *       also support impls with method: service(HttpServletRequest, HttpServletResponse)
+ */
+public class HTTPDefaultServiceOperationSelectorInterceptor implements Interceptor {
+
+    private Invoker next;
+    private List<Operation> operations;
+    
+    public HTTPDefaultServiceOperationSelectorInterceptor(RuntimeEndpoint endpoint) {
+        Interface serviceInterface = endpoint.getService().getInterfaceContract().getInterface();
+        this.operations = serviceInterface.getOperations();
+    }
+
+    @Override
+    public Message invoke(Message msg) {
+        HTTPContext context = msg.getBindingContext();
+        HttpServletRequest request = context.getRequest();
+        String path = request.getPathInfo();
+        if (path.startsWith("/")) {
+            path = path.substring(1);
+        }
+
+        for (Operation op : operations) {
+            if (op.getName().equals(path)) {
+                msg.setOperation(op);
+                return next.invoke(msg);
+            }
+        }
+        
+        throw new ServiceRuntimeException("No matching operation: " + path);
+    }
+
+    @Override
+    public void setNext(Invoker next) {
+        this.next = next;
+    }
+
+    @Override
+    public Invoker getNext() {
+        return next;
+    }
+
+}

Added: tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultWireFormatProviderFactory.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultWireFormatProviderFactory.java?rev=990712&view=auto
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultWireFormatProviderFactory.java (added)
+++ tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultWireFormatProviderFactory.java Mon Aug 30 07:34:19 2010
@@ -0,0 +1,68 @@
+/*
+ * 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.format;
+
+import org.apache.tuscany.sca.binding.http.HTTPDefaultWireFormat;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.invocation.Interceptor;
+import org.apache.tuscany.sca.invocation.Phase;
+import org.apache.tuscany.sca.provider.WireFormatProvider;
+import org.apache.tuscany.sca.provider.WireFormatProviderFactory;
+import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
+import org.apache.tuscany.sca.runtime.RuntimeEndpointReference;
+
+public class HTTPDefaultWireFormatProviderFactory implements WireFormatProviderFactory<HTTPDefaultWireFormat> {
+
+    public HTTPDefaultWireFormatProviderFactory(ExtensionPointRegistry extensionPoints) {
+    }
+
+    @Override
+    public Class<HTTPDefaultWireFormat> getModelType() {
+        return null;
+    }
+
+    @Override
+    public WireFormatProvider createReferenceWireFormatProvider(RuntimeEndpointReference endpointReference) {
+        return null;
+    }
+
+    @Override
+    public WireFormatProvider createServiceWireFormatProvider(final RuntimeEndpoint endpoint) {
+        return new WireFormatProvider() {
+            @Override
+            public InterfaceContract configureWireFormatInterfaceContract(InterfaceContract interfaceContract) {
+                // TODO: Ideally this wants to set the databinding on a per request basis from the 
+                // http content type and accept headers and so support things like json or xml etc,
+                // for now to get started just use json 
+                interfaceContract.getInterface().resetDataBinding("JSON");
+                return interfaceContract;
+            }
+            @Override
+            public Interceptor createInterceptor() {
+                return new HTTPDefaultWireFormatServiceInterceptor(endpoint);
+            }
+            @Override
+            public String getPhase() {
+                return Phase.SERVICE_BINDING_WIREFORMAT;
+            }};
+    }
+
+}

Added: tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultWireFormatServiceInterceptor.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultWireFormatServiceInterceptor.java?rev=990712&view=auto
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultWireFormatServiceInterceptor.java (added)
+++ tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultWireFormatServiceInterceptor.java Mon Aug 30 07:34:19 2010
@@ -0,0 +1,229 @@
+/*
+ * 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.format;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.tuscany.sca.binding.http.provider.HTTPContext;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.invocation.Interceptor;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
+import org.oasisopen.sca.ServiceRuntimeException;
+
+/**
+ * Handles the default wire format for the http binding
+ * 
+ * 1- determine the request and response format (xml, json, etc) from the 
+ *    binding config or content type header and accept headers
+ *    - TODO: need a way to configure the databinding framework based on that format
+ * 2- get the request contents from the HttpServletRequest
+ *    - for a post its just the request body
+ *    - for a get need to convert the query string into a body based on the format (xml, json, etc)
+ * 3- send the request on down the wire
+ * 4- set the response contents in the HttpServletResponse 
+ *    (the databinding should already have put it in the correct format)
+ * 
+ */
+public class HTTPDefaultWireFormatServiceInterceptor implements Interceptor {
+
+    private Invoker next;
+    private String jsonpCallbackName = "callback";
+    
+    public HTTPDefaultWireFormatServiceInterceptor(RuntimeEndpoint endpoint) {
+    }
+
+    @Override
+    public void setNext(Invoker next) {
+        this.next = next;
+    }
+
+    @Override
+    public Invoker getNext() {
+        return next;
+    }
+
+    @Override
+    public Message invoke(Message msg) {
+        try {
+            return invokeResponse(getNext().invoke(invokeRequest(msg)));
+        } catch (IOException e) {
+            throw new ServiceRuntimeException(e);
+        }
+    }
+
+    private Message invokeRequest(Message msg) throws IOException {
+        HTTPContext context = msg.getBindingContext();
+        HttpServletRequest servletRequest = context.getRequest();
+        if ("GET".equals(servletRequest.getMethod())) {
+            msg.setBody(getRequestFromQueryString(msg.getOperation(), servletRequest));
+        } else {
+            msg.setBody(read(servletRequest));
+        }
+        return msg;
+    }
+
+    private Message invokeResponse(Message msg) throws IOException {
+        HTTPContext context = msg.getBindingContext();
+        HttpServletRequest servletRequest = context.getRequest();
+        HttpServletResponse servletResponse = context.getResponse();
+        
+        if (msg.isFault()) {            
+            servletResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, String.valueOf(msg.getBody()));
+        } else {
+            String response = getResponseAsString(servletRequest, servletResponse, msg.getBody());
+            servletResponse.getOutputStream().println(response);
+        }
+        
+        return msg;
+    }
+
+    /**
+     * Turn the request into a string array of JSON structures. The data binding
+     * layer will then convert each of the individual parameters into the appropriate
+     * types for the implementation interface
+     *
+     * From ML thread: http://apache.markmail.org/message/ix3vvyomronellmi
+     * 1- if the binding configuration contains a mapping from query parameter name to operation parameter then use that. 
+     * 2- if the service interface or impl uses jaxrs annotations to name the parameters then use that mapping
+     * 3- if the query parameters are name arg0, arg1 etc than use those names for the mapping,
+     * 4- otherwise use the order in the query string. 
+     */
+    protected Object[] getRequestFromQueryString(Operation operation, ServletRequest servletRequest) {
+        
+        List<DataType> types = operation.getInputType().getLogical();
+        int typesIndex = 0;
+        
+        List<String> jsonRequestArray = new ArrayList<String>();
+        
+        for (String name : getOrderedParameterNames(servletRequest)) {
+            String jsonRequest = "";
+            // quote string parameters so clients work in the usual javascript way               
+            if (typesIndex < types.size() && String.class.equals(types.get(typesIndex).getGenericType())) {
+                String x = servletRequest.getParameter(name);
+                if (x.startsWith("\"") || x.startsWith("'")) {
+                    jsonRequest += x;
+                } else {
+                    if (x.contains("\"")) {
+                        jsonRequest += "'" + x + "'";
+                    } else {
+                        jsonRequest += "\"" + x + "\"";
+                    }
+                }
+            } else {               
+                jsonRequest += servletRequest.getParameter(name);
+            }  
+            jsonRequestArray.add(jsonRequest);
+        }
+
+        return jsonRequestArray.toArray();
+    }    
+    
+    /**
+     * Get the request parameter names in the correct order.
+     * Either the query parameters are named arg0, arg1, arg2 etc or else use the order 
+     * from the order in the query string. Eg, the url:
+     *   http://localhost:8085/HelloWorldService/sayHello2?first=petra&last=arnold&callback=foo"
+     * should invoke:
+     *   sayHello2("petra", "arnold")
+     * so the parameter names should be ordered: "first", "last"
+     */
+    protected List<String> getOrderedParameterNames(ServletRequest servletRequest) {
+        List<String> orderedNames = new ArrayList<String>();
+        Set<String> parameterNames = servletRequest.getParameterMap().keySet();
+        if (parameterNames.contains("arg0")) {
+            for (int i=0; i<parameterNames.size(); i++) {
+                String name = "arg" + i;
+                if (parameterNames.contains(name)) {
+                    orderedNames.add(name);
+                } else {
+                    break;
+                }
+            }
+        } else {
+            final String queryString = ((HttpServletRequest)servletRequest).getQueryString();
+            SortedSet<String> sortedNames = new TreeSet<String>(new Comparator<String>(){
+                public int compare(String o1, String o2) {
+                    int i = queryString.indexOf(o1);
+                    int j = queryString.indexOf(o2);
+                    return i - j;
+                }});
+            for (String name : parameterNames) {
+                // ignore system and jsonpCallbackName parameters
+                if (!name.startsWith("_") && !name.equals(jsonpCallbackName)) {
+                    sortedNames.add(name);    
+                }
+            }
+            orderedNames.addAll(sortedNames);
+        }
+        return orderedNames;
+    }
+    
+    /**
+     * The databinding layer will have converted the return type into a JSON string so simply 
+     * add wrap it for return.
+     */
+    protected String getResponseAsString(HttpServletRequest servletRequest, HttpServletResponse servletResponse, Object response) {
+        String jsonResponse = response.toString();
+
+        if ("GET".equals(servletRequest.getMethod())) {
+            // handle JSONP callback name padding
+            String callback = servletRequest.getParameter(jsonpCallbackName);
+            if (callback != null && callback.length() > 1) {
+                jsonResponse = callback + "(" + jsonResponse + ");";
+            }
+        }
+
+        return jsonResponse;
+    }    
+
+    protected static String read(HttpServletRequest servletRequest) throws IOException {
+        InputStream is = servletRequest.getInputStream();
+        BufferedReader reader = null;
+        try {
+            reader = new BufferedReader(new InputStreamReader(is));
+            StringBuffer sb = new StringBuffer();
+            String str;
+            while ((str = reader.readLine()) != null) {
+                sb.append(str);
+            }
+            return sb.toString();
+        } finally {
+            if (reader != null) {
+                reader.close();
+            }
+        }
+    }
+}

Copied: tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingServiceServlet.java (from r988392, tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingListenerServlet.java)
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingServiceServlet.java?p2=tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingServiceServlet.java&p1=tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingListenerServlet.java&r1=988392&r2=990712&rev=990712&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingListenerServlet.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingServiceServlet.java Mon Aug 30 07:34:19 2010
@@ -20,443 +20,34 @@
 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.assembly.Binding;
-import org.apache.tuscany.sca.common.http.HTTPCacheContext;
-import org.apache.tuscany.sca.common.http.HTTPContentTypeMapper;
-import org.apache.tuscany.sca.invocation.Invoker;
 import org.apache.tuscany.sca.invocation.Message;
 import org.apache.tuscany.sca.invocation.MessageFactory;
+import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
 
-/**
- * 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;
-    
-    transient private Binding binding;
+public class HTTPBindingServiceServlet extends HttpServlet {
+    private static final long serialVersionUID = 1L;
 
-    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;
+    protected transient MessageFactory messageFactory;
+    protected transient RuntimeEndpoint wire;
     
-    /**
-     * Constructs a new HTTPServiceListenerServlet.
-     */
-    public HTTPBindingListenerServlet(Binding binding, MessageFactory messageFactory) {
-        this.binding = binding;
+    public HTTPBindingServiceServlet(RuntimeEndpoint wire, MessageFactory messageFactory) {
+        this.wire = wire;
         this.messageFactory = messageFactory;
     }
-
     
     @Override
     protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-        super.service(request, response);
+        HTTPContext bindingContext = new HTTPContext();
+        bindingContext.setRequest(request);
+        bindingContext.setResponse(response);
+        Message msg = messageFactory.createMessage();
+        msg.setBindingContext(bindingContext);
+        wire.invoke(msg);
     }    
-    
-    @Override
-    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-        // Get the request path
-        String pathInfo = request.getPathInfo();
-        if (pathInfo == null || pathInfo.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;
-        }
-        String path = URLDecoder.decode(pathInfo, "UTF-8");
-
-        // Invoke the get operation on the service implementation
-        Message requestMessage = messageFactory.createMessage();
-
-        String id = path.substring(1);
-        
-        Message responseMessage = null;
-        HTTPCacheContext cacheContext = null;
-        try { 
-           cacheContext = HTTPCacheContext.createCacheContextFromRequest(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());
-        }
-        
-        if(response.getContentType() == null || response.getContentType().length() == 0){
-            // Calculate content-type based on extension
-            String contentType = HTTPContentTypeMapper.getContentType(id);
-            if(contentType != null && contentType.length() >0) {
-                response.setContentType(contentType);
-            }
-        }
-        
-        // 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;
-        HTTPCacheContext cacheContext = null;
-        try { 
-           cacheContext = HTTPCacheContext.createCacheContextFromRequest(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;
-        HTTPCacheContext cacheContext = null;
-        try { 
-           cacheContext = HTTPCacheContext.createCacheContextFromRequest(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;
-        HTTPCacheContext cacheContext = null;
-        try { 
-           cacheContext = HTTPCacheContext.createCacheContextFromRequest(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());
-        }
-
-
-        // Test if the ETag and LastModified are returned as a cache context.
-    	Object body = responseMessage.getBody();
-    	if ( body.getClass() == HTTPCacheContext.class ) {
-    		// Transfer to header if so.
-    		HTTPCacheContext cc = (HTTPCacheContext)responseMessage.getBody();
-    		if (( cc != null ) && ( cc.isEnabled() )) {
-    			String eTag = cc.getETag();
-            	if ( eTag != null )
-            		response.setHeader( "ETag", cc.getETag() );
-            	String lastModified = cc.getLastModified();
-            	if ( lastModified != null)
-            		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;
-    }
 }

Added: tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPContext.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPContext.java?rev=990712&view=auto
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPContext.java (added)
+++ tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPContext.java Mon Aug 30 07:34:19 2010
@@ -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.binding.http.provider;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Holder to pass servlet request and response between the Inteceptors
+ */
+public class HTTPContext {
+    
+    private HttpServletRequest request;
+    private HttpServletResponse response;
+
+    public HttpServletRequest getRequest() {
+        return request;
+    }
+    public void setRequest(HttpServletRequest request) {
+        this.request = request;
+    }
+    public HttpServletResponse getResponse() {
+        return response;
+    }
+    public void setResponse(HttpServletResponse response) {
+        this.response = response;
+    }
+
+}

Modified: tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java?rev=990712&r1=990711&r2=990712&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java Mon Aug 30 07:34:19 2010
@@ -22,6 +22,8 @@ package org.apache.tuscany.sca.binding.h
 import javax.servlet.Servlet;
 
 import org.apache.tuscany.sca.binding.http.HTTPBinding;
+import org.apache.tuscany.sca.binding.http.HTTPDefaultOperationSelector;
+import org.apache.tuscany.sca.binding.http.HTTPDefaultWireFormat;
 import org.apache.tuscany.sca.core.ExtensionPointRegistry;
 import org.apache.tuscany.sca.host.http.ServletHost;
 import org.apache.tuscany.sca.interfacedef.InterfaceContract;
@@ -36,8 +38,6 @@ import org.apache.tuscany.sca.provider.O
 import org.apache.tuscany.sca.provider.ProviderFactoryExtensionPoint;
 import org.apache.tuscany.sca.provider.WireFormatProvider;
 import org.apache.tuscany.sca.provider.WireFormatProviderFactory;
-import org.apache.tuscany.sca.runtime.RuntimeComponent;
-import org.apache.tuscany.sca.runtime.RuntimeComponentService;
 import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
 
 /**
@@ -49,17 +49,15 @@ public class HTTPServiceBindingProvider 
     private ExtensionPointRegistry extensionPoints;
     
     private RuntimeEndpoint endpoint;
-    private RuntimeComponent component;
-    private RuntimeComponentService service;  
-    private InterfaceContract serviceContract;
     private HTTPBinding binding;
     private MessageFactory messageFactory;
-    
     private OperationSelectorProvider osProvider;
     private WireFormatProvider wfProvider;
-    
     private ServletHost servletHost;
     private String servletMapping;
+    private InterfaceContract interfaceContract;
+    private boolean widget;
+
     private HTTPBindingListenerServlet bindingListenerServlet;
    
     public HTTPServiceBindingProvider(RuntimeEndpoint endpoint,
@@ -68,18 +66,24 @@ public class HTTPServiceBindingProvider 
                                       ServletHost servletHost) {
     	
     	this.endpoint = endpoint;
-        this.component = (RuntimeComponent)endpoint.getComponent();
-        this.service = (RuntimeComponentService)endpoint.getService();
         this.binding = (HTTPBinding)endpoint.getBinding();
+        this.widget = "Widget".equals(binding.getName());
         
         this.extensionPoints = extensionPoints;
         this.messageFactory = messageFactory;
         this.servletHost = servletHost;
         
-        // retrieve operation selector and wire format service providers
+        if (binding.getOperationSelector() == null && !widget) {
+            binding.setOperationSelector(new HTTPDefaultOperationSelector());
+        }
+        if (binding.getRequestWireFormat() == null && !widget) {
+            binding.setRequestWireFormat(new HTTPDefaultWireFormat());
+        }
+        if (binding.getResponseWireFormat() == null && !widget) {
+            binding.setResponseWireFormat(new HTTPDefaultWireFormat());
+        }
         
         ProviderFactoryExtensionPoint  providerFactories = extensionPoints.getExtensionPoint(ProviderFactoryExtensionPoint.class);
-
         
         if (binding.getOperationSelector() != null) {
             // Configure the interceptors for operation selection
@@ -97,23 +101,36 @@ public class HTTPServiceBindingProvider 
             }            
         }
 
-        
-        
         //clone the service contract to avoid databinding issues
         try {
-            this.serviceContract = (InterfaceContract) service.getInterfaceContract().clone();
+            interfaceContract = (InterfaceContract)endpoint.getComponentServiceInterfaceContract().clone();
             
             // configure data binding
             if (this.wfProvider != null) {
-                wfProvider.configureWireFormatInterfaceContract(service.getInterfaceContract());
+                wfProvider.configureWireFormatInterfaceContract(interfaceContract);
             }
         } catch(CloneNotSupportedException e) {
-            this.serviceContract = service.getInterfaceContract();
+            // shouldn't happen
         }
         
+        servletMapping = binding.getURI();
+        if (!servletMapping.endsWith("/")) {
+            servletMapping += "/";
+        }
+        if (!servletMapping.endsWith("*")) {
+            servletMapping += "*";
+        }
     }
 
     public void start() {
+        if (widget) {
+            start1x();
+        } else {
+            servletHost.addServletMapping(servletMapping, new HTTPBindingServiceServlet(endpoint, messageFactory));
+        }
+    }
+    
+    public void start1x() {
         // Get the invokers for the supported operations
         Servlet servlet = null;
         bindingListenerServlet = new HTTPBindingListenerServlet(binding, messageFactory );
@@ -122,39 +139,39 @@ public class HTTPServiceBindingProvider 
             String operationName = operation.getName();
             if (operationName.equals("get")) { 
                 Invoker getInvoker = invocationChain.getHeadInvoker();
-               	bindingListenerServlet.setGetInvoker(getInvoker);
+                bindingListenerServlet.setGetInvoker(getInvoker);
                 servlet = bindingListenerServlet;
             } else if (operationName.equals("conditionalGet")) {
                 Invoker conditionalGetInvoker = invocationChain.getHeadInvoker();
-               	bindingListenerServlet.setConditionalGetInvoker(conditionalGetInvoker);
+                bindingListenerServlet.setConditionalGetInvoker(conditionalGetInvoker);
                 servlet = bindingListenerServlet;
             } else if (operationName.equals("delete")) {
                 Invoker deleteInvoker = invocationChain.getHeadInvoker();
-               	bindingListenerServlet.setDeleteInvoker(deleteInvoker);
+                bindingListenerServlet.setDeleteInvoker(deleteInvoker);
                 servlet = bindingListenerServlet;
             } else if (operationName.equals("conditionalDelete")) {
                 Invoker conditionalDeleteInvoker = invocationChain.getHeadInvoker();
-               	bindingListenerServlet.setConditionalDeleteInvoker(conditionalDeleteInvoker);
+                bindingListenerServlet.setConditionalDeleteInvoker(conditionalDeleteInvoker);
                 servlet = bindingListenerServlet;
             } else if (operationName.equals("put")) {
                 Invoker putInvoker = invocationChain.getHeadInvoker();
-               	bindingListenerServlet.setPutInvoker(putInvoker);
+                bindingListenerServlet.setPutInvoker(putInvoker);
                 servlet = bindingListenerServlet;
             } else if (operationName.equals("conditionalPut")) {
                 Invoker conditionalPutInvoker = invocationChain.getHeadInvoker();
-               	bindingListenerServlet.setConditionalPutInvoker(conditionalPutInvoker);
+                bindingListenerServlet.setConditionalPutInvoker(conditionalPutInvoker);
                 servlet = bindingListenerServlet;
             } else if (operationName.equals("post")) {
                 Invoker postInvoker = invocationChain.getHeadInvoker();
-               	bindingListenerServlet.setPostInvoker(postInvoker);
+                bindingListenerServlet.setPostInvoker(postInvoker);
                 servlet = bindingListenerServlet;
             } else if (operationName.equals("conditionalPost")) {
                 Invoker conditionalPostInvoker = invocationChain.getHeadInvoker();
-               	bindingListenerServlet.setConditionalPostInvoker(conditionalPostInvoker);
+                bindingListenerServlet.setConditionalPostInvoker(conditionalPostInvoker);
                 servlet = bindingListenerServlet;
             } else if (operationName.equals("service")) {
                 Invoker serviceInvoker = invocationChain.getHeadInvoker();
-                servlet = new HTTPServiceListenerServlet(binding, serviceInvoker, messageFactory);
+//                servlet = new HTTPServiceListenerServlet(binding, serviceInvoker, messageFactory);
                 break;
             } 
         }
@@ -174,14 +191,13 @@ public class HTTPServiceBindingProvider 
         
         servletHost.addServletMapping(servletMapping, servlet);
     }
-
+    
     public void stop() {        
-        // Unregister the Servlet from the Servlet host
         servletHost.removeServletMapping(servletMapping);
     }
 
     public InterfaceContract getBindingInterfaceContract() {
-        return service.getInterfaceContract();
+        return interfaceContract;
     }
     
     public boolean supportsOneWayInvocation() {
@@ -192,6 +208,8 @@ public class HTTPServiceBindingProvider 
      * Add specific http interceptor to invocation chain
      */
     public void configure() {
+        
+        if (widget) return;
 
         InvocationChain bindingChain = endpoint.getBindingInvocationChain();
 

Added: tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.OperationSelectorProviderFactory
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.OperationSelectorProviderFactory?rev=990712&view=auto
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.OperationSelectorProviderFactory (added)
+++ tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.OperationSelectorProviderFactory Mon Aug 30 07:34:19 2010
@@ -0,0 +1,18 @@
+# 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. 
+
+org.apache.tuscany.sca.binding.http.format.HTTPDefaultOperationSelectorProviderFactory;model=org.apache.tuscany.sca.binding.http.HTTPDefaultOperationSelector

Added: tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.WireFormatProviderFactory
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.WireFormatProviderFactory?rev=990712&view=auto
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.WireFormatProviderFactory (added)
+++ tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.WireFormatProviderFactory Mon Aug 30 07:34:19 2010
@@ -0,0 +1,18 @@
+# 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. 
+
+org.apache.tuscany.sca.binding.http.format.HTTPDefaultWireFormatProviderFactory;model=org.apache.tuscany.sca.binding.http.HTTPDefaultWireFormat

Added: tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/Helloworld.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/Helloworld.java?rev=990712&view=auto
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/Helloworld.java (added)
+++ tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/Helloworld.java Mon Aug 30 07:34:19 2010
@@ -0,0 +1,8 @@
+package org.apache.tuscany.sca.binding.http;
+
+import org.oasisopen.sca.annotation.Remotable;
+
+@Remotable
+public interface Helloworld {
+	String sayHello(String name);
+}

Added: tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HelloworldImpl.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HelloworldImpl.java?rev=990712&view=auto
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HelloworldImpl.java (added)
+++ tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HelloworldImpl.java Mon Aug 30 07:34:19 2010
@@ -0,0 +1,10 @@
+package org.apache.tuscany.sca.binding.http;
+
+public class HelloworldImpl implements Helloworld {
+
+	@Override
+	public String sayHello(String name) {
+		return "Hello " + name;
+	}
+
+}

Added: tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HelloworldTestCase.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HelloworldTestCase.java?rev=990712&view=auto
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HelloworldTestCase.java (added)
+++ tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HelloworldTestCase.java Mon Aug 30 07:34:19 2010
@@ -0,0 +1,85 @@
+/*
+ * 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.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+
+import junit.framework.Assert;
+
+import org.apache.tuscany.sca.node.Node;
+import org.apache.tuscany.sca.node.NodeFactory;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * HTTP binding unit tests for Helloworld service.
+ */
+public class HelloworldTestCase {
+
+    private static Node node;
+    
+    @BeforeClass
+    public static void setUp() throws Exception {
+        node = NodeFactory.newInstance().createNode("helloworld.composite", new String[] {"target/test-classes"});
+        node.start();
+    }
+
+    @AfterClass
+    public static void tearDown() throws Exception {
+        if (node != null) {
+            node.stop();
+        }
+    }
+
+    @Test
+    public void testGet() throws Exception {
+        URL url = new URL("http://localhost:8080/HelloworldComponent/Helloworld/sayHello?name=Petra");
+        InputStream is = url.openStream();
+        Assert.assertEquals("\"Hello Petra\"", read(is));
+    }
+
+    @Test
+    public void testGetArg0() throws Exception {
+        URL url = new URL("http://localhost:8080/HelloworldComponent/Helloworld/sayHello?arg0=Petra");
+        InputStream is = url.openStream();
+        Assert.assertEquals("\"Hello Petra\"", read(is));
+    }
+    private static String read(InputStream is) throws IOException {
+        BufferedReader reader = null;
+        try {
+            reader = new BufferedReader(new InputStreamReader(is));
+            StringBuffer sb = new StringBuffer();
+            String str;
+            while ((str = reader.readLine()) != null) {
+                sb.append(str);
+            }
+            return sb.toString();
+        } finally {
+            if (reader != null) {
+                reader.close();
+            }
+        }
+    }
+
+}

Added: tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/resources/helloworld.composite
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/resources/helloworld.composite?rev=990712&view=auto
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/resources/helloworld.composite (added)
+++ tuscany/sca-java-2.x/trunk/modules/binding-http-runtime/src/test/resources/helloworld.composite Mon Aug 30 07:34:19 2010
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    * 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.    
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+	targetNamespace="http://sample/test"
+	xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.1"
+	name="helloworld">
+
+    <component name="HelloworldComponent">
+        <implementation.java class="org.apache.tuscany.sca.binding.http.HelloworldImpl"/>
+        <service name="Helloworld">
+    		<tuscany:binding.http />
+    	</service>
+    </component>
+
+</composite>