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 2021/02/14 16:57:32 UTC

[juneau] branch master updated: Add RemoteGet/RemotePut/RemotePost/RemoteDelete 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 ab2137f  Add RemoteGet/RemotePut/RemotePost/RemoteDelete annotations.
ab2137f is described below

commit ab2137f090bc904e9a210a1b98c04d876110984d
Author: JamesBognar <ja...@salesforce.com>
AuthorDate: Sun Feb 14 11:57:03 2021 -0500

    Add RemoteGet/RemotePut/RemotePost/RemoteDelete annotations.
---
 .../remote/{RemoteOp.java => RemoteDelete.java}    | 41 +++++----------------
 .../http/remote/{RemoteOp.java => RemoteGet.java}  | 41 +++++----------------
 .../org/apache/juneau/http/remote/RemoteOp.java    |  6 ++-
 .../http/remote/{RemoteOp.java => RemotePost.java} | 43 +++++-----------------
 .../http/remote/{RemoteOp.java => RemotePut.java}  | 42 +++++----------------
 .../org/apache/juneau/reflect/AnnotationList.java  | 12 ++++++
 .../rest/client/remote/RemoteOperationMeta.java    | 30 ++++++++-------
 .../rest/client/remote/RemoteOperationReturn.java  | 10 ++---
 8 files changed, 75 insertions(+), 150 deletions(-)

diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteOp.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteDelete.java
similarity index 78%
copy from juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteOp.java
copy to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteDelete.java
index 9ce91eb..e44b6e6 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteOp.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteDelete.java
@@ -18,6 +18,7 @@ import static java.lang.annotation.RetentionPolicy.*;
 import java.io.*;
 import java.lang.annotation.*;
 
+import org.apache.juneau.annotation.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,7 +35,8 @@ import org.apache.juneau.http.annotation.*;
 @Target(METHOD)
 @Retention(RUNTIME)
 @Inherited
-public @interface RemoteOp {
+@AnnotationGroup(RemoteOp.class)
+public @interface RemoteDelete {
 
 	/**
 	 * REST service path.
@@ -53,36 +55,16 @@ public @interface RemoteOp {
 	 * <h5 class='figure'>Example:</h5>
 	 * <p class='bcode'>
 	 * 	<jc>// POST /pet</jc>
-	 * 	<ja>@RemoteOp</ja>
+	 * 	<ja>@RemoteDelete</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.
+	 * Note that you can also use {@link #value()} to specify the path in shortened form.
 	 */
 	String path() default "";
 
 	/**
-	 * Defines the HTTP method to use for REST calls.
-	 *
-	 * <p>
-	 * If not specified, then the method is inferred from the Java method name.
-	 *
-	 * <h5 class='figure'>Example:</h5>
-	 * <p class='bcode'>
-	 * 	<jc>// POST /pet</jc>
-	 * 	<ja>@RemoteOp</ja>
-	 * 	<jk>public void</jk> postPet(...) {...}
-	 * </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 "";
-
-	/**
 	 * The value the remote method returns.
 	 *
 	 * <p>
@@ -121,25 +103,20 @@ public @interface RemoteOp {
 	RemoteReturn returns() default RemoteReturn.BODY;
 
 	/**
-	 * REST method name and path.
+	 * REST path.
 	 *
 	 * <p>
-	 * Can be used to provide a shortened combined form for the {@link #method()} and {@link #path()} values.
+	 * Can be used to provide a shortened form for the {@link #path()} value.
 	 *
 	 * <p>
 	 * The following examples are considered equivalent.
 	 * <p class='bcode w800'>
 	 * 	<jc>// Normal form</jc>
-	 * 	<ja>@RemoteOp</ja>(method=<jsf>PUT</jsf>, path=<js>"/{propertyName}"</js>)
+	 * 	<ja>@RemoteDelete</ja>(path=<js>"/{propertyName}"</js>)
 	 *
 	 * 	<jc>// Shortened form</jc>
-	 * 	<ja>@RemoteOp</ja>(<js>"PUT /{propertyName}"</js>)
+	 * 	<ja>@RemoteDelete</ja>(<js>"/{propertyName}"</js>)
 	 * </p>
-	 *
-	 * <ul class='notes'>
-	 * 	<li>
-	 * 		The path portion is optional.
-	 * </ul>
 	 */
 	String value() default "";
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteOp.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteGet.java
similarity index 79%
copy from juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteOp.java
copy to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteGet.java
index 9ce91eb..d375a7a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteOp.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteGet.java
@@ -18,6 +18,7 @@ import static java.lang.annotation.RetentionPolicy.*;
 import java.io.*;
 import java.lang.annotation.*;
 
+import org.apache.juneau.annotation.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,7 +35,8 @@ import org.apache.juneau.http.annotation.*;
 @Target(METHOD)
 @Retention(RUNTIME)
 @Inherited
-public @interface RemoteOp {
+@AnnotationGroup(RemoteOp.class)
+public @interface RemoteGet {
 
 	/**
 	 * REST service path.
@@ -53,8 +55,8 @@ public @interface RemoteOp {
 	 * <h5 class='figure'>Example:</h5>
 	 * <p class='bcode'>
 	 * 	<jc>// POST /pet</jc>
-	 * 	<ja>@RemoteOp</ja>
-	 * 	<jk>public void</jk> postPet(...) {...}
+	 * 	<ja>@RemoteGet</ja>
+	 * 	<jk>public</jk> Pet getPet(...);
 	 * </p>
 	 *
 	 * <p>
@@ -63,26 +65,6 @@ public @interface RemoteOp {
 	String path() default "";
 
 	/**
-	 * Defines the HTTP method to use for REST calls.
-	 *
-	 * <p>
-	 * If not specified, then the method is inferred from the Java method name.
-	 *
-	 * <h5 class='figure'>Example:</h5>
-	 * <p class='bcode'>
-	 * 	<jc>// POST /pet</jc>
-	 * 	<ja>@RemoteOp</ja>
-	 * 	<jk>public void</jk> postPet(...) {...}
-	 * </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 "";
-
-	/**
 	 * The value the remote method returns.
 	 *
 	 * <p>
@@ -121,25 +103,20 @@ public @interface RemoteOp {
 	RemoteReturn returns() default RemoteReturn.BODY;
 
 	/**
-	 * REST method name and path.
+	 * REST path.
 	 *
 	 * <p>
-	 * Can be used to provide a shortened combined form for the {@link #method()} and {@link #path()} values.
+	 * Can be used to provide a shortened form for the {@link #path()} value.
 	 *
 	 * <p>
 	 * The following examples are considered equivalent.
 	 * <p class='bcode w800'>
 	 * 	<jc>// Normal form</jc>
-	 * 	<ja>@RemoteOp</ja>(method=<jsf>PUT</jsf>, path=<js>"/{propertyName}"</js>)
+	 * 	<ja>@RemoteGet</ja>(path=<js>"/{propertyName}"</js>)
 	 *
 	 * 	<jc>// Shortened form</jc>
-	 * 	<ja>@RemoteOp</ja>(<js>"PUT /{propertyName}"</js>)
+	 * 	<ja>@RemoteGet</ja>(<js>"/{propertyName}"</js>)
 	 * </p>
-	 *
-	 * <ul class='notes'>
-	 * 	<li>
-	 * 		The path portion is optional.
-	 * </ul>
 	 */
 	String value() default "";
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteOp.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteOp.java
index 9ce91eb..ab84baf 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteOp.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteOp.java
@@ -18,6 +18,7 @@ import static java.lang.annotation.RetentionPolicy.*;
 import java.io.*;
 import java.lang.annotation.*;
 
+import org.apache.juneau.annotation.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,6 +35,7 @@ import org.apache.juneau.http.annotation.*;
 @Target(METHOD)
 @Retention(RUNTIME)
 @Inherited
+@AnnotationGroup(RemoteOp.class)
 public @interface RemoteOp {
 
 	/**
@@ -54,7 +56,7 @@ public @interface RemoteOp {
 	 * <p class='bcode'>
 	 * 	<jc>// POST /pet</jc>
 	 * 	<ja>@RemoteOp</ja>
-	 * 	<jk>public void</jk> postPet(...) {...}
+	 * 	<jk>public void</jk> postPet(...);
 	 * </p>
 	 *
 	 * <p>
@@ -72,7 +74,7 @@ public @interface RemoteOp {
 	 * <p class='bcode'>
 	 * 	<jc>// POST /pet</jc>
 	 * 	<ja>@RemoteOp</ja>
-	 * 	<jk>public void</jk> postPet(...) {...}
+	 * 	<jk>public void</jk> postPet(...);
 	 * </p>
 	 *
 	 * <br>If the method cannot be inferred, then the default is <js>"GET"</js>.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteOp.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemotePost.java
similarity index 77%
copy from juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteOp.java
copy to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemotePost.java
index 9ce91eb..8014c47 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteOp.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemotePost.java
@@ -18,6 +18,7 @@ import static java.lang.annotation.RetentionPolicy.*;
 import java.io.*;
 import java.lang.annotation.*;
 
+import org.apache.juneau.annotation.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,7 +35,8 @@ import org.apache.juneau.http.annotation.*;
 @Target(METHOD)
 @Retention(RUNTIME)
 @Inherited
-public @interface RemoteOp {
+@AnnotationGroup(RemoteOp.class)
+public @interface RemotePost {
 
 	/**
 	 * REST service path.
@@ -53,36 +55,16 @@ public @interface RemoteOp {
 	 * <h5 class='figure'>Example:</h5>
 	 * <p class='bcode'>
 	 * 	<jc>// POST /pet</jc>
-	 * 	<ja>@RemoteOp</ja>
-	 * 	<jk>public void</jk> postPet(...) {...}
+	 * 	<ja>@RemotePost</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.
+	 * Note that you can also use {@link #value()} to specify the path in shortened form.
 	 */
 	String path() default "";
 
 	/**
-	 * Defines the HTTP method to use for REST calls.
-	 *
-	 * <p>
-	 * If not specified, then the method is inferred from the Java method name.
-	 *
-	 * <h5 class='figure'>Example:</h5>
-	 * <p class='bcode'>
-	 * 	<jc>// POST /pet</jc>
-	 * 	<ja>@RemoteOp</ja>
-	 * 	<jk>public void</jk> postPet(...) {...}
-	 * </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 "";
-
-	/**
 	 * The value the remote method returns.
 	 *
 	 * <p>
@@ -121,25 +103,20 @@ public @interface RemoteOp {
 	RemoteReturn returns() default RemoteReturn.BODY;
 
 	/**
-	 * REST method name and path.
+	 * REST path.
 	 *
 	 * <p>
-	 * Can be used to provide a shortened combined form for the {@link #method()} and {@link #path()} values.
+	 * Can be used to provide a shortened form for the {@link #path()} value.
 	 *
 	 * <p>
 	 * The following examples are considered equivalent.
 	 * <p class='bcode w800'>
 	 * 	<jc>// Normal form</jc>
-	 * 	<ja>@RemoteOp</ja>(method=<jsf>PUT</jsf>, path=<js>"/{propertyName}"</js>)
+	 * 	<ja>@RemotePost</ja>(path=<js>"/{propertyName}"</js>)
 	 *
 	 * 	<jc>// Shortened form</jc>
-	 * 	<ja>@RemoteOp</ja>(<js>"PUT /{propertyName}"</js>)
+	 * 	<ja>@RemotePost</ja>(<js>"/{propertyName}"</js>)
 	 * </p>
-	 *
-	 * <ul class='notes'>
-	 * 	<li>
-	 * 		The path portion is optional.
-	 * </ul>
 	 */
 	String value() default "";
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteOp.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemotePut.java
similarity index 79%
copy from juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteOp.java
copy to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemotePut.java
index 9ce91eb..e8cb678 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemoteOp.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RemotePut.java
@@ -18,6 +18,7 @@ import static java.lang.annotation.RetentionPolicy.*;
 import java.io.*;
 import java.lang.annotation.*;
 
+import org.apache.juneau.annotation.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,7 +35,8 @@ import org.apache.juneau.http.annotation.*;
 @Target(METHOD)
 @Retention(RUNTIME)
 @Inherited
-public @interface RemoteOp {
+@AnnotationGroup(RemoteOp.class)
+public @interface RemotePut {
 
 	/**
 	 * REST service path.
@@ -52,9 +54,8 @@ public @interface RemoteOp {
 	 *
 	 * <h5 class='figure'>Example:</h5>
 	 * <p class='bcode'>
-	 * 	<jc>// POST /pet</jc>
-	 * 	<ja>@RemoteOp</ja>
-	 * 	<jk>public void</jk> postPet(...) {...}
+	 * 	<ja>@RemotePut</ja>
+	 * 	<jk>public void</jk> putPet(...);
 	 * </p>
 	 *
 	 * <p>
@@ -63,26 +64,6 @@ public @interface RemoteOp {
 	String path() default "";
 
 	/**
-	 * Defines the HTTP method to use for REST calls.
-	 *
-	 * <p>
-	 * If not specified, then the method is inferred from the Java method name.
-	 *
-	 * <h5 class='figure'>Example:</h5>
-	 * <p class='bcode'>
-	 * 	<jc>// POST /pet</jc>
-	 * 	<ja>@RemoteOp</ja>
-	 * 	<jk>public void</jk> postPet(...) {...}
-	 * </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 "";
-
-	/**
 	 * The value the remote method returns.
 	 *
 	 * <p>
@@ -121,25 +102,20 @@ public @interface RemoteOp {
 	RemoteReturn returns() default RemoteReturn.BODY;
 
 	/**
-	 * REST method name and path.
+	 * REST path.
 	 *
 	 * <p>
-	 * Can be used to provide a shortened combined form for the {@link #method()} and {@link #path()} values.
+	 * Can be used to provide a shortened form for the {@link #path()} value.
 	 *
 	 * <p>
 	 * The following examples are considered equivalent.
 	 * <p class='bcode w800'>
 	 * 	<jc>// Normal form</jc>
-	 * 	<ja>@RemoteOp</ja>(method=<jsf>PUT</jsf>, path=<js>"/{propertyName}"</js>)
+	 * 	<ja>@RemotePut</ja>(path=<js>"/{propertyName}"</js>)
 	 *
 	 * 	<jc>// Shortened form</jc>
-	 * 	<ja>@RemoteOp</ja>(<js>"PUT /{propertyName}"</js>)
+	 * 	<ja>@RemotePut</ja>(<js>"/{propertyName}"</js>)
 	 * </p>
-	 *
-	 * <ul class='notes'>
-	 * 	<li>
-	 * 		The path portion is optional.
-	 * </ul>
 	 */
 	String value() default "";
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/AnnotationList.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/AnnotationList.java
index e400048..57749fe 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/AnnotationList.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/AnnotationList.java
@@ -83,4 +83,16 @@ public class AnnotationList extends ArrayList<AnnotationInfo<?>> {
 		}
 		return l;
 	}
+
+	/**
+	 * Filters this list using the specified test.
+	 *
+	 * @param test The test to use to filter this list.
+	 * @return A new list containing only the filtered elements.
+	 */
+	public AnnotationList filter(Predicate<AnnotationInfo<?>> test) {
+		AnnotationList al = new AnnotationList(null);
+		stream().filter(test).forEach(x->al.add(x));
+		return al;
+	}
 }
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationMeta.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationMeta.java
index 3991332..2dbdfa7 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationMeta.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationMeta.java
@@ -83,22 +83,26 @@ public class RemoteOperationMeta {
 
 			MethodInfo mi = MethodInfo.of(m);
 
-			RemoteOp op = mi.getLastAnnotation(RemoteOp.class);
-			if (op == null)
-				op = mi.getReturnType().unwrap(Value.class,Optional.class).getLastAnnotation(RemoteOp.class);
-
-			httpMethod = op == null ? "" : op.method();
-			path = op == null ? "" : op.path();
-
-			if (op != null && ! op.value().isEmpty()) {
-				String v = op.value().trim();
-				int i = v.indexOf(' ');
+			AnnotationList al = mi.getAnnotationGroupList(RemoteOp.class);
+			if (al.isEmpty())
+				al = mi.getReturnType().unwrap(Value.class,Optional.class).getAnnotationGroupList(RemoteOp.class);
+
+			httpMethod = al.getValues(String.class, "method").stream().filter(x -> isNotEmpty(x)).findFirst().orElse("").trim();
+			path = al.getValues(String.class, "path").stream().filter(x -> isNotEmpty(x)).findFirst().orElse("").trim();
+
+			String value1 = al.filter(x->x.isType(RemoteOp.class)).getValues(String.class, "value").stream().filter(x -> isNotEmpty(x)).findFirst().orElse("").trim();
+			String value2 = al.filter(x->!x.isType(RemoteOp.class)).getValues(String.class, "value").stream().filter(x -> isNotEmpty(x)).findFirst().orElse("").trim();
+			
+			if (isNotEmpty(value1)) {
+				int i = value1.indexOf(' ');
 				if (i == -1) {
-					httpMethod = v;
+					httpMethod = value1;
 				} else {
-					httpMethod = v.substring(0, i).trim();
-					path = v.substring(i).trim();
+					httpMethod = value1.substring(0, i).trim();
+					path = value1.substring(i).trim();
 				}
+			} else if (isNotEmpty(value2)) {
+				path = value2;
 			}
 
 			if (path.isEmpty()) {
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationReturn.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationReturn.java
index 7e2fd51..8987fe2 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationReturn.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationReturn.java
@@ -40,9 +40,9 @@ public final class RemoteOperationReturn {
 	RemoteOperationReturn(MethodInfo m) {
 		ClassInfo rt = m.getReturnType();
 
-		RemoteOp op = m.getLastAnnotation(RemoteOp.class);
-		if (op == null)
-			op = m.getReturnType().unwrap(Value.class,Optional.class).getLastAnnotation(RemoteOp.class);
+		AnnotationList al = m.getAnnotationGroupList(RemoteOp.class);
+		if (al.isEmpty())
+			al = m.getReturnType().unwrap(Value.class,Optional.class).getAnnotationGroupList(RemoteOp.class);
 
 		RemoteReturn rv = null;
 
@@ -56,8 +56,8 @@ public final class RemoteOperationReturn {
 
 		if (rt.is(void.class) || rt.is(Void.class))
 			rv = RemoteReturn.NONE;
-		else if (op != null)
-			rv = op.returns();
+		else if (! al.isEmpty())
+			rv = al.getValues(RemoteReturn.class,"returns").stream().findFirst().orElse(RemoteReturn.BODY);
 		else
 			rv = RemoteReturn.BODY;