Return-Path: X-Original-To: apmail-cxf-commits-archive@www.apache.org Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 7620F17E18 for ; Wed, 28 Jan 2015 17:27:11 +0000 (UTC) Received: (qmail 80348 invoked by uid 500); 28 Jan 2015 17:27:12 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 80293 invoked by uid 500); 28 Jan 2015 17:27:11 -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 80283 invoked by uid 99); 28 Jan 2015 17:27:11 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 28 Jan 2015 17:27:11 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id BB78CE03EE; Wed, 28 Jan 2015 17:27:11 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: sergeyb@apache.org To: commits@cxf.apache.org Message-Id: <456fc1de725946fa9a31487cfca0b360@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: cxf git commit: [CXF-6200] Initial support for setting custom model java types and having default methods used with regular methods Date: Wed, 28 Jan 2015 17:27:11 +0000 (UTC) Repository: cxf Updated Branches: refs/heads/master e5e222baf -> 4710298eb [CXF-6200] Initial support for setting custom model java types and having default methods used with regular methods Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/4710298e Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/4710298e Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/4710298e Branch: refs/heads/master Commit: 4710298ebad5e5acd3654b4bdb1a7839e444e39d Parents: e5e222b Author: Sergey Beryozkin Authored: Wed Jan 28 17:26:57 2015 +0000 Committer: Sergey Beryozkin Committed: Wed Jan 28 17:26:57 2015 +0000 ---------------------------------------------------------------------- .../cxf/jaxrs/JAXRSServiceFactoryBean.java | 2 +- .../org/apache/cxf/jaxrs/model/Parameter.java | 11 ++- .../apache/cxf/jaxrs/utils/ResourceUtils.java | 88 +++++++++++--------- .../src/main/resources/schemas/jaxrs-common.xsd | 1 + ...AXRSClientServerUserResourceDefaultTest.java | 23 ++++- 5 files changed, 83 insertions(+), 42 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/4710298e/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServiceFactoryBean.java ---------------------------------------------------------------------- diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServiceFactoryBean.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServiceFactoryBean.java index 6230e24..b674185 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServiceFactoryBean.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServiceFactoryBean.java @@ -189,7 +189,7 @@ public class JAXRSServiceFactoryBean extends AbstractServiceFactoryBean { Map map = userResourcesAsMap(resources); for (Class sClass : sClasses) { ClassResourceInfo cri = ResourceUtils.createServiceClassResourceInfo( - map, map.get(sClass.getName()), sClass, false, true, enableStatic, getBus()); + map, map.get(sClass.getName()), sClass, true, enableStatic, getBus()); if (cri != null) { classResourceInfos.add(cri); } http://git-wip-us.apache.org/repos/asf/cxf/blob/4710298e/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/Parameter.java ---------------------------------------------------------------------- diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/Parameter.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/Parameter.java index 4e04680..d2fbe40 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/Parameter.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/Parameter.java @@ -28,6 +28,7 @@ public class Parameter { private String aValue; private boolean isEncoded; private String defaultValue; + private Class javaType; public Parameter() { @@ -91,8 +92,14 @@ public class Parameter { public void setDefaultValue(String dValue) { defaultValue = dValue; } + public void setJavaType(Class jType) { + this.javaType = jType; + } public Class getJavaType() { - //TODO: support the conversion from "xs:int" or Java class names (DOMSource, etc) - return type == ParameterType.REQUEST_BODY ? InputStream.class : String.class; + if (javaType == null) { + return type == ParameterType.REQUEST_BODY ? InputStream.class : String.class; + } else { + return javaType; + } } } http://git-wip-us.apache.org/repos/asf/cxf/blob/4710298e/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java ---------------------------------------------------------------------- diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java index c549936..f524f10 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java @@ -75,9 +75,11 @@ import org.apache.cxf.common.classloader.ClassLoaderUtils; import org.apache.cxf.common.i18n.BundleUtils; import org.apache.cxf.common.jaxb.JAXBUtils; import org.apache.cxf.common.logging.LogUtils; +import org.apache.cxf.common.util.StringUtils; import org.apache.cxf.helpers.CastUtils; import org.apache.cxf.helpers.DOMUtils; import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; +import org.apache.cxf.jaxrs.ext.DefaultMethod; import org.apache.cxf.jaxrs.ext.xml.ElementClass; import org.apache.cxf.jaxrs.ext.xml.XMLName; import org.apache.cxf.jaxrs.lifecycle.PerRequestResourceProvider; @@ -188,13 +190,12 @@ public final class ResourceUtils { Bus bus) { final boolean isDefaultClass = defaultClass != null; Class sClass = !isDefaultClass ? loadClass(model.getName()) : defaultClass; - return createServiceClassResourceInfo(resources, model, sClass, isDefaultClass, - isRoot, enableStatic, bus); + return createServiceClassResourceInfo(resources, model, sClass, isRoot, enableStatic, bus); } public static ClassResourceInfo createServiceClassResourceInfo( Map resources, UserResource model, - Class sClass, boolean isDefaultClass, boolean isRoot, boolean enableStatic, Bus bus) { + Class sClass, boolean isRoot, boolean enableStatic, Bus bus) { if (model == null) { throw new RuntimeException("Resource class " + sClass.getName() + " has no model info"); } @@ -203,47 +204,50 @@ public final class ResourceUtils { model.getConsumes(), model.getProduces(), bus); URITemplate t = URITemplate.createTemplate(model.getPath()); cri.setURITemplate(t); + MethodDispatcher md = new MethodDispatcher(); Map ops = model.getOperationsAsMap(); - if (!isDefaultClass) { - for (Method m : cri.getServiceClass().getMethods()) { - UserOperation op = ops.get(m.getName()); - if (op == null || op.getName() == null) { - continue; - } - OperationResourceInfo ori = - new OperationResourceInfo(m, cri, URITemplate.createTemplate(op.getPath()), - op.getVerb(), op.getConsumes(), op.getProduces(), - op.getParameters(), - op.isOneway()); - String rClassName = m.getReturnType().getName(); - if (op.getVerb() == null) { - if (resources.containsKey(rClassName)) { - ClassResourceInfo subCri = rClassName.equals(model.getName()) ? cri - : createServiceClassResourceInfo(resources, resources.get(rClassName), - m.getReturnType(), false, false, enableStatic, bus); - if (subCri != null) { - cri.addSubClassResourceInfo(subCri); - md.bind(ori, m); - } + + Method defaultMethod = null; + Map methodNames = new HashMap(); + for (Method m : cri.getServiceClass().getMethods()) { + if (m.getAnnotation(DefaultMethod.class) != null) { + // if needed we can also support multiple default methods + defaultMethod = m; + } + methodNames.put(m.getName(), m); + } + + for (Map.Entry entry : ops.entrySet()) { + UserOperation op = entry.getValue(); + Method actualMethod = methodNames.get(op.getName()); + if (actualMethod == null) { + actualMethod = defaultMethod; + } + if (actualMethod == null) { + continue; + } + OperationResourceInfo ori = + new OperationResourceInfo(actualMethod, cri, URITemplate.createTemplate(op.getPath()), + op.getVerb(), op.getConsumes(), op.getProduces(), + op.getParameters(), + op.isOneway()); + String rClassName = actualMethod.getReturnType().getName(); + if (op.getVerb() == null) { + if (resources.containsKey(rClassName)) { + ClassResourceInfo subCri = rClassName.equals(model.getName()) ? cri + : createServiceClassResourceInfo(resources, resources.get(rClassName), + actualMethod.getReturnType(), false, enableStatic, bus); + if (subCri != null) { + cri.addSubClassResourceInfo(subCri); + md.bind(ori, actualMethod); } - } else { - md.bind(ori, m); } + } else { + md.bind(ori, actualMethod); } - } else { - Method m = cri.getServiceClass().getMethods()[0]; - for (Map.Entry entry : ops.entrySet()) { - UserOperation op = entry.getValue(); - OperationResourceInfo ori = - new OperationResourceInfo(m, cri, URITemplate.createTemplate(op.getPath()), - op.getVerb(), op.getConsumes(), op.getProduces(), - op.getParameters(), - op.isOneway()); - md.bind(ori, m); - } - } + cri.setMethodDispatcher(md); return checkMethodDispatcher(cri) ? cri : null; @@ -701,6 +705,14 @@ public final class ResourceUtils { Parameter p = new Parameter(paramEl.getAttribute("type"), i, paramEl.getAttribute("name")); p.setEncoded(Boolean.valueOf(paramEl.getAttribute("encoded"))); p.setDefaultValue(paramEl.getAttribute("defaultValue")); + String pClass = paramEl.getAttribute("class"); + if (!StringUtils.isEmpty(pClass)) { + try { + p.setJavaType(ClassLoaderUtils.loadClass(pClass, ResourceUtils.class)); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } params.add(p); } op.setParameters(params); http://git-wip-us.apache.org/repos/asf/cxf/blob/4710298e/rt/frontend/jaxrs/src/main/resources/schemas/jaxrs-common.xsd ---------------------------------------------------------------------- diff --git a/rt/frontend/jaxrs/src/main/resources/schemas/jaxrs-common.xsd b/rt/frontend/jaxrs/src/main/resources/schemas/jaxrs-common.xsd index 8dbd6df..b42570e 100644 --- a/rt/frontend/jaxrs/src/main/resources/schemas/jaxrs-common.xsd +++ b/rt/frontend/jaxrs/src/main/resources/schemas/jaxrs-common.xsd @@ -60,6 +60,7 @@ + http://git-wip-us.apache.org/repos/asf/cxf/blob/4710298e/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerUserResourceDefaultTest.java ---------------------------------------------------------------------- diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerUserResourceDefaultTest.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerUserResourceDefaultTest.java index eaabad5..259a114 100644 --- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerUserResourceDefaultTest.java +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerUserResourceDefaultTest.java @@ -45,6 +45,8 @@ import org.apache.commons.httpclient.methods.GetMethod; import org.apache.cxf.helpers.CastUtils; import org.apache.cxf.jaxrs.JAXRSInvoker; import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; +import org.apache.cxf.jaxrs.client.WebClient; +import org.apache.cxf.jaxrs.ext.DefaultMethod; import org.apache.cxf.jaxrs.ext.MessageContext; import org.apache.cxf.jaxrs.ext.MessageContextImpl; import org.apache.cxf.jaxrs.model.AbstractResourceInfo; @@ -83,8 +85,15 @@ public class JAXRSClientServerUserResourceDefaultTest extends AbstractBusClientS op.setVerb("GET"); op.setParameters(Collections.singletonList(new Parameter(ParameterType.PATH, "id"))); + UserOperation op2 = new UserOperation(); + op2.setPath("echobook"); + op2.setName("echo"); + op2.setVerb("POST"); + op2.setParameters(Collections.singletonList(new Parameter(ParameterType.REQUEST_BODY, null))); + List ops = new ArrayList(); ops.add(op); + ops.add(op2); ur.setOperations(ops); @@ -132,6 +141,14 @@ public class JAXRSClientServerUserResourceDefaultTest extends AbstractBusClientS "application/xml", 200, 999); } + @Test + public void testEchoBook() throws Exception { + WebClient wc = WebClient.create("http://localhost:" + PORT + "/default/echobook"); + Book b = wc.type("application/xml").accept("application/xml").post(new Book("echo", 333L), Book.class); + assertEquals("echo", b.getName()); + assertEquals(333L, b.getId()); + } + private void getAndCompare(String address, String acceptType, int expectedStatus, @@ -166,6 +183,7 @@ public class JAXRSClientServerUserResourceDefaultTest extends AbstractBusClientS private HttpHeaders headers; private Map books = Collections.singletonMap("123", new Book("CXF in Action", 123L)); @Path("{a:.*}") + @DefaultMethod public Response handle() { if (HttpMethod.GET.equals(request.getMethod())) { String id = ui.getPathParameters().getFirst("id"); @@ -175,6 +193,9 @@ public class JAXRSClientServerUserResourceDefaultTest extends AbstractBusClientS throw new NotAllowedException("GET"); } } + public Book echo(Book book) { + return book; + } } public static class CustomModelInvoker extends JAXRSInvoker { @@ -183,7 +204,7 @@ public class JAXRSClientServerUserResourceDefaultTest extends AbstractBusClientS public Object invoke(Exchange exchange, Object request, Object resourceObject) { MessageContext mc = new MessageContextImpl(exchange.getInMessage()); List params = CastUtils.cast((List)request); - if (params.size() > 0) { + if (params.size() == 1 && "999".equals(params.get(0))) { Long bookId = Long.valueOf(params.get(0).toString()); Book book = new Book("CXF in Action", bookId); Response r = Response.ok(book,