Return-Path: Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: (qmail 60674 invoked from network); 5 Nov 2009 18:23:25 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 5 Nov 2009 18:23:25 -0000 Received: (qmail 93150 invoked by uid 500); 5 Nov 2009 18:23:24 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 93064 invoked by uid 500); 5 Nov 2009 18:23:24 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 93055 invoked by uid 99); 5 Nov 2009 18:23:24 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 05 Nov 2009 18:23:24 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 05 Nov 2009 18:23:18 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id EDF2423888BD; Thu, 5 Nov 2009 18:22:54 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r833112 [1/2] - in /cxf/trunk: rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/ rt/frontend/jaxrs/src/main/java/org/... Date: Thu, 05 Nov 2009 18:22:53 -0000 To: commits@cxf.apache.org From: sergeyb@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20091105182254.EDF2423888BD@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: sergeyb Date: Thu Nov 5 18:22:51 2009 New Revision: 833112 URL: http://svn.apache.org/viewvc?rev=833112&view=rev Log: JAXRS : support for redirects (JSP, etc) plus a lot of other changes/fixes accumulated during the last few weeks, more to follow in a few days Added: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/ResourceComparator.java (with props) cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/RequestDispatcherProvider.java (with props) cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookServerRequestDispatch.java (with props) cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreDispatch.java (with props) cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/CustomOutFaultInterceptor.java (with props) cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/FaultyRequestHandler.java (with props) cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSRequestDispatcherTest.java (with props) cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_dispatch/ cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_dispatch/WEB-INF/ cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_dispatch/WEB-INF/beans.xml (with props) cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_dispatch/WEB-INF/web.xml (with props) cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_dispatch/book.html (with props) cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_dispatch/bookRequestScope.jsp cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_dispatch/bookSessionScope.jsp 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/JAXRSServerFactoryBean.java cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpHeadersImpl.java cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpServletResponseFilter.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/interceptor/JAXRSOutInterceptor.java cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/Messages.properties 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/model/OperationResourceInfoComparator.java cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONUtils.java cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/Messages.properties cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/Messages.properties cxf/trunk/rt/frontend/jaxrs/src/main/resources/schemas/jaxrs.xsd 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/ext/MessageContextImplTest.java cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JSONProviderTest.java cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/AbstractHTTPDestination.java cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/AbstractHTTPServlet.java cxf/trunk/systests/jaxrs/pom.xml cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookServer.java cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.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=833112&r1=833111&r2=833112&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 Thu Nov 5 18:22:51 2009 @@ -153,7 +153,7 @@ try { Message msg = exchange.getInMessage(); MultivaluedMap values = getTemplateValues(msg); - String subResourcePath = (String)msg.get(JAXRSUtils.RELATIVE_PATH); + String subResourcePath = values.getFirst(URITemplate.FINAL_MATCH_GROUP); String httpMethod = (String)msg.get(Message.HTTP_REQUEST_METHOD); String contentType = (String)msg.get(Message.CONTENT_TYPE); if (contentType == null) { @@ -177,15 +177,15 @@ } OperationResourceInfo subOri = JAXRSUtils.findTargetMethod(subCri, - subResourcePath, + exchange.getInMessage(), httpMethod, values, contentType, - acceptContentType); + acceptContentType, + true); exchange.put(OperationResourceInfo.class, subOri); - msg.put(JAXRSUtils.RELATIVE_PATH, values.getFirst(URITemplate.FINAL_MATCH_GROUP)); msg.put(URITemplate.TEMPLATE_PARAMETERS, values); // work out request parameters for the sub-resouce class. Here we // presume Inputstream has not been consumed yet by the root resource class. Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java?rev=833112&r1=833111&r2=833112&view=diff ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java (original) +++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java Thu Nov 5 18:22:51 2009 @@ -32,6 +32,7 @@ import org.apache.cxf.endpoint.ServerImpl; import org.apache.cxf.feature.AbstractFeature; import org.apache.cxf.helpers.CastUtils; +import org.apache.cxf.jaxrs.ext.ResourceComparator; import org.apache.cxf.jaxrs.impl.RequestPreprocessor; import org.apache.cxf.jaxrs.lifecycle.PerRequestResourceProvider; import org.apache.cxf.jaxrs.lifecycle.ResourceProvider; @@ -61,6 +62,7 @@ private boolean start = true; private Map languageMappings; private Map extensionMappings; + private ResourceComparator rc; public JAXRSServerFactoryBean() { this(new JAXRSServiceFactoryBean()); @@ -70,6 +72,10 @@ super(sf); } + public void setResourceComparator(ResourceComparator rcomp) { + rc = rcomp; + } + public void setStaticSubresourceResolution(boolean enableStatic) { serviceFactory.setEnableStaticResolution(enableStatic); } @@ -99,7 +105,9 @@ factory.setRequestPreprocessor( new RequestPreprocessor(languageMappings, extensionMappings)); - + if (rc != null) { + ep.put("org.apache.cxf.jaxrs.comparator", rc); + } if (start) { server.start(); Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java?rev=833112&r1=833111&r2=833112&view=diff ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java (original) +++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java Thu Nov 5 18:22:51 2009 @@ -360,7 +360,7 @@ } } else { - reportNoMessageHandler("NO_MSG_WRITER", cls); + reportNoMessageHandler("NO_MSG_WRITER", cls, contentType); } } @@ -405,7 +405,7 @@ } else if (cls == Response.class) { return r; } else { - reportNoMessageHandler("NO_MSG_READER", cls); + reportNoMessageHandler("NO_MSG_READER", cls, contentType); } return null; } @@ -439,11 +439,12 @@ } } - protected static void reportNoMessageHandler(String name, Class cls) { + protected static void reportNoMessageHandler(String name, Class cls, MediaType ct) { org.apache.cxf.common.i18n.Message errorMsg = new org.apache.cxf.common.i18n.Message(name, BUNDLE, - cls); + cls, + ct.toString()); LOG.severe(errorMsg.toString()); throw new WebApplicationException(415); } Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java?rev=833112&r1=833111&r2=833112&view=diff ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java (original) +++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java Thu Nov 5 18:22:51 2009 @@ -109,19 +109,19 @@ } public HttpServletRequest getHttpServletRequest() { - return JAXRSUtils.createServletResourceValue(m, HttpServletRequest.class); + return getContext(HttpServletRequest.class); } public HttpServletResponse getHttpServletResponse() { - return JAXRSUtils.createServletResourceValue(m, HttpServletResponse.class); + return getContext(HttpServletResponse.class); } public ServletConfig getServletConfig() { - return JAXRSUtils.createServletResourceValue(m, ServletConfig.class); + return getContext(ServletConfig.class); } public ServletContext getServletContext() { - return JAXRSUtils.createServletResourceValue(m, ServletContext.class); + return getContext(ServletContext.class); } public void put(Object key, Object value) { Added: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/ResourceComparator.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/ResourceComparator.java?rev=833112&view=auto ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/ResourceComparator.java (added) +++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/ResourceComparator.java Thu Nov 5 18:22:51 2009 @@ -0,0 +1,53 @@ +/** + * 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.ext; + +import org.apache.cxf.jaxrs.model.ClassResourceInfo; +import org.apache.cxf.jaxrs.model.OperationResourceInfo; +import org.apache.cxf.message.Message; + +/** + * Can be used to affect the way the JAXRS selection algorithm chooses + * between multiple matching resource classes and methods + * + */ +public interface ResourceComparator { + + /** + * Compares two resource classes + * @param cri1 First resource class + * @param cri2 Second resource class + * @param message incoming message + * @return -1 if cri1 < cri2, 1 if if cri1 > cri2, 0 otherwise + */ + int compare(ClassResourceInfo cri1, + ClassResourceInfo cri2, + Message message); + + /** + * Compares two resource methods + * @param oper1 First resource method + * @param oper2 Second resource method + * @param message incoming message + * @return -1 if oper1 < oper2, 1 if if oper1 > oper2, 0 otherwise + */ + int compare(OperationResourceInfo oper1, + OperationResourceInfo oper2, + Message message); +} Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/ResourceComparator.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/ResourceComparator.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpHeadersImpl.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpHeadersImpl.java?rev=833112&r1=833111&r2=833112&view=diff ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpHeadersImpl.java (original) +++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpHeadersImpl.java Thu Nov 5 18:22:51 2009 @@ -44,7 +44,7 @@ public class HttpHeadersImpl implements HttpHeaders { - // TODO : it can optimized, "Mastering Regular Expressions" has the asnwers + // TODO : it can be optimized, "Mastering Regular Expressions" has the answers private static final String COMPLEX_HEADER_EXPRESSION = "((\"(([^\"])|(?<=\\\\)\")*\")|([^\",]*))(;[\\w]+)?"; private static final Pattern COMPLEX_HEADER_PATTERN = Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpServletResponseFilter.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpServletResponseFilter.java?rev=833112&r1=833111&r2=833112&view=diff ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpServletResponseFilter.java (original) +++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpServletResponseFilter.java Thu Nov 5 18:22:51 2009 @@ -35,6 +35,12 @@ } @Override + public void setStatus(int sc) { + super.setStatus(sc); + m.getExchange().put(Message.RESPONSE_CODE, sc); + } + + @Override public ServletOutputStream getOutputStream() throws IOException { return new ServletOutputStreamFilter(super.getOutputStream(), m); } 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=833112&r1=833111&r2=833112&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 Thu Nov 5 18:22:51 2009 @@ -112,7 +112,8 @@ MultivaluedMap values = new MetadataMap(); ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, rawPath, - values); + values, + message); if (resource == null) { org.apache.cxf.common.i18n.Message errorMsg = new org.apache.cxf.common.i18n.Message("NO_ROOT_EXC", @@ -140,11 +141,12 @@ values = new MetadataMap(); resource = JAXRSUtils.selectResourceClass(resources, rawPath, - values); + values, + message); } try { ori = JAXRSUtils.findTargetMethod(resource, - values.getFirst(URITemplate.FINAL_MATCH_GROUP), httpMethod, values, + message, httpMethod, values, requestContentType, acceptContentTypes, false); setMessageProperties(message, ori, values); } catch (WebApplicationException ex) { @@ -170,11 +172,12 @@ values = new MetadataMap(); resource = JAXRSUtils.selectResourceClass(resources, rawPath, - values); + values, + message); } try { - ori = JAXRSUtils.findTargetMethod(resource, values.getFirst(URITemplate.FINAL_MATCH_GROUP), - httpMethod, values, requestContentType, acceptContentTypes); + ori = JAXRSUtils.findTargetMethod(resource, message, + httpMethod, values, requestContentType, acceptContentTypes, true); setMessageProperties(message, ori, values); } catch (WebApplicationException ex) { if (ex.getResponse() != null && ex.getResponse().getStatus() == 405 @@ -205,7 +208,6 @@ private void setMessageProperties(Message message, OperationResourceInfo ori, MultivaluedMap values) { message.getExchange().put(OperationResourceInfo.class, ori); - message.put(JAXRSUtils.RELATIVE_PATH, values.getFirst(URITemplate.FINAL_MATCH_GROUP)); message.put(URITemplate.TEMPLATE_PARAMETERS, values); } } Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java?rev=833112&r1=833111&r2=833112&view=diff ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java (original) +++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java Thu Nov 5 18:22:51 2009 @@ -99,7 +99,7 @@ private void processResponse(Message message) { - if (isResponseAlreadyCommited(message)) { + if (isResponseAlreadyHandled(message)) { return; } @@ -137,7 +137,9 @@ serializeMessage(message, response, ori, true); } else { - message.put(Message.RESPONSE_CODE, 204); + Object customStatus = message.getExchange().get(Message.RESPONSE_CODE); + int status = customStatus == null ? 204 : (Integer)customStatus; + message.put(Message.RESPONSE_CODE, status); } } @@ -213,6 +215,7 @@ OutputStream outOriginal = message.getContent(OutputStream.class); if (writer == null) { + message.put(Message.CONTENT_TYPE, "text/plain"); message.put(Message.RESPONSE_CODE, 500); writeResponseErrorMessage(outOriginal, "NO_MSG_WRITER", targetType.getSimpleName()); return; @@ -231,6 +234,11 @@ responseType, responseHeaders, message.getContent(OutputStream.class)); + + if (isResponseRedirected(message)) { + return; + } + Object newContentType = responseHeaders.getFirst(HttpHeaders.CONTENT_TYPE); if (newContentType != null) { message.put(Message.CONTENT_TYPE, newContentType.toString()); @@ -401,15 +409,25 @@ headers.putSingle(HttpHeaders.DATE, format.format(new Date())); } + private boolean isResponseAlreadyHandled(Message m) { + return isResponseAlreadyCommited(m) || isResponseRedirected(m); + } + private boolean isResponseAlreadyCommited(Message m) { return Boolean.TRUE.equals(m.getExchange().get(AbstractHTTPDestination.RESPONSE_COMMITED)); } + + private boolean isResponseRedirected(Message outMessage) { + return Boolean.TRUE.equals(outMessage.get(AbstractHTTPDestination.REQUEST_REDIRECTED)); + } private void writeResponseToStream(OutputStream os, Object responseObj) { try { byte[] bytes = responseObj.toString().getBytes("UTF-8"); os.write(bytes, 0, bytes.length); } catch (Exception ex) { + LOG.severe("Problem with writing the data to the output stream"); + ex.printStackTrace(); throw new RuntimeException(ex); } } Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/Messages.properties URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/Messages.properties?rev=833112&r1=833111&r2=833112&view=diff ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/Messages.properties (original) +++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/Messages.properties Thu Nov 5 18:22:51 2009 @@ -18,7 +18,7 @@ # under the License. # # -SERIALIZE_ERROR =.Error serializing the response, please check the server logs, response class : {0}. -NO_MSG_WRITER =.No message body writer found for response class : {0}. -NO_ROOT_EXC =.No root resource matching request path {0} is found. +SERIALIZE_ERROR = Error serializing the response, please check the server logs, response class : {0}. +NO_MSG_WRITER = No message body writer has been found for response class {0}. +NO_ROOT_EXC = No root resource matching request path {0} has been found. HEAD_WITHOUT_ENTITY = Entity body returned by GET-supporting resource method will be dropped as HEAD was the actual http request method \ No newline at end of file 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=833112&r1=833111&r2=833112&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 Thu Nov 5 18:22:51 2009 @@ -21,10 +21,34 @@ import java.util.Comparator; +import org.apache.cxf.endpoint.Endpoint; +import org.apache.cxf.jaxrs.ext.ResourceComparator; +import org.apache.cxf.message.Message; + public class ClassResourceInfoComparator implements Comparator { + + private Message message; + private ResourceComparator rc; + public ClassResourceInfoComparator(Message m) { + this.message = m; + if (message != null) { + Object o = m.getExchange().get(Endpoint.class).get("org.apache.cxf.jaxrs.comparator"); + if (o != null) { + rc = (ResourceComparator)o; + } + } + } + public int compare(ClassResourceInfo cr1, ClassResourceInfo cr2) { + if (rc != null) { + int result = rc.compare(cr1, cr2, message); + if (result != 0) { + return result; + } + } + return URITemplate.compareTemplates( cr1.getURITemplate(), cr2.getURITemplate()); Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/OperationResourceInfoComparator.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/OperationResourceInfoComparator.java?rev=833112&r1=833111&r2=833112&view=diff ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/OperationResourceInfoComparator.java (original) +++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/OperationResourceInfoComparator.java Thu Nov 5 18:22:51 2009 @@ -21,12 +21,35 @@ import java.util.Comparator; +import org.apache.cxf.endpoint.Endpoint; +import org.apache.cxf.jaxrs.ext.ResourceComparator; import org.apache.cxf.jaxrs.utils.JAXRSUtils; +import org.apache.cxf.message.Message; public class OperationResourceInfoComparator implements Comparator { + private Message message; + private ResourceComparator rc; + + public OperationResourceInfoComparator(Message m) { + this.message = m; + if (message != null) { + Object o = m.getExchange().get(Endpoint.class).get("org.apache.cxf.jaxrs.comparator"); + if (o != null) { + rc = (ResourceComparator)o; + } + } + } + public int compare(OperationResourceInfo e1, OperationResourceInfo e2) { + if (rc != null) { + int result = rc.compare(e1, e2, message); + if (result != 0) { + return result; + } + } + if (e1.getHttpMethod() != null && e2.getHttpMethod() == null || e1.getHttpMethod() == null && e2.getHttpMethod() != null) { // subresource method takes precedence over a subresource locator Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java?rev=833112&r1=833111&r2=833112&view=diff ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java (original) +++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java Thu Nov 5 18:22:51 2009 @@ -93,11 +93,16 @@ private Map collectionWrapperMap; private List jaxbElementClassNames; private Map cProperties; + private Map uProperties; public void setContextProperties(Map contextProperties) { cProperties = contextProperties; } + public void setUnmarshallerProperties(Map unmarshalProperties) { + uProperties = unmarshalProperties; + } + public void setUnmarshallAsJaxbElement(boolean value) { unmarshalAsJaxbElement = value; } @@ -113,7 +118,18 @@ public void setJaxbElementClassMap(Map map) { jaxbElementClassMap = map; } - + + protected void checkContentLength() { + if (mc != null) { + List values = mc.getHttpHeaders().getRequestHeader(HttpHeaders.CONTENT_LENGTH); + if (values.size() == 1 && "0".equals(values.get(0))) { + String message = new org.apache.cxf.common.i18n.Message("EMPTY_BODY", BUNDLE).toString(); + LOG.warning(message); + throw new WebApplicationException(400); + } + } + } + @SuppressWarnings("unchecked") protected Object convertToJaxbElementIfNeeded(Object obj, Class cls, Type genericType) throws Exception { @@ -393,6 +409,11 @@ if (schema != null) { unmarshaller.setSchema(schema); } + if (uProperties != null) { + for (Map.Entry entry : uProperties.entrySet()) { + unmarshaller.setProperty(entry.getKey(), entry.getValue()); + } + } return unmarshaller; } Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java?rev=833112&r1=833111&r2=833112&view=diff ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java (original) +++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java Thu Nov 5 18:22:51 2009 @@ -27,7 +27,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -69,7 +68,7 @@ Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, Marshaller.JAXB_SCHEMA_LOCATION}); - private Map mProperties = new HashMap(); + private Map mProperties = Collections.emptyMap(); private boolean enableStreaming; private ValidationEventHandler eventHandler; @@ -135,6 +134,9 @@ MultivaluedMap headers, InputStream is) throws IOException { try { + + checkContentLength(); + boolean isCollection = InjectionUtils.isSupportedCollectionOrArray(type); Class theType = isCollection ? InjectionUtils.getActualType(genericType) : type; theType = getActualType(theType, genericType, anns); Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java?rev=833112&r1=833111&r2=833112&view=diff ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java (original) +++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java Thu Nov 5 18:22:51 2009 @@ -59,6 +59,9 @@ @Provider public class JSONProvider extends AbstractJAXBProvider { + private static final String MAPPED_CONVENTION = "mapped"; + private static final String BADGER_FISH_CONVENTION = "badgerfish"; + private ConcurrentHashMap namespaceMap = new ConcurrentHashMap(); private boolean serializeAsArray; @@ -72,6 +75,14 @@ private boolean writeXsiType = true; private boolean readXsiType = true; private boolean ignoreNamespaces; + private String convention = MAPPED_CONVENTION; + + public void setConvention(String value) { + if (!MAPPED_CONVENTION.equals(value) && !BADGER_FISH_CONVENTION.equals(value)) { + throw new IllegalArgumentException("Unsupported convention \"" + value); + } + convention = value; + } public void setIgnoreNamespaces(boolean ignoreNamespaces) { this.ignoreNamespaces = ignoreNamespaces; @@ -178,7 +189,11 @@ protected XMLStreamReader createReader(Class type, InputStream is) throws Exception { - return JSONUtils.createStreamReader(is, readXsiType, namespaceMap); + if (BADGER_FISH_CONVENTION.equals(convention)) { + return JSONUtils.createBadgerFishReader(is); + } else { + return JSONUtils.createStreamReader(is, readXsiType, namespaceMap); + } } protected InputStream getInputStream(Class cls, Type type, InputStream is) throws Exception { @@ -282,6 +297,9 @@ startTag = "{\"" + qname.getLocalPart() + "\":["; } endTag = "]}"; + } else if (serializeAsArray) { + startTag = "["; + endTag = "]"; } else { startTag = "{"; endTag = "}"; @@ -314,6 +332,11 @@ protected XMLStreamWriter createWriter(Object actualObject, Class actualClass, Type genericType, String enc, OutputStream os, boolean isCollection) throws Exception { + + if (BADGER_FISH_CONVENTION.equals(convention)) { + return JSONUtils.createBadgerFishWriter(os); + } + QName qname = getQName(actualClass, genericType, actualObject, true); XMLStreamWriter writer = JSONUtils.createStreamWriter(os, qname, writeXsiType && !ignoreNamespaces, namespaceMap, serializeAsArray, arrayKeys, Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONUtils.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONUtils.java?rev=833112&r1=833111&r2=833112&view=diff ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONUtils.java (original) +++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONUtils.java Thu Nov 5 18:22:51 2009 @@ -31,6 +31,8 @@ import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.QName; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; @@ -40,6 +42,8 @@ import org.apache.cxf.staxutils.DelegatingXMLStreamWriter; import org.apache.cxf.staxutils.DepthXMLStreamReader; import org.codehaus.jettison.AbstractXMLStreamWriter; +import org.codehaus.jettison.badgerfish.BadgerFishXMLInputFactory; +import org.codehaus.jettison.badgerfish.BadgerFishXMLOutputFactory; import org.codehaus.jettison.mapped.Configuration; import org.codehaus.jettison.mapped.MappedNamespaceConvention; import org.codehaus.jettison.mapped.MappedXMLInputFactory; @@ -54,6 +58,16 @@ private JSONUtils() { } + public static XMLStreamWriter createBadgerFishWriter(OutputStream os) throws XMLStreamException { + XMLOutputFactory factory = new BadgerFishXMLOutputFactory(); + return factory.createXMLStreamWriter(os); + } + + public static XMLStreamReader createBadgerFishReader(InputStream is) throws XMLStreamException { + XMLInputFactory factory = new BadgerFishXMLInputFactory(); + return factory.createXMLStreamReader(is); + } + public static XMLStreamWriter createStreamWriter(OutputStream os, QName qname, boolean writeXsiType, Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/Messages.properties URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/Messages.properties?rev=833112&r1=833111&r2=833112&view=diff ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/Messages.properties (original) +++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/Messages.properties Thu Nov 5 18:22:51 2009 @@ -22,4 +22,5 @@ UNSUPPORTED_ENCODING=Unsupported encoding : {0}, defaulting to UTF-8 NO_COLLECTION_ROOT=No collection name is provided NO_MSG_WRITER =.No message body writer found for class : {0}. +EMPTY_BODY=Message body is empty Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java?rev=833112&r1=833111&r2=833112&view=diff ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java (original) +++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java Thu Nov 5 18:22:51 2009 @@ -39,6 +39,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; +import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.ext.MessageBodyReader; @@ -62,7 +63,7 @@ @Provider @Consumes({"multipart/related", "multipart/mixed", "multipart/alternative" }) @Produces({"multipart/related", "multipart/mixed", "multipart/alternative" }) -public class MultipartProvider +public class MultipartProvider extends AbstractConfigurableProvider implements MessageBodyReader, MessageBodyWriter { private static final Logger LOG = LogUtils.getL7dLogger(MultipartProvider.class); @@ -100,10 +101,21 @@ return false; } + protected void checkContentLength() { + if (mc != null) { + List values = mc.getHttpHeaders().getRequestHeader(HttpHeaders.CONTENT_LENGTH); + if (values.size() == 1 && "0".equals(values.get(0))) { + String message = new org.apache.cxf.common.i18n.Message("EMPTY_BODY", BUNDLE).toString(); + LOG.warning(message); + throw new WebApplicationException(400); + } + } + } + public Object readFrom(Class c, Type t, Annotation[] anns, MediaType mt, MultivaluedMap headers, InputStream is) throws IOException, WebApplicationException { - + checkContentLength(); List infos = AttachmentUtils.getAttachments(mc, attachmentDir, attachmentThreshold); Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java?rev=833112&r1=833111&r2=833112&view=diff ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java (original) +++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java Thu Nov 5 18:22:51 2009 @@ -38,6 +38,7 @@ import javax.ws.rs.ext.MessageBodyWriter; import org.apache.cxf.Bus; +import org.apache.cxf.common.classloader.ClassLoaderUtils; import org.apache.cxf.common.logging.LogUtils; import org.apache.cxf.common.util.ClassHelper; import org.apache.cxf.endpoint.Endpoint; @@ -58,22 +59,8 @@ private static final ProviderFactory SHARED_FACTORY = new ProviderFactory(); static { - // TODO : do dynamic instantiation of JSON and few other default providers - JSONProvider jsonProvider = null; - try { - jsonProvider = new JSONProvider(); - } catch (Throwable ex) { - String message = "Problem with instantiating the default JSON provider, "; - if (ex.getMessage() != null) { - message += ex.getMessage(); - } else { - message += "exception class : " + ex.getClass().getName(); - } - LOG.info(message); - } - - SHARED_FACTORY.setProviders(new JAXBElementProvider(), - jsonProvider, + SHARED_FACTORY.setProviders(createProvider("org.apache.cxf.jaxrs.provider.JAXBElementProvider"), + createProvider("org.apache.cxf.jaxrs.provider.JSONProvider"), new BinaryDataProvider(), new SourceProvider(), new FormEncodingProvider(), @@ -104,6 +91,21 @@ private ProviderFactory() { } + private static Object createProvider(String className) { + try { + return ClassLoaderUtils.loadClass(className, ProviderFactory.class).newInstance(); + } catch (Throwable ex) { + String message = "Problem with instantiating the default provider " + className; + if (ex.getMessage() != null) { + message += ex.getMessage(); + } else { + message += ", exception class : " + ex.getClass().getName(); + } + LOG.info(message); + } + return null; + } + public static ProviderFactory getInstance() { return new ProviderFactory(); } Added: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/RequestDispatcherProvider.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/RequestDispatcherProvider.java?rev=833112&view=auto ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/RequestDispatcherProvider.java (added) +++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/RequestDispatcherProvider.java Thu Nov 5 18:22:51 2009 @@ -0,0 +1,253 @@ +/** + * 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.IOException; +import java.io.OutputStream; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.ResourceBundle; +import java.util.logging.Logger; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.PathSegment; +import javax.ws.rs.core.UriInfo; +import javax.ws.rs.ext.MessageBodyWriter; + +import org.apache.cxf.common.i18n.BundleUtils; +import org.apache.cxf.common.logging.LogUtils; +import org.apache.cxf.jaxrs.ext.MessageContext; +import org.apache.cxf.transport.http.AbstractHTTPDestination; + +@Produces("text/html") +public class RequestDispatcherProvider extends AbstractConfigurableProvider + implements MessageBodyWriter { + + private static final ResourceBundle BUNDLE = BundleUtils.getBundle(RequestDispatcherProvider.class); + private static final Logger LOG = LogUtils.getL7dLogger(RequestDispatcherProvider.class); + + private static final String ABSOLUTE_PATH_PARAMETER = "absolute.path"; + private static final String BASE_PATH_PARAMETER = "base.path"; + private static final String RELATIVE_PATH_PARAMETER = "relative.path"; + + private static final String REQUEST_SCOPE = "request"; + private static final String SESSION_SCOPE = "session"; + + private String servletContextPath; + private String resourcePath; + private Map classResources = Collections.emptyMap(); + + private String scope = REQUEST_SCOPE; + private Map beanNames = Collections.emptyMap(); + private String dispatcherName; + private String servletPath; + + @Context + private MessageContext mc; + + public long getSize(Object t, Class type, Type genericType, Annotation[] annotations, MediaType mt) { + return -1; + } + + public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, MediaType mt) { + return resourcePath != null || classResources.containsKey(type.getName()); + } + + public void writeTo(Object o, Class clazz, Type genericType, Annotation[] annotations, + MediaType type, MultivaluedMap headers, OutputStream os) + throws IOException { + + ServletContext sc = getServletContext(); + String path = resourcePath != null ? resourcePath : classResources.get(clazz.getName()); + RequestDispatcher rd = getRequestDispatcher(sc, clazz, path); + + try { + mc.put(AbstractHTTPDestination.REQUEST_REDIRECTED, Boolean.TRUE); + + String theServletPath = servletPath == null ? "/" : servletPath; + HttpServletRequestFilter servletRequest = + new HttpServletRequestFilter(mc.getHttpServletRequest(), path, theServletPath); + if (REQUEST_SCOPE.equals(scope)) { + servletRequest.setAttribute(getBeanName(o), o); + } else if (SESSION_SCOPE.equals(scope)) { + servletRequest.getSession(true).setAttribute(getBeanName(o), o); + } + setRequestParameters(servletRequest); + rd.forward(servletRequest, mc.getHttpServletResponse()); + } catch (Throwable ex) { + mc.put(AbstractHTTPDestination.REQUEST_REDIRECTED, Boolean.FALSE); + ex.printStackTrace(); + throw new WebApplicationException(ex); + } + } + + protected ServletContext getServletContext() { + ServletContext sc = mc.getServletContext(); + if (servletContextPath != null) { + sc = sc.getContext(servletContextPath); + if (sc == null) { + String message = + new org.apache.cxf.common.i18n.Message("RESOURCE_DISPATCH_NOT_FOUND", + BUNDLE, servletContextPath).toString(); + LOG.severe(message); + throw new WebApplicationException(); + } + } + return sc; + } + + protected RequestDispatcher getRequestDispatcher(ServletContext sc, Class clazz, String path) { + + RequestDispatcher rd = dispatcherName != null ? sc.getNamedDispatcher(dispatcherName) + : sc.getRequestDispatcher(path); + if (rd == null) { + String message = + new org.apache.cxf.common.i18n.Message("RESOURCE_PATH_NOT_FOUND", + BUNDLE, path).toString(); + LOG.severe(message); + throw new WebApplicationException(); + } + return rd; + } + + public void setResourcePath(String resourcePath) { + this.resourcePath = resourcePath; + } + + public void setServletContextPath(String servletContextPath) { + this.servletContextPath = servletContextPath; + } + + public void setScope(String scope) { + this.scope = scope; + } + + public void setBeanNames(Map beanNames) { + this.beanNames = beanNames; + } + + protected String getBeanName(Object bean) { + String name = beanNames.get(bean.getClass().getName()); + return name != null ? name : bean.getClass().getSimpleName().toLowerCase(); + } + + protected void setRequestParameters(HttpServletRequestFilter request) { + if (mc != null) { + UriInfo ui = mc.getUriInfo(); + MultivaluedMap params = ui.getPathParameters(); + for (Map.Entry> entry : params.entrySet()) { + String value = entry.getValue().get(0); + int ind = value.indexOf(";"); + if (ind > 0) { + value = value.substring(0, ind); + } + request.setParameter(entry.getKey(), value); + } + + List segments = ui.getPathSegments(); + if (segments.size() > 0) { + doSetRequestParameters(request, segments.get(segments.size() - 1).getMatrixParameters()); + } + doSetRequestParameters(request, ui.getQueryParameters()); + request.setParameter(ABSOLUTE_PATH_PARAMETER, ui.getAbsolutePath().toString()); + request.setParameter(RELATIVE_PATH_PARAMETER, ui.getPath()); + request.setParameter(BASE_PATH_PARAMETER, ui.getBaseUri().toString()); + } + } + + protected void doSetRequestParameters(HttpServletRequestFilter req, + MultivaluedMap params) { + for (Map.Entry> entry : params.entrySet()) { + req.setParameters(entry.getKey(), entry.getValue()); + } + } + + public void setDispatcherName(String name) { + this.dispatcherName = name; + } + + public void setServletPath(String path) { + this.servletPath = path; + } + + private static class HttpServletRequestFilter extends HttpServletRequestWrapper { + + private Map params; + private String path; + private String servletPath; + + @SuppressWarnings("unchecked") + public HttpServletRequestFilter(HttpServletRequest request, String path, String servletPath) { + super(request); + this.path = path; + this.servletPath = servletPath; + params = new HashMap(request.getParameterMap()); + } + + @Override + public String getServletPath() { + return servletPath; + } + + @Override + public String getPathInfo() { + return path; + } + + @Override + public String getRequestURI() { + return path; + } + + public void setParameter(String name, String value) { + params.put(name, new String[]{value}); + } + + public void setParameters(String name, List values) { + params.put(name, values.toArray(new String[]{})); + } + + @Override + public String getParameter(String name) { + String[] values = params.get(name); + if (values == null || values.length == 0) { + return null; + } + return values[0]; + } + + @Override + public Map getParameterMap() { + return params; + } + + } +} Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/RequestDispatcherProvider.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/RequestDispatcherProvider.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java?rev=833112&r1=833111&r2=833112&view=diff ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java (original) +++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java Thu Nov 5 18:22:51 2009 @@ -49,7 +49,7 @@ @Provider @Produces({"application/xml", "application/*+xml", "text/xml" }) -@Consumes({"application/xml", "application/*+xml", "text/xml" }) +@Consumes({"application/xml", "application/*+xml", "text/xml", "text/html" }) public class SourceProvider implements MessageBodyReader, MessageBodyWriter { 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=833112&r1=833111&r2=833112&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 Thu Nov 5 18:22:51 2009 @@ -98,7 +98,6 @@ public final class JAXRSUtils { public static final MediaType ALL_TYPES = new MediaType(); - public static final String RELATIVE_PATH = "relative.path"; public static final String ROOT_RESOURCE_CLASS = "root.resource.class"; public static final String IGNORE_MESSAGE_WRITERS = "ignore.message.writers"; public static final String ROOT_INSTANCE = "service.root.instance"; @@ -218,7 +217,8 @@ public static ClassResourceInfo selectResourceClass(List resources, String path, - MultivaluedMap values) { + MultivaluedMap values, + Message message) { LOG.fine(new org.apache.cxf.common.i18n.Message("START_CRI_MATCH", BUNDLE, @@ -230,7 +230,7 @@ SortedMap> candidateList = new TreeMap>( - new ClassResourceInfoComparator()); + new ClassResourceInfoComparator(message)); for (ClassResourceInfo cri : resources) { MultivaluedMap map = new MetadataMap(); @@ -264,18 +264,8 @@ return null; } - public static OperationResourceInfo findTargetMethod(ClassResourceInfo resource, - String path, - String httpMethod, - MultivaluedMap values, - String requestContentType, - List acceptContentTypes) { - return JAXRSUtils.findTargetMethod(resource, path, httpMethod, values, requestContentType, - acceptContentTypes, true); - } - - public static OperationResourceInfo findTargetMethod(ClassResourceInfo resource, - String path, + public static OperationResourceInfo findTargetMethod(ClassResourceInfo resource, + Message message, String httpMethod, MultivaluedMap values, String requestContentType, @@ -289,9 +279,14 @@ LOG.fine(msg.toString()); } + String path = values.getFirst(URITemplate.FINAL_MATCH_GROUP); + if (path == null) { + path = "/"; + } + SortedMap> candidateList = new TreeMap>( - new OperationResourceInfoComparator()); + new OperationResourceInfoComparator(message)); MediaType requestType = requestContentType == null ? ALL_TYPES : MediaType.valueOf(requestContentType); @@ -812,8 +807,11 @@ if (genericType instanceof ParameterizedType) { return ProviderFactory.getInstance(m).createContextResolver( ((ParameterizedType)genericType).getActualTypeArguments()[0], m); + } else if (m != null) { + return ProviderFactory.getInstance(m).createContextResolver(genericType, m); + } else { + return null; } - return null; } public static Object createResourceValue(Message m, Type genericType, Class clazz) { Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/Messages.properties URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/Messages.properties?rev=833112&r1=833111&r2=833112&view=diff ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/Messages.properties (original) +++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/Messages.properties Thu Nov 5 18:22:51 2009 @@ -18,7 +18,7 @@ # under the License. # # -NO_RESOURCE_OP_EXC=No resource methods found for resource class {0} +NO_RESOURCE_OP_EXC=No resource methods have been found for resource class {0} GET_INSTEAD_OF_HEAD=Resource class {0} does not support HEAD http method, method {1} supporting GET http method will be invoked NO_CONTENT_TYPE_SPECIFIED=No Content-Type specified for HTTP {0} METHOD_INJECTION_FAILURE=Method {0} injection failure @@ -29,7 +29,7 @@ CLASS_CONSTRUCTOR_FAILURE=Class {0} can not be instantiated using a constructor with a single String argument CLASS_VALUE_OF_FAILURE=Instance of class {0} can not be created using static valueOf(String) or fromString(String) methods WRONG_PARAMETER_TYPE=Parameter Class {0} has no constructor with single String parameter, static valueOf(String) or fromString(String) methods -NO_MSG_READER=.No message body reader found for request class : {0}, ContentType : {1}. +NO_MSG_READER=No message body reader has been found for request class {0}, ContentType : {1}. NO_SUBRESOURCE_METHOD_FOUND=No operation matching request path {0} is found on subresource, HTTP Method : {1}, ContentType : {2}, Accept : {3}. NO_OP_EXC=.No operation matching request path {0} is found, HTTP Method : {1}, ContentType : {2}, Accept : {3}. START_OPER_MATCH=Trying to select a resource operation on the resource class {0} Modified: cxf/trunk/rt/frontend/jaxrs/src/main/resources/schemas/jaxrs.xsd URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/resources/schemas/jaxrs.xsd?rev=833112&r1=833111&r2=833112&view=diff ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/resources/schemas/jaxrs.xsd (original) +++ cxf/trunk/rt/frontend/jaxrs/src/main/resources/schemas/jaxrs.xsd Thu Nov 5 18:22:51 2009 @@ -53,6 +53,7 @@ + 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=833112&r1=833111&r2=833112&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 Thu Nov 5 18:22:51 2009 @@ -33,7 +33,6 @@ import org.apache.cxf.jaxrs.impl.MetadataMap; 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.ProviderFactory; import org.apache.cxf.jaxrs.resources.Book; import org.apache.cxf.jaxrs.resources.Chapter; @@ -73,26 +72,31 @@ String contentTypes = "text/xml"; String acceptContentTypes = "text/xml"; - MetadataMap values = new MetadataMap(); - ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, "/books", values); - OperationResourceInfo ori = JAXRSUtils.findTargetMethod(resource, - values.getFirst(URITemplate.FINAL_MATCH_GROUP), - "PUT", values, contentTypes, - JAXRSUtils.sortMediaTypes(acceptContentTypes)); - assertNotNull(ori); - assertEquals("resourceMethod needs to be selected", "putEntity", - ori.getMethodToInvoke().getName()); - 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.get(ProviderFactory.class.getName()); - EasyMock.expectLastCall().andReturn(ProviderFactory.getInstance()); + EasyMock.expectLastCall().andReturn(ProviderFactory.getInstance()).times(2); + e.get("org.apache.cxf.jaxrs.comparator"); + EasyMock.expectLastCall().andReturn(null); EasyMock.replay(e); ex.put(Endpoint.class, e); + MetadataMap values = new MetadataMap(); + ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, "/books", values, + m); + OperationResourceInfo ori = JAXRSUtils.findTargetMethod(resource, + m, + "PUT", values, contentTypes, + JAXRSUtils.sortMediaTypes(acceptContentTypes), + true); + assertNotNull(ori); + assertEquals("resourceMethod needs to be selected", "putEntity", + ori.getMethodToInvoke().getName()); + String value = "The Book2"; m.setContent(InputStream.class, new ByteArrayInputStream(value.getBytes())); List params = JAXRSUtils.processParameters(ori, values, m); @@ -111,26 +115,31 @@ String contentTypes = "text/xml"; String acceptContentTypes = "text/xml"; - MetadataMap values = new MetadataMap(); - ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, "/books", values); - OperationResourceInfo ori = JAXRSUtils.findTargetMethod(resource, - values.getFirst(URITemplate.FINAL_MATCH_GROUP), - methodName, values, contentTypes, - JAXRSUtils.sortMediaTypes(acceptContentTypes)); - assertNotNull(ori); - assertEquals("resourceMethod needs to be selected", methodName.toLowerCase() + "Entity", - ori.getMethodToInvoke().getName()); - 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.get(ProviderFactory.class.getName()); - EasyMock.expectLastCall().andReturn(ProviderFactory.getInstance()); + EasyMock.expectLastCall().andReturn(ProviderFactory.getInstance()).times(2); + e.get("org.apache.cxf.jaxrs.comparator"); + EasyMock.expectLastCall().andReturn(null); EasyMock.replay(e); ex.put(Endpoint.class, e); + MetadataMap values = new MetadataMap(); + ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, "/books", values, + m); + OperationResourceInfo ori = JAXRSUtils.findTargetMethod(resource, + m, + methodName, values, contentTypes, + JAXRSUtils.sortMediaTypes(acceptContentTypes), + true); + assertNotNull(ori); + assertEquals("resourceMethod needs to be selected", methodName.toLowerCase() + "Entity", + ori.getMethodToInvoke().getName()); + String value = "The Book2"; m.setContent(InputStream.class, new ByteArrayInputStream(value.getBytes())); List params = JAXRSUtils.processParameters(ori, values, m); @@ -151,11 +160,12 @@ String acceptContentTypes = "text/xml,*/*"; MetadataMap values = new MetadataMap(); - ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/resource", values); + ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/resource", values, + new MessageImpl()); OperationResourceInfo ori = JAXRSUtils.findTargetMethod(resource, - values.getFirst(URITemplate.FINAL_MATCH_GROUP), + null, "GET", values, contentTypes, - JAXRSUtils.sortMediaTypes(acceptContentTypes)); + JAXRSUtils.sortMediaTypes(acceptContentTypes), true); assertNotNull(ori); assertEquals("resourceMethod needs to be selected", "resourceMethod", ori.getMethodToInvoke().getName()); @@ -171,11 +181,12 @@ String acceptContentTypes = "application/xml;q=0.5,application/json"; MetadataMap values = new MetadataMap(); - ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/resource1", values); + ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/resource1", values, + new MessageImpl()); OperationResourceInfo ori = JAXRSUtils.findTargetMethod(resource, - values.getFirst(URITemplate.FINAL_MATCH_GROUP), + null, "GET", values, contentTypes, - JAXRSUtils.sortMediaTypes(acceptContentTypes)); + JAXRSUtils.sortMediaTypes(acceptContentTypes), true); assertNotNull(ori); assertEquals("jsonResource needs to be selected", "jsonResource", ori.getMethodToInvoke().getName()); @@ -195,22 +206,24 @@ //If acceptContentTypes does not specify a specific Mime type, the //method is declared with a most specific ProduceMime type is selected. MetadataMap values = new MetadataMap(); - ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d", values); - OperationResourceInfo ori = JAXRSUtils.findTargetMethod(resource, - values.getFirst(URITemplate.FINAL_MATCH_GROUP), + 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))); + Collections.singletonList(MediaType.valueOf(acceptContentTypes)), true); 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); + resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/1", values, + new MessageImpl()); ori = JAXRSUtils.findTargetMethod(resource, - values.getFirst(URITemplate.FINAL_MATCH_GROUP), + null, "GET", values, contentTypes, - JAXRSUtils.parseMediaTypes(acceptContentTypes)); + JAXRSUtils.parseMediaTypes(acceptContentTypes), true); assertNotNull(ori); assertEquals("readMethod needs to be selected", "readMethod", ori.getMethodToInvoke().getName()); @@ -218,42 +231,47 @@ contentTypes = "application/xml"; acceptContentTypes = "application/xml"; - resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/1", values); + resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/1", values, new MessageImpl()); ori = JAXRSUtils.findTargetMethod(resource, - values.getFirst(URITemplate.FINAL_MATCH_GROUP), + null, "GET", values, contentTypes, - Collections.singletonList(MediaType.valueOf(acceptContentTypes))); + Collections.singletonList(MediaType.valueOf(acceptContentTypes)) + , true); 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); + resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/1/bar/baz/baz", values, + new MessageImpl()); ori = JAXRSUtils.findTargetMethod(resource, - values.getFirst(URITemplate.FINAL_MATCH_GROUP), + null, "GET", values, contentTypes, - Collections.singletonList(MediaType.valueOf(acceptContentTypes))); + Collections.singletonList(MediaType.valueOf(acceptContentTypes)), + true); 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); + resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/1", values, new MessageImpl()); ori = JAXRSUtils.findTargetMethod(resource, - values.getFirst(URITemplate.FINAL_MATCH_GROUP), + null, "GET", values, contentTypes, - Collections.singletonList(MediaType.valueOf(acceptContentTypes))); + Collections.singletonList(MediaType.valueOf(acceptContentTypes)), + true); assertNotNull(ori); assertEquals("unlimitedPath needs to be selected", "unlimitedPath", ori.getMethodToInvoke().getName()); - resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/1/2", values); + resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/1/2", values, new MessageImpl()); ori = JAXRSUtils.findTargetMethod(resource, - values.getFirst(URITemplate.FINAL_MATCH_GROUP), + null, "GET", values, contentTypes, - Collections.singletonList(MediaType.valueOf(acceptContentTypes))); + Collections.singletonList(MediaType.valueOf(acceptContentTypes)), + true); assertNotNull(ori); assertEquals("limitedPath needs to be selected", "limitedPath", ori.getMethodToInvoke().getName()); @@ -268,40 +286,41 @@ List resources = ((JAXRSServiceImpl)sf.getService()).getClassResourceInfos(); MetadataMap values = new MetadataMap(); - ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/custom", values); + 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, - values.getFirst(URITemplate.FINAL_MATCH_GROUP), + null, "GET", values, contentTypes, - JAXRSUtils.sortMediaTypes(acceptContentTypes)); + JAXRSUtils.sortMediaTypes(acceptContentTypes), true); assertNotNull(ori); assertEquals("readBar", ori.getMethodToInvoke().getName()); acceptContentTypes = "application/foo,application/bar"; - resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/custom", values); + resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/custom", values, new MessageImpl()); ori = JAXRSUtils.findTargetMethod(resource, - values.getFirst(URITemplate.FINAL_MATCH_GROUP), + null, "GET", values, contentTypes, - JAXRSUtils.sortMediaTypes(acceptContentTypes)); + JAXRSUtils.sortMediaTypes(acceptContentTypes), true); 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); + resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/custom", values, new MessageImpl()); ori = JAXRSUtils.findTargetMethod(resource, - values.getFirst(URITemplate.FINAL_MATCH_GROUP), + null, "GET", values, contentTypes, - JAXRSUtils.sortMediaTypes(acceptContentTypes)); + JAXRSUtils.sortMediaTypes(acceptContentTypes), true); 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); + resource = JAXRSUtils.selectResourceClass(resources, "/1/2/3/d/custom", values, new MessageImpl()); ori = JAXRSUtils.findTargetMethod(resource, - values.getFirst(URITemplate.FINAL_MATCH_GROUP), + null, "GET", values, contentTypes, - JAXRSUtils.sortMediaTypes(acceptContentTypes)); + JAXRSUtils.sortMediaTypes(acceptContentTypes), true); assertNotNull(ori); assertEquals("readFoo", ori.getMethodToInvoke().getName()); Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/MessageContextImplTest.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/MessageContextImplTest.java?rev=833112&r1=833111&r2=833112&view=diff ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/MessageContextImplTest.java (original) +++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/MessageContextImplTest.java Thu Nov 5 18:22:51 2009 @@ -27,14 +27,20 @@ import javax.ws.rs.core.Request; import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.UriInfo; +import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.Providers; +import javax.xml.bind.JAXBContext; +import org.apache.cxf.endpoint.Endpoint; import org.apache.cxf.jaxrs.impl.HttpHeadersImpl; import org.apache.cxf.jaxrs.impl.HttpServletResponseFilter; import org.apache.cxf.jaxrs.impl.ProvidersImpl; import org.apache.cxf.jaxrs.impl.RequestImpl; import org.apache.cxf.jaxrs.impl.SecurityContextImpl; import org.apache.cxf.jaxrs.impl.UriInfoImpl; +import org.apache.cxf.jaxrs.provider.ProviderFactory; +import org.apache.cxf.message.Exchange; +import org.apache.cxf.message.ExchangeImpl; import org.apache.cxf.message.Message; import org.apache.cxf.message.MessageImpl; import org.apache.cxf.transport.http.AbstractHTTPDestination; @@ -131,9 +137,41 @@ assertSame(request.getClass(), mc.getContext(ServletConfig.class).getClass()); } + @SuppressWarnings("unchecked") + @Test + public void testContextResolver() { + ContextResolver resolver = new CustomContextResolver(); + ProviderFactory factory = ProviderFactory.getInstance(); + factory.registerUserProvider(resolver); + + Message m = new MessageImpl(); + Exchange ex = new ExchangeImpl(); + m.setExchange(ex); + ex.setInMessage(m); + Endpoint e = EasyMock.createMock(Endpoint.class); + e.get(ProviderFactory.class.getName()); + EasyMock.expectLastCall().andReturn(factory); + EasyMock.replay(e); + ex.put(Endpoint.class, e); + MessageContext mc = new MessageContextImpl(m); + ContextResolver resolver2 = + mc.getResolver(ContextResolver.class, JAXBContext.class); + assertNotNull(resolver2); + assertSame(resolver2, resolver); + } + @Test public void testNoContext() { MessageContext mc = new MessageContextImpl(new MessageImpl()); assertNull(mc.getContext(Message.class)); } + + public static class CustomContextResolver implements ContextResolver { + + public JAXBContext getContext(Class type) { + // TODO Auto-generated method stub + return null; + } + + } } Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JSONProviderTest.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JSONProviderTest.java?rev=833112&r1=833111&r2=833112&view=diff ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JSONProviderTest.java (original) +++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/JSONProviderTest.java Thu Nov 5 18:22:51 2009 @@ -180,6 +180,22 @@ } @Test + public void testWriteToSingleTagBadgerFish() throws Exception { + JSONProvider p = new JSONProvider(); + p.setConvention("badgerfish"); + TagVO tag = createTag("a", "b"); + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + + p.writeTo(tag, (Class)TagVO.class, TagVO.class, TagVO.class.getAnnotations(), + MediaType.APPLICATION_JSON_TYPE, new MetadataMap(), os); + + String s = os.toString(); + assertEquals("{\"tagVO\":{\"group\":{\"$\":\"b\"},\"name\":{\"$\":\"a\"}}}", s); + + } + + @Test public void testWriteToSingleQualifiedTag() throws Exception { JSONProvider p = new JSONProvider(); Map namespaceMap = new HashMap(); @@ -197,6 +213,22 @@ } @Test + public void testWriteToSingleQualifiedTagBadgerFish() throws Exception { + JSONProvider p = new JSONProvider(); + p.setConvention("badgerfish"); + TagVO2 tag = createTag2("a", "b"); + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + + p.writeTo(tag, (Class)TagVO2.class, TagVO2.class, TagVO2.class.getAnnotations(), + MediaType.APPLICATION_JSON_TYPE, new MetadataMap(), os); + + String s = os.toString(); + assertEquals("{\"ns2:thetag\":{\"@xmlns\":{\"ns2\":\"http:\\/\\/tags\"}," + + "\"group\":{\"$\":\"b\"},\"name\":{\"$\":\"a\"}}}", s); + } + + @Test public void testDropRootElement() throws Exception { JSONProvider p = new JSONProvider(); p.setDropRootElement(true); @@ -219,20 +251,29 @@ public void testWriteQualifiedCollection() throws Exception { String data = "{\"ns1.tag\":[{\"group\":\"b\",\"name\":\"a\"}" + ",{\"group\":\"d\",\"name\":\"c\"}]}"; - doWriteQualifiedCollection(false, data); + doWriteQualifiedCollection(false, false, data); } @Test public void testWriteQualifiedCollection2() throws Exception { String data = "{{\"group\":\"b\",\"name\":\"a\"}" + ",{\"group\":\"d\",\"name\":\"c\"}}"; - doWriteQualifiedCollection(true, data); + doWriteQualifiedCollection(true, false, data); } - public void doWriteQualifiedCollection(boolean drop, String data) throws Exception { + @Test + public void testWriteQualifiedCollection3() throws Exception { + String data = "[{\"group\":\"b\",\"name\":\"a\"}" + + ",{\"group\":\"d\",\"name\":\"c\"}]"; + doWriteQualifiedCollection(true, true, data); + } + + public void doWriteQualifiedCollection(boolean drop, boolean serializeAsArray, String data) + throws Exception { JSONProvider p = new JSONProvider(); p.setCollectionWrapperName("{http://tags}tag"); p.setDropCollectionWrapperElement(drop); + p.setSerializeAsArray(serializeAsArray); Map namespaceMap = new HashMap(); namespaceMap.put("http://tags", "ns1"); p.setNamespaceMap(namespaceMap); @@ -243,9 +284,9 @@ Method m = CollectionsResource.class.getMethod("getTags", new Class[0]); p.writeTo(tags, m.getReturnType(), m.getGenericReturnType(), new Annotation[0], MediaType.APPLICATION_JSON_TYPE, new MetadataMap(), os); - String s = os.toString(); assertEquals(s, data); + } @Test