You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2008/03/04 21:48:02 UTC

svn commit: r633633 [1/2] - in /incubator/cxf/trunk: rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ rt/frontend/jaxrs/s...

Author: dkulp
Date: Tue Mar  4 12:47:58 2008
New Revision: 633633

URL: http://svn.apache.org/viewvc?rev=633633&view=rev
Log:
[CXF-1015] Patch from Sergey B. applied for a bunch of JAX-RS things.   Nicely done.

Added:
    incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/BinaryDataProvider.java   (with props)
    incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/CacheControlHeaderProvider.java   (with props)
    incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/CookieHeaderProvider.java   (with props)
    incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/EntityTagHeaderProvider.java   (with props)
    incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/HttpHeadersImpl.java   (with props)
    incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/PathSegmentImpl.java   (with props)
    incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/RequestImpl.java   (with props)
    incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java
      - copied, changed from r633505, incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/DOMSourceProvider.java
    incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/UriBuilderImpl.java   (with props)
    incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/UriInfoImpl.java   (with props)
    incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/VariantListBuilderImpl.java   (with props)
    incubator/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/ClassResourceInfoTest.java   (with props)
    incubator/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/BinaryDataProviderTest.java   (with props)
    incubator/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/CookieHeaderProviderTest.java   (with props)
    incubator/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/EntityTagHeaderProviderTest.java   (with props)
    incubator/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/HttpHeadersImplTest.java   (with props)
    incubator/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/SourceProviderTest.java   (with props)
    incubator/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/UriBuilderImplTest.java   (with props)
    incubator/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/UriInfoImplTest.java   (with props)
Removed:
    incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/DOMSourceProvider.java
Modified:
    incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java
    incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServiceFactoryBean.java
    incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSUtils.java
    incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/MetadataMap.java
    incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java
    incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ClassResourceInfo.java
    incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/URITemplate.java
    incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MediaTypeHeaderProvider.java
    incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactoryImpl.java
    incubator/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/JAXRSServiceFactoryBeanTest.java
    incubator/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/JAXRSUtilsTest.java
    incubator/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/URITemplateTest.java
    incubator/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryImplTest.java
    incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/AtomBookStore.java
    incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/AtomClientBookTest.java
    incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/AtomUtils.java

Modified: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java?rev=633633&r1=633632&r2=633633&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java (original)
+++ incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java Tue Mar  4 12:47:58 2008
@@ -22,9 +22,9 @@
 
 import java.lang.reflect.Method;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
+
+import javax.ws.rs.core.MultivaluedMap;
 
 import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor;
@@ -48,9 +48,12 @@
     public Object invoke(Exchange exchange, Object request) {
         OperationResourceInfo ori = exchange.get(OperationResourceInfo.class);
 
-        ClassResourceInfo classResourceInfo = ori.getClassResourceInfo();
-        Method m = classResourceInfo.getMethodDispatcher().getMethod(ori);
+        ClassResourceInfo cri = ori.getClassResourceInfo();
+        Method m = cri.getMethodDispatcher().getMethod(ori);
         Object resourceObject = getServiceObject(exchange);
+        if (cri.isRoot()) {
+            JAXRSUtils.injectHttpContextValues(resourceObject, ori, exchange.getInMessage());
+        }
 
         List<Object> params = null;
         if (request instanceof List) {
@@ -75,7 +78,7 @@
             resourceObjects = new ArrayList<Object>();
             resourceObjects.add(result);
             
-            Map<String, String> values = new HashMap<String, String>();                 
+            MultivaluedMap<String, String> values = new MetadataMap<String, String>();                 
             Message msg = exchange.getInMessage();
             String subResourcePath = (String)msg.get(JAXRSInInterceptor.RELATIVE_PATH);
             String httpMethod = (String)msg.get(Message.HTTP_REQUEST_METHOD); 
@@ -87,10 +90,13 @@
             if (acceptContentType == null) {
                 acceptContentType = "*/*";
             }
-            ClassResourceInfo subCri = JAXRSUtils.findSubResourceClass(classResourceInfo, result.getClass());
-            OperationResourceInfo subOri = JAXRSUtils.findTargetMethod(subCri, subResourcePath, 
-                                                                       httpMethod, values, 
-                                                                       contentType, acceptContentType);
+            ClassResourceInfo subCri = JAXRSUtils.findSubResourceClass(cri, result.getClass());
+            OperationResourceInfo subOri = JAXRSUtils.findTargetMethod(subCri, 
+                                                                       subResourcePath, 
+                                                                       httpMethod, 
+                                                                       values, 
+                                                                       contentType, 
+                                                                       acceptContentType);
             exchange.put(OperationResourceInfo.class, subOri);
             msg.put(JAXRSInInterceptor.RELATIVE_PATH, subResourcePath);
             // work out request parameters for the sub-resouce class. Here we
@@ -110,10 +116,10 @@
         Object serviceObject = null;
         
         OperationResourceInfo ori = exchange.get(OperationResourceInfo.class);
-        ClassResourceInfo classResourceInfo = ori.getClassResourceInfo();
+        ClassResourceInfo cri = ori.getClassResourceInfo();
         
         if (resourceObjects != null) {
-            Class c  = classResourceInfo.getResourceClass();
+            Class c  = cri.getResourceClass();
             for (Object resourceObject : resourceObjects) {
                 if (c.isInstance(resourceObject)) {
                     serviceObject = resourceObject;
@@ -122,9 +128,11 @@
         }
         
         if (serviceObject == null) {
-            serviceObject = classResourceInfo.getResourceProvider().getInstance();
+            serviceObject = cri.getResourceProvider().getInstance();
         }
         
         return serviceObject;
     }
+    
+    
 }

Modified: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServiceFactoryBean.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServiceFactoryBean.java?rev=633633&r1=633632&r2=633633&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServiceFactoryBean.java (original)
+++ incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServiceFactoryBean.java Tue Mar  4 12:47:58 2008
@@ -131,22 +131,9 @@
     }
 
     protected ClassResourceInfo createRootClassResourceInfo(final Class<?> c) {
-        Path uriTemplateAnnotation = c.getAnnotation(Path.class);
-        if (uriTemplateAnnotation == null) {
-            return null;
-        }
-
-        ClassResourceInfo classResourceInfo = createClassResourceInfo(c);
-
-        String annotationValue = uriTemplateAnnotation.value();
-        if (!annotationValue.startsWith("/")) {
-            annotationValue = "/" + annotationValue;
-        }
-        String suffixPattern = (uriTemplateAnnotation.limited())
-            ? URITemplate.LIMITED_REGEX_SUFFIX : URITemplate.UNLIMITED_REGEX_SUFFIX;
-        URITemplate t = new URITemplate(annotationValue, suffixPattern);
-        classResourceInfo.setURITemplate(t);
         
+        ClassResourceInfo classResourceInfo = createClassResourceInfo(c, true);
+
         //TODO: Using information from annotation to determine which lifecycle provider to use
         ResourceProvider rp = resourceProviders.get(c);
         if (rp != null) {
@@ -162,60 +149,53 @@
         return classResourceInfo;
     }
 
-    protected ClassResourceInfo createClassResourceInfo(final Class<?> c) {
-        ClassResourceInfo classResourceInfo  = new ClassResourceInfo(c);
+    protected ClassResourceInfo createClassResourceInfo(final Class<?> c, boolean root) {
+        ClassResourceInfo cri  = new ClassResourceInfo(c, root);
 
-        MethodDispatcher md = createOperation(c, classResourceInfo);
-        classResourceInfo.setMethodDispatcher(md);
-        return classResourceInfo;
+        URITemplate t = URITemplate.createTemplate(null, c.getAnnotation(Path.class));
+        cri.setURITemplate(t);
+        
+        MethodDispatcher md = createOperation(cri);
+        cri.setMethodDispatcher(md);
+        return cri;
     }
 
-    protected MethodDispatcher createOperation(Class c, ClassResourceInfo cri) {
+    protected MethodDispatcher createOperation(ClassResourceInfo cri) {
         MethodDispatcher md = new MethodDispatcher();
-        for (Method m : c.getMethods()) {
+        for (Method m : cri.getResourceClass().getMethods()) {
+            
+                       
             String httpMethod = JAXRSUtils.getHttpMethodValue(m);
             
-            if (m.getAnnotation(Path.class) != null && httpMethod != null) {
+            if (httpMethod != null && m.getAnnotation(Path.class) != null) {
                 /*
                  * Sub-resource method, URI template created by concatenating
                  * the URI template of the resource class with the URI template
                  * of the method
                  */
                 OperationResourceInfo ori = new OperationResourceInfo(m, cri);
-                String uriTemplate = m.getAnnotation(Path.class).value();
-                if (!uriTemplate.startsWith("/")) {
-                    uriTemplate = "/" + uriTemplate;
-                }
-
-                ori.setURITemplate(new URITemplate(uriTemplate, URITemplate.UNLIMITED_REGEX_SUFFIX));
-
+                URITemplate t = 
+                    URITemplate.createTemplate(cri, m.getAnnotation(Path.class));
+                ori.setURITemplate(t);
                 ori.setHttpMethod(httpMethod);
-
                 md.bind(ori, m);
             } else if (m.getAnnotation(Path.class) != null) {
                 // sub-resource locator
                 OperationResourceInfo ori = new OperationResourceInfo(m, cri);
-                String uriTemplate = m.getAnnotation(Path.class).value();
-                if (!uriTemplate.startsWith("/")) {
-                    uriTemplate = "/" + uriTemplate;
-                }                
-                ori.setURITemplate(new URITemplate(uriTemplate,
-                                                   URITemplate.LIMITED_REGEX_SUFFIX));
+                URITemplate t = 
+                    URITemplate.createTemplate(cri, m.getAnnotation(Path.class));
+                ori.setURITemplate(t);
                 md.bind(ori, m);     
-                
-                //REVISIT: Check the return type is indeed a sub-resource type
                 Class subResourceClass = m.getReturnType();
-                
-                //Iterate through sub-resources
-                ClassResourceInfo subCri = createClassResourceInfo(subResourceClass);
+                ClassResourceInfo subCri = createClassResourceInfo(subResourceClass, false);
                 cri.addSubClassResourceInfo(subCri);
             } else if (httpMethod != null) {
                 OperationResourceInfo ori = new OperationResourceInfo(m, cri);
-                String uriTemplate = "/";
-                ori.setURITemplate(new URITemplate(uriTemplate, URITemplate.UNLIMITED_REGEX_SUFFIX));
+                URITemplate t = 
+                    URITemplate.createTemplate(cri, null);
+                ori.setURITemplate(t);
                 ori.setHttpMethod(httpMethod);
                 md.bind(ori, m);
-                
             }
         }
 

Modified: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSUtils.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSUtils.java?rev=633633&r1=633632&r2=633633&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSUtils.java (original)
+++ incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSUtils.java Tue Mar  4 12:47:58 2008
@@ -23,6 +23,7 @@
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
 import java.net.URLDecoder;
@@ -30,6 +31,7 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
@@ -44,7 +46,12 @@
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.UriParam;
 import javax.ws.rs.core.HttpContext;
+import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.PathSegment;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.UriInfo;
 import javax.ws.rs.ext.MessageBodyReader;
 import javax.ws.rs.ext.ProviderFactory;
 
@@ -54,6 +61,10 @@
 import org.apache.cxf.jaxrs.model.ClassResourceInfo;
 import org.apache.cxf.jaxrs.model.OperationResourceInfo;
 import org.apache.cxf.jaxrs.model.URITemplate;
+import org.apache.cxf.jaxrs.provider.HttpHeadersImpl;
+import org.apache.cxf.jaxrs.provider.PathSegmentImpl;
+import org.apache.cxf.jaxrs.provider.RequestImpl;
+import org.apache.cxf.jaxrs.provider.UriInfoImpl;
 import org.apache.cxf.message.Message;
 
 public final class JAXRSUtils {
@@ -72,6 +83,17 @@
         }
         return null;
     }
+    
+    public static List<PathSegment> getPathSegments(String thePath, boolean decode) {
+        String[] segments = thePath.split("/");
+        List<PathSegment> theList = new ArrayList<PathSegment>();
+        for (String path : segments) {
+            if (!StringUtils.isEmpty(path)) {
+                theList.add(new PathSegmentImpl(path, decode));
+            }
+        }
+        return theList;
+    }
 
     public static List<MediaType> getMediaTypes(String[] values) {
         List<MediaType> supportedMimeTypes = new ArrayList<MediaType>(values.length);
@@ -94,14 +116,14 @@
     public static OperationResourceInfo findTargetResourceClass(List<ClassResourceInfo> resources,
                                                                 String path, 
                                                                 String httpMethod,
-                                                                Map<String, String> values,
+                                                                MultivaluedMap<String, String> values,
                                                                 String requestContentType, 
                                                                 String acceptContentTypes) {
         
         for (ClassResourceInfo resource : resources) {
             URITemplate uriTemplate = resource.getURITemplate();
             if (uriTemplate.match(path, values)) {
-                String subResourcePath = values.get(URITemplate.RIGHT_HAND_VALUE);
+                String subResourcePath = values.getFirst(URITemplate.RIGHT_HAND_VALUE);
                 OperationResourceInfo ori = findTargetMethod(resource, subResourcePath, httpMethod, values,
                                                              requestContentType, acceptContentTypes);
                 if (ori != null) {
@@ -115,7 +137,7 @@
     public static OperationResourceInfo findTargetMethod(ClassResourceInfo resource, 
                                                          String path,
                                                          String httpMethod, 
-                                                         Map<String, String> values, 
+                                                         MultivaluedMap<String, String> values, 
                                                          String requestContentType, 
                                                          String acceptContentTypes) {
         List<OperationResourceInfo> candidateList = new ArrayList<OperationResourceInfo>();
@@ -226,7 +248,7 @@
     
     //Message contains following information: PATH, HTTP_REQUEST_METHOD, CONTENT_TYPE, InputStream.
     public static List<Object> processParameters(OperationResourceInfo ori, 
-                                                 Map<String, String> values, 
+                                                 MultivaluedMap<String, String> values, 
                                                  Message message) {
         
         
@@ -253,43 +275,113 @@
     private static Object processParameter(Class<?> parameterClass, 
                                            Type parameterType,
                                            Annotation[] parameterAnnotations, 
-                                           Map<String, String> values,
+                                           MultivaluedMap<String, String> values,
                                            Message message,
                                            OperationResourceInfo ori) {
         InputStream is = message.getContent(InputStream.class);
         String contentType = (String)message.get(Message.CONTENT_TYPE);
         
         String path = (String)message.get(JAXRSInInterceptor.RELATIVE_PATH);
-        String httpMethod = (String)message.get(Message.HTTP_REQUEST_METHOD);
-
-        Object result = null;
-
+        
         if ((parameterAnnotations == null || parameterAnnotations.length == 0)
-            && ("PUT".equals(httpMethod) || "POST".equals(httpMethod))) {
-            result = readFromMessageBody(parameterClass, 
+            && ("PUT".equals(ori.getHttpMethod()) || "POST".equals(ori.getHttpMethod()))) {
+            return readFromMessageBody(parameterClass, 
                                          is, 
                                          MediaType.parse(contentType),
                                          ori.getConsumeTypes());
+        } else if (parameterAnnotations[0].annotationType() == HttpContext.class
+                   && ori.getClassResourceInfo().isRoot()) {
+            return createHttpContextValue(message, parameterClass, ori);
         } else if (parameterAnnotations[0].annotationType() == UriParam.class) {
-            result = readFromUriParam((UriParam)parameterAnnotations[0], parameterClass, parameterType,
+            return readFromUriParam((UriParam)parameterAnnotations[0], parameterClass, parameterType,
                                       parameterAnnotations, path, values);
-        } else if (parameterAnnotations[0].annotationType() == QueryParam.class) {
-            result = readQueryString((QueryParam)parameterAnnotations[0], parameterClass, message);
+        }  
+        
+        Object result = null;
+
+        // TODO : deal with @DefaultValues
+        if (parameterAnnotations[0].annotationType() == QueryParam.class) {
+            result = readQueryString((QueryParam)parameterAnnotations[0], parameterClass, message, null);
         } else if (parameterAnnotations[0].annotationType() == MatrixParam.class) {
-            //TODO
+            result = processMatrixParam(message, ((MatrixParam)parameterAnnotations[0]).value(), null);
         } else if (parameterAnnotations[0].annotationType() == HeaderParam.class) {
-            //TODO
-        } else if (parameterAnnotations[0].annotationType() == HttpContext.class) {
-            //TODO
-        }
+            result = processHeaderParam(message, ((HeaderParam)parameterAnnotations[0]).value(), null);
+        } 
 
         return result;
     }
+    
+    // TODO:
+    private static Object processMatrixParam(Message m, String value, String defaultValue) {
+        return null;
+    }
+    
+    public static MultivaluedMap<String, String> getMatrixParams(String path, boolean decode) {
+        int index = path.indexOf(';');
+        return index == -1 ? new MetadataMap<String, String>()
+                           : JAXRSUtils.getStructuredParams(path.substring(index + 1), ";", decode);
+    }
+    
+    @SuppressWarnings("unchecked")
+    private static Object processHeaderParam(Message m, String header, String defaultValue) {
+        Map<String, List<String>> headers = (Map<String, List<String>>)m.get(Message.PROTOCOL_HEADERS);
+        List<String> values = headers.get(header);
+        StringBuilder sb = new StringBuilder();
+        if (values != null) {
+            for (Iterator<String> it = values.iterator(); it.hasNext();) {
+                sb.append(it.next());
+                if (it.hasNext()) {
+                    sb.append(',');
+                }
+            }
+        }
+        return sb.length() > 0 ? sb.toString() : defaultValue;
+    }
+    
+    public static Object createHttpContextValue(Message m, 
+                                                 Class<?> clazz,
+                                                 OperationResourceInfo ori) {
+        if (UriInfo.class.isAssignableFrom(clazz)) {
+            return new UriInfoImpl(m, ori.getURITemplate());
+        }
+        if (HttpHeaders.class.isAssignableFrom(clazz)) {
+            return new HttpHeadersImpl(m);
+        }
+        if (Request.class.isAssignableFrom(clazz)) {
+            return new RequestImpl(m);
+        }
+        
+        return null;
+    }
 
-    private static Object readQueryString(QueryParam queryParam, Class<?> parameter, Message message) {
+    private static Object readFromUriParam(UriParam uriParamAnnotation,
+                                           Class<?> parameter,
+                                           Type parameterType,
+                                           Annotation[] parameterAnnotations,
+                                           String path,
+                                           MultivaluedMap<String, String> values) {
+        String parameterName = uriParamAnnotation.value();
+        if (parameterName == null || parameterName.length() == 0) {
+            // Invalid URI parameter name
+            return null;
+        }
+
+        Object result = values.getFirst(parameterName);
+
+        if (parameter.isPrimitive()) {
+            result = PrimitiveUtils.read((String)result, parameter);
+        }
+        return result;
+    }
+    
+    //TODO : multiple query string parsing, do it once
+    private static Object readQueryString(QueryParam queryParam, Class<?> parameter,
+                                          Message m, String defaultValue) {
         String queryName = queryParam.value();
 
-        Object result = getQueries(message).get(queryName);
+        Object result = getStructuredParams((String)m.get(Message.QUERY_STRING),
+                                   "&",
+                                   true).getFirst(queryName);
 
         if (parameter.isPrimitive()) {
             result = PrimitiveUtils.read((String)result, parameter);
@@ -302,20 +394,24 @@
      * @param message
      * @return a Map of query parameters.
      */
-    protected  static Map<String, String> getQueries(Message message) {
-        Map<String, String> queries = new LinkedHashMap<String, String>();
-        String query = (String)message.get(Message.QUERY_STRING);
+    public static MultivaluedMap<String, String> getStructuredParams(String query, 
+                                                                    String sep, 
+                                                                    boolean decode) {
+        MultivaluedMap<String, String> queries = 
+            new MetadataMap<String, String>(new LinkedHashMap<String, List<String>>());
+        
         if (!StringUtils.isEmpty(query)) {            
-            List<String> parts = Arrays.asList(query.split("&"));
+            List<String> parts = Arrays.asList(query.split(sep));
             for (String part : parts) {
                 String[] keyValue = part.split("=");
-                queries.put(keyValue[0], uriDecode(keyValue[1]));
+                queries.add(keyValue[0], 
+                            decode ? uriDecode(keyValue[1]) : keyValue[1]);
             }
         }
         return queries;
     }
 
-    private static String uriDecode(String query) {
+    public static String uriDecode(String query) {
         try {
             query = URLDecoder.decode(query, "UTF-8");
         } catch (UnsupportedEncodingException e) {
@@ -348,25 +444,7 @@
         return null;
     }
 
-    private static Object readFromUriParam(UriParam uriParamAnnotation,
-                                           Class<?> parameter,
-                                           Type parameterType,
-                                           Annotation[] parameterAnnotations,
-                                           String path,
-                                           Map<String, String> values) {
-        String parameterName = uriParamAnnotation.value();
-        if (parameterName == null || parameterName.length() == 0) {
-            // Invalid URI parameter name
-            return null;
-        }
-
-        Object result = values.get(parameterName);
-
-        if (parameter.isPrimitive()) {
-            result = PrimitiveUtils.read((String)result, parameter);
-        }
-        return result;
-    }
+    
 
     public static boolean matchMimeTypes(MediaType requestContentType, 
                                          MediaType acceptContentType, 
@@ -453,5 +531,20 @@
             });
         }
         return types;
+    }
+    
+    public static void injectHttpContextValues(Object o,
+                                         OperationResourceInfo ori,
+                                         Message m) {
+        
+        for (Field f : ori.getClassResourceInfo().getHttpContexts()) {
+            Object value = createHttpContextValue(m, f.getType(), ori);
+            f.setAccessible(true);
+            try {
+                f.set(o, value);
+            } catch (IllegalAccessException ex) {
+                // ignore
+            }
+        }
     }
 }

Modified: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/MetadataMap.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/MetadataMap.java?rev=633633&r1=633632&r2=633633&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/MetadataMap.java (original)
+++ incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/MetadataMap.java Tue Mar  4 12:47:58 2008
@@ -30,7 +30,15 @@
 
 public class MetadataMap<K, V> implements MultivaluedMap<K, V> {
 
-    private Map<K, List<V>> m = new HashMap<K, List<V>>();
+    private Map<K, List<V>> m;
+    
+    public MetadataMap() {
+        this(new HashMap<K, List<V>>());
+    }
+    
+    public MetadataMap(Map<K, List<V>> store) {
+        this.m = store;
+    }
     
     public void add(K key, V value) {
         List<V> data = m.get(key);

Modified: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java?rev=633633&r1=633632&r2=633633&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java (original)
+++ incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java Tue Mar  4 12:47:58 2008
@@ -19,14 +19,15 @@
 
 package org.apache.cxf.jaxrs.interceptor;
 
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 import java.util.logging.Logger;
 
+import javax.ws.rs.core.MultivaluedMap;
+
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.jaxrs.JAXRSServiceImpl;
 import org.apache.cxf.jaxrs.JAXRSUtils;
+import org.apache.cxf.jaxrs.MetadataMap;
 import org.apache.cxf.jaxrs.model.ClassResourceInfo;
 import org.apache.cxf.jaxrs.model.OperationResourceInfo;
 import org.apache.cxf.jaxrs.model.URITemplate;
@@ -89,7 +90,7 @@
         Service service = message.getExchange().get(Service.class);
         List<ClassResourceInfo> resources = ((JAXRSServiceImpl)service).getClassResourceInfos();
 
-        Map<String, String> values = new HashMap<String, String>();
+        MultivaluedMap<String, String> values = new MetadataMap<String, String>();
         OperationResourceInfo ori = JAXRSUtils.findTargetResourceClass(resources, 
                                                                        path, 
                                                                        httpMethod, 
@@ -105,7 +106,7 @@
         LOG.info("Found operation: " + ori.getMethod().getName());
         
         message.getExchange().put(OperationResourceInfo.class, ori);
-        message.put(RELATIVE_PATH, values.get(URITemplate.RIGHT_HAND_VALUE));
+        message.put(RELATIVE_PATH, values.getFirst(URITemplate.RIGHT_HAND_VALUE));
       
         //2. Process parameters
         List<Object> params = JAXRSUtils

Modified: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ClassResourceInfo.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ClassResourceInfo.java?rev=633633&r1=633632&r2=633633&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ClassResourceInfo.java (original)
+++ incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ClassResourceInfo.java Tue Mar  4 12:47:58 2008
@@ -19,22 +19,39 @@
 
 package org.apache.cxf.jaxrs.model;
 
+import java.lang.reflect.Field;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
+import javax.ws.rs.core.HttpContext;
+
 import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
 
 public class ClassResourceInfo {
+    
+    private boolean root;
     private Class<?> resourceClass;
     private URITemplate uriTemplate;
     private MethodDispatcher methodDispatcher;
     private ResourceProvider resourceProvider;
     private List<ClassResourceInfo> subClassResourceInfo = new ArrayList<ClassResourceInfo>();
+    private List<Field> httpContexts;
 
     public ClassResourceInfo(Class<?> theResourceClass) {
+        this(theResourceClass, false);
+    }
+    
+    public ClassResourceInfo(Class<?> theResourceClass, boolean theRoot) {
         resourceClass = theResourceClass;
+        root = theRoot;
+        initHttpContexts();
     }
 
+    public boolean isRoot() {
+        return root;
+    }
+    
     public Class<?> getResourceClass() {
         return resourceClass;
     }
@@ -73,5 +90,27 @@
 
     public void setResourceProvider(ResourceProvider rp) {
         resourceProvider = rp;
-    }    
+    }
+    
+    private void initHttpContexts() {
+        if (resourceClass == null || !root) {
+            return;
+        }
+        httpContexts = new ArrayList<Field>();
+        Field[] fields = resourceClass.getDeclaredFields();
+        
+        for (Field f : fields) {
+            HttpContext context = f.getAnnotation(HttpContext.class);
+            if (context != null) {
+                httpContexts.add(f);               
+            }
+        }
+    }
+    
+    
+    @SuppressWarnings("unchecked")
+    public List<Field> getHttpContexts() {
+        return httpContexts == null ? Collections.EMPTY_LIST 
+               : Collections.unmodifiableList(httpContexts);
+    }                               
 }

Modified: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/URITemplate.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/URITemplate.java?rev=633633&r1=633632&r2=633633&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/URITemplate.java (original)
+++ incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/URITemplate.java Tue Mar  4 12:47:58 2008
@@ -23,10 +23,12 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import javax.ws.rs.Path;
+import javax.ws.rs.core.MultivaluedMap;
+
 public final class URITemplate {
     public static final String LIMITED_REGEX_SUFFIX = "(/.*)?";
     public static final String UNLIMITED_REGEX_SUFFIX = "(/)?";
@@ -89,6 +91,10 @@
         templateRegexPattern = Pattern.compile(templateRegex);
     }
 
+    public String getValue() {
+        return template;
+    }
+    
     private void copyURITemplateCharacters(String templateValue, int start, int end, StringBuilder b) {
         for (int i = start; i < end; i++) {
             char c = templateValue.charAt(i);
@@ -100,7 +106,7 @@
         }
     }
 
-    public boolean match(String uri, Map<String, String> templateVariableToValue) {
+    public boolean match(String uri, MultivaluedMap<String, String> templateVariableToValue) {
         //templateVariableToValue.clear();
 
         if (uri == null) {
@@ -119,21 +125,44 @@
         // Assign the matched template values to template variables
         int i = 1;
         for (String name : templateVariables) {
-            String previousValue = templateVariableToValue.get(name);
+            String previousValue = templateVariableToValue.getFirst(name);
             String currentValue = m.group(i++);
 
             if (previousValue != null && !previousValue.equals(currentValue)) {
                 return false;
             }
 
-            templateVariableToValue.put(name, currentValue);
+            templateVariableToValue.putSingle(name, currentValue);
         }
 
         // The right hand side value, might be used to further resolve sub-resources.
         if (regexSuffix != null) {
-            templateVariableToValue.put(RIGHT_HAND_VALUE, m.group(i));
+            templateVariableToValue.putSingle(RIGHT_HAND_VALUE, m.group(i));
         }
 
         return true;
+    }
+    
+    public static URITemplate createTemplate(ClassResourceInfo cri,
+                                             Path path) {
+        
+        if (path == null) {
+            return cri == null ? new URITemplate("/", URITemplate.UNLIMITED_REGEX_SUFFIX)
+                               : cri.getURITemplate();
+        }
+        
+        String prefix = cri != null && !cri.isRoot() ? cri.getURITemplate().getValue() : "/";
+        if (!prefix.endsWith("/")) {
+            prefix += "/";
+        }                
+        String pathValue = path.value();
+        if (pathValue.startsWith("/")) {
+            pathValue = pathValue.length() == 1 ? "" : pathValue.substring(1);
+        }
+                
+        String suffixPattern = (path.limited())
+            ? URITemplate.LIMITED_REGEX_SUFFIX : URITemplate.UNLIMITED_REGEX_SUFFIX;
+        
+        return new URITemplate(prefix + pathValue, suffixPattern);
     }
 }

Added: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/BinaryDataProvider.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/BinaryDataProvider.java?rev=633633&view=auto
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/BinaryDataProvider.java (added)
+++ incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/BinaryDataProvider.java Tue Mar  4 12:47:58 2008
@@ -0,0 +1,89 @@
+/**
+ * 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.cxf.jaxrs.provider;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.MessageBodyWriter;
+
+import org.apache.cxf.helpers.IOUtils;
+
+public class BinaryDataProvider 
+    implements MessageBodyReader<Object>, MessageBodyWriter<Object> {
+
+    public boolean isReadable(Class<?> type) {
+        return byte[].class.isAssignableFrom(type)
+               || InputStream.class.isAssignableFrom(type);
+    }
+
+    public Object readFrom(Class<Object> clazz, MediaType type, 
+                           MultivaluedMap<String, String> headers, InputStream is)
+        throws IOException {
+        if (InputStream.class.isAssignableFrom(clazz)) {
+            return is;
+        }
+        if (byte[].class.isAssignableFrom(clazz)) {
+            // lets worry about the optimization later
+            return IOUtils.readBytesFromStream(is);
+        }
+        throw new IOException("Unrecognized class");
+    }
+
+    public long getSize(Object t) {
+        if (byte[].class.isAssignableFrom(t.getClass())) {
+            return ((byte[])t).length;
+        }
+        return -1;
+    }
+
+    public boolean isWriteable(Class<?> type) {
+        return byte[].class.isAssignableFrom(type)
+            || InputStream.class.isAssignableFrom(type)
+            || File.class.isAssignableFrom(type);
+    }
+
+    public void writeTo(Object o, MediaType type, 
+                        MultivaluedMap<String, Object> headers, OutputStream os)
+        throws IOException {
+        // TODO : use media types properly here
+        
+        if (InputStream.class.isAssignableFrom(o.getClass())) {
+            IOUtils.copyAndCloseInput((InputStream)o, os);
+        } else if (File.class.isAssignableFrom(o.getClass())) {
+            IOUtils.copyAndCloseInput(new BufferedInputStream(
+                                         new FileInputStream((File)o)), os);
+        } else if (byte[].class.isAssignableFrom(o.getClass())) {
+            // lets worry about the optimization later
+            os.write((byte[])o);
+        } else {
+            throw new IOException("Unrecognized class");
+        }
+
+    }
+
+}

Propchange: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/BinaryDataProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/BinaryDataProvider.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/CacheControlHeaderProvider.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/CacheControlHeaderProvider.java?rev=633633&view=auto
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/CacheControlHeaderProvider.java (added)
+++ incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/CacheControlHeaderProvider.java Tue Mar  4 12:47:58 2008
@@ -0,0 +1,44 @@
+/**
+ * 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.cxf.jaxrs.provider;
+
+import java.text.ParseException;
+
+import javax.ws.rs.core.CacheControl;
+import javax.ws.rs.ext.HeaderProvider;
+import javax.ws.rs.ext.Provider;
+
+@Provider
+public class CacheControlHeaderProvider implements HeaderProvider<CacheControl> {
+
+    public CacheControl fromString(String header) throws ParseException {
+        return new CacheControl();
+    }
+
+    public boolean supports(Class<?> type) {
+        return CacheControl.class.isAssignableFrom(type);
+    }
+
+    public String toString(CacheControl header) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}

Propchange: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/CacheControlHeaderProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/CacheControlHeaderProvider.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/CookieHeaderProvider.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/CookieHeaderProvider.java?rev=633633&view=auto
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/CookieHeaderProvider.java (added)
+++ incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/CookieHeaderProvider.java Tue Mar  4 12:47:58 2008
@@ -0,0 +1,84 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.jaxrs.provider;
+
+import java.text.ParseException;
+
+import javax.ws.rs.core.Cookie;
+import javax.ws.rs.ext.HeaderProvider;
+
+public class CookieHeaderProvider implements HeaderProvider<Cookie> {
+
+    private static final String VERSION = "$Version";
+    private static final String PATH = "$Path";
+    private static final String DOMAIN = "$Domain";
+    
+    public Cookie fromString(String c) throws ParseException {
+        
+        int version = -1;
+        String name = null;
+        String value = null;
+        String path = null;
+        String domain = null;
+        
+        // ignore the fact the possible version may be seperated by ','        
+        String[] tokens = c.split(";");
+        for (String token : tokens) {
+            if (token.startsWith(VERSION)) {
+                version = Integer.parseInt(token.substring(VERSION.length() + 1));
+            } else if (token.startsWith(PATH)) {
+                path = token.substring(PATH.length() + 1);
+            } else if (token.startsWith(DOMAIN)) {
+                domain = token.substring(DOMAIN.length() + 1);
+            } else {
+                int i = token.indexOf('=');
+                if (i != -1) {
+                    name = token.substring(0, i);
+                    value = i == token.length()  + 1 ? "" : token.substring(i + 1);
+                }
+            }
+        }
+        
+        if (name == null) {
+            throw new ParseException("No Cookie name can be found : " + c, 0);
+        }
+        
+        return new Cookie(name, value, path, domain, version);
+    }
+
+    public boolean supports(Class<?> type) {
+        return Cookie.class.isAssignableFrom(type);
+    }
+
+    public String toString(Cookie c) {
+        StringBuilder sb = new StringBuilder();
+        if (c.getVersion() != -1) {
+            sb.append(VERSION).append('=').append(c.getVersion()).append(';');
+        }
+        sb.append(c.getName()).append('=').append(c.getValue());
+        if (c.getPath() != null) {
+            sb.append(';').append(PATH).append('=').append(c.getPath());
+        }
+        if (c.getDomain() != null) {
+            sb.append(';').append(DOMAIN).append('=').append(c.getDomain());
+        }
+        return sb.toString();
+    }
+
+}

Propchange: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/CookieHeaderProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/CookieHeaderProvider.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/EntityTagHeaderProvider.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/EntityTagHeaderProvider.java?rev=633633&view=auto
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/EntityTagHeaderProvider.java (added)
+++ incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/EntityTagHeaderProvider.java Tue Mar  4 12:47:58 2008
@@ -0,0 +1,59 @@
+/**
+ * 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.cxf.jaxrs.provider;
+
+import java.text.ParseException;
+
+import javax.ws.rs.core.EntityTag;
+import javax.ws.rs.ext.HeaderProvider;
+import javax.ws.rs.ext.Provider;
+
+@Provider
+public class EntityTagHeaderProvider implements HeaderProvider<EntityTag> {
+
+    private static final String WEAK_PREFIX = "W/";
+    
+    public EntityTag fromString(String header) throws ParseException {
+        int i = header.indexOf(WEAK_PREFIX);
+        if (i != -1) {
+            if (i + 2 < header.length()) {
+                return new EntityTag(header.substring(i + 2), true);
+            } else {
+                return new EntityTag("", true);
+            }
+        } 
+        
+        return new EntityTag(header);
+    }
+
+    public boolean supports(Class type) {
+        return EntityTag.class.isAssignableFrom(type);
+    }
+
+    public String toString(EntityTag tag) {
+        StringBuilder sb = new StringBuilder();
+        if (tag.isWeak()) {
+            sb.append(WEAK_PREFIX);
+        }
+        sb.append(tag.getValue());
+        return sb.toString();
+    }
+
+}

Propchange: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/EntityTagHeaderProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/EntityTagHeaderProvider.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/HttpHeadersImpl.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/HttpHeadersImpl.java?rev=633633&view=auto
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/HttpHeadersImpl.java (added)
+++ incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/HttpHeadersImpl.java Tue Mar  4 12:47:58 2008
@@ -0,0 +1,77 @@
+/**
+ * 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.cxf.jaxrs.provider;
+
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.Cookie;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.apache.cxf.jaxrs.JAXRSUtils;
+import org.apache.cxf.jaxrs.MetadataMap;
+import org.apache.cxf.message.Message;
+
+public class HttpHeadersImpl implements HttpHeaders {
+
+    private Message m;
+    private MultivaluedMap<String, String> headers;
+    
+    @SuppressWarnings("unchecked")
+    public HttpHeadersImpl(Message message) {
+        this.m = message;
+        this.headers = new MetadataMap<String, String>(
+            (Map<String, List<String>>)message.get(Message.PROTOCOL_HEADERS));
+    }
+    
+    public List<MediaType> getAcceptableMediaTypes() {
+        return JAXRSUtils.parseMediaTypes((String)m.get(Message.ACCEPT_CONTENT_TYPE));
+    }
+
+    public List<Cookie> getCookies() {
+        List<String> cs = headers.get("Cookie");
+        List<Cookie> cl = new ArrayList<Cookie>(); 
+        for (String c : cs) {
+            cl.add(Cookie.parse(c));
+        }
+        return cl;
+    }
+
+    public String getLanguage() {
+        String l = headers.getFirst("Content-Language");
+        return l == null ? "UTF-8" : l;
+    }
+
+    public MediaType getMediaType() {
+        return MediaType.parse((String)m.get(Message.CONTENT_TYPE));
+    }
+
+    public MultivaluedMap<String, String> getRequestHeaders() {
+        // should we really worry about immutability given that the Message does not ?
+        MultivaluedMap<String, String> map = new MetadataMap<String, String>();
+        map.putAll(headers);
+        return map;
+    }
+
+}

Propchange: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/HttpHeadersImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/HttpHeadersImpl.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MediaTypeHeaderProvider.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MediaTypeHeaderProvider.java?rev=633633&r1=633632&r2=633633&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MediaTypeHeaderProvider.java (original)
+++ incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MediaTypeHeaderProvider.java Tue Mar  4 12:47:58 2008
@@ -27,7 +27,9 @@
 
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.ext.HeaderProvider;
+import javax.ws.rs.ext.Provider;
 
+@Provider
 public class MediaTypeHeaderProvider implements HeaderProvider<MediaType> {
 
     public MediaType fromString(String mType) throws ParseException {

Added: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/PathSegmentImpl.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/PathSegmentImpl.java?rev=633633&view=auto
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/PathSegmentImpl.java (added)
+++ incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/PathSegmentImpl.java Tue Mar  4 12:47:58 2008
@@ -0,0 +1,47 @@
+/**
+ * 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.cxf.jaxrs.provider;
+
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.PathSegment;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.cxf.jaxrs.JAXRSUtils;
+
+@Provider
+public class PathSegmentImpl implements PathSegment {
+
+    private String path;
+    private boolean decode;
+    
+    public PathSegmentImpl(String path, boolean decode) {
+        this.path = path;
+        this.decode = decode;
+    }
+    
+    public MultivaluedMap<String, String> getMatrixParameters() {
+        return JAXRSUtils.getMatrixParams(path, decode);
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+}

Propchange: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/PathSegmentImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/PathSegmentImpl.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactoryImpl.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactoryImpl.java?rev=633633&r1=633632&r2=633633&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactoryImpl.java (original)
+++ incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactoryImpl.java Tue Mar  4 12:47:58 2008
@@ -28,6 +28,8 @@
 import javax.ws.rs.ProduceMime;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response.Builder;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.Variant.VariantListBuilder;
 import javax.ws.rs.ext.HeaderProvider;
 import javax.ws.rs.ext.MessageBodyReader;
 import javax.ws.rs.ext.MessageBodyWriter;
@@ -50,13 +52,17 @@
         setProviders(defaultMessageReaders,
                      defaultMessageWriters,
                      new JSONProvider(),
+                     new BinaryDataProvider(),
                      new JAXBElementProvider(),
                      new StringProvider(),
-                     new DOMSourceProvider(),
+                     new SourceProvider(),
                      new AtomFeedProvider(),
                      new AtomEntryProvider(),
                      new FormEncodingReaderProvider());
         headerProviders.add(new MediaTypeHeaderProvider());
+        headerProviders.add(new CacheControlHeaderProvider());
+        headerProviders.add(new EntityTagHeaderProvider());
+        headerProviders.add(new CookieHeaderProvider());
     }
     
     
@@ -65,6 +71,12 @@
         if (type.isAssignableFrom(Builder.class)) {
             return type.cast(new BuilderImpl());
         } 
+        if (type.isAssignableFrom(UriBuilder.class)) {
+            return type.cast(new UriBuilderImpl());
+        }
+        if (type.isAssignableFrom(VariantListBuilder.class)) {
+            return type.cast(new VariantListBuilderImpl());
+        }
         return null;
     }
    

Added: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/RequestImpl.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/RequestImpl.java?rev=633633&view=auto
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/RequestImpl.java (added)
+++ incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/RequestImpl.java Tue Mar  4 12:47:58 2008
@@ -0,0 +1,79 @@
+/**
+ * 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.cxf.jaxrs.provider;
+
+import java.util.Date;
+import java.util.List;
+
+import javax.ws.rs.core.EntityTag;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Variant;
+
+import org.apache.cxf.message.Message;
+
+/**
+ * This is actually a complete no-op implementation, null is a valid response,
+ * by default all the precondions are met.
+ *
+ */
+
+public class RequestImpl implements Request {
+    
+    public RequestImpl(Message m) {
+        // complete
+    }
+
+    public Response evaluatePreconditions(EntityTag eTag) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Response evaluatePreconditions(Date lastModified) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Response evaluatePreconditions(EntityTag eTag, Variant variant) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Response evaluatePreconditions(Date lastModified, Variant variant) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Response evaluatePreconditions(Date lastModified, EntityTag eTag) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Response evaluatePreconditions(Date lastModified, EntityTag eTag, Variant variant) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Variant selectVariant(List<Variant> arg0) throws IllegalArgumentException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}

Propchange: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/RequestImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/RequestImpl.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Copied: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java (from r633505, incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/DOMSourceProvider.java)
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java?p2=incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java&p1=incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/DOMSourceProvider.java&r1=633505&r2=633633&rev=633633&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/DOMSourceProvider.java (original)
+++ incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java Tue Mar  4 12:47:58 2008
@@ -30,48 +30,53 @@
 import javax.ws.rs.ext.Provider;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Source;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerException;
 import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
 
 import org.w3c.dom.Document;
 
-import org.xml.sax.SAXException;
-
 @Provider
-public class DOMSourceProvider implements 
-    MessageBodyReader<DOMSource>, MessageBodyWriter<DOMSource> {
+public class SourceProvider implements 
+    MessageBodyReader<Object>, MessageBodyWriter<Source> {
 
     public boolean isWriteable(Class<?> type) {
-        return DOMSource.class.isAssignableFrom(type);
+        return Source.class.isAssignableFrom(type);
     }
     
     public boolean isReadable(Class<?> type) {
-        return DOMSource.class.isAssignableFrom(type);
+        return Source.class.isAssignableFrom(type);
     }
     
-    public DOMSource readFrom(Class<DOMSource> source, MediaType media,
-                              MultivaluedMap<String, String> httpHeaders, InputStream is) throws IOException {
-        Document doc = null;
-        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-        DocumentBuilder builder;
-        try {
-            builder = factory.newDocumentBuilder();
-            doc = builder.parse(is);
-        } catch (SAXException e) {
-            e.printStackTrace();
-
-        } catch (ParserConfigurationException e1) {
-            e1.printStackTrace();
+    public Object readFrom(Class<Object> source, MediaType media,
+                           MultivaluedMap<String, String> httpHeaders, InputStream is) throws IOException {
+        if (DOMSource.class.isAssignableFrom(source)) {
+            Document doc = null;
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder builder;
+            try {
+                builder = factory.newDocumentBuilder();
+                doc = builder.parse(is);
+            } catch (Exception e) {
+                IOException ioex = new IOException("Problem creating a Source object");
+                ioex.setStackTrace(e.getStackTrace());
+                throw ioex;
+            }
+    
+            return new DOMSource(doc);
+        } else if (StreamSource.class.isAssignableFrom(source)
+                   || Source.class.isAssignableFrom(source)) {
+            return new StreamSource(is);
         }
-
-        return new DOMSource(doc);
+        
+        throw new IOException("Unrecognized source");
     }
 
-    public void writeTo(DOMSource source, MediaType media, MultivaluedMap<String, Object> httpHeaders,
+    public void writeTo(Source source, MediaType media, MultivaluedMap<String, Object> httpHeaders,
                         OutputStream os) throws IOException {
         StreamResult result = new StreamResult(os);
         TransformerFactory tf = TransformerFactory.newInstance();
@@ -83,7 +88,7 @@
         }
     }
     
-    public long getSize(DOMSource source) {
+    public long getSize(Source source) {
         return -1;
     }
 }

Added: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/UriBuilderImpl.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/UriBuilderImpl.java?rev=633633&view=auto
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/UriBuilderImpl.java (added)
+++ incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/UriBuilderImpl.java Tue Mar  4 12:47:58 2008
@@ -0,0 +1,239 @@
+/**
+ * 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.cxf.jaxrs.provider;
+
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.PathSegment;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriBuilderException;
+
+import org.apache.cxf.jaxrs.JAXRSUtils;
+import org.apache.cxf.jaxrs.MetadataMap;
+
+public class UriBuilderImpl extends UriBuilder {
+    
+    private String scheme;
+    private String userInfo;
+    private int port;
+    private String host;
+    private List<PathSegment> paths;
+    private MultivaluedMap<String, String> matrix;
+    private String fragment;
+    private MultivaluedMap<String, String> query;
+    
+       
+    public UriBuilderImpl() {
+    }
+    
+    public UriBuilderImpl(URI uri) {
+        setUriParts(uri);
+    }
+
+    @Override
+    public URI build() throws UriBuilderException {
+        
+        try {
+            return new URI(scheme, 
+                           userInfo, 
+                           host, 
+                           port, 
+                           buildPath(), 
+                           buildQuery(), 
+                           fragment);
+        } catch (URISyntaxException ex) {
+            throw new UriBuilderException("URI can not be built", ex);
+        }
+        
+    }
+
+    @Override
+    public URI build(Map<String, String> parts) throws IllegalArgumentException, UriBuilderException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public URI build(String... values) throws IllegalArgumentException, UriBuilderException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+//CHECKSTYLE:OFF
+    @Override
+    public UriBuilder clone() {
+        return new UriBuilderImpl(build());
+    }
+//CHECKSTYLE:ON
+    
+    @Override
+    public UriBuilder encode(boolean enable) {
+        //this.encode = enable;
+        return this;
+    }
+
+    @Override
+    public UriBuilder fragment(String theFragment) throws IllegalArgumentException {
+        this.fragment = theFragment;
+        return this;
+    }
+
+    @Override
+    public UriBuilder host(String theHost) throws IllegalArgumentException {
+        this.host = theHost;
+        return this;
+    }
+
+    @Override
+    public UriBuilder matrixParam(String name, String value) throws IllegalArgumentException {
+        matrix.putSingle(name, value);
+        return this;
+    }
+
+    @Override
+    public UriBuilder path(String... segments) throws IllegalArgumentException {
+        if (paths == null) {
+            paths = new ArrayList<PathSegment>();
+        }
+        for (String segment : segments) {
+            paths.add(new PathSegmentImpl(segment, false));
+        }
+        return this;
+    }
+
+    @Override
+    public UriBuilder path(Class resource) throws IllegalArgumentException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UriBuilder path(Method... methods) throws IllegalArgumentException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UriBuilder path(Class resource, String method) throws IllegalArgumentException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UriBuilder port(int thePort) throws IllegalArgumentException {
+        this.port = thePort;
+        return this;
+    }
+
+    @Override
+    public UriBuilder queryParam(String name, String value) throws IllegalArgumentException {
+        if (query == null) {
+            query = new MetadataMap<String, String>();
+        }
+        query.add(name, value);
+        return this;
+    }
+
+    @Override
+    public UriBuilder replaceMatrixParams(String m) throws IllegalArgumentException {
+        matrix = JAXRSUtils.getStructuredParams(m, ";", true);
+        return this;
+    }
+
+    @Override
+    public UriBuilder replacePath(String p) throws IllegalArgumentException {
+        paths = JAXRSUtils.getPathSegments(p, false);
+        return this;
+    }
+
+    @Override
+    public UriBuilder replaceQueryParams(String q) throws IllegalArgumentException {
+        this.query = JAXRSUtils.getStructuredParams(q, "&", true);
+        return this;
+    }
+
+    @Override
+    public UriBuilder scheme(String s) throws IllegalArgumentException {
+        scheme = s;
+        return this;
+    }
+
+    @Override
+    public UriBuilder schemeSpecificPart(String ssp) throws IllegalArgumentException {
+        //schemeSpPart = ssp;
+        return this;
+    }
+
+    @Override
+    public UriBuilder uri(URI uri) throws IllegalArgumentException {
+        setUriParts(uri);
+        return this;
+    }
+
+    @Override
+    public UriBuilder userInfo(String ui) throws IllegalArgumentException {
+        this.userInfo = ui;
+        return this;
+    }
+
+    private void setUriParts(URI uri) {
+        scheme = uri.getScheme();
+        port = uri.getPort();
+        host = uri.getHost();
+        paths = JAXRSUtils.getPathSegments(uri.getPath(), false);
+        fragment = uri.getFragment();
+        query = JAXRSUtils.getStructuredParams(uri.getQuery(), "&", true);
+        userInfo = uri.getUserInfo();
+    }
+    
+    private String buildPath() {
+        StringBuilder sb = new StringBuilder();
+        for (PathSegment ps : paths) {
+            String p = ps.getPath();
+            if (!p.startsWith("/")) {
+                sb.append('/');    
+            }
+            sb.append(p);
+        }
+        return sb.toString();
+        
+    }
+    
+    private String buildQuery() {
+        StringBuilder b = new StringBuilder();
+        for (Iterator<Map.Entry<String, List<String>>> it = query.entrySet().iterator(); it.hasNext();) {
+            Map.Entry<String, List<String>> entry = it.next();
+            b.append(entry.getKey()).append('=').append(entry.getValue().get(0));
+            if (it.hasNext()) {
+                b.append('&');
+            }
+        }
+        return b.length() > 0 ? b.toString() : null;
+    }
+    
+    
+}

Propchange: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/UriBuilderImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/UriBuilderImpl.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/UriInfoImpl.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/UriInfoImpl.java?rev=633633&view=auto
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/UriInfoImpl.java (added)
+++ incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/UriInfoImpl.java Tue Mar  4 12:47:58 2008
@@ -0,0 +1,121 @@
+/**
+ * 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.cxf.jaxrs.provider;
+
+import java.net.URI;
+import java.util.List;
+
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.PathSegment;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.cxf.jaxrs.JAXRSUtils;
+import org.apache.cxf.jaxrs.MetadataMap;
+import org.apache.cxf.jaxrs.model.URITemplate;
+import org.apache.cxf.message.Message;
+
+public class UriInfoImpl implements UriInfo {
+
+    private URITemplate template; 
+    private Message message;
+    
+    public UriInfoImpl(Message m, URITemplate template) {
+        this.message = m;
+        this.template = template;
+    }
+    
+    public URI getAbsolutePath() {
+        String address = getEndpointAddress();
+        address = address.endsWith("/") ? address.substring(0, address.length() - 1)
+                                        : address; 
+        return URI.create(address + getPath());
+    }
+
+    public UriBuilder getAbsolutePathBuilder() {
+        return new UriBuilderImpl(getAbsolutePath());
+    }
+
+    public URI getBaseUri() {
+        return URI.create(getEndpointAddress());
+    }
+
+    public UriBuilder getBaseUriBuilder() {
+        return new UriBuilderImpl(getBaseUri());
+    }
+
+    public String getPath() {
+        return getPath(true);
+    }
+
+    public String getPath(boolean decode) {
+        
+        String path = (String)message.get(Message.PATH_INFO);
+        return decode ? JAXRSUtils.uriDecode(path) : path;
+    }
+
+    public List<PathSegment> getPathSegments() {
+        return getPathSegments(true);
+    }
+
+    public List<PathSegment> getPathSegments(boolean decode) {
+        return JAXRSUtils.getPathSegments(getPath(), decode);
+    }
+
+    public MultivaluedMap<String, String> getQueryParameters() {
+        return getQueryParameters(true);
+    }
+
+    public MultivaluedMap<String, String> getQueryParameters(boolean decode) {
+        return JAXRSUtils.getStructuredParams((String)message.get(Message.QUERY_STRING),
+                                              "&",
+                                              decode);
+    }
+
+    //TODO : check the fragment as well
+    public URI getRequestUri() {
+        String queries = (String)message.get(Message.QUERY_STRING);
+        return URI.create(getEndpointAddress() 
+                          + message.get(Message.PATH_INFO)
+                          + (queries == null ? "" : "?" + queries));
+    }
+
+    public UriBuilder getRequestUriBuilder() {
+        return new UriBuilderImpl(getRequestUri());
+    }
+
+    public MultivaluedMap<String, String> getTemplateParameters() {
+        return getTemplateParameters(true);
+    }
+
+    public MultivaluedMap<String, String> getTemplateParameters(boolean decode) {
+        // this needs to be changed
+        MetadataMap<String, String> values = new MetadataMap<String, String>();
+        template.match(getPath(decode), values);
+        return values;
+    }
+
+    protected String getEndpointAddress() {
+        String value = message.getExchange().getDestination().getAddress()
+               .getAddress().getValue();
+        
+        return value;
+    }
+}

Propchange: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/UriInfoImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/UriInfoImpl.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/VariantListBuilderImpl.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/VariantListBuilderImpl.java?rev=633633&view=auto
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/VariantListBuilderImpl.java (added)
+++ incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/VariantListBuilderImpl.java Tue Mar  4 12:47:58 2008
@@ -0,0 +1,107 @@
+/**
+ * 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.cxf.jaxrs.provider;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Variant;
+import javax.ws.rs.core.Variant.VariantListBuilder;
+
+public class VariantListBuilderImpl extends VariantListBuilder {
+    
+    private Set<String> charsets = new HashSet<String>();
+    private Set<String> encodings = new HashSet<String>();
+    private Set<String> languages = new HashSet<String>();
+    private Set<MediaType> mediaTypes = new HashSet<MediaType>();
+    private List<Variant> variants = new ArrayList<Variant>();
+    
+    public VariantListBuilderImpl() {
+        
+    }
+
+    @Override
+    public VariantListBuilder add() {
+        addVariants();
+        resetMeta();
+        return this;
+    }
+
+    @Override
+    public List<Variant> build() {
+        List<Variant> vs = new ArrayList<Variant>(variants);
+        reset();
+        return vs;
+    }
+
+    @Override
+    public VariantListBuilder charsets(String... csets) {
+        charsets.addAll(Arrays.asList(csets));
+        return this;
+    }
+
+    @Override
+    public VariantListBuilder encodings(String... encs) {
+        encodings.addAll(Arrays.asList(encs));
+        return this;
+    }
+
+    @Override
+    public VariantListBuilder languages(String... ls) {
+        languages.addAll(Arrays.asList(ls));
+        return this;
+    }
+
+    @Override
+    public VariantListBuilder mediaTypes(MediaType... types) {
+        mediaTypes.addAll(Arrays.asList(types));
+        return this;
+    }
+
+    private void reset() {
+        variants.clear();
+        resetMeta();
+    }
+    
+    private void resetMeta() {
+        mediaTypes.clear();
+        languages.clear();
+        encodings.clear();
+        charsets.clear();
+    }
+    
+    private void addVariants() {
+        for (MediaType type : mediaTypes) {
+            for (String lang : languages) {
+                for (String charset : charsets) {
+                    for (String enc : encodings) {
+                        variants.add(new Variant(type, lang, charset, enc));
+                    }
+                }
+            }
+        }
+    }
+    
+}

Propchange: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/VariantListBuilderImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/VariantListBuilderImpl.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: incubator/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/JAXRSServiceFactoryBeanTest.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/JAXRSServiceFactoryBeanTest.java?rev=633633&r1=633632&r2=633633&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/JAXRSServiceFactoryBeanTest.java (original)
+++ incubator/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/JAXRSServiceFactoryBeanTest.java Tue Mar  4 12:47:58 2008
@@ -18,9 +18,9 @@
  */
 package org.apache.cxf.jaxrs;
 
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
+
+import javax.ws.rs.core.MultivaluedMap;
 
 import org.apache.cxf.jaxrs.model.ClassResourceInfo;
 import org.apache.cxf.jaxrs.model.MethodDispatcher;
@@ -49,7 +49,7 @@
         ClassResourceInfo rootCri = resources.get(0);
         assertNotNull(rootCri.getURITemplate());
         URITemplate template = rootCri.getURITemplate();
-        Map<String, String> values = new HashMap<String, String>();
+        MultivaluedMap<String, String> values = new MetadataMap<String, String>();
         assertTrue(template.match("/bookstore/books/123", values));     
         assertFalse(rootCri.hasSubResources());   
         MethodDispatcher md = rootCri.getMethodDispatcher();
@@ -94,7 +94,7 @@
         ClassResourceInfo rootCri = resources.get(0);
         assertNotNull(rootCri.getURITemplate());
         URITemplate template = rootCri.getURITemplate();
-        Map<String, String> values = new HashMap<String, String>();
+        MultivaluedMap<String, String> values = new MetadataMap<String, String>();
         assertTrue(template.match("/bookstore/books/123", values));     
         assertTrue(rootCri.hasSubResources());   
         MethodDispatcher md = rootCri.getMethodDispatcher();
@@ -124,7 +124,7 @@
         // Verify sub-resource ClassResourceInfo: Book
         assertEquals(1, rootCri.getSubClassResourceInfo().size());
         ClassResourceInfo subCri = rootCri.getSubClassResourceInfo().get(0);        
-        assertTrue(subCri.getURITemplate() == null);
+        assertEquals(subCri.getURITemplate().getValue(), "/");
         assertEquals(org.apache.cxf.jaxrs.resources.Book.class, subCri.getResourceClass());
         MethodDispatcher subMd = subCri.getMethodDispatcher();
         assertEquals(2, subMd.getOperationResourceInfos().size());