cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject svn commit: r1445113 - in /cxf/trunk/rt: frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/ frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ frontend/jaxrs/src/main/java/org/apache/...
Date Tue, 12 Feb 2013 11:52:06 GMT
Author: sergeyb
Date: Tue Feb 12 11:52:06 2013
New Revision: 1445113

URL: http://svn.apache.org/r1445113
Log:
[CXF-4822] Initial attempt at updating the selection algorithm to get root resources with the same path checked

Modified:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ClassResourceInfoComparator.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
    cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/SelectMethodCandidatesTest.java
    cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java
    cxf/trunk/rt/rs/security/cors/src/main/java/org/apache/cxf/rs/security/cors/CrossOriginResourceSharingFilter.java

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java?rev=1445113&r1=1445112&r2=1445113&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSInvoker.java Tue Feb 12 11:52:06 2013
@@ -234,7 +234,8 @@ public class JAXRSInvoker extends Abstra
                     throw new NotFoundException();
                 }
 
-                OperationResourceInfo subOri = JAXRSUtils.findTargetMethod(subCri,
+                OperationResourceInfo subOri = JAXRSUtils.findTargetMethod(
+                                                         Collections.singletonMap(subCri, values),
                                                          inMessage,
                                                          httpMethod,
                                                          values,
@@ -266,7 +267,8 @@ public class JAXRSInvoker extends Abstra
                 Response excResponse;
                 if (JAXRSUtils.noResourceMethodForOptions(ex.getResponse(), 
                         (String)exchange.getInMessage().get(Message.HTTP_REQUEST_METHOD))) {
-                    excResponse = JAXRSUtils.createResponse(subCri, null, null, 200, true);
+                    excResponse = JAXRSUtils.createResponse(Collections.singletonList(subCri), 
+                                                            null, null, 200, true);
                 } else {
                     excResponse = JAXRSUtils.convertFaultToResponse(ex, exchange.getInMessage());
                 }

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java?rev=1445113&r1=1445112&r2=1445113&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java Tue Feb 12 11:52:06 2013
@@ -21,6 +21,7 @@ package org.apache.cxf.jaxrs.interceptor
 
 import java.io.IOException;
 import java.util.List;
+import java.util.Map;
 import java.util.ResourceBundle;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -35,7 +36,6 @@ import javax.ws.rs.core.Response;
 
 import org.apache.cxf.common.i18n.BundleUtils;
 import org.apache.cxf.common.logging.LogUtils;
-import org.apache.cxf.jaxrs.JAXRSServiceImpl;
 import org.apache.cxf.jaxrs.ext.RequestHandler;
 import org.apache.cxf.jaxrs.impl.MetadataMap;
 import org.apache.cxf.jaxrs.impl.RequestPreprocessor;
@@ -53,7 +53,6 @@ import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageUtils;
 import org.apache.cxf.phase.AbstractPhaseInterceptor;
 import org.apache.cxf.phase.Phase;
-import org.apache.cxf.service.Service;
 
 public class JAXRSInInterceptor extends AbstractPhaseInterceptor<Message> {
 
@@ -135,8 +134,7 @@ public class JAXRSInInterceptor extends 
         String rawPath = HttpUtils.getPathToMatch(message, true);
         
         //1. Matching target resource class
-        Service service = message.getExchange().get(Service.class);
-        List<ClassResourceInfo> resources = ((JAXRSServiceImpl)service).getClassResourceInfos();
+        List<ClassResourceInfo> resources = JAXRSUtils.getRootResources(message);
 
         String acceptTypes = HttpUtils.getProtocolHeader(message, Message.ACCEPT_CONTENT_TYPE, null);
         if (acceptTypes == null) {
@@ -151,44 +149,47 @@ public class JAXRSInInterceptor extends 
         }
         message.getExchange().put(Message.ACCEPT_CONTENT_TYPE, acceptContentTypes);
 
-        MultivaluedMap<String, String> values = new MetadataMap<String, String>();
-        ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, 
-                                          rawPath, 
-                                          values,
-                                          message);
-        if (resource == null) {
+        Map<ClassResourceInfo, MultivaluedMap<String, String>> matchedResources = 
+            JAXRSUtils.selectResourceClass(resources, rawPath, message);
+        if (matchedResources == null) {
             org.apache.cxf.common.i18n.Message errorMsg = 
                 new org.apache.cxf.common.i18n.Message("NO_ROOT_EXC", 
                                                    BUNDLE,
                                                    message.get(Message.REQUEST_URI),
                                                    rawPath);
             LOG.warning(errorMsg.toString());
-            Response resp = JAXRSUtils.createResponse(null, message, errorMsg.toString(), 
+            Response resp = JAXRSUtils.createResponse(resources, message, errorMsg.toString(), 
                     Response.Status.NOT_FOUND.getStatusCode(), false);
             throw new NotFoundException(resp);
         }
 
-        message.getExchange().put(JAXRSUtils.ROOT_RESOURCE_CLASS, resource);
-
         String httpMethod = HttpUtils.getProtocolHeader(message, Message.HTTP_REQUEST_METHOD, "POST");
-        OperationResourceInfo ori = null;     
+        MultivaluedMap<String, String> matchedValues = new MetadataMap<String, String>();
+        
         
+        OperationResourceInfo ori = null;     
         boolean operChecked = false;
         List<ProviderInfo<RequestHandler>> shs = providerFactory.getRequestHandlers();
         for (ProviderInfo<RequestHandler> sh : shs) {
             if (ori == null && !operChecked) {
                 try {                
-                    ori = JAXRSUtils.findTargetMethod(resource, 
-                        message, httpMethod, values, 
+                    ori = JAXRSUtils.findTargetMethod(matchedResources, 
+                        message, httpMethod, matchedValues,
                         requestContentType, acceptContentTypes, false);
-                    setExchangeProperties(message, ori, values, resources.size());
+                    setExchangeProperties(message, ori, matchedValues, resources.size());
                 } catch (WebApplicationException ex) {
                     operChecked = true;
                 }
                 
             }
             InjectionUtils.injectContexts(sh.getProvider(), sh, message);
-            Response response = sh.getProvider().handleRequest(message, resource);
+            ClassResourceInfo cri = null;
+            if (ori == null && matchedResources.size() == 1) {
+                cri = matchedResources.keySet().iterator().next();
+            } else {
+                cri = ori.getClassResourceInfo();
+            }
+            Response response = sh.getProvider().handleRequest(message, cri);
             if (response != null) {
                 message.getExchange().put(Response.class, response);
                 return;
@@ -198,12 +199,12 @@ public class JAXRSInInterceptor extends 
         
         if (ori == null) {
             try {                
-                ori = JAXRSUtils.findTargetMethod(resource, message, 
-                                            httpMethod, values, requestContentType, acceptContentTypes, true);
-                setExchangeProperties(message, ori, values, resources.size());
+                ori = JAXRSUtils.findTargetMethod(matchedResources, message, 
+                                            httpMethod, matchedValues, requestContentType, acceptContentTypes, true);
+                setExchangeProperties(message, ori, matchedValues, resources.size());
             } catch (WebApplicationException ex) {
                 if (JAXRSUtils.noResourceMethodForOptions(ex.getResponse(), httpMethod)) {
-                    Response response = JAXRSUtils.createResponse(resource, null, null, 200, true);
+                    Response response = JAXRSUtils.createResponse(resources, null, null, 200, true);
                     message.getExchange().put(Response.class, response);
                     return;
                 } else {
@@ -221,7 +222,7 @@ public class JAXRSInInterceptor extends 
             LOG.fine("Found operation: " + ori.getMethodToInvoke().getName());
         }
         
-        setExchangeProperties(message, ori, values, resources.size());
+        setExchangeProperties(message, ori, matchedValues, resources.size());
         
         // Global and name-bound post-match request filters
         if (JAXRSUtils.runContainerRequestFilters(providerFactory,
@@ -234,7 +235,7 @@ public class JAXRSInInterceptor extends 
         
         //Process parameters
         try {
-            List<Object> params = JAXRSUtils.processParameters(ori, values, message);
+            List<Object> params = JAXRSUtils.processParameters(ori, matchedValues, message);
             message.setContent(List.class, params);
         } catch (IOException ex) {
             Response excResponse = JAXRSUtils.convertFaultToResponse(ex, message);
@@ -252,6 +253,7 @@ public class JAXRSInInterceptor extends 
                                       int numberOfResources) {
         message.put(Message.REST_MESSAGE, Boolean.TRUE);
         message.getExchange().put(OperationResourceInfo.class, ori);
+        message.getExchange().put(JAXRSUtils.ROOT_RESOURCE_CLASS, ori.getClassResourceInfo());
         message.put(RESOURCE_METHOD, ori.getMethodToInvoke());
         message.put(URITemplate.TEMPLATE_PARAMETERS, values);
         

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ClassResourceInfoComparator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ClassResourceInfoComparator.java?rev=1445113&r1=1445112&r2=1445113&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ClassResourceInfoComparator.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ClassResourceInfoComparator.java Tue Feb 12 11:52:06 2013
@@ -41,17 +41,18 @@ public class ClassResourceInfoComparator
     }
     
     public int compare(ClassResourceInfo cr1, ClassResourceInfo cr2) {
-        
+        int result = 0;
         if (rc != null) {
-            int result = rc.compare(cr1, cr2, message);
+            result = rc.compare(cr1, cr2, message);
             if (result != 0) {
                 return result;
             }
         }
         
-        return URITemplate.compareTemplates(
-               cr1.getURITemplate(), 
+        result = URITemplate.compareTemplates(
+               cr1.getURITemplate(),
                cr2.getURITemplate());
+        return result == 0 ? -1 : result;
     }
 }
     

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java?rev=1445113&r1=1445112&r2=1445113&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java Tue Feb 12 11:52:06 2013
@@ -33,6 +33,7 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
@@ -97,6 +98,7 @@ import org.apache.cxf.common.logging.Log
 import org.apache.cxf.common.util.PackageUtils;
 import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.helpers.XMLUtils;
+import org.apache.cxf.jaxrs.JAXRSServiceImpl;
 import org.apache.cxf.jaxrs.ext.ContextProvider;
 import org.apache.cxf.jaxrs.ext.MessageContext;
 import org.apache.cxf.jaxrs.ext.MessageContextImpl;
@@ -136,6 +138,7 @@ import org.apache.cxf.jaxrs.provider.Ser
 import org.apache.cxf.jaxrs.utils.multipart.AttachmentUtils;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageUtils;
+import org.apache.cxf.service.Service;
 import org.apache.cxf.transport.http.AbstractHTTPDestination;
 
 public final class JAXRSUtils {
@@ -294,19 +297,19 @@ public final class JAXRSUtils {
         
     }
     
-    public static ClassResourceInfo selectResourceClass(List<ClassResourceInfo> resources,
-                                                 String path, 
-                                                 MultivaluedMap<String, String> values,
-                                                 Message message) {
+    public static Map<ClassResourceInfo, MultivaluedMap<String, String>> selectResourceClass(
+        List<ClassResourceInfo> resources, String path, Message message) {
+        
         boolean isFineLevelLoggable = LOG.isLoggable(Level.FINE); 
         if (isFineLevelLoggable) {
             LOG.fine(new org.apache.cxf.common.i18n.Message("START_CRI_MATCH", 
                                                         BUNDLE, 
                                                         path).toString());
         }
-        if (resources.size() == 1) { 
+        if (resources.size() == 1) {
+            MultivaluedMap<String, String> values = new MetadataMap<String, String>();
             return resources.get(0).getURITemplate().match(path, values)
-                   ? resources.get(0) : null;
+                   ? Collections.singletonMap(resources.get(0), values) : null;
         }
         
         SortedMap<ClassResourceInfo, MultivaluedMap<String, String>> candidateList = 
@@ -333,47 +336,43 @@ public final class JAXRSUtils {
         }
         
         if (!candidateList.isEmpty()) {
-            Map.Entry<ClassResourceInfo, MultivaluedMap<String, String>> firstEntry = 
-                candidateList.entrySet().iterator().next();
-            values.putAll(firstEntry.getValue());
-            ClassResourceInfo cri = firstEntry.getKey();
-            if (isFineLevelLoggable) {
-                LOG.fine(new org.apache.cxf.common.i18n.Message("CRI_SELECTED", 
-                                                         BUNDLE, 
-                                                         cri.getServiceClass().getName(),
-                                                         path, cri.getURITemplate().getValue()).toString());
+            Map<ClassResourceInfo, MultivaluedMap<String, String>> cris = 
+                new LinkedHashMap<ClassResourceInfo, MultivaluedMap<String, String>>(candidateList.size());
+            ClassResourceInfo firstCri = null;
+            for (Map.Entry<ClassResourceInfo, MultivaluedMap<String, String>> entry : candidateList.entrySet()) {
+                ClassResourceInfo cri = entry.getKey();
+                if (cris.isEmpty()) {
+                    firstCri = cri;
+                    cris.put(cri, entry.getValue());
+                } else if (URITemplate.compareTemplates(firstCri.getURITemplate(), cri.getURITemplate()) == 0) {
+                    cris.put(cri, entry.getValue());
+                } else {
+                    break;
+                }
+                if (isFineLevelLoggable) {
+                    LOG.fine(new org.apache.cxf.common.i18n.Message("CRI_SELECTED", 
+                                                             BUNDLE, 
+                                                             cri.getServiceClass().getName(),
+                                                             path, cri.getURITemplate().getValue()).toString());
+                }
             }
-            return cri;
+            return cris;
         }
         
         return null;
     }
-
-    public static OperationResourceInfo findTargetMethod(ClassResourceInfo resource,
-                                                         Message message,
-                                                         String httpMethod, 
-                                                         MultivaluedMap<String, String> values, 
-                                                         String requestContentType, 
-                                                         List<MediaType> acceptContentTypes,
-                                                         boolean logNow) {
-        boolean isFineLevelLoggable = LOG.isLoggable(Level.FINE); 
-        if (isFineLevelLoggable) {
-            org.apache.cxf.common.i18n.Message msg = 
-                new org.apache.cxf.common.i18n.Message("START_OPER_MATCH", 
-                                                       BUNDLE,
-                                                       resource.getServiceClass().getName());
-            LOG.fine(msg.toString());
-            
-        }
-        String path = values.getFirst(URITemplate.FINAL_MATCH_GROUP);
-        if (path == null) {
-            path = "/";
-        }
+    
+    public static OperationResourceInfo findTargetMethod(
+        Map<ClassResourceInfo, MultivaluedMap<String, String>> matchedResources,
+        Message message,
+        String httpMethod, 
+        MultivaluedMap<String, String> matchedValues,
+        String requestContentType, 
+        List<MediaType> acceptContentTypes,
+        boolean logNow) {
         
-        SortedMap<OperationResourceInfo, MultivaluedMap<String, String>> candidateList = 
-            new TreeMap<OperationResourceInfo, MultivaluedMap<String, String>>(
-                new OperationResourceInfoComparator(message, httpMethod));
-
+        final boolean isFineLevelLoggable = LOG.isLoggable(Level.FINE); 
+                
         MediaType requestType;
         try {
             requestType = requestContentType == null
@@ -381,72 +380,91 @@ public final class JAXRSUtils {
         } catch (IllegalArgumentException ex) {
             throw new NotSupportedException(ex);
         }
+        
+        SortedMap<OperationResourceInfo, MultivaluedMap<String, String>> candidateList = 
+            new TreeMap<OperationResourceInfo, MultivaluedMap<String, String>>(
+                new OperationResourceInfoComparator(message, httpMethod));
 
         int pathMatched = 0;
         int methodMatched = 0;
         int consumeMatched = 0;
         int produceMatched = 0;
         
-        boolean subresourcesOnly = true;
-        for (MediaType acceptType : acceptContentTypes) {
-            for (OperationResourceInfo ori : resource.getMethodDispatcher().getOperationResourceInfos()) {
-                URITemplate uriTemplate = ori.getURITemplate();
-                MultivaluedMap<String, String> map = new MetadataMap<String, String>(values);
-                if (uriTemplate != null && uriTemplate.match(path, map)) {
-                    boolean added = false;
-                    if (ori.isSubResourceLocator()) {
-                        candidateList.put(ori, map);
-                        added = true;
-                    } else {
-                        String finalGroup = map.getFirst(URITemplate.FINAL_MATCH_GROUP);
-                        if (finalGroup == null || StringUtils.isEmpty(finalGroup)
-                            || finalGroup.equals("/")) {
-                            pathMatched++;
-                            boolean mMatched = matchHttpMethod(ori.getHttpMethod(), httpMethod);
-                            boolean cMatched = matchConsumeTypes(requestType, ori);
-                            boolean pMatched = matchProduceTypes(acceptType, ori);
-                            if (mMatched && cMatched && pMatched) {
-                                subresourcesOnly = false;
-                                candidateList.put(ori, map);
-                                added = true;
+        for (Map.Entry<ClassResourceInfo, MultivaluedMap<String, String>> rEntry : matchedResources.entrySet()) {
+            ClassResourceInfo resource = rEntry.getKey();
+            MultivaluedMap<String, String> values = rEntry.getValue();
+            
+            String path = getCurrentPath(values);
+            if (isFineLevelLoggable) {
+                org.apache.cxf.common.i18n.Message msg = 
+                    new org.apache.cxf.common.i18n.Message("START_OPER_MATCH", 
+                                                           BUNDLE,
+                                                           resource.getServiceClass().getName());
+                LOG.fine(msg.toString());
+                
+            }
+            
+            boolean subresourcesOnly = true;
+            for (MediaType acceptType : acceptContentTypes) {
+                for (OperationResourceInfo ori : resource.getMethodDispatcher().getOperationResourceInfos()) {
+                    URITemplate uriTemplate = ori.getURITemplate();
+                    MultivaluedMap<String, String> map = new MetadataMap<String, String>(values);
+                    if (uriTemplate != null && uriTemplate.match(path, map)) {
+                        boolean added = false;
+                        if (ori.isSubResourceLocator()) {
+                            candidateList.put(ori, map);
+                            added = true;
+                        } else {
+                            String finalGroup = map.getFirst(URITemplate.FINAL_MATCH_GROUP);
+                            if (finalGroup == null || StringUtils.isEmpty(finalGroup)
+                                || finalGroup.equals("/")) {
+                                pathMatched++;
+                                boolean mMatched = matchHttpMethod(ori.getHttpMethod(), httpMethod);
+                                boolean cMatched = matchConsumeTypes(requestType, ori);
+                                boolean pMatched = matchProduceTypes(acceptType, ori);
+                                if (mMatched && cMatched && pMatched) {
+                                    subresourcesOnly = false;
+                                    candidateList.put(ori, map);
+                                    added = true;
+                                } else {
+                                    methodMatched = mMatched ? methodMatched + 1 : methodMatched;
+                                    produceMatched = pMatched ? produceMatched + 1 : produceMatched;
+                                    consumeMatched = cMatched ? consumeMatched + 1 : consumeMatched;
+                                    logNoMatchMessage(ori, path, httpMethod, requestType, acceptContentTypes);
+                                }
                             } else {
-                                methodMatched = mMatched ? methodMatched + 1 : methodMatched;
-                                produceMatched = pMatched ? produceMatched + 1 : produceMatched;
-                                consumeMatched = cMatched ? consumeMatched + 1 : consumeMatched;
                                 logNoMatchMessage(ori, path, httpMethod, requestType, acceptContentTypes);
                             }
-                        } else {
-                            logNoMatchMessage(ori, path, httpMethod, requestType, acceptContentTypes);
                         }
+                        if (added && isFineLevelLoggable) {
+                            LOG.fine(new org.apache.cxf.common.i18n.Message("OPER_SELECTED_POSSIBLY", 
+                                      BUNDLE, 
+                                      ori.getMethodToInvoke().getName()).toString());
+                        }
+                    } else {
+                        logNoMatchMessage(ori, path, httpMethod, requestType, acceptContentTypes);
                     }
-                    if (added && isFineLevelLoggable) {
-                        LOG.fine(new org.apache.cxf.common.i18n.Message("OPER_SELECTED_POSSIBLY", 
-                                  BUNDLE, 
-                                  ori.getMethodToInvoke().getName()).toString());
-                    }
-                } else {
-                    logNoMatchMessage(ori, path, httpMethod, requestType, acceptContentTypes);
                 }
-            }
-            if (!candidateList.isEmpty() && !subresourcesOnly) {
-                break;
+                if (!candidateList.isEmpty() && !subresourcesOnly) {
+                    break;
+                }
             }
         }
         if (!candidateList.isEmpty()) {
             Map.Entry<OperationResourceInfo, MultivaluedMap<String, String>> firstEntry = 
                 candidateList.entrySet().iterator().next();
-            values.clear();
-            values.putAll(firstEntry.getValue());
+            matchedValues.clear();
+            matchedValues.putAll(firstEntry.getValue());
             OperationResourceInfo ori = firstEntry.getKey();
             if (headMethodPossible(ori.getHttpMethod(), httpMethod)) {
                 LOG.info(new org.apache.cxf.common.i18n.Message("GET_INSTEAD_OF_HEAD", 
-                         BUNDLE, resource.getServiceClass().getName(), 
+                         BUNDLE, ori.getClassResourceInfo().getServiceClass().getName(), 
                          ori.getMethodToInvoke().getName()).toString());
             }
             if (isFineLevelLoggable) {
                 LOG.fine(new org.apache.cxf.common.i18n.Message("OPER_SELECTED", 
                                BUNDLE, ori.getMethodToInvoke().getName(), 
-                               resource.getServiceClass().getName()).toString());
+                               ori.getClassResourceInfo().getServiceClass().getName()).toString());
             }
             return ori;
         }
@@ -464,13 +482,14 @@ public final class JAXRSUtils {
         } else {
             status = 406;
         }
-        
-        String name = resource.isRoot() ? "NO_OP_EXC" : "NO_SUBRESOURCE_METHOD_FOUND";
+        Map.Entry<ClassResourceInfo, MultivaluedMap<String, String>> firstCri = 
+            matchedResources.entrySet().iterator().next();
+        String name = firstCri.getKey().isRoot() ? "NO_OP_EXC" : "NO_SUBRESOURCE_METHOD_FOUND";
         org.apache.cxf.common.i18n.Message errorMsg = 
             new org.apache.cxf.common.i18n.Message(name, 
                                                    BUNDLE,
                                                    message.get(Message.REQUEST_URI),
-                                                   path,
+                                                   getCurrentPath(firstCri.getValue()),
                                                    httpMethod,
                                                    requestType.toString(),
                                                    convertTypesToString(acceptContentTypes));
@@ -478,10 +497,20 @@ public final class JAXRSUtils {
             LOG.warning(errorMsg.toString());
         }
         Response response = 
-            createResponse(resource, message, errorMsg.toString(), status, methodMatched == 0);
+            createResponse(getRootResources(message), message, errorMsg.toString(), status, methodMatched == 0);
         throw new ClientErrorException(response);
         
     }    
+
+    private static String getCurrentPath(MultivaluedMap<String, String> values) {
+        String path = values.getFirst(URITemplate.FINAL_MATCH_GROUP);
+        return path == null ?  "/" : path;
+    }
+    
+    public static List<ClassResourceInfo> getRootResources(Message message) {
+        Service service = message.getExchange().get(Service.class);
+        return ((JAXRSServiceImpl)service).getClassResourceInfos();
+    }
     
     public static boolean noResourceMethodForOptions(Response exResponse, String httpMethod) {
         return exResponse != null && exResponse.getStatus() == 405 
@@ -508,11 +537,15 @@ public final class JAXRSUtils {
         LOG.fine(errorMsg.toString());
     }
 
-    public static Response createResponse(ClassResourceInfo cri, Message msg,
+    public static Response createResponse(List<ClassResourceInfo> cris, Message msg,
                                           String responseMessage, int status, boolean addAllow) {
         ResponseBuilder rb = Response.status(status);
         if (addAllow) {
-            Set<String> allowedMethods = cri.getAllowedMethods();
+            Set<String> allowedMethods = new HashSet<String>();
+            for (ClassResourceInfo cri : cris) {
+                allowedMethods.addAll(cri.getAllowedMethods());
+            }
+            
             for (String m : allowedMethods) {
                 rb.header("Allow", m);
             }

Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/SelectMethodCandidatesTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/SelectMethodCandidatesTest.java?rev=1445113&r1=1445112&r2=1445113&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/SelectMethodCandidatesTest.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/SelectMethodCandidatesTest.java Tue Feb 12 11:52:06 2013
@@ -23,8 +23,14 @@ import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
+import javax.ws.rs.Consumes;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
 
 import org.apache.cxf.endpoint.Endpoint;
 import org.apache.cxf.jaxrs.fortest.BookEntity;
@@ -105,13 +111,11 @@ public class SelectMethodCandidatesTest 
         ex.put(Endpoint.class, e);
         
         MetadataMap<String, String> values = new MetadataMap<String, String>();
-        ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, "/books", values,
-                                                                    m);
-        OperationResourceInfo ori = JAXRSUtils.findTargetMethod(resource, 
-                                                                m, 
-                                    "POST", values, contentTypes, 
-                                    JAXRSUtils.sortMediaTypes(acceptContentTypes),
-                                    true);
+        OperationResourceInfo ori = findTargetResourceClass(resources, m, 
+                                                            "/books",
+                                                            "POST",
+                                                            values, contentTypes, 
+                                                            JAXRSUtils.sortMediaTypes(acceptContentTypes));
         assertNotNull(ori);
         assertEquals("resourceMethod needs to be selected", "postEntity",
                      ori.getMethodToInvoke().getName());
@@ -157,13 +161,11 @@ public class SelectMethodCandidatesTest 
         ex.put(Endpoint.class, e);
         
         MetadataMap<String, String> values = new MetadataMap<String, String>();
-        ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, "/books", values,
-                                                                    m);
-        OperationResourceInfo ori = JAXRSUtils.findTargetMethod(resource, 
-                                                                m, 
-                                    "PUT", values, contentTypes, 
-                                    JAXRSUtils.sortMediaTypes(acceptContentTypes),
-                                    true);
+        OperationResourceInfo ori = findTargetResourceClass(resources, m, 
+                                                            "/books",
+                                                            "PUT",
+                                                            values, contentTypes, 
+                                                            JAXRSUtils.sortMediaTypes(acceptContentTypes));
         assertNotNull(ori);
         assertEquals("resourceMethod needs to be selected", "putEntity",
                      ori.getMethodToInvoke().getName());
@@ -178,6 +180,67 @@ public class SelectMethodCandidatesTest 
         assertEquals("The Book", c.getTitle());
     }
     
+    @Test
+    public void testRootResourcesWithSameName() throws Exception {
+        doTestRootResourcesWithSameName("/a/books", "put", RootResource.class);
+        doTestRootResourcesWithSameName("/a1/books", "put", RootResource.class);
+    }
+    
+    @Test
+    public void testRootResourcesWithSameName2() throws Exception {
+        doTestRootResourcesWithSameName("/a/books/1", "put", RootResource2.class);
+        doTestRootResourcesWithSameName("/c/thebooks", "put2", RootResource2.class);
+        doTestRootResourcesWithSameName("/b/books", "put", RootResource3.class);
+    }
+    
+    
+    private void doTestRootResourcesWithSameName(String path, String methodName, Class<?> expectedRoot) 
+        throws Exception {
+        JAXRSServiceFactoryBean sf = new JAXRSServiceFactoryBean();
+        sf.setResourceClasses(RootResource.class, RootResource2.class, RootResource3.class);
+        sf.create();
+        List<ClassResourceInfo> resources = ((JAXRSServiceImpl)sf.getService()).getClassResourceInfos();
+        assertEquals(3, resources.size());
+        String contentTypes = "text/xml";
+        String acceptContentTypes = "text/xml";
+        
+        Message m = prepareMessage();
+        
+        MetadataMap<String, String> values = new MetadataMap<String, String>();
+        OperationResourceInfo ori = findTargetResourceClass(resources, m, 
+                                                            path,
+                                                            "PUT",
+                                                            values, contentTypes, 
+                                                            JAXRSUtils.sortMediaTypes(acceptContentTypes));
+        assertNotNull(ori);
+        assertEquals("resourceMethod needs to be selected", methodName,
+                     ori.getMethodToInvoke().getName());
+        
+        assertSame(expectedRoot, ori.getClassResourceInfo().getServiceClass());
+    }
+    
+    private Message prepareMessage() {
+        Message m = new MessageImpl();
+        m.put(Message.CONTENT_TYPE, "text/xml");
+        Exchange ex = new ExchangeImpl();
+        ex.setInMessage(m);
+        m.setExchange(ex);
+        Endpoint e = EasyMock.createMock(Endpoint.class);
+        e.isEmpty();
+        EasyMock.expectLastCall().andReturn(true).anyTimes();
+        e.size();
+        EasyMock.expectLastCall().andReturn(0).anyTimes();
+        e.getEndpointInfo();
+        EasyMock.expectLastCall().andReturn(null).anyTimes();
+        e.get(ServerProviderFactory.class.getName());
+        EasyMock.expectLastCall().andReturn(ServerProviderFactory.getInstance()).times(3);
+        e.get("org.apache.cxf.jaxrs.comparator");
+        EasyMock.expectLastCall().andReturn(null);
+        EasyMock.replay(e);
+        ex.put(Endpoint.class, e);
+        return m;
+    }
+    
     private void doTestGenericSuperType(Class<?> serviceClass, String methodName) throws Exception {
         JAXRSServiceFactoryBean sf = new JAXRSServiceFactoryBean();
         sf.setResourceClasses(serviceClass);
@@ -206,13 +269,11 @@ public class SelectMethodCandidatesTest 
         ex.put(Endpoint.class, e);
         
         MetadataMap<String, String> values = new MetadataMap<String, String>();
-        ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, "/books", values,
-                                                                    m);
-        OperationResourceInfo ori = JAXRSUtils.findTargetMethod(resource, 
-                                                                m, 
-                                    methodName, values, contentTypes, 
-                                    JAXRSUtils.sortMediaTypes(acceptContentTypes),
-                                    true);
+        OperationResourceInfo ori = findTargetResourceClass(resources, m, 
+                                                            "/books",
+                                                            methodName,
+                                                            values, contentTypes, 
+                                                            JAXRSUtils.sortMediaTypes(acceptContentTypes));
         assertNotNull(ori);
         assertEquals("resourceMethod needs to be selected", methodName.toLowerCase() + "Entity",
                      ori.getMethodToInvoke().getName());
@@ -256,12 +317,11 @@ public class SelectMethodCandidatesTest 
         String acceptContentTypes = "text/xml,*/*";
         
         MetadataMap<String, String> values = new MetadataMap<String, String>();
-        ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, path, values,
-                                                                    new MessageImpl());
-        OperationResourceInfo ori = JAXRSUtils.findTargetMethod(resource, 
-                                    null, 
-                                    "GET", values, contentTypes, 
-                                    JAXRSUtils.sortMediaTypes(acceptContentTypes), true);
+        OperationResourceInfo ori = findTargetResourceClass(resources, null, 
+                                                            path,
+                                                            "GET",
+                                                            values, contentTypes, 
+                                                            JAXRSUtils.sortMediaTypes(acceptContentTypes));
         assertNotNull(ori);
         assertEquals("resourceMethod needs to be selected", method,
                      ori.getMethodToInvoke().getName());
@@ -277,12 +337,12 @@ public class SelectMethodCandidatesTest 
         String acceptContentTypes = "application/xml;q=0.5,application/json";
         
         MetadataMap<String, String> values = new MetadataMap<String, String>();
-        ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/resource1", values,
-                                                                    new MessageImpl());
-        OperationResourceInfo ori = JAXRSUtils.findTargetMethod(resource, 
-                                    null, 
-                                    "GET", values, contentTypes, 
-                                    JAXRSUtils.sortMediaTypes(acceptContentTypes), true);
+        OperationResourceInfo ori = findTargetResourceClass(resources, null, 
+                                                            "/1/2/3/d/resource1",
+                                                            "GET",
+                                                            values, contentTypes, 
+                                                            JAXRSUtils.sortMediaTypes(acceptContentTypes));
+        
         assertNotNull(ori);
         assertEquals("jsonResource needs to be selected", "jsonResource",
                      ori.getMethodToInvoke().getName());
@@ -302,24 +362,23 @@ public class SelectMethodCandidatesTest 
         //If acceptContentTypes does not specify a specific Mime type, the  
         //method is declared with a most specific ProduceMime type is selected.
         MetadataMap<String, String> values = new MetadataMap<String, String>();
-        ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d", values,
-                                                                    new MessageImpl());
-        OperationResourceInfo ori = JAXRSUtils.findTargetMethod(resource,
-                                    null, 
-                                    "GET", values, contentTypes, 
-                                    Collections.singletonList(MediaType.valueOf(acceptContentTypes)), true);
+        OperationResourceInfo ori = findTargetResourceClass(resources, null, 
+                                                            "/1/2/3/d",
+                                                            "GET",
+                                                            values, contentTypes, 
+            Collections.singletonList(MediaType.valueOf(acceptContentTypes)));
+        
         assertNotNull(ori);
         assertEquals("listMethod needs to be selected", "listMethod", 
                      ori.getMethodToInvoke().getName());
         
         
         acceptContentTypes = "application/xml,application/json";
-        resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/1", values,
-                                                  new MessageImpl());
-        ori = JAXRSUtils.findTargetMethod(resource, 
-                                        null, 
-                                        "GET", values, contentTypes, 
-                                        JAXRSUtils.parseMediaTypes(acceptContentTypes), true);
+        ori = findTargetResourceClass(resources, null, 
+                                                            "/1/2/3/d/1",
+                                                            "GET",
+                                                            values, contentTypes, 
+                                                            JAXRSUtils.parseMediaTypes(acceptContentTypes));
         assertNotNull(ori);
         assertEquals("readMethod needs to be selected", "readMethod", 
                      ori.getMethodToInvoke().getName());
@@ -327,47 +386,42 @@ public class SelectMethodCandidatesTest 
         
         contentTypes = "application/xml";
         acceptContentTypes = "application/xml";
-        resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/1", values, new MessageImpl());
-        ori = JAXRSUtils.findTargetMethod(resource, 
-                                        null, 
-                                        "GET", values, contentTypes, 
-                                        Collections.singletonList(MediaType.valueOf(acceptContentTypes))
-                                        , true);
+        ori = findTargetResourceClass(resources, null, 
+                                                            "/1/2/3/d/1",
+                                                            "GET",
+                                                            values, contentTypes, 
+            Collections.singletonList(MediaType.valueOf(acceptContentTypes)));
         assertNotNull(ori);
         assertEquals("readMethod needs to be selected", "readMethod", 
                      ori.getMethodToInvoke().getName());
         
         contentTypes = "application/json";
         acceptContentTypes = "application/json";
-        resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/1/bar/baz/baz", values,
-                                                  new MessageImpl());
-        ori = JAXRSUtils.findTargetMethod(resource, 
-                                        null, 
-                                        "GET", values, contentTypes, 
-                                        Collections.singletonList(MediaType.valueOf(acceptContentTypes)),
-                                        true);
+        ori = findTargetResourceClass(resources, null, 
+                                      "/1/2/3/d/1/bar/baz/baz",
+                                      "GET",
+                                      values, contentTypes, 
+            Collections.singletonList(MediaType.valueOf(acceptContentTypes)));
         assertNotNull(ori);
         assertEquals("readMethod2 needs to be selected", "readMethod2", 
                      ori.getMethodToInvoke().getName());
         
         contentTypes = "application/json";
         acceptContentTypes = "application/json";
-        resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/1", values, new MessageImpl());
-        ori = JAXRSUtils.findTargetMethod(resource, 
-                                        null, 
-                                        "GET", values, contentTypes, 
-                                        Collections.singletonList(MediaType.valueOf(acceptContentTypes)),
-                                        true);
+        ori = findTargetResourceClass(resources, null, 
+                                      "/1/2/3/d/1",
+                                      "GET",
+                                      values, contentTypes, 
+            Collections.singletonList(MediaType.valueOf(acceptContentTypes)));
         assertNotNull(ori);
         assertEquals("unlimitedPath needs to be selected", "unlimitedPath", 
                      ori.getMethodToInvoke().getName());
         
-        resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/1/2", values, new MessageImpl());
-        ori = JAXRSUtils.findTargetMethod(resource, 
-                                        null, 
-                                        "GET", values, contentTypes, 
-                                        Collections.singletonList(MediaType.valueOf(acceptContentTypes)),
-                                        true);
+        ori = findTargetResourceClass(resources, null, 
+                                      "/1/2/3/d/1/2",
+                                      "GET",
+                                      values, contentTypes, 
+            Collections.singletonList(MediaType.valueOf(acceptContentTypes)));
         assertNotNull(ori);
         assertEquals("limitedPath needs to be selected", "limitedPath", 
                      ori.getMethodToInvoke().getName());
@@ -381,44 +435,104 @@ public class SelectMethodCandidatesTest 
         sf.create();
         List<ClassResourceInfo> resources = ((JAXRSServiceImpl)sf.getService()).getClassResourceInfos();
         
-        MetadataMap<String, String> values = new MetadataMap<String, String>();
-        ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/custom", values,
-                                                                    new MessageImpl());
-        
         String contentTypes = "*/*";
         String acceptContentTypes = "application/bar,application/foo";
-        OperationResourceInfo ori = JAXRSUtils.findTargetMethod(resource, 
-                                    null, 
-                                    "GET", values, contentTypes, 
-                                    JAXRSUtils.sortMediaTypes(acceptContentTypes), true);
+        
+        MetadataMap<String, String> values = new MetadataMap<String, String>();
+        OperationResourceInfo ori = findTargetResourceClass(resources, null, 
+                                      "/1/2/3/d/custom",
+                                      "GET",
+                                      values, contentTypes, 
+                                      JAXRSUtils.sortMediaTypes(acceptContentTypes));
+        
         assertNotNull(ori);
         assertEquals("readBar", ori.getMethodToInvoke().getName());
         acceptContentTypes = "application/foo,application/bar";
-        resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/custom", values, new MessageImpl());
-        ori = JAXRSUtils.findTargetMethod(resource, 
-                                    null, 
-                                    "GET", values, contentTypes, 
-                                    JAXRSUtils.sortMediaTypes(acceptContentTypes), true);
+        ori = findTargetResourceClass(resources, null, 
+                                      "/1/2/3/d/custom",
+                                      "GET",
+                                      values, contentTypes, 
+                                      JAXRSUtils.sortMediaTypes(acceptContentTypes));
         assertNotNull(ori);
         assertEquals("readFoo", ori.getMethodToInvoke().getName());
         
         acceptContentTypes = "application/foo;q=0.5,application/bar";
-        resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/custom", values, new MessageImpl());
-        ori = JAXRSUtils.findTargetMethod(resource, 
-                                    null, 
-                                    "GET", values, contentTypes, 
-                                    JAXRSUtils.sortMediaTypes(acceptContentTypes), true);
+        ori = findTargetResourceClass(resources, null, 
+                                      "/1/2/3/d/custom",
+                                      "GET",
+                                      values, contentTypes, 
+                                      JAXRSUtils.sortMediaTypes(acceptContentTypes));
         assertNotNull(ori);
         assertEquals("readBar", ori.getMethodToInvoke().getName());
         
         acceptContentTypes = "application/foo,application/bar;q=0.5";
-        resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/custom", values, new MessageImpl());
-        ori = JAXRSUtils.findTargetMethod(resource, 
-                                    null, 
-                                    "GET", values, contentTypes, 
-                                    JAXRSUtils.sortMediaTypes(acceptContentTypes), true);
+        ori = findTargetResourceClass(resources, null, 
+                                      "/1/2/3/d/custom",
+                                      "GET",
+                                      values, contentTypes, 
+                                      JAXRSUtils.sortMediaTypes(acceptContentTypes));
         assertNotNull(ori);
         assertEquals("readFoo", ori.getMethodToInvoke().getName());
         
     }
+    
+    private static OperationResourceInfo findTargetResourceClass(List<ClassResourceInfo> resources,
+                                                                 Message message,
+                                                                 String path, 
+                                                                 String httpMethod,
+                                                                 MultivaluedMap<String, String> values,
+                                                                 String requestContentType, 
+                                                                 List<MediaType> acceptContentTypes) {
+        message = message == null ? new MessageImpl() : message; 
+        Map<ClassResourceInfo, MultivaluedMap<String, String>> mResources 
+            = JAXRSUtils.selectResourceClass(resources, path, message);
+         
+        if (mResources != null) {
+            OperationResourceInfo ori = JAXRSUtils.findTargetMethod(mResources, null, httpMethod, 
+                                                    values, requestContentType, acceptContentTypes, true);
+            if (ori != null) {
+                return ori;
+            }
+        }
+         
+        return null;
+    }
+    @Path("{a}")
+    @Produces("text/xml")
+    @Consumes("text/xml")
+    public static class RootResource {
+        @PUT
+        @Path("books")
+        public void put() {
+            
+        }
+    }
+    
+    @Path("{b}")
+    @Produces("text/xml")
+    @Consumes("text/xml")
+    public static class RootResource2 {
+        @PUT
+        @Path("books/1")
+        public void put() {
+            
+        }
+        
+        @PUT
+        @Path("thebooks")
+        public void put2() {
+            
+        }
+    }
+    
+    @Path("b")
+    @Produces("text/xml")
+    @Consumes("text/xml")
+    public static class RootResource3 {
+        @PUT
+        @Path("books")
+        public void put() {
+            
+        }
+    }
 }

Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java?rev=1445113&r1=1445112&r2=1445113&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java Tue Feb 12 11:52:06 2013
@@ -30,6 +30,7 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 import java.util.UUID;
 
 import javax.servlet.ServletConfig;
@@ -158,19 +159,23 @@ public class JAXRSUtilsTest extends Asse
                               org.apache.cxf.jaxrs.resources.BookStore.class);
         sf.create();        
         List<ClassResourceInfo> resources = ((JAXRSServiceImpl)sf.getService()).getClassResourceInfos();
-        MultivaluedMap<String, String> map = new MetadataMap<String, String>();
-        ClassResourceInfo bStore = JAXRSUtils.selectResourceClass(resources, "/bookstore", map, null);
+        
+        ClassResourceInfo bStore = firstResource(JAXRSUtils.selectResourceClass(resources, "/bookstore", null));
         assertEquals(bStore.getResourceClass(), org.apache.cxf.jaxrs.resources.BookStore.class);
         
-        bStore = JAXRSUtils.selectResourceClass(resources, "/bookstore/", map, null);
+        bStore = firstResource(JAXRSUtils.selectResourceClass(resources, "/bookstore/", null));
         assertEquals(bStore.getResourceClass(), 
                      org.apache.cxf.jaxrs.resources.BookStore.class);
         
-        bStore = JAXRSUtils.selectResourceClass(resources, "/bookstore/bar", map, null);
+        bStore = firstResource(JAXRSUtils.selectResourceClass(resources, "/bookstore/bar", null));
         assertEquals(bStore.getResourceClass(), 
                      org.apache.cxf.jaxrs.resources.BookStoreNoSubResource.class);
     }
     
+    private static ClassResourceInfo firstResource(Map<ClassResourceInfo, MultivaluedMap<String, String>> map) {
+        return map == null ? null : map.entrySet().iterator().next().getKey();
+    }
+    
     @Test
     public void testInjectCustomContext() throws Exception {
         final CustomerContext contextImpl = new CustomerContext() {
@@ -266,19 +271,19 @@ public class JAXRSUtilsTest extends Asse
                               org.apache.cxf.jaxrs.resources.TestResourceTemplate2.class);
         sf.create();        
         List<ClassResourceInfo> resources = ((JAXRSServiceImpl)sf.getService()).getClassResourceInfos();
-        MultivaluedMap<String, String> map = new MetadataMap<String, String>();
-        ClassResourceInfo bStore = JAXRSUtils.selectResourceClass(resources, "/1", map, null);
+        
+        ClassResourceInfo bStore = firstResource(JAXRSUtils.selectResourceClass(resources, "/1", null));
         assertEquals(bStore.getResourceClass(), org.apache.cxf.jaxrs.resources.TestResourceTemplate1.class);
         
-        bStore = JAXRSUtils.selectResourceClass(resources, "/1/", map, null);
+        bStore = firstResource(JAXRSUtils.selectResourceClass(resources, "/1/", null));
         assertEquals(bStore.getResourceClass(), 
                      org.apache.cxf.jaxrs.resources.TestResourceTemplate1.class);
         
-        bStore = JAXRSUtils.selectResourceClass(resources, "/1/foo", map, null);
+        bStore = firstResource(JAXRSUtils.selectResourceClass(resources, "/1/foo", null));
         assertEquals(bStore.getResourceClass(), 
                      org.apache.cxf.jaxrs.resources.TestResourceTemplate2.class);
         
-        bStore = JAXRSUtils.selectResourceClass(resources, "/1/foo/bar", map, null);
+        bStore = firstResource(JAXRSUtils.selectResourceClass(resources, "/1/foo/bar", null));
         assertEquals(bStore.getResourceClass(), 
                      org.apache.cxf.jaxrs.resources.TestResourceTemplate2.class);
     }
@@ -290,11 +295,10 @@ public class JAXRSUtilsTest extends Asse
                               org.apache.cxf.jaxrs.resources.TestResourceTemplate3.class);
         sf.create();        
         List<ClassResourceInfo> resources = ((JAXRSServiceImpl)sf.getService()).getClassResourceInfos();
-        MultivaluedMap<String, String> map = new MetadataMap<String, String>();
-        ClassResourceInfo bStore = JAXRSUtils.selectResourceClass(resources, "/", map, null);
+        ClassResourceInfo bStore = firstResource(JAXRSUtils.selectResourceClass(resources, "/", null));
         assertEquals(bStore.getResourceClass(), org.apache.cxf.jaxrs.resources.TestResourceTemplate3.class);
         
-        bStore = JAXRSUtils.selectResourceClass(resources, "/test", map, null);
+        bStore = firstResource(JAXRSUtils.selectResourceClass(resources, "/test", null));
         assertEquals(bStore.getResourceClass(), 
                      org.apache.cxf.jaxrs.resources.TestResourceTemplate4.class);
         
@@ -1410,6 +1414,11 @@ public class JAXRSUtilsTest extends Asse
         assertEquals("3", list.get(1));
     }
     
+    private Map<ClassResourceInfo, MultivaluedMap<String, String>> getMap(ClassResourceInfo cri) {
+        
+        return Collections.singletonMap(cri, (MultivaluedMap<String, String>)new MetadataMap<String, String>());
+    }
+    
     @Test
     public void testSelectResourceMethod() throws Exception {
         ClassResourceInfo cri = new ClassResourceInfo(Customer.class);
@@ -1428,22 +1437,22 @@ public class JAXRSUtilsTest extends Asse
         md.bind(ori2, Customer.class.getMethod("getItPlain", new Class[]{}));
         cri.setMethodDispatcher(md);
         
-        OperationResourceInfo ori = JAXRSUtils.findTargetMethod(cri, null, "GET", 
+        OperationResourceInfo ori = JAXRSUtils.findTargetMethod(getMap(cri), null, "GET", 
               new MetadataMap<String, String>(), "*/*", getTypes("text/plain"), true);
         
         assertSame(ori, ori2);
         
-        ori = JAXRSUtils.findTargetMethod(cri, null, "GET", new MetadataMap<String, String>(), 
+        ori = JAXRSUtils.findTargetMethod(getMap(cri), null, "GET", new MetadataMap<String, String>(), 
                                               "*/*", getTypes("text/xml"), true);
                          
         assertSame(ori, ori1);
         
-        ori = JAXRSUtils.findTargetMethod(cri, null, "GET", new MetadataMap<String, String>(), 
+        ori = JAXRSUtils.findTargetMethod(getMap(cri), null, "GET", new MetadataMap<String, String>(), 
                                           "*/*", 
                                           JAXRSUtils.sortMediaTypes(getTypes("*,text/plain,text/xml")), true);
                      
         assertSame(ori, ori2);
-        ori = JAXRSUtils.findTargetMethod(cri, null, "GET", new MetadataMap<String, String>(), 
+        ori = JAXRSUtils.findTargetMethod(getMap(cri), null, "GET", new MetadataMap<String, String>(), 
                                           "*/*", 
                                           JAXRSUtils.sortMediaTypes(getTypes("*,text/plain, text/xml,x/y")),
                                           true);
@@ -1818,11 +1827,11 @@ public class JAXRSUtilsTest extends Asse
                                                                 String requestContentType, 
                                                                 List<MediaType> acceptContentTypes) {
         
-        ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, path, values,
-                                                                    new MessageImpl());
+        Map<ClassResourceInfo, MultivaluedMap<String, String>> mResources 
+            = JAXRSUtils.selectResourceClass(resources, path, new MessageImpl());
         
-        if (resource != null) {
-            OperationResourceInfo ori = JAXRSUtils.findTargetMethod(resource, null, httpMethod, 
+        if (mResources != null) {
+            OperationResourceInfo ori = JAXRSUtils.findTargetMethod(mResources, null, httpMethod, 
                                                    values, requestContentType, acceptContentTypes, true);
             if (ori != null) {
                 return ori;

Modified: cxf/trunk/rt/rs/security/cors/src/main/java/org/apache/cxf/rs/security/cors/CrossOriginResourceSharingFilter.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/cors/src/main/java/org/apache/cxf/rs/security/cors/CrossOriginResourceSharingFilter.java?rev=1445113&r1=1445112&r2=1445113&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/cors/src/main/java/org/apache/cxf/rs/security/cors/CrossOriginResourceSharingFilter.java (original)
+++ cxf/trunk/rt/rs/security/cors/src/main/java/org/apache/cxf/rs/security/cors/CrossOriginResourceSharingFilter.java Tue Feb 12 11:52:06 2013
@@ -25,6 +25,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.regex.Pattern;
 
 import javax.ws.rs.core.Context;
@@ -35,7 +36,6 @@ import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.ResponseBuilder;
 
 import org.apache.cxf.common.util.ReflectionUtil;
-import org.apache.cxf.jaxrs.JAXRSServiceImpl;
 import org.apache.cxf.jaxrs.ext.RequestHandler;
 import org.apache.cxf.jaxrs.ext.ResponseHandler;
 import org.apache.cxf.jaxrs.impl.MetadataMap;
@@ -45,7 +45,6 @@ import org.apache.cxf.jaxrs.model.URITem
 import org.apache.cxf.jaxrs.utils.HttpUtils;
 import org.apache.cxf.jaxrs.utils.JAXRSUtils;
 import org.apache.cxf.message.Message;
-import org.apache.cxf.service.Service;
 
 /**
  * A single class that provides both an input and an output filter for CORS, following
@@ -263,29 +262,27 @@ public class CrossOriginResourceSharingF
     private Method getPreflightMethod(Message m, String httpMethod) {
         String requestUri = HttpUtils.getPathToMatch(m, true);
         
-        Service service = m.getExchange().get(Service.class);
-        List<ClassResourceInfo> resources = ((JAXRSServiceImpl)service).getClassResourceInfos();
-        MultivaluedMap<String, String> values = new MetadataMap<String, String>();
-        ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, 
-                                                                    requestUri, 
-                                                                    values,
-                                                                    m);
-        if (resource == null) {
+        List<ClassResourceInfo> resources = JAXRSUtils.getRootResources(m);
+        Map<ClassResourceInfo, MultivaluedMap<String, String>> matchedResources = 
+            JAXRSUtils.selectResourceClass(resources, requestUri, m);
+        if (matchedResources == null) {
             return null;
         }
-        OperationResourceInfo ori = findPreflightMethod(resource, requestUri, httpMethod, values, m);
+        MultivaluedMap<String, String> values = new MetadataMap<String, String>();
+        OperationResourceInfo ori = findPreflightMethod(matchedResources, requestUri, httpMethod, values, m);
         return ori == null ? null : ori.getAnnotatedMethod();
     }
     
     
-    private OperationResourceInfo findPreflightMethod(ClassResourceInfo resource, 
+    private OperationResourceInfo findPreflightMethod(
+        Map<ClassResourceInfo, MultivaluedMap<String, String>> matchedResources, 
                                                       String requestUri,
                                                       String httpMethod,
                                                       MultivaluedMap<String, String> values, 
                                                       Message m) {
         final String contentType = MediaType.WILDCARD;
         final MediaType acceptType = MediaType.WILDCARD_TYPE;
-        OperationResourceInfo ori = JAXRSUtils.findTargetMethod(resource, 
+        OperationResourceInfo ori = JAXRSUtils.findTargetMethod(matchedResources, 
                                     m, httpMethod, values, 
                                     contentType, 
                                     Collections.singletonList(acceptType), 
@@ -295,13 +292,13 @@ public class CrossOriginResourceSharingF
         }
         if (ori.isSubResourceLocator()) {
             Class<?> cls = ori.getMethodToInvoke().getReturnType();
-            ClassResourceInfo subcri = resource.getSubResource(cls, cls);
+            ClassResourceInfo subcri = ori.getClassResourceInfo().getSubResource(cls, cls);
             if (subcri == null) {
                 return null;
             } else {
                 MultivaluedMap<String, String> newValues = new MetadataMap<String, String>();
                 newValues.putAll(values);
-                return findPreflightMethod(subcri, 
+                return findPreflightMethod(Collections.singletonMap(subcri, newValues), 
                                            values.getFirst(URITemplate.FINAL_MATCH_GROUP),
                                            httpMethod, 
                                            newValues, 



Mime
View raw message