You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2020/11/12 19:40:09 UTC

[juneau] branch master updated: Add @RemoteMethod(value) and @RestMethod(value) annotations.

This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new a8cbb94  Add @RemoteMethod(value) and @RestMethod(value) annotations.
a8cbb94 is described below

commit a8cbb94815a0ba038d97b2796a12d5c20031507f
Author: JamesBognar <ja...@salesforce.com>
AuthorDate: Thu Nov 12 14:40:01 2020 -0500

    Add @RemoteMethod(value) and @RestMethod(value) annotations.
---
 .../org/apache/juneau/http/remote/Remote_Test.java | 12 ++++++++
 .../apache/juneau/http/remote/RemoteMethod.java    | 29 ++++++++++++++++++++
 juneau-doc/docs/ReleaseNotes/9.0.0.html            | 20 ++++++++++++++
 .../rest/client/remote/RemoteMethodMeta.java       | 11 ++++++++
 .../rest/annotation/RestMethodAnnotation_Test.java | 11 ++++++--
 .../apache/juneau/rest/annotation/RestMethod.java  | 28 +++++++++++++++++++
 .../rest/annotation/RestMethodAnnotation.java      | 32 ++++++++++++++++++++--
 7 files changed, 138 insertions(+), 5 deletions(-)

diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/http/remote/Remote_Test.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/http/remote/Remote_Test.java
index 3876a94..13d5047 100644
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/http/remote/Remote_Test.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/http/remote/Remote_Test.java
@@ -239,17 +239,29 @@ public class Remote_Test {
 		public String x1() {
 			return "foo";
 		}
+		@RestMethod("GET")
+		public String x2() {
+			return "bar";
+		}
+		@RestMethod("GET /x3")
+		public String x3x() {
+			return "baz";
+		}
 	}
 
 	@Remote(path="/")
 	public static interface C1 {
 		String x1();
+		@RemoteMethod("GET") String x2();
+		@RemoteMethod("GET /x3") String x3x();
 	}
 
 	@Test
 	public void c01_overriddenRootUrl() throws Exception {
 		C1 x = client(C.class).build().getRemote(C1.class,"http://localhost/C1");
 		assertEquals("foo",x.x1());
+		assertEquals("bar",x.x2());
+		assertEquals("baz",x.x3x());
 	}
 
 	@Test
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteMethod.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteMethod.java
index 071b372..a5db17b 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteMethod.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteMethod.java
@@ -56,6 +56,9 @@ public @interface RemoteMethod {
 	 * 	<ja>@RemoteMethod</ja>
 	 * 	<jk>public void</jk> postPet(...) {...}
 	 * </p>
+	 *
+	 * <p>
+	 * Note that you can also use {@link #value()} to specify the method name and path in shortened form.
 	 */
 	String path() default "";
 
@@ -73,6 +76,9 @@ public @interface RemoteMethod {
 	 * </p>
 	 *
 	 * <br>If the method cannot be inferred, then the default is <js>"GET"</js>.
+	 *
+	 * <p>
+	 * Note that you can also use {@link #value()} to specify the method name and path in shortened form.
 	 */
 	String method() default "";
 
@@ -113,4 +119,27 @@ public @interface RemoteMethod {
 	 * </ul>
 	 */
 	RemoteReturn returns() default RemoteReturn.BODY;
+
+	/**
+	 * REST method name and path.
+	 *
+	 * <p>
+	 * Can be used to provide a shortened combined form for the {@link #method()} and {@link #path()} values.
+	 *
+	 * <p>
+	 * The following examples are considered equivalent.
+	 * <p class='bcode w800'>
+	 * 	<jc>// Normal form</jc>
+	 * 	<ja>@RemoteMethod</ja>(method=<jsf>PUT</jsf>, path=<js>"/{propertyName}"</js>)
+	 *
+	 * 	<jc>// Shortened form</jc>
+	 * 	<ja>@RemoteMethod</ja>(<js>"PUT /{propertyName}"</js>)
+	 * </p>
+	 *
+	 * <ul class='notes'>
+	 * 	<li>
+	 * 		The path portion is optional.
+	 * </ul>
+	 */
+	String value() default "";
 }
diff --git a/juneau-doc/docs/ReleaseNotes/9.0.0.html b/juneau-doc/docs/ReleaseNotes/9.0.0.html
index 30a3eff..e5b5031 100644
--- a/juneau-doc/docs/ReleaseNotes/9.0.0.html
+++ b/juneau-doc/docs/ReleaseNotes/9.0.0.html
@@ -40,6 +40,15 @@ Juneau 9.0.0 is a major release.
 		<jk>public</jk> Object myRestMethod() { ... }
 	}
 		</p>
+	<li>
+		New shortened form {@link oaj.http.remote.annotation.RemoteMethod#value()} for specifying http method name and path.
+		<p class='bpcode w800'>
+	<jc>// Normal form</jc>
+	<ja>@RemoteMethod</ja>(method=<jsf>PUT</jsf>, path=<js>"/foo"</js>)
+	
+	<jc>// Shortened form</jc>
+	<ja>@RemoteMethod</ja>(<js>"PUT /foo"</js>)
+		</p>
 </ul>
 
 <h5 class='topic w800'>juneau-rest-server</h5>
@@ -48,6 +57,17 @@ Juneau 9.0.0 is a major release.
 		Removed deprecated APIs.
 	<li>
 		Removed the <c><ja>@RestMethod</ja>(name)</c> annotation.  Use <c><ja>@RestMethod</ja>(method)</c> instead.
+	<li>
+		New shortened form {@link oajr.annotation.RestMethod#value()} for specifying http method name and path.
+		<p class='bpcode w800'>
+	<jc>// Normal form</jc>
+	<ja>@RestMethod</ja>(method=<jsf>PUT</jsf>, path=<js>"/{propertyName}"</js>)
+	
+	<jc>// Shortened form</jc>
+	<ja>@RestMethod</ja>(<js>"PUT /{propertyName}"</js>)
+		</p>
+	<li>
+		<c><ja>@RestMethod</ja>(name)</c> annotation.  Use <c><ja>@RestMethod</ja>(method)</c> instead.
 </ul>
 
 <h5 class='topic w800'>juneau-rest-server-springboot</h5>
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteMethodMeta.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteMethodMeta.java
index 3eaa498..5aa45dd 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteMethodMeta.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteMethodMeta.java
@@ -90,6 +90,17 @@ public class RemoteMethodMeta {
 			httpMethod = rm == null ? "" : rm.method();
 			path = rm == null ? "" : rm.path();
 
+			if (rm != null && ! rm.value().isEmpty()) {
+				String v = rm.value().trim();
+				int i = v.indexOf(' ');
+				if (i == -1) {
+					httpMethod = v;
+				} else {
+					httpMethod = v.substring(0, i).trim();
+					path = v.substring(i).trim();
+				}
+			}
+
 			if (path.isEmpty()) {
 				path = HttpUtils.detectHttpPath(m, true);
 			}
diff --git a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/RestMethodAnnotation_Test.java b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/RestMethodAnnotation_Test.java
index 8b31d7c..121159c 100644
--- a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/RestMethodAnnotation_Test.java
+++ b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation/RestMethodAnnotation_Test.java
@@ -65,6 +65,7 @@ public class RestMethodAnnotation_Test {
 		.serializers(Serializer.class)
 		.summary("summary")
 		.swagger(MethodSwaggerAnnotation.DEFAULT)
+		.value("value")
 		.build();
 
 	RestMethod a2 = RestMethodAnnotation.create()
@@ -99,6 +100,7 @@ public class RestMethodAnnotation_Test {
 		.serializers(Serializer.class)
 		.summary("summary")
 		.swagger(MethodSwaggerAnnotation.DEFAULT)
+		.value("value")
 		.build();
 
 	@Test
@@ -135,7 +137,8 @@ public class RestMethodAnnotation_Test {
 				+ "rolesDeclared:'rolesDeclared',"
 				+ "serializers:['org.apache.juneau.serializer.Serializer'],"
 				+ "summary:'summary',"
-				+ "swagger:{consumes:[],deprecated:'',description:[],externalDocs:{description:[],url:'',value:[]},operationId:'',parameters:[],produces:[],responses:[],schemes:[],summary:[],tags:[],value:[]}"
+				+ "swagger:{consumes:[],deprecated:'',description:[],externalDocs:{description:[],url:'',value:[]},operationId:'',parameters:[],produces:[],responses:[],schemes:[],summary:[],tags:[],value:[]},"
+				+ "value:'value'"
 			+ "}"
 		);
 	}
@@ -212,7 +215,8 @@ public class RestMethodAnnotation_Test {
 		rolesDeclared="rolesDeclared",
 		serializers=Serializer.class,
 		summary="summary",
-		swagger=@MethodSwagger
+		swagger=@MethodSwagger,
+		value="value"
 	)
 	public static class D1 {}
 	RestMethod d1 = D1.class.getAnnotationsByType(RestMethod.class)[0];
@@ -248,7 +252,8 @@ public class RestMethodAnnotation_Test {
 		rolesDeclared="rolesDeclared",
 		serializers=Serializer.class,
 		summary="summary",
-		swagger=@MethodSwagger
+		swagger=@MethodSwagger,
+		value="value"
 	)
 	public static class D2 {}
 	RestMethod d2 = D2.class.getAnnotationsByType(RestMethod.class)[0];
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
index a29e3c9..bc322d4 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
@@ -390,6 +390,9 @@ public @interface RestMethod {
 	 * Note that you can use {@link org.apache.juneau.http.HttpMethod} for constant values.
 	 *
 	 * <p>
+	 * Note that you can also use {@link #value()} to specify the method name and path in shortened form.
+	 *
+	 * <p>
 	 * Besides the standard HTTP method names, the following can also be specified:
 	 * <ul class='spaced-list'>
 	 * 	<li>
@@ -520,6 +523,8 @@ public @interface RestMethod {
 	 * 	<jk>public void</jk> get() {...}
 	 * </p>
 	 *
+	 * <p>
+	 * Note that you can also use {@link #value()} to specify the method name and path in shortened form.
 	 *
 	 * <ul class='seealso'>
 	 * 	<li class='ja'>{@link org.apache.juneau.http.annotation.Path}
@@ -829,4 +834,27 @@ public @interface RestMethod {
 	 * </ul>
 	 */
 	MethodSwagger swagger() default @MethodSwagger;
+
+	/**
+	 * REST method name and path.
+	 *
+	 * <p>
+	 * Can be used to provide a shortened combined form for the {@link #method()} and {@link #path()} values.
+	 *
+	 * <p>
+	 * The following examples are considered equivalent.
+	 * <p class='bcode w800'>
+	 * 	<jc>// Normal form</jc>
+	 * 	<ja>@RestMethod</ja>(method=<jsf>PUT</jsf>, path=<js>"/{propertyName}"</js>)
+	 *
+	 * 	<jc>// Shortened form</jc>
+	 * 	<ja>@RestMethod</ja>(<js>"PUT /{propertyName}"</js>)
+	 * </p>
+	 *
+	 * <ul class='notes'>
+	 * 	<li>
+	 * 		The path portion is optional.
+	 * </ul>
+	 */
+	String value() default "";
 }
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethodAnnotation.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethodAnnotation.java
index d27c4b4..588d613 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethodAnnotation.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethodAnnotation.java
@@ -69,7 +69,7 @@ public class RestMethodAnnotation {
 		Logging logging = LoggingAnnotation.DEFAULT;
 		MethodSwagger swagger = MethodSwaggerAnnotation.DEFAULT;
 		Property[] properties = new Property[0];
-		String clientVersion="", debug="", defaultAccept="", defaultCharset="", defaultContentType="", maxInput="", method="", path="", rolesDeclared="", roleGuard="", summary="";
+		String clientVersion="", debug="", defaultAccept="", defaultCharset="", defaultContentType="", maxInput="", method="", path="", rolesDeclared="", roleGuard="", summary="", value="";
 		String[] consumes={}, defaultFormData={}, defaultQuery={}, description={}, flags={}, paths={}, produces={}, reqAttrs={}, reqHeaders={};
 
 		/**
@@ -418,6 +418,17 @@ public class RestMethodAnnotation {
 			return this;
 		}
 
+		/**
+		 * Sets the {@link RestMethod#value()} property on this annotation.
+		 *
+		 * @param value The new value for this property.
+		 * @return This object (for method chaining).
+		 */
+		public Builder value(String value) {
+			this.value = value;
+			return this;
+		}
+
 		// <FluentSetters>
 
 		@Override /* GENERATED - TargetedAnnotationBuilder */
@@ -445,7 +456,7 @@ public class RestMethodAnnotation {
 		private final Logging logging;
 		private final MethodSwagger swagger;
 		private final Property[] properties;
-		private final String clientVersion, debug, defaultAccept, defaultCharset, defaultContentType, maxInput, method, path, rolesDeclared, roleGuard, summary;
+		private final String clientVersion, debug, defaultAccept, defaultCharset, defaultContentType, maxInput, method, path, rolesDeclared, roleGuard, summary, value;
 		private final String[] consumes, defaultFormData, defaultQuery, description, flags, paths, produces, reqAttrs, reqHeaders;
 
 		Impl(Builder b) {
@@ -480,6 +491,7 @@ public class RestMethodAnnotation {
 			this.serializers = copyOf(b.serializers);
 			this.summary = b.summary;
 			this.swagger = b.swagger;
+			this.value = b.value;
 			postConstruct();
 		}
 
@@ -632,6 +644,11 @@ public class RestMethodAnnotation {
 		public MethodSwagger swagger() {
 			return swagger;
 		}
+
+		@Override /* RestMethod */
+		public String value() {
+			return value;
+		}
 	}
 
 	/**
@@ -771,6 +788,17 @@ public class RestMethodAnnotation {
 			if (! a.method().isEmpty())
 				psb.set(RESTMETHOD_httpMethod, string(a.method()));
 
+			if (! a.value().isEmpty()) {
+				String v = string(a.value()).trim();
+				int i = v.indexOf(' ');
+				if (i == -1) {
+					psb.set(RESTMETHOD_httpMethod, v);
+				} else {
+					psb.set(RESTMETHOD_httpMethod, v.substring(0, i).trim());
+					psb.prependTo(RESTMETHOD_paths,  v.substring(i).trim());
+				}
+			}
+
 			if (a.priority() != 0)
 				psb.set(RESTMETHOD_priority, a.priority());