[ https://issues.apache.org/jira/browse/CXF-7743?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16490345#comment-16490345 ]
ASF GitHub Bot commented on CXF-7743: ------------------------------------- amarkevich closed pull request #419: [CXF-7743] wadl2java: generate throws declaration for fault response URL: https://github.com/apache/cxf/pull/419 This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/SourceGenerator.java b/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/SourceGenerator.java index d381b4eb302..c0a6558a182 100644 --- a/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/SourceGenerator.java +++ b/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/SourceGenerator.java @@ -125,7 +125,7 @@ private static final String TAB = " "; private static final List<String> HTTP_OK_STATUSES = - Arrays.asList(new String[] {"200", "201", "202", "203", "204"}); + Arrays.asList(new String[] {"200", "201", "202", "203", "204"}); private static final Set<Class<?>> OPTIONAL_PARAMS = new HashSet<Class<?>>(Arrays.<Class<?>>asList(QueryParam.class, @@ -845,6 +845,9 @@ private void writeResourceMethod(Element methodEl, writeRequestTypes(firstRequestEl, classPackage, repElement, inParamElements, jaxpSourceRequired, sbMethodCode, sbMethodDocs, imports, info, suspendedAsync); sbMethodCode.append(")"); + + writeThrows(responseEls, sbMethodCode, sbMethodDocs, imports, info); + if (info.isInterfaceGenerated()) { sbMethodCode.append(";"); } else { @@ -913,6 +916,13 @@ private void writeMethodParamDocs(Element paramEl, String name, StringBuilder sb } } + private void writeMethodThrowsDocs(Element paramEl, String name, StringBuilder sbDoc) { + String text = getDocText(paramEl); + if (text != null) { + sbDoc.append(" * @throws ").append(name).append(" ").append(text).append(getLineSep()).append(TAB); + } + } + private void writeMethodResponseDocs(Element responseEl, StringBuilder sbDoc) { String text = getDocText(responseEl); if (text != null) { @@ -1203,22 +1213,36 @@ private void writeJaxrResponse(StringBuilder sbCode, Set<String> imports) { sbCode.append(Response.class.getSimpleName()).append(" "); } - private Element getOKResponse(List<Element> responseEls) { - for (int i = 0; i < responseEls.size(); i++) { - String statusValue = responseEls.get(i).getAttribute("status"); - if (statusValue.length() == 0) { - return responseEls.get(i); + private static Element getOKResponse(List<Element> responseEls) { + for (Element responseEl : responseEls) { + String statusValue = responseEl.getAttribute("status"); + if (statusValue.isEmpty()) { + return responseEl; } - String[] statuses = statusValue.split("\\s"); - for (String status : statuses) { + for (String status : statusValue.split("\\s")) { if (HTTP_OK_STATUSES.contains(status)) { - return responseEls.get(i); + return responseEl; } } } return null; } + private static List<Element> getErrorResponses(List<Element> responseEls) { + final List<Element> result = new ArrayList<>(); + for (Element responseEl : responseEls) { + if (responseEl.hasAttribute("status")) { + for (String statusValue : responseEl.getAttribute("status").split("\\s")) { + if (400 <= Integer.parseInt(statusValue)) { + result.add(responseEl); + break; + } + } + } + } + return result; + } + private void writeSubResponseType(boolean recursive, String ns, String localName, StringBuilder sbCode, Set<String> imports) { if (!recursive && ns.length() > 0) { @@ -1486,7 +1510,7 @@ private String getTypicalClassName(String name) { private List<Element> getWadlElements(Element parent, String name) { List<Element> elements = parent != null ? DOMUtils.getChildrenWithName(parent, getWadlNamespace(), name) - : CastUtils.cast(Collections.emptyList(), Element.class); + : Collections.emptyList(); if (!"resource".equals(name)) { for (int i = 0; i < elements.size(); i++) { Element el = elements.get(i); @@ -1715,6 +1739,32 @@ private void writeFormatAnnotations(List<Element> repElements, StringBuilder sbC sbCode.append(getLineSep()).append(TAB); } + private void writeThrows(List<Element> responseEls, StringBuilder sbCode, StringBuilder sbMethodDocs, + Set<String> imports, ContextInfo info) { + final List<Element> throwsParamEls = new ArrayList<>(); + for (Element errorResp : getErrorResponses(responseEls)) { + for (Element errorRep : getWadlElements(errorResp, "representation")) { + throwsParamEls.addAll(getWadlElements(errorRep, "param")); + } + } + if (!throwsParamEls.isEmpty()) { + sbCode.append(" throws "); + boolean comma = false; + for (Element paramEl : throwsParamEls) { + if (!comma) { + comma = true; + } else { + sbCode.append(", "); + } + final String javaThrowsName = getPrimitiveType(paramEl, info, imports); + sbCode.append(javaThrowsName); + if (sbMethodDocs != null) { + writeMethodThrowsDocs(paramEl, javaThrowsName, sbMethodDocs); + } + } + } + } + private void createJavaSourceFile(File src, QName qname, StringBuilder sbCode, StringBuilder sbImports, boolean serviceClass) { String content = sbImports.toString() + getLineSep() + sbCode.toString(); diff --git a/tools/wadlto/jaxrs/src/test/java/org/apache/cxf/tools/wadlto/jaxrs/JAXRSContainerTest.java b/tools/wadlto/jaxrs/src/test/java/org/apache/cxf/tools/wadlto/jaxrs/JAXRSContainerTest.java index 3c75b7f55ba..566f3dc7f4b 100644 --- a/tools/wadlto/jaxrs/src/test/java/org/apache/cxf/tools/wadlto/jaxrs/JAXRSContainerTest.java +++ b/tools/wadlto/jaxrs/src/test/java/org/apache/cxf/tools/wadlto/jaxrs/JAXRSContainerTest.java @@ -25,7 +25,10 @@ import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; +import java.nio.file.Files; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.validation.Valid; import javax.ws.rs.Consumes; @@ -157,6 +160,56 @@ public void testOnewayMethod() throws Exception { } } + @Test + public void testThrows() throws Exception { + JAXRSContainer container = new JAXRSContainer(null); + + ToolContext context = new ToolContext(); + context.put(WadlToolConstants.CFG_OUTPUTDIR, output.getCanonicalPath()); + context.put(WadlToolConstants.CFG_WADLURL, getLocation("/wadl/test.xml")); + context.put(WadlToolConstants.CFG_COMPILE, Boolean.TRUE); + context.put(WadlToolConstants.CFG_INTERFACE, Boolean.TRUE); + context.put(WadlToolConstants.CFG_IMPL, Boolean.TRUE); + context.put(WadlToolConstants.CFG_CREATE_JAVA_DOCS, Boolean.TRUE); + container.setContext(context); + container.execute(); + + assertNotNull(output.list()); + + List<File> javaFiles = FileUtils.getFilesRecurse(output, ".+\\." + "java" + "$"); + assertEquals(2, javaFiles.size()); + for (File f : javaFiles) { + if (!f.getName().endsWith("Impl.java")) { + assertTrue( + Files.readAllLines(f.toPath()).contains(" * @throws IOException if something going wrong")); + } + } + + ClassCollector cc = context.get(ClassCollector.class); + assertEquals(2, cc.getServiceClassNames().size()); + + final Map<String, Class<?>[]> methods = new HashMap<>(); + methods.put("listRepositories", new Class<?>[] {}); + methods.put("createRepository", new Class<?>[] {java.io.IOException.class}); + methods.put("deleteRepository", + new Class<?>[] {javax.ws.rs.NotFoundException.class, java.io.IOException.class}); + methods.put("postThename", new Class<?>[] {java.io.IOException.class, java.lang.NoSuchMethodException.class}); + try (URLClassLoader loader = new URLClassLoader(new URL[]{output.toURI().toURL()})) { + for (String className : cc.getServiceClassNames().values()) { + final Class<?> generatedClass = loader.loadClass(className); + for (Map.Entry<String, Class<?>[]> entry : methods.entrySet()) { + Method m; + try { + m = generatedClass.getMethod(entry.getKey(), String.class); + } catch (NoSuchMethodException e) { + m = generatedClass.getMethod(entry.getKey(), String.class, String.class); + } + assertArrayEquals(entry.getValue(), m.getExceptionTypes()); + } + } + } + } + @Test public void testCodeGenInterfacesMultipleInXmlReps() { try { diff --git a/tools/wadlto/jaxrs/src/test/resources/wadl/test.xml b/tools/wadlto/jaxrs/src/test/resources/wadl/test.xml index ec6a9c6fd3e..7a8d3161808 100644 --- a/tools/wadlto/jaxrs/src/test/resources/wadl/test.xml +++ b/tools/wadlto/jaxrs/src/test/resources/wadl/test.xml @@ -1,55 +1,91 @@ -<application xmlns="http://wadl.dev.java.net/2009/02" xmlns:xs="http://www.w3.org/2001/XMLSchema" > - <grammars /> - <resources> - <resource id="Test" path="/repository"> - <doc> - Repository Resource - </doc> +<application xmlns="http://wadl.dev.java.net/2009/02" + xmlns:xs="http://www.w3.org/2001/XMLSchema"> + <grammars /> + <resources> + <resource id="Test" path="/repository"> + <doc> + Repository Resource + </doc> <param name="top" style="template" type="xs:string"> <doc> - Repository Index - </doc> + Repository Index + </doc> </param> - <method name="GET" id="listRepositories"> - <doc> - List Repositories - </doc> - <response> - <doc> - JSON Repository Representation - </doc> - <representation mediaType="application/json" /> - </response> - </method> + <method name="GET" id="listRepositories"> + <doc> + List Repositories + </doc> + <response> + <doc> + JSON Repository Representation + </doc> + <representation mediaType="application/json" /> + </response> + <response status="500" /> + </method> + + <resource path="{the-name}"> + <param name="the-name" style="template" type="xs:string" /> + + <method name="PUT" id="createRepository"> + <request> + </request> + <response> + </response> + <response status="500"> + <representation mediaType="text/plain"> + <param name="error" style="plain" + type="java.io.IOException"> + <doc> + if something going wrong + </doc> + </param> + </representation> + </response> + </method> + <method name="DELETE" id="deleteRepository"> + <response status="404"> + <representation mediaType="text/plain"> + <param name="error" style="plain" + type="javax.ws.rs.NotFoundException" /> + </representation> + </response> + <response status="500"> + <representation mediaType="text/plain"> + <param name="error" style="plain" + type="java.io.IOException" /> + </representation> + </response> + </method> - <resource path="{the-name}"> - <param name="the-name" style="template" type="xs:string"/> - - <method name="PUT" id="createRepository" > - <request> - </request> - <response> - </response> - </method> - <method name="DELETE" id="deleteRepository"> - </method> - <method name="POST"> - <request> - <representation mediaType="text/plain"> - <doc> - Text Plain representation - </doc> - <param name="id" style="plain" type="xsd:anyType"/> - </representation> - </request> - <response> - <representation mediaType="text/plain"> - <param name="result" style="plain" type="xs:string"/> - </representation> - </response> - </method> - </resource> - </resource> - </resources> + <request> + <representation mediaType="text/plain"> + <doc> + Text Plain representation + </doc> + <param name="id" style="plain" + type="xsd:anyType" /> + </representation> + </request> + <response> + <representation mediaType="text/plain"> + <param name="result" style="plain" + type="xs:string" /> + </representation> + </response> + <response status="500 501"> + <representation mediaType="text/plain"> + <param name="error" style="plain" + type="java.io.IOException" /> + </representation> + <representation mediaType="text/plain"> + <param name="error" style="plain" + type="java.lang.NoSuchMethodException" /> + </representation> + </response> + </method> + </resource> + </resource> + </resources> </application> \ No newline at end of file ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org > wadl2java: generate throws declaration for fault response > --------------------------------------------------------- > > Key: CXF-7743 > URL: https://issues.apache.org/jira/browse/CXF-7743 > Project: CXF > Issue Type: New Feature > Components: Tooling > Affects Versions: 3.2.4 > Reporter: Alexey Markevich > Assignee: Alexey Markevich > Priority: Major > > According to [1] the response status attribute can contains status code. In > case 4xx-5xx representation/param/@type can be set to java exception class > name. > Previously the impl can use unchecked exceptions only with raw > ResponseExceptionMapper<Exception> on client side. > 1. https://www.w3.org/Submission/wadl/#x3-200002.10 -- This message was sent by Atlassian JIRA (v7.6.3#76005)