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 2017/06/02 00:00:30 UTC
[1/3] incubator-juneau git commit: Improvements to
@Query/@FormData/@Header/@Path remoteable annotations.
Repository: incubator-juneau
Updated Branches:
refs/heads/master 13f816fb6 -> 93aadae1d
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RequestBeanProxyTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RequestBeanProxyTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RequestBeanProxyTest.java
new file mode 100644
index 0000000..93403fb
--- /dev/null
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RequestBeanProxyTest.java
@@ -0,0 +1,1988 @@
+// ***************************************************************************************************************************
+// * 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.juneau.rest.test;
+
+import static org.junit.Assert.*;
+
+import java.io.*;
+import java.util.*;
+
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.plaintext.*;
+import org.apache.juneau.remoteable.*;
+import org.apache.juneau.rest.client.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.utils.*;
+import org.junit.*;
+import org.junit.runners.*;
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class RequestBeanProxyTest extends RestTestcase {
+
+ private <T> T getProxyPlainText(Class<T> t) {
+ RestClient rc = TestMicroservice.client(PlainTextSerializer.class, PlainTextParser.class).plainTextParts().build();
+ addClientToLifecycle(rc);
+ return rc.getRemoteableProxy(t, null);
+ }
+
+ private <T> T getProxyUon(Class<T> t) {
+ RestClient rc = TestMicroservice.client(PlainTextSerializer.class, PlainTextParser.class).build();
+ addClientToLifecycle(rc);
+ return rc.getRemoteableProxy(t, null);
+ }
+
+ //-------------------------------------------------------------------------------------------------------------------
+ // @Query
+ //-------------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void a01_querySimpleValsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_Query.class).querySimpleValsPlainText(new RequestBean_QuerySimpleVals());
+ assertEquals("{a:'a1',b:'b1',c:'c1',d:'d1',e:'',g:'true',h:'123'}", r);
+ }
+
+ @Test
+ public void a02_querySimpleValsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Query.class).querySimpleValsUon(new RequestBean_QuerySimpleVals());
+ assertEquals("{a:'a1',b:'b1',c:'c1',d:'d1',e:'',g:'\\'true\\'',h:'\\'123\\''}", r);
+ }
+
+ @Test
+ public void a03_querySimpleValsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Query.class).querySimpleValsX(new RequestBean_QuerySimpleVals());
+ assertEquals("{a:'xa1x',b:'xb1x',c:'xc1x',d:'xd1x',e:'xx',g:'xtruex',h:'x123x'}", r);
+ }
+
+ @Test
+ public void a04_queryMapsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_Query.class).queryMapsPlainText(new RequestBean_QueryMaps());
+ assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
+ }
+
+ @Test
+ public void a05_queryMapsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Query.class).queryMapsUon(new RequestBean_QueryMaps());
+ assertEquals("{a1:'v1',a2:'123',a4:'',b1:'\\'true\\'',b2:'\\'123\\'',b3:'\\'null\\'',c1:'v1',c2:'123',c4:''}", r);
+ }
+
+ @Test
+ public void a06_queryMapsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Query.class).queryMapsX(new RequestBean_QueryMaps());
+ assertEquals("{a1:'xv1x',a2:'x123x',a4:'xx',b1:'xtruex',b2:'x123x',b3:'xnullx',c1:'xv1x',c2:'x123x',c4:'xx'}", r);
+ }
+
+ @Test
+ public void a07_queryNameValuePairsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_Query.class).queryNameValuePairsPlainText(new RequestBean_QueryNameValuePairs());
+ assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
+ }
+
+ @Test
+ public void a08_queryNameValuePairsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Query.class).queryNameValuePairsUon(new RequestBean_QueryNameValuePairs());
+ assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
+ }
+
+ @Test
+ public void a09_queryNameValuePairsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Query.class).queryNameValuePairsX(new RequestBean_QueryNameValuePairs());
+ assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
+ }
+
+ @Test
+ public void a10_queryCharSequence() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Query.class).queryCharSequence(new RequestBean_QueryCharSequence());
+ assertEquals("{baz:'qux',foo:'bar'}", r);
+ }
+
+ @Test
+ public void a11_queryReader() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Query.class).queryReader(new RequestBean_QueryReader());
+ assertEquals("{baz:'qux',foo:'bar'}", r);
+ }
+
+ @Test
+ public void a12_queryCollectionsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_Query.class).queryCollectionsPlainText(new RequestBean_QueryCollections());
+ assertEquals("{a:'foo,,true,123,null,true,123,null',b:'foo,,true,123,null,true,123,null',c:'foo||true|123|null|true|123|null',d:'',f:'foo,,true,123,null,true,123,null',g:'foo||true|123|null|true|123|null',h:''}", r);
+ }
+
+ @Test
+ public void a13_queryCollectionsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Query.class).queryCollectionsUon(new RequestBean_QueryCollections());
+ assertEquals("{a:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',b:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',c:'foo||true|123|null|true|123|null',d:'@()',f:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',g:'foo||true|123|null|true|123|null',h:'@()'}", r);
+ }
+
+ @Test
+ public void a14_queryCollectionsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Query.class).queryCollectionsX(new RequestBean_QueryCollections());
+ assertEquals("{a:'fooXXtrueX123XnullXtrueX123Xnull',b:'fooXXtrueX123XnullXtrueX123Xnull',c:'fooXXtrueX123XnullXtrueX123Xnull',d:'',f:'fooXXtrueX123XnullXtrueX123Xnull',g:'fooXXtrueX123XnullXtrueX123Xnull',h:''}", r);
+ }
+
+ @Remoteable(path="/testRequestBeanProxy")
+ public static interface RequestBeanProxy_Query {
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String querySimpleValsPlainText(@RequestBean RequestBean_QuerySimpleVals rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String querySimpleValsUon(@RequestBean RequestBean_QuerySimpleVals rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String querySimpleValsX(@RequestBean(serializer=XSerializer.class) RequestBean_QuerySimpleVals rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryMapsPlainText(@RequestBean RequestBean_QueryMaps rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryMapsUon(@RequestBean RequestBean_QueryMaps rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryMapsX(@RequestBean(serializer=XSerializer.class) RequestBean_QueryMaps rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryNameValuePairsPlainText(@RequestBean RequestBean_QueryNameValuePairs rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryNameValuePairsUon(@RequestBean RequestBean_QueryNameValuePairs rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryNameValuePairsX(@RequestBean(serializer=XSerializer.class) RequestBean_QueryNameValuePairs rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryCharSequence(@RequestBean RequestBean_QueryCharSequence rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryReader(@RequestBean RequestBean_QueryReader rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryCollectionsPlainText(@RequestBean RequestBean_QueryCollections rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryCollectionsUon(@RequestBean RequestBean_QueryCollections rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryCollectionsX(@RequestBean(serializer=XSerializer.class) RequestBean_QueryCollections rb);
+ }
+
+ public static class RequestBean_QuerySimpleVals {
+
+ @Query
+ public String getA() {
+ return "a1";
+ }
+
+ @Query("b")
+ public String getX1() {
+ return "b1";
+ }
+
+ @Query(name="c")
+ public String getX2() {
+ return "c1";
+ }
+
+ @Query
+ @BeanProperty("d")
+ public String getX3() {
+ return "d1";
+ }
+
+ @Query("e")
+ public String getX4() {
+ return "";
+ }
+
+ @Query("f")
+ public String getX5() {
+ return null;
+ }
+
+ @Query("g")
+ public String getX6() {
+ return "true";
+ }
+
+ @Query("h")
+ public String getX7() {
+ return "123";
+ }
+ }
+
+ public static class RequestBean_QueryMaps {
+
+ @Query
+ public Map<String,Object> getA() {
+ return new AMap<String,Object>().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
+ }
+
+ @Query("*")
+ public Map<String,Object> getB() {
+ return new AMap<String,Object>().append("b1","true").append("b2", "123").append("b3", "null");
+ }
+
+ @Query(name="*")
+ public Map<String,Object> getC() {
+ return new AMap<String,Object>().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
+ }
+
+ @Query("*")
+ public Map<String,Object> getD() {
+ return null;
+ }
+ }
+
+ public static class RequestBean_QueryNameValuePairs {
+
+ @Query
+ public NameValuePairs getA() {
+ return new NameValuePairs().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
+ }
+
+ @Query("*")
+ public NameValuePairs getB() {
+ return new NameValuePairs().append("b1","true").append("b2", "123").append("b3", "null");
+ }
+
+ @Query(name="*")
+ public NameValuePairs getC() {
+ return new NameValuePairs().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
+ }
+
+ @Query("*")
+ public NameValuePairs getD() {
+ return null;
+ }
+ }
+
+ public static class RequestBean_QueryCharSequence {
+
+ @Query("*")
+ public StringBuilder getA() {
+ return new StringBuilder("foo=bar&baz=qux");
+ }
+ }
+
+ public static class RequestBean_QueryReader {
+
+ @Query("*")
+ public Reader getA() {
+ return new StringReader("foo=bar&baz=qux");
+ }
+ }
+
+ public static class RequestBean_QueryCollections {
+
+ @Query
+ public List<Object> getA() {
+ return new AList<Object>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
+ }
+
+ @Query("b")
+ public List<Object> getX1() {
+ return new AList<Object>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
+ }
+
+ @Query(name="c", serializer=ListSerializer.class)
+ public List<Object> getX2() {
+ return new AList<Object>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
+ }
+
+ @Query("d")
+ public List<Object> getX3() {
+ return new AList<Object>();
+ }
+
+ @Query("e")
+ public List<Object> getX4() {
+ return null;
+ }
+
+ @Query("f")
+ public Object[] getX5() {
+ return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
+ }
+
+ @Query(name="g", serializer=ListSerializer.class)
+ public Object[] getX6() {
+ return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
+ }
+
+ @Query("h")
+ public Object[] getX7() {
+ return new Object[]{};
+ }
+
+ @Query("i")
+ public Object[] getX8() {
+ return null;
+ }
+ }
+
+ //-------------------------------------------------------------------------------------------------------------------
+ // @QueryIfNE
+ //-------------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void b01_queryIfNESimpleValsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_QueryIfNE.class).querySimpleValsPlainText(new RequestBean_QueryIfNESimpleVals());
+ assertEquals("{a:'a1',b:'b1',c:'c1',d:'d1',g:'true',h:'123'}", r);
+ }
+
+ @Test
+ public void b02_queryIfNESimpleValsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_QueryIfNE.class).querySimpleValsUon(new RequestBean_QueryIfNESimpleVals());
+ assertEquals("{a:'a1',b:'b1',c:'c1',d:'d1',g:'\\'true\\'',h:'\\'123\\''}", r);
+ }
+
+ @Test
+ public void b03_queryIfNESimpleValsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_QueryIfNE.class).querySimpleValsX(new RequestBean_QueryIfNESimpleVals());
+ assertEquals("{a:'xa1x',b:'xb1x',c:'xc1x',d:'xd1x',g:'xtruex',h:'x123x'}", r);
+ }
+
+ @Test
+ public void b04_queryIfNEMapsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_QueryIfNE.class).queryMapsPlainText(new RequestBean_QueryIfNEMaps());
+ assertEquals("{a1:'v1',a2:'123',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123'}", r);
+ }
+
+ @Test
+ public void b05_queryIfNEMapsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_QueryIfNE.class).queryMapsUon(new RequestBean_QueryIfNEMaps());
+ assertEquals("{a1:'v1',a2:'123',b1:'\\'true\\'',b2:'\\'123\\'',b3:'\\'null\\'',c1:'v1',c2:'123'}", r);
+ }
+
+ @Test
+ public void b06_queryIfNEMapsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_QueryIfNE.class).queryMapsX(new RequestBean_QueryIfNEMaps());
+ assertEquals("{a1:'xv1x',a2:'x123x',b1:'xtruex',b2:'x123x',b3:'xnullx',c1:'xv1x',c2:'x123x'}", r);
+ }
+
+ @Test
+ public void b07_queryIfNENameValuePairsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_QueryIfNE.class).queryNameValuePairsPlainText(new RequestBean_QueryIfNENameValuePairs());
+ assertEquals("{a1:'v1',a2:'123',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123'}", r);
+ }
+
+ @Test
+ public void b08_queryIfNENameValuePairsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_QueryIfNE.class).queryNameValuePairsUon(new RequestBean_QueryIfNENameValuePairs());
+ assertEquals("{a1:'v1',a2:'123',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123'}", r);
+ }
+
+ @Test
+ public void b09_queryIfNENameValuePairsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_QueryIfNE.class).queryNameValuePairsX(new RequestBean_QueryIfNENameValuePairs());
+ assertEquals("{a1:'v1',a2:'123',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123'}", r);
+ }
+
+ @Test
+ public void b10_queryIfNECharSequence() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_QueryIfNE.class).queryCharSequence(new RequestBean_QueryIfNECharSequence());
+ assertEquals("{baz:'qux',foo:'bar'}", r);
+ }
+
+ @Test
+ public void b11_queryIfNEReader() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_QueryIfNE.class).queryReader(new RequestBean_QueryIfNEReader());
+ assertEquals("{baz:'qux',foo:'bar'}", r);
+ }
+
+ @Test
+ public void b12_queryIfNECollectionsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_QueryIfNE.class).queryCollectionsPlainText(new RequestBean_QueryIfNECollections());
+ assertEquals("{a:'foo,,true,123,null,true,123,null',b:'foo,,true,123,null,true,123,null',c:'foo||true|123|null|true|123|null',f:'foo,,true,123,null,true,123,null',g:'foo||true|123|null|true|123|null'}", r);
+ }
+
+ @Test
+ public void b13_queryIfNECollectionsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_QueryIfNE.class).queryCollectionsUon(new RequestBean_QueryIfNECollections());
+ assertEquals("{a:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',b:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',c:'foo||true|123|null|true|123|null',f:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',g:'foo||true|123|null|true|123|null'}", r);
+ }
+
+ @Test
+ public void b14_queryIfNECollectionsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_QueryIfNE.class).queryCollectionsX(new RequestBean_QueryIfNECollections());
+ assertEquals("{a:'fooXXtrueX123XnullXtrueX123Xnull',b:'fooXXtrueX123XnullXtrueX123Xnull',c:'fooXXtrueX123XnullXtrueX123Xnull',f:'fooXXtrueX123XnullXtrueX123Xnull',g:'fooXXtrueX123XnullXtrueX123Xnull'}", r);
+ }
+
+ @Remoteable(path="/testRequestBeanProxy")
+ public static interface RequestBeanProxy_QueryIfNE {
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String querySimpleValsPlainText(@RequestBean RequestBean_QueryIfNESimpleVals rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String querySimpleValsUon(@RequestBean RequestBean_QueryIfNESimpleVals rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String querySimpleValsX(@RequestBean(serializer=XSerializer.class) RequestBean_QueryIfNESimpleVals rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryMapsPlainText(@RequestBean RequestBean_QueryIfNEMaps rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryMapsUon(@RequestBean RequestBean_QueryIfNEMaps rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryMapsX(@RequestBean(serializer=XSerializer.class) RequestBean_QueryIfNEMaps rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryNameValuePairsPlainText(@RequestBean RequestBean_QueryIfNENameValuePairs rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryNameValuePairsUon(@RequestBean RequestBean_QueryIfNENameValuePairs rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryNameValuePairsX(@RequestBean(serializer=XSerializer.class) RequestBean_QueryIfNENameValuePairs rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryCharSequence(@RequestBean RequestBean_QueryIfNECharSequence rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryReader(@RequestBean RequestBean_QueryIfNEReader rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryCollectionsPlainText(@RequestBean RequestBean_QueryIfNECollections rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryCollectionsUon(@RequestBean RequestBean_QueryIfNECollections rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoQuery")
+ String queryCollectionsX(@RequestBean(serializer=XSerializer.class) RequestBean_QueryIfNECollections rb);
+ }
+
+ public static class RequestBean_QueryIfNESimpleVals {
+
+ @QueryIfNE
+ public String getA() {
+ return "a1";
+ }
+
+ @QueryIfNE("b")
+ public String getX1() {
+ return "b1";
+ }
+
+ @QueryIfNE(name="c")
+ public String getX2() {
+ return "c1";
+ }
+
+ @QueryIfNE
+ @BeanProperty("d")
+ public String getX3() {
+ return "d1";
+ }
+
+ @QueryIfNE("e")
+ public String getX4() {
+ return "";
+ }
+
+ @QueryIfNE("f")
+ public String getX5() {
+ return null;
+ }
+
+ @QueryIfNE("g")
+ public String getX6() {
+ return "true";
+ }
+
+ @QueryIfNE("h")
+ public String getX7() {
+ return "123";
+ }
+ }
+
+ public static class RequestBean_QueryIfNEMaps {
+
+ @QueryIfNE
+ public Map<String,Object> getA() {
+ return new AMap<String,Object>().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
+ }
+
+ @QueryIfNE("*")
+ public Map<String,Object> getB() {
+ return new AMap<String,Object>().append("b1","true").append("b2", "123").append("b3", "null");
+ }
+
+ @QueryIfNE(name="*")
+ public Map<String,Object> getC() {
+ return new AMap<String,Object>().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
+ }
+
+ @QueryIfNE("*")
+ public Map<String,Object> getD() {
+ return null;
+ }
+ }
+
+ public static class RequestBean_QueryIfNENameValuePairs {
+
+ @QueryIfNE
+ public NameValuePairs getA() {
+ return new NameValuePairs().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
+ }
+
+ @QueryIfNE("*")
+ public NameValuePairs getB() {
+ return new NameValuePairs().append("b1","true").append("b2", "123").append("b3", "null");
+ }
+
+ @QueryIfNE(name="*")
+ public NameValuePairs getC() {
+ return new NameValuePairs().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
+ }
+
+ @QueryIfNE("*")
+ public NameValuePairs getD() {
+ return null;
+ }
+ }
+
+ public static class RequestBean_QueryIfNECharSequence {
+
+ @QueryIfNE("*")
+ public StringBuilder getA() {
+ return new StringBuilder("foo=bar&baz=qux");
+ }
+ }
+
+ public static class RequestBean_QueryIfNEReader {
+
+ @QueryIfNE("*")
+ public Reader getA() {
+ return new StringReader("foo=bar&baz=qux");
+ }
+ }
+
+ public static class RequestBean_QueryIfNECollections {
+
+ @QueryIfNE
+ public List<Object> getA() {
+ return new AList<Object>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
+ }
+
+ @QueryIfNE("b")
+ public List<Object> getX1() {
+ return new AList<Object>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
+ }
+
+ @QueryIfNE(name="c", serializer=ListSerializer.class)
+ public List<Object> getX2() {
+ return new AList<Object>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
+ }
+
+ @QueryIfNE("d")
+ public List<Object> getX3() {
+ return new AList<Object>();
+ }
+
+ @QueryIfNE("e")
+ public List<Object> getX4() {
+ return null;
+ }
+
+ @QueryIfNE("f")
+ public Object[] getX5() {
+ return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
+ }
+
+ @QueryIfNE(name="g", serializer=ListSerializer.class)
+ public Object[] getX6() {
+ return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
+ }
+
+ @QueryIfNE("h")
+ public Object[] getX7() {
+ return new Object[]{};
+ }
+
+ @QueryIfNE("i")
+ public Object[] getX8() {
+ return null;
+ }
+ }
+
+ //-------------------------------------------------------------------------------------------------------------------
+ // @FormData
+ //-------------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void c01_formDataSimpleValsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_FormData.class).formDataSimpleValsPlainText(new RequestBean_FormDataSimpleVals());
+ assertEquals("{a:'a1',b:'b1',c:'c1',d:'d1',e:'',g:'true',h:'123'}", r);
+ }
+
+ @Test
+ public void c02_formDataSimpleValsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_FormData.class).formDataSimpleValsUon(new RequestBean_FormDataSimpleVals());
+ assertEquals("{a:'a1',b:'b1',c:'c1',d:'d1',e:'',g:'\\'true\\'',h:'\\'123\\''}", r);
+ }
+
+ @Test
+ public void c03_formDataSimpleValsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_FormData.class).formDataSimpleValsX(new RequestBean_FormDataSimpleVals());
+ assertEquals("{a:'xa1x',b:'xb1x',c:'xc1x',d:'xd1x',e:'xx',g:'xtruex',h:'x123x'}", r);
+ }
+
+ @Test
+ public void c04_formDataMapsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_FormData.class).formDataMapsPlainText(new RequestBean_FormDataMaps());
+ assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
+ }
+
+ @Test
+ public void c05_formDataMapsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_FormData.class).formDataMapsUon(new RequestBean_FormDataMaps());
+ assertEquals("{a1:'v1',a2:'123',a4:'',b1:'\\'true\\'',b2:'\\'123\\'',b3:'\\'null\\'',c1:'v1',c2:'123',c4:''}", r);
+ }
+
+ @Test
+ public void c06_formDataMapsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_FormData.class).formDataMapsX(new RequestBean_FormDataMaps());
+ assertEquals("{a1:'xv1x',a2:'x123x',a4:'xx',b1:'xtruex',b2:'x123x',b3:'xnullx',c1:'xv1x',c2:'x123x',c4:'xx'}", r);
+ }
+
+ @Test
+ public void c07_formDataNameValuePairsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_FormData.class).formDataNameValuePairsPlainText(new RequestBean_FormDataNameValuePairs());
+ assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
+ }
+
+ @Test
+ public void c08_formDataNameValuePairsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_FormData.class).formDataNameValuePairsUon(new RequestBean_FormDataNameValuePairs());
+ assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
+ }
+
+ @Test
+ public void c09_formDataNameValuePairsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_FormData.class).formDataNameValuePairsX(new RequestBean_FormDataNameValuePairs());
+ assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
+ }
+
+ @Test
+ public void c10_formDataCharSequence() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_FormData.class).formDataCharSequence(new RequestBean_FormDataCharSequence());
+ assertEquals("{baz:'qux',foo:'bar'}", r);
+ }
+
+ @Test
+ public void c11_formDataReader() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_FormData.class).formDataReader(new RequestBean_FormDataReader());
+ assertEquals("{baz:'qux',foo:'bar'}", r);
+ }
+
+ @Test
+ public void c12_formDataCollectionsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_FormData.class).formDataCollectionsPlainText(new RequestBean_FormDataCollections());
+ assertEquals("{a:'foo,,true,123,null,true,123,null',b:'foo,,true,123,null,true,123,null',c:'foo||true|123|null|true|123|null',d:'',f:'foo,,true,123,null,true,123,null',g:'foo||true|123|null|true|123|null',h:''}", r);
+ }
+
+ @Test
+ public void c13_formDataCollectionsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_FormData.class).formDataCollectionsUon(new RequestBean_FormDataCollections());
+ assertEquals("{a:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',b:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',c:'foo||true|123|null|true|123|null',d:'@()',f:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',g:'foo||true|123|null|true|123|null',h:'@()'}", r);
+ }
+
+ @Test
+ public void c14_formDataCollectionsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_FormData.class).formDataCollectionsX(new RequestBean_FormDataCollections());
+ assertEquals("{a:'fooXXtrueX123XnullXtrueX123Xnull',b:'fooXXtrueX123XnullXtrueX123Xnull',c:'fooXXtrueX123XnullXtrueX123Xnull',d:'',f:'fooXXtrueX123XnullXtrueX123Xnull',g:'fooXXtrueX123XnullXtrueX123Xnull',h:''}", r);
+ }
+
+ @Remoteable(path="/testRequestBeanProxy")
+ public static interface RequestBeanProxy_FormData {
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataSimpleValsPlainText(@RequestBean RequestBean_FormDataSimpleVals rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataSimpleValsUon(@RequestBean RequestBean_FormDataSimpleVals rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataSimpleValsX(@RequestBean(serializer=XSerializer.class) RequestBean_FormDataSimpleVals rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataMapsPlainText(@RequestBean RequestBean_FormDataMaps rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataMapsUon(@RequestBean RequestBean_FormDataMaps rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataMapsX(@RequestBean(serializer=XSerializer.class) RequestBean_FormDataMaps rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataNameValuePairsPlainText(@RequestBean RequestBean_FormDataNameValuePairs rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataNameValuePairsUon(@RequestBean RequestBean_FormDataNameValuePairs rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataNameValuePairsX(@RequestBean(serializer=XSerializer.class) RequestBean_FormDataNameValuePairs rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataCharSequence(@RequestBean RequestBean_FormDataCharSequence rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataReader(@RequestBean RequestBean_FormDataReader rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataCollectionsPlainText(@RequestBean RequestBean_FormDataCollections rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataCollectionsUon(@RequestBean RequestBean_FormDataCollections rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataCollectionsX(@RequestBean(serializer=XSerializer.class) RequestBean_FormDataCollections rb);
+ }
+
+ public static class RequestBean_FormDataSimpleVals {
+
+ @FormData
+ public String getA() {
+ return "a1";
+ }
+
+ @FormData("b")
+ public String getX1() {
+ return "b1";
+ }
+
+ @FormData(name="c")
+ public String getX2() {
+ return "c1";
+ }
+
+ @FormData
+ @BeanProperty("d")
+ public String getX3() {
+ return "d1";
+ }
+
+ @FormData("e")
+ public String getX4() {
+ return "";
+ }
+
+ @FormData("f")
+ public String getX5() {
+ return null;
+ }
+
+ @FormData("g")
+ public String getX6() {
+ return "true";
+ }
+
+ @FormData("h")
+ public String getX7() {
+ return "123";
+ }
+ }
+
+ public static class RequestBean_FormDataMaps {
+
+ @FormData
+ public Map<String,Object> getA() {
+ return new AMap<String,Object>().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
+ }
+
+ @FormData("*")
+ public Map<String,Object> getB() {
+ return new AMap<String,Object>().append("b1","true").append("b2", "123").append("b3", "null");
+ }
+
+ @FormData(name="*")
+ public Map<String,Object> getC() {
+ return new AMap<String,Object>().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
+ }
+
+ @FormData("*")
+ public Map<String,Object> getD() {
+ return null;
+ }
+ }
+
+ public static class RequestBean_FormDataNameValuePairs {
+
+ @FormData
+ public NameValuePairs getA() {
+ return new NameValuePairs().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
+ }
+
+ @FormData("*")
+ public NameValuePairs getB() {
+ return new NameValuePairs().append("b1","true").append("b2", "123").append("b3", "null");
+ }
+
+ @FormData(name="*")
+ public NameValuePairs getC() {
+ return new NameValuePairs().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
+ }
+
+ @FormData("*")
+ public NameValuePairs getD() {
+ return null;
+ }
+ }
+
+ public static class RequestBean_FormDataCharSequence {
+
+ @FormData("*")
+ public StringBuilder getA() {
+ return new StringBuilder("foo=bar&baz=qux");
+ }
+ }
+
+ public static class RequestBean_FormDataReader {
+
+ @FormData("*")
+ public Reader getA() {
+ return new StringReader("foo=bar&baz=qux");
+ }
+ }
+
+ public static class RequestBean_FormDataCollections {
+
+ @FormData
+ public List<Object> getA() {
+ return new AList<Object>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
+ }
+
+ @FormData("b")
+ public List<Object> getX1() {
+ return new AList<Object>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
+ }
+
+ @FormData(name="c", serializer=ListSerializer.class)
+ public List<Object> getX2() {
+ return new AList<Object>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
+ }
+
+ @FormData("d")
+ public List<Object> getX3() {
+ return new AList<Object>();
+ }
+
+ @FormData("e")
+ public List<Object> getX4() {
+ return null;
+ }
+
+ @FormData("f")
+ public Object[] getX5() {
+ return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
+ }
+
+ @FormData(name="g", serializer=ListSerializer.class)
+ public Object[] getX6() {
+ return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
+ }
+
+ @FormData("h")
+ public Object[] getX7() {
+ return new Object[]{};
+ }
+
+ @FormData("i")
+ public Object[] getX8() {
+ return null;
+ }
+ }
+
+ //-------------------------------------------------------------------------------------------------------------------
+ // @FormDataIfNE
+ //-------------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void d01_formDataIfNESimpleValsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_FormDataIfNE.class).formDataSimpleValsPlainText(new RequestBean_FormDataIfNESimpleVals());
+ assertEquals("{a:'a1',b:'b1',c:'c1',d:'d1',g:'true',h:'123'}", r);
+ }
+
+ @Test
+ public void d02_formDataIfNESimpleValsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_FormDataIfNE.class).formDataSimpleValsUon(new RequestBean_FormDataIfNESimpleVals());
+ assertEquals("{a:'a1',b:'b1',c:'c1',d:'d1',g:'\\'true\\'',h:'\\'123\\''}", r);
+ }
+
+ @Test
+ public void d03_formDataIfNESimpleValsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_FormDataIfNE.class).formDataSimpleValsX(new RequestBean_FormDataIfNESimpleVals());
+ assertEquals("{a:'xa1x',b:'xb1x',c:'xc1x',d:'xd1x',g:'xtruex',h:'x123x'}", r);
+ }
+
+ @Test
+ public void d04_formDataIfNEMapsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_FormDataIfNE.class).formDataMapsPlainText(new RequestBean_FormDataIfNEMaps());
+ assertEquals("{a1:'v1',a2:'123',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123'}", r);
+ }
+
+ @Test
+ public void d05_formDataIfNEMapsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_FormDataIfNE.class).formDataMapsUon(new RequestBean_FormDataIfNEMaps());
+ assertEquals("{a1:'v1',a2:'123',b1:'\\'true\\'',b2:'\\'123\\'',b3:'\\'null\\'',c1:'v1',c2:'123'}", r);
+ }
+
+ @Test
+ public void d06_formDataIfNEMapsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_FormDataIfNE.class).formDataMapsX(new RequestBean_FormDataIfNEMaps());
+ assertEquals("{a1:'xv1x',a2:'x123x',b1:'xtruex',b2:'x123x',b3:'xnullx',c1:'xv1x',c2:'x123x'}", r);
+ }
+
+ @Test
+ public void d07_formDataIfNENameValuePairsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_FormDataIfNE.class).formDataNameValuePairsPlainText(new RequestBean_FormDataIfNENameValuePairs());
+ assertEquals("{a1:'v1',a2:'123',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123'}", r);
+ }
+
+ @Test
+ public void d08_formDataIfNENameValuePairsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_FormDataIfNE.class).formDataNameValuePairsUon(new RequestBean_FormDataIfNENameValuePairs());
+ assertEquals("{a1:'v1',a2:'123',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123'}", r);
+ }
+
+ @Test
+ public void d09_formDataIfNENameValuePairsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_FormDataIfNE.class).formDataNameValuePairsX(new RequestBean_FormDataIfNENameValuePairs());
+ assertEquals("{a1:'v1',a2:'123',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123'}", r);
+ }
+
+ @Test
+ public void d10_formDataIfNECharSequence() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_FormDataIfNE.class).formDataCharSequence(new RequestBean_FormDataIfNECharSequence());
+ assertEquals("{baz:'qux',foo:'bar'}", r);
+ }
+
+ @Test
+ public void d11_formDataIfNEReader() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_FormDataIfNE.class).formDataReader(new RequestBean_FormDataIfNEReader());
+ assertEquals("{baz:'qux',foo:'bar'}", r);
+ }
+
+ @Test
+ public void d12_formDataIfNECollectionsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_FormDataIfNE.class).formDataCollectionsPlainText(new RequestBean_FormDataIfNECollections());
+ assertEquals("{a:'foo,,true,123,null,true,123,null',b:'foo,,true,123,null,true,123,null',c:'foo||true|123|null|true|123|null',f:'foo,,true,123,null,true,123,null',g:'foo||true|123|null|true|123|null'}", r);
+ }
+
+ @Test
+ public void d13_formDataIfNECollectionsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_FormDataIfNE.class).formDataCollectionsUon(new RequestBean_FormDataIfNECollections());
+ assertEquals("{a:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',b:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',c:'foo||true|123|null|true|123|null',f:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',g:'foo||true|123|null|true|123|null'}", r);
+ }
+
+ @Test
+ public void d14_formDataIfNECollectionsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_FormDataIfNE.class).formDataCollectionsX(new RequestBean_FormDataIfNECollections());
+ assertEquals("{a:'fooXXtrueX123XnullXtrueX123Xnull',b:'fooXXtrueX123XnullXtrueX123Xnull',c:'fooXXtrueX123XnullXtrueX123Xnull',f:'fooXXtrueX123XnullXtrueX123Xnull',g:'fooXXtrueX123XnullXtrueX123Xnull'}", r);
+ }
+
+ @Remoteable(path="/testRequestBeanProxy")
+ public static interface RequestBeanProxy_FormDataIfNE {
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataSimpleValsPlainText(@RequestBean RequestBean_FormDataIfNESimpleVals rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataSimpleValsUon(@RequestBean RequestBean_FormDataIfNESimpleVals rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataSimpleValsX(@RequestBean(serializer=XSerializer.class) RequestBean_FormDataIfNESimpleVals rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataMapsPlainText(@RequestBean RequestBean_FormDataIfNEMaps rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataMapsUon(@RequestBean RequestBean_FormDataIfNEMaps rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataMapsX(@RequestBean(serializer=XSerializer.class) RequestBean_FormDataIfNEMaps rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataNameValuePairsPlainText(@RequestBean RequestBean_FormDataIfNENameValuePairs rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataNameValuePairsUon(@RequestBean RequestBean_FormDataIfNENameValuePairs rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataNameValuePairsX(@RequestBean(serializer=XSerializer.class) RequestBean_FormDataIfNENameValuePairs rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataCharSequence(@RequestBean RequestBean_FormDataIfNECharSequence rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataReader(@RequestBean RequestBean_FormDataIfNEReader rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataCollectionsPlainText(@RequestBean RequestBean_FormDataIfNECollections rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataCollectionsUon(@RequestBean RequestBean_FormDataIfNECollections rb);
+
+ @RemoteMethod(httpMethod="POST", path="/echoFormData")
+ String formDataCollectionsX(@RequestBean(serializer=XSerializer.class) RequestBean_FormDataIfNECollections rb);
+ }
+
+ public static class RequestBean_FormDataIfNESimpleVals {
+
+ @FormDataIfNE
+ public String getA() {
+ return "a1";
+ }
+
+ @FormDataIfNE("b")
+ public String getX1() {
+ return "b1";
+ }
+
+ @FormDataIfNE(name="c")
+ public String getX2() {
+ return "c1";
+ }
+
+ @FormDataIfNE
+ @BeanProperty("d")
+ public String getX3() {
+ return "d1";
+ }
+
+ @FormDataIfNE("e")
+ public String getX4() {
+ return "";
+ }
+
+ @FormDataIfNE("f")
+ public String getX5() {
+ return null;
+ }
+
+ @FormDataIfNE("g")
+ public String getX6() {
+ return "true";
+ }
+
+ @FormDataIfNE("h")
+ public String getX7() {
+ return "123";
+ }
+ }
+
+ public static class RequestBean_FormDataIfNEMaps {
+
+ @FormDataIfNE
+ public Map<String,Object> getA() {
+ return new AMap<String,Object>().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
+ }
+
+ @FormDataIfNE("*")
+ public Map<String,Object> getB() {
+ return new AMap<String,Object>().append("b1","true").append("b2", "123").append("b3", "null");
+ }
+
+ @FormDataIfNE(name="*")
+ public Map<String,Object> getC() {
+ return new AMap<String,Object>().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
+ }
+
+ @FormDataIfNE("*")
+ public Map<String,Object> getD() {
+ return null;
+ }
+ }
+
+ public static class RequestBean_FormDataIfNENameValuePairs {
+
+ @FormDataIfNE
+ public NameValuePairs getA() {
+ return new NameValuePairs().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
+ }
+
+ @FormDataIfNE("*")
+ public NameValuePairs getB() {
+ return new NameValuePairs().append("b1","true").append("b2", "123").append("b3", "null");
+ }
+
+ @FormDataIfNE(name="*")
+ public NameValuePairs getC() {
+ return new NameValuePairs().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
+ }
+
+ @FormDataIfNE("*")
+ public NameValuePairs getD() {
+ return null;
+ }
+ }
+
+ public static class RequestBean_FormDataIfNECharSequence {
+
+ @FormDataIfNE("*")
+ public StringBuilder getA() {
+ return new StringBuilder("foo=bar&baz=qux");
+ }
+ }
+
+ public static class RequestBean_FormDataIfNEReader {
+
+ @FormDataIfNE("*")
+ public Reader getA() {
+ return new StringReader("foo=bar&baz=qux");
+ }
+ }
+
+ public static class RequestBean_FormDataIfNECollections {
+
+ @FormDataIfNE
+ public List<Object> getA() {
+ return new AList<Object>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
+ }
+
+ @FormDataIfNE("b")
+ public List<Object> getX1() {
+ return new AList<Object>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
+ }
+
+ @FormDataIfNE(name="c", serializer=ListSerializer.class)
+ public List<Object> getX2() {
+ return new AList<Object>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
+ }
+
+ @FormDataIfNE("d")
+ public List<Object> getX3() {
+ return new AList<Object>();
+ }
+
+ @FormDataIfNE("e")
+ public List<Object> getX4() {
+ return null;
+ }
+
+ @FormDataIfNE("f")
+ public Object[] getX5() {
+ return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
+ }
+
+ @FormDataIfNE(name="g", serializer=ListSerializer.class)
+ public Object[] getX6() {
+ return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
+ }
+
+ @FormDataIfNE("h")
+ public Object[] getX7() {
+ return new Object[]{};
+ }
+
+ @FormDataIfNE("i")
+ public Object[] getX8() {
+ return null;
+ }
+ }
+
+ //-------------------------------------------------------------------------------------------------------------------
+ // @Header
+ //-------------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void e01_headerSimpleValsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_Header.class).headerSimpleValsPlainText(new RequestBean_HeaderSimpleVals());
+ assertEquals("{a:'a1',b:'b1',c:'c1',d:'d1',e:'',g:'true',h:'123'}", r);
+ }
+
+ @Test
+ public void e02_headerSimpleValsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Header.class).headerSimpleValsUon(new RequestBean_HeaderSimpleVals());
+ assertEquals("{a:'a1',b:'b1',c:'c1',d:'d1',e:'',g:'true',h:'123'}", r);
+ }
+
+ @Test
+ public void e03_headerSimpleValsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Header.class).headerSimpleValsX(new RequestBean_HeaderSimpleVals());
+ assertEquals("{a:'xa1x',b:'xb1x',c:'xc1x',d:'xd1x',e:'xx',g:'xtruex',h:'x123x'}", r);
+ }
+
+ @Test
+ public void e04_headerMapsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_Header.class).headerMapsPlainText(new RequestBean_HeaderMaps());
+ assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
+ }
+
+ @Test
+ public void e05_headerMapsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Header.class).headerMapsUon(new RequestBean_HeaderMaps());
+ assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
+ }
+
+ @Test
+ public void e06_headerMapsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Header.class).headerMapsX(new RequestBean_HeaderMaps());
+ assertEquals("{a1:'xv1x',a2:'x123x',a4:'xx',b1:'xtruex',b2:'x123x',b3:'xnullx',c1:'xv1x',c2:'x123x',c4:'xx'}", r);
+ }
+
+ @Test
+ public void e07_headerNameValuePairsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_Header.class).headerNameValuePairsPlainText(new RequestBean_HeaderNameValuePairs());
+ assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
+ }
+
+ @Test
+ public void e08_headerNameValuePairsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Header.class).headerNameValuePairsUon(new RequestBean_HeaderNameValuePairs());
+ assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
+ }
+
+ @Test
+ public void e09_headerNameValuePairsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Header.class).headerNameValuePairsX(new RequestBean_HeaderNameValuePairs());
+ assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
+ }
+
+ @Test
+ public void e10_headerCollectionsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_Header.class).headerCollectionsPlainText(new RequestBean_HeaderCollections());
+ assertEquals("{a:'foo,,true,123,null,true,123,null',b:'foo,,true,123,null,true,123,null',c:'foo||true|123|null|true|123|null',d:'',f:'foo,,true,123,null,true,123,null',g:'foo||true|123|null|true|123|null',h:''}", r);
+ }
+
+ @Test
+ public void e11_headerCollectionsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Header.class).headerCollectionsUon(new RequestBean_HeaderCollections());
+ assertEquals("{a:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',b:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',c:'foo||true|123|null|true|123|null',d:'@()',f:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',g:'foo||true|123|null|true|123|null',h:'@()'}", r);
+ }
+
+ @Test
+ public void e12_headerCollectionsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Header.class).headerCollectionsX(new RequestBean_HeaderCollections());
+ assertEquals("{a:'fooXXtrueX123XnullXtrueX123Xnull',b:'fooXXtrueX123XnullXtrueX123Xnull',c:'fooXXtrueX123XnullXtrueX123Xnull',d:'',f:'fooXXtrueX123XnullXtrueX123Xnull',g:'fooXXtrueX123XnullXtrueX123Xnull',h:''}", r);
+ }
+
+ @Remoteable(path="/testRequestBeanProxy")
+ public static interface RequestBeanProxy_Header {
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerSimpleValsPlainText(@RequestBean RequestBean_HeaderSimpleVals rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerSimpleValsUon(@RequestBean RequestBean_HeaderSimpleVals rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerSimpleValsX(@RequestBean(serializer=XSerializer.class) RequestBean_HeaderSimpleVals rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerMapsPlainText(@RequestBean RequestBean_HeaderMaps rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerMapsUon(@RequestBean RequestBean_HeaderMaps rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerMapsX(@RequestBean(serializer=XSerializer.class) RequestBean_HeaderMaps rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerNameValuePairsPlainText(@RequestBean RequestBean_HeaderNameValuePairs rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerNameValuePairsUon(@RequestBean RequestBean_HeaderNameValuePairs rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerNameValuePairsX(@RequestBean(serializer=XSerializer.class) RequestBean_HeaderNameValuePairs rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerCollectionsPlainText(@RequestBean RequestBean_HeaderCollections rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerCollectionsUon(@RequestBean RequestBean_HeaderCollections rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerCollectionsX(@RequestBean(serializer=XSerializer.class) RequestBean_HeaderCollections rb);
+ }
+
+ public static class RequestBean_HeaderSimpleVals {
+
+ @Header
+ public String getA() {
+ return "a1";
+ }
+
+ @Header("b")
+ public String getX1() {
+ return "b1";
+ }
+
+ @Header(name="c")
+ public String getX2() {
+ return "c1";
+ }
+
+ @Header
+ @BeanProperty("d")
+ public String getX3() {
+ return "d1";
+ }
+
+ @Header("e")
+ public String getX4() {
+ return "";
+ }
+
+ @Header("f")
+ public String getX5() {
+ return null;
+ }
+
+ @Header("g")
+ public String getX6() {
+ return "true";
+ }
+
+ @Header("h")
+ public String getX7() {
+ return "123";
+ }
+ }
+
+ public static class RequestBean_HeaderMaps {
+
+ @Header
+ public Map<String,Object> getA() {
+ return new AMap<String,Object>().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
+ }
+
+ @Header("*")
+ public Map<String,Object> getB() {
+ return new AMap<String,Object>().append("b1","true").append("b2", "123").append("b3", "null");
+ }
+
+ @Header(name="*")
+ public Map<String,Object> getC() {
+ return new AMap<String,Object>().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
+ }
+
+ @Header("*")
+ public Map<String,Object> getD() {
+ return null;
+ }
+ }
+
+ public static class RequestBean_HeaderNameValuePairs {
+
+ @Header
+ public NameValuePairs getA() {
+ return new NameValuePairs().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
+ }
+
+ @Header("*")
+ public NameValuePairs getB() {
+ return new NameValuePairs().append("b1","true").append("b2", "123").append("b3", "null");
+ }
+
+ @Header(name="*")
+ public NameValuePairs getC() {
+ return new NameValuePairs().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
+ }
+
+ @Header("*")
+ public NameValuePairs getD() {
+ return null;
+ }
+ }
+
+ public static class RequestBean_HeaderCollections {
+
+ @Header
+ public List<Object> getA() {
+ return new AList<Object>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
+ }
+
+ @Header("b")
+ public List<Object> getX1() {
+ return new AList<Object>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
+ }
+
+ @Header(name="c", serializer=ListSerializer.class)
+ public List<Object> getX2() {
+ return new AList<Object>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
+ }
+
+ @Header("d")
+ public List<Object> getX3() {
+ return new AList<Object>();
+ }
+
+ @Header("e")
+ public List<Object> getX4() {
+ return null;
+ }
+
+ @Header("f")
+ public Object[] getX5() {
+ return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
+ }
+
+ @Header(name="g", serializer=ListSerializer.class)
+ public Object[] getX6() {
+ return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
+ }
+
+ @Header("h")
+ public Object[] getX7() {
+ return new Object[]{};
+ }
+
+ @Header("i")
+ public Object[] getX8() {
+ return null;
+ }
+ }
+
+ //-------------------------------------------------------------------------------------------------------------------
+ // @HeaderIfNE
+ //-------------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void f01_headerIfNESimpleValsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_HeaderIfNE.class).headerSimpleValsPlainText(new RequestBean_HeaderIfNESimpleVals());
+ assertEquals("{a:'a1',b:'b1',c:'c1',d:'d1',g:'true',h:'123'}", r);
+ }
+
+ @Test
+ public void f02_headerIfNESimpleValsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_HeaderIfNE.class).headerSimpleValsUon(new RequestBean_HeaderIfNESimpleVals());
+ assertEquals("{a:'a1',b:'b1',c:'c1',d:'d1',g:'true',h:'123'}", r);
+ }
+
+ @Test
+ public void f03_headerIfNESimpleValsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_HeaderIfNE.class).headerSimpleValsX(new RequestBean_HeaderIfNESimpleVals());
+ assertEquals("{a:'xa1x',b:'xb1x',c:'xc1x',d:'xd1x',g:'xtruex',h:'x123x'}", r);
+ }
+
+ @Test
+ public void f04_headerIfNEMapsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_HeaderIfNE.class).headerMapsPlainText(new RequestBean_HeaderIfNEMaps());
+ assertEquals("{a1:'v1',a2:'123',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123'}", r);
+ }
+
+ @Test
+ public void f05_headerIfNEMapsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_HeaderIfNE.class).headerMapsUon(new RequestBean_HeaderIfNEMaps());
+ assertEquals("{a1:'v1',a2:'123',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123'}", r);
+ }
+
+ @Test
+ public void f06_headerIfNEMapsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_HeaderIfNE.class).headerMapsX(new RequestBean_HeaderIfNEMaps());
+ assertEquals("{a1:'xv1x',a2:'x123x',b1:'xtruex',b2:'x123x',b3:'xnullx',c1:'xv1x',c2:'x123x'}", r);
+ }
+
+ @Test
+ public void f07_headerIfNENameValuePairsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_HeaderIfNE.class).headerNameValuePairsPlainText(new RequestBean_HeaderIfNENameValuePairs());
+ assertEquals("{a1:'v1',a2:'123',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123'}", r);
+ }
+
+ @Test
+ public void f08_headerIfNENameValuePairsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_HeaderIfNE.class).headerNameValuePairsUon(new RequestBean_HeaderIfNENameValuePairs());
+ assertEquals("{a1:'v1',a2:'123',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123'}", r);
+ }
+
+ @Test
+ public void f09_headerIfNENameValuePairsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_HeaderIfNE.class).headerNameValuePairsX(new RequestBean_HeaderIfNENameValuePairs());
+ assertEquals("{a1:'v1',a2:'123',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123'}", r);
+ }
+
+ @Test
+ public void f10_headerIfNECollectionsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_HeaderIfNE.class).headerCollectionsPlainText(new RequestBean_HeaderIfNECollections());
+ assertEquals("{a:'foo,,true,123,null,true,123,null',b:'foo,,true,123,null,true,123,null',c:'foo||true|123|null|true|123|null',f:'foo,,true,123,null,true,123,null',g:'foo||true|123|null|true|123|null'}", r);
+ }
+
+ @Test
+ public void f11_headerIfNECollectionsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_HeaderIfNE.class).headerCollectionsUon(new RequestBean_HeaderIfNECollections());
+ assertEquals("{a:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',b:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',c:'foo||true|123|null|true|123|null',f:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',g:'foo||true|123|null|true|123|null'}", r);
+ }
+
+ @Test
+ public void f12_headerIfNECollectionsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_HeaderIfNE.class).headerCollectionsX(new RequestBean_HeaderIfNECollections());
+ assertEquals("{a:'fooXXtrueX123XnullXtrueX123Xnull',b:'fooXXtrueX123XnullXtrueX123Xnull',c:'fooXXtrueX123XnullXtrueX123Xnull',f:'fooXXtrueX123XnullXtrueX123Xnull',g:'fooXXtrueX123XnullXtrueX123Xnull'}", r);
+ }
+
+ @Remoteable(path="/testRequestBeanProxy")
+ public static interface RequestBeanProxy_HeaderIfNE {
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerSimpleValsPlainText(@RequestBean RequestBean_HeaderIfNESimpleVals rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerSimpleValsUon(@RequestBean RequestBean_HeaderIfNESimpleVals rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerSimpleValsX(@RequestBean(serializer=XSerializer.class) RequestBean_HeaderIfNESimpleVals rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerMapsPlainText(@RequestBean RequestBean_HeaderIfNEMaps rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerMapsUon(@RequestBean RequestBean_HeaderIfNEMaps rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerMapsX(@RequestBean(serializer=XSerializer.class) RequestBean_HeaderIfNEMaps rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerNameValuePairsPlainText(@RequestBean RequestBean_HeaderIfNENameValuePairs rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerNameValuePairsUon(@RequestBean RequestBean_HeaderIfNENameValuePairs rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerNameValuePairsX(@RequestBean(serializer=XSerializer.class) RequestBean_HeaderIfNENameValuePairs rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerCollectionsPlainText(@RequestBean RequestBean_HeaderIfNECollections rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerCollectionsUon(@RequestBean RequestBean_HeaderIfNECollections rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoHeaders")
+ String headerCollectionsX(@RequestBean(serializer=XSerializer.class) RequestBean_HeaderIfNECollections rb);
+ }
+
+ public static class RequestBean_HeaderIfNESimpleVals {
+
+ @HeaderIfNE
+ public String getA() {
+ return "a1";
+ }
+
+ @HeaderIfNE("b")
+ public String getX1() {
+ return "b1";
+ }
+
+ @HeaderIfNE(name="c")
+ public String getX2() {
+ return "c1";
+ }
+
+ @HeaderIfNE
+ @BeanProperty("d")
+ public String getX3() {
+ return "d1";
+ }
+
+ @HeaderIfNE("e")
+ public String getX4() {
+ return "";
+ }
+
+ @HeaderIfNE("f")
+ public String getX5() {
+ return null;
+ }
+
+ @HeaderIfNE("g")
+ public String getX6() {
+ return "true";
+ }
+
+ @HeaderIfNE("h")
+ public String getX7() {
+ return "123";
+ }
+ }
+
+ public static class RequestBean_HeaderIfNEMaps {
+
+ @HeaderIfNE
+ public Map<String,Object> getA() {
+ return new AMap<String,Object>().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
+ }
+
+ @HeaderIfNE("*")
+ public Map<String,Object> getB() {
+ return new AMap<String,Object>().append("b1","true").append("b2", "123").append("b3", "null");
+ }
+
+ @HeaderIfNE(name="*")
+ public Map<String,Object> getC() {
+ return new AMap<String,Object>().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
+ }
+
+ @HeaderIfNE("*")
+ public Map<String,Object> getD() {
+ return null;
+ }
+ }
+
+ public static class RequestBean_HeaderIfNENameValuePairs {
+
+ @HeaderIfNE
+ public NameValuePairs getA() {
+ return new NameValuePairs().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
+ }
+
+ @HeaderIfNE("*")
+ public NameValuePairs getB() {
+ return new NameValuePairs().append("b1","true").append("b2", "123").append("b3", "null");
+ }
+
+ @HeaderIfNE(name="*")
+ public NameValuePairs getC() {
+ return new NameValuePairs().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
+ }
+
+ @HeaderIfNE("*")
+ public NameValuePairs getD() {
+ return null;
+ }
+ }
+
+ public static class RequestBean_HeaderIfNECollections {
+
+ @HeaderIfNE
+ public List<Object> getA() {
+ return new AList<Object>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
+ }
+
+ @HeaderIfNE("b")
+ public List<Object> getX1() {
+ return new AList<Object>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
+ }
+
+ @HeaderIfNE(name="c", serializer=ListSerializer.class)
+ public List<Object> getX2() {
+ return new AList<Object>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
+ }
+
+ @HeaderIfNE("d")
+ public List<Object> getX3() {
+ return new AList<Object>();
+ }
+
+ @HeaderIfNE("e")
+ public List<Object> getX4() {
+ return null;
+ }
+
+ @HeaderIfNE("f")
+ public Object[] getX5() {
+ return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
+ }
+
+ @HeaderIfNE(name="g", serializer=ListSerializer.class)
+ public Object[] getX6() {
+ return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
+ }
+
+ @HeaderIfNE("h")
+ public Object[] getX7() {
+ return new Object[]{};
+ }
+
+ @HeaderIfNE("i")
+ public Object[] getX8() {
+ return null;
+ }
+ }
+
+ //-------------------------------------------------------------------------------------------------------------------
+ // @Path
+ //-------------------------------------------------------------------------------------------------------------------
+
+ @Test
+ public void g01_pathSimpleValsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_Path.class).pathSimpleValsPlainText(new RequestBean_PathSimpleVals());
+ assertEquals("a1/b1/c1/d1//null/true/123", r);
+ }
+
+ @Test
+ public void g02_pathSimpleValsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Path.class).pathSimpleValsUon(new RequestBean_PathSimpleVals());
+ assertEquals("a1/b1/c1/d1//null/'true'/'123'", r);
+ }
+
+ @Test
+ public void g03_pathSimpleValsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Path.class).pathSimpleValsX(new RequestBean_PathSimpleVals());
+ assertEquals("xa1x/xb1x/xc1x/xd1x/xx/NULL/xtruex/x123x", r);
+ }
+
+ @Test
+ public void g04_pathMapsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_Path.class).pathMapsPlainText(new RequestBean_PathMaps());
+ assertEquals("v1/123/null//true/123/null/v1/123/null/", r);
+ }
+
+ @Test
+ public void g05_pathMapsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Path.class).pathMapsUon(new RequestBean_PathMaps());
+ assertEquals("v1/123/null//'true'/'123'/'null'/v1/123/null/", r);
+ }
+
+ @Test
+ public void g06_pathMapsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Path.class).pathMapsX(new RequestBean_PathMaps());
+ assertEquals("xv1x/x123x/NULL/xx/xtruex/x123x/xnullx/xv1x/x123x/NULL/xx", r);
+ }
+
+ @Test
+ public void g07_pathNameValuePairsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_Path.class).pathNameValuePairsPlainText(new RequestBean_PathNameValuePairs());
+ assertEquals("plainText/v1/123/null//true/123/null/v1/123/null/", r);
+ }
+
+ @Test
+ public void g08_pathNameValuePairsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Path.class).pathNameValuePairsUon(new RequestBean_PathNameValuePairs());
+ assertEquals("v1/'123'/null//'true'/'123'/'null'/v1/'123'/null/", r);
+ }
+
+ @Test
+ public void g09_pathNameValuePairsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Path.class).pathNameValuePairsX(new RequestBean_PathNameValuePairs());
+ assertEquals("xv1x/x123x/NULL/xx/xtruex/x123x/xnullx/xv1x/x123x/NULL/xx", r);
+ }
+
+ @Test
+ public void g10_pathCollectionsPlainText() throws Exception {
+ String r = getProxyPlainText(RequestBeanProxy_Path.class).pathCollectionsPlainText(new RequestBean_PathCollections());
+ assertEquals("foo,,true,123,null,true,123,null/foo,,true,123,null,true,123,null/foo||true|123|null|true|123|null//null/foo,,true,123,null,true,123,null/foo||true|123|null|true|123|null//null", r);
+ }
+
+ @Test
+ public void g11_pathCollectionsUon() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Path.class).pathCollectionsUon(new RequestBean_PathCollections());
+ assertEquals("@(foo,'','true','123','null',true,123,null)/@(foo,'','true','123','null',true,123,null)/foo||true|123|null|true|123|null/@()/null/@(foo,'','true','123','null',true,123,null)/foo||true|123|null|true|123|null/@()/null", r);
+ }
+
+ @Test
+ public void g12_pathCollectionsX() throws Exception {
+ String r = getProxyUon(RequestBeanProxy_Path.class).pathCollectionsX(new RequestBean_PathCollections());
+ assertEquals("fooXXtrueX123XnullXtrueX123Xnull/fooXXtrueX123XnullXtrueX123Xnull/fooXXtrueX123XnullXtrueX123Xnull//NULL/fooXXtrueX123XnullXtrueX123Xnull/fooXXtrueX123XnullXtrueX123Xnull//NULL", r);
+ }
+
+ @Remoteable(path="/testRequestBeanProxy")
+ public static interface RequestBeanProxy_Path {
+
+ @RemoteMethod(httpMethod="GET", path="/echoPath/{a}/{b}/{c}/{d}/{e}/{f}/{g}/{h}")
+ String pathSimpleValsPlainText(@RequestBean RequestBean_PathSimpleVals rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoPath/{a}/{b}/{c}/{d}/{e}/{f}/{g}/{h}")
+ String pathSimpleValsUon(@RequestBean RequestBean_PathSimpleVals rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoPath/{a}/{b}/{c}/{d}/{e}/{f}/{g}/{h}")
+ String pathSimpleValsX(@RequestBean(serializer=XSerializer.class) RequestBean_PathSimpleVals rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoPath/{a1}/{a2}/{a3}/{a4}/{b1}/{b2}/{b3}/{c1}/{c2}/{c3}/{c4}")
+ String pathMapsPlainText(@RequestBean RequestBean_PathMaps rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoPath/{a1}/{a2}/{a3}/{a4}/{b1}/{b2}/{b3}/{c1}/{c2}/{c3}/{c4}")
+ String pathMapsUon(@RequestBean RequestBean_PathMaps rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoPath/{a1}/{a2}/{a3}/{a4}/{b1}/{b2}/{b3}/{c1}/{c2}/{c3}/{c4}")
+ String pathMapsX(@RequestBean(serializer=XSerializer.class) RequestBean_PathMaps rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoPath/plainText/{a1}/{a2}/{a3}/{a4}/{b1}/{b2}/{b3}/{c1}/{c2}/{c3}/{c4}")
+ String pathNameValuePairsPlainText(@RequestBean RequestBean_PathNameValuePairs rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoPath/{a1}/{a2}/{a3}/{a4}/{b1}/{b2}/{b3}/{c1}/{c2}/{c3}/{c4}")
+ String pathNameValuePairsUon(@RequestBean RequestBean_PathNameValuePairs rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoPath/{a1}/{a2}/{a3}/{a4}/{b1}/{b2}/{b3}/{c1}/{c2}/{c3}/{c4}")
+ String pathNameValuePairsX(@RequestBean(serializer=XSerializer.class) RequestBean_PathNameValuePairs rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoPath/{a}/{b}/{c}/{d}/{e}/{f}/{g}/{h}/{i}")
+ String pathCollectionsPlainText(@RequestBean RequestBean_PathCollections rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoPath/{a}/{b}/{c}/{d}/{e}/{f}/{g}/{h}/{i}")
+ String pathCollectionsUon(@RequestBean RequestBean_PathCollections rb);
+
+ @RemoteMethod(httpMethod="GET", path="/echoPath/{a}/{b}/{c}/{d}/{e}/{f}/{g}/{h}/{i}")
+ String pathCollectionsX(@RequestBean(serializer=XSerializer.class) RequestBean_PathCollections rb);
+ }
+
+ public static class RequestBean_PathSimpleVals {
+
+ @Path
+ public String getA() {
+ return "a1";
+ }
+
+ @Path("b")
+ public String getX1() {
+ return "b1";
+ }
+
+ @Path(name="c")
+ public String getX2() {
+ return "c1";
+ }
+
+ @Path
+ @BeanProperty("d")
+ public String getX3() {
+ return "d1";
+ }
+
+ @Path("e")
+ public String getX4() {
+ return "";
+ }
+
+ @Path("f")
+ public String getX5() {
+ return null;
+ }
+
+ @Path("g")
+ public String getX6() {
+ return "true";
+ }
+
+ @Path("h")
+ public String getX7() {
+ return "123";
+ }
+ }
+
+ public static class RequestBean_PathMaps {
+
+ @Path
+ public Map<String,Object> getA() {
+ return new AMap<String,Object>().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
+ }
+
+ @Path("*")
+ public Map<String,Object> getB() {
+ return new AMap<String,Object>().append("b1","true").append("b2", "123").append("b3", "null");
+ }
+
+ @Path(name="*")
+ public Map<String,Object> getC() {
+ return new AMap<String,Object>().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
+ }
+
+ @Path("*")
+ public Map<String,Object> getD() {
+ return null;
+ }
+ }
+
+ public static class RequestBean_PathNameValuePairs {
+
+ @Path
+ public NameValuePairs getA() {
+ return new NameValuePairs().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
+ }
+
+ @Path("*")
+ public NameValuePairs getB() {
+ return new NameValuePairs().append("b1","true").append("b2", "123").append("b3", "null");
+ }
+
+ @Path(name="*")
+ public NameValuePairs getC() {
+ return new NameValuePairs().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
+ }
+
+ @Path("*")
+ public NameValuePairs getD() {
+ return null;
+ }
+ }
+
+ public static class RequestBean_PathCollections {
+
+ @Path
+ public List<Object> getA() {
+ return new AList<Object>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
+ }
+
+ @Path("b")
+ public List<Object> getX1() {
+ return new AList<Object>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
+ }
+
+ @Path(name="c", serializer=ListSerializer.class)
+ public List<Object> getX2() {
+ return new AList<Object>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
+ }
+
+ @Path("d")
+ public List<Object> getX3() {
+ return new AList<Object>();
+ }
+
+ @Path("e")
+ public List<Object> getX4() {
+ return null;
+ }
+
+ @Path("f")
+ public Object[] getX5() {
+ return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
+ }
+
+ @Path(name="g", serializer=ListSerializer.class)
+ public Object[] getX6() {
+ return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
+ }
+
+ @Path("h")
+ public Object[] getX7() {
+ return new Object[]{};
+ }
+
+ @Path("i")
+ public Object[] getX8() {
+ return null;
+ }
+ }
+
+ //-------------------------------------------------------------------------------------------------------------------
+ // Support classes
+ //-------------------------------------------------------------------------------------------------------------------
+
+ public static class XSerializer implements PartSerializer {
+ @Override
+ public String serialize(PartType type, Object value) {
+ if (value == null)
+ return "NULL";
+ if (value instanceof Collection)
+ return StringUtils.join((Collection<?>)value, "X");
+ if (ArrayUtils.isArray(value))
+ return StringUtils.join(ArrayUtils.toList(value, Object.class), "X");
+ return "x" + value + "x";
+ }
+ }
+
+ public static class ListSerializer implements PartSerializer {
+ @Override
+ public String serialize(PartType type, Object value) {
+ if (value == null)
+ return "NULL";
+ if (value instanceof Collection)
+ return StringUtils.join((Collection<?>)value, '|');
+ if (ArrayUtils.isArray(value))
+ return StringUtils.join(ArrayUtils.toList(value, Object.class), "|");
+ return "?" + value + "?";
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RestTestcase.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RestTestcase.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RestTestcase.java
index 5a85bde..521c965 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RestTestcase.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RestTestcase.java
@@ -46,7 +46,7 @@ public class RestTestcase {
*/
protected RestClient getClient(String label, Serializer serializer, Parser parser) {
if (! clients.containsKey(label))
- clients.put(label, TestMicroservice.client(serializer, parser).build());
+ clients.put(label, TestMicroservice.client(serializer, parser).pooled().build());
return clients.get(label);
}
@@ -59,6 +59,10 @@ public class RestTestcase {
return clients.get(label);
}
+ protected void addClientToLifecycle(RestClient c) {
+ clients.put(UUID.randomUUID().toString(), c);
+ }
+
@SuppressWarnings("unchecked")
protected <T> T getCached(String label, Class<T> c) {
return (T)cache.get(label);
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/_TestSuite.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/_TestSuite.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/_TestSuite.java
index eb2f247..485fbed 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/_TestSuite.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/_TestSuite.java
@@ -58,6 +58,7 @@ import org.junit.runners.Suite.*;
PathVariableTest.class,
PropertiesTest.class,
QueryTest.class,
+ RequestBeanProxyTest.class,
RestClientTest.class,
RestUtilsTest.class,
SerializersTest.class,
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-rest/src/main/java/org/apache/juneau/rest/RequestFormData.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestFormData.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestFormData.java
index 62adf90..453bb8b 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestFormData.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestFormData.java
@@ -17,6 +17,7 @@ import java.util.*;
import org.apache.juneau.*;
import org.apache.juneau.internal.*;
+import org.apache.juneau.json.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.urlencoding.*;
@@ -99,7 +100,7 @@ public class RequestFormData extends LinkedHashMap<String,String[]> {
// Fix for behavior difference between Tomcat and WAS.
// getParameter("foo") on "&foo" in Tomcat returns "".
// getParameter("foo") on "&foo" in WAS returns null.
- if (v.length == 1 && v[0] == null)
+ if (v.length == 1 && v[0] == null)
return "";
return v[0];
@@ -286,4 +287,24 @@ public class RequestFormData extends LinkedHashMap<String,String[]> {
private <T> T parseValue(String val, ClassMeta<T> c) throws ParseException {
return parser.parsePart(val, c);
}
+
+ /**
+ * Converts the form data parameters to a readable string.
+ *
+ * @param sorted Sort the form data parameters by name.
+ * @return A JSON string containing the contents of the form data parameters.
+ */
+ public String toString(boolean sorted) {
+ Map<String,Object> m = (sorted ? new TreeMap<String,Object>() : new LinkedHashMap<String,Object>());
+ for (Map.Entry<String,String[]> e : this.entrySet()) {
+ String[] v = e.getValue();
+ m.put(e.getKey(), v.length == 1 ? v[0] : v);
+ }
+ return JsonSerializer.DEFAULT_LAX.toString(m);
+ }
+
+ @Override /* Object */
+ public String toString() {
+ return toString(false);
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-rest/src/main/java/org/apache/juneau/rest/RequestHeaders.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestHeaders.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestHeaders.java
index 03b7c38..cc0709d 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestHeaders.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestHeaders.java
@@ -19,6 +19,7 @@ import org.apache.juneau.*;
import org.apache.juneau.http.*;
import org.apache.juneau.http.Date;
import org.apache.juneau.internal.*;
+import org.apache.juneau.json.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.urlencoding.*;
@@ -204,6 +205,28 @@ public class RequestHeaders extends TreeMap<String,String[]> {
}
/**
+ * Returns a copy of this object, but only with the specified header names copied.
+ * @param headers The headers to include in the copy.
+ * @return A new headers object.
+ */
+ public RequestHeaders subset(String...headers) {
+ RequestHeaders rh2 = new RequestHeaders().setParser(parser).setBeanSession(beanSession).setQueryParams(queryParams);
+ for (String h : headers)
+ if (containsKey(h))
+ rh2.put(h, get(h));
+ return rh2;
+ }
+
+ /**
+ * Same as {@link #subset(String...)}, but allows you to specify header names as a comma-delimited list.
+ * @param headers The headers to include in the copy.
+ * @return A new headers object.
+ */
+ public RequestHeaders subset(String headers) {
+ return subset(StringUtils.split(headers, ','));
+ }
+
+ /**
* Returns the <code>Accept</code> header on the request.
* <p>
* Content-Types that are acceptable for the response.
@@ -671,4 +694,24 @@ public class RequestHeaders extends TreeMap<String,String[]> {
public Warning getWarning() {
return Warning.forString(getFirst("Warning"));
}
+
+ /**
+ * Converts the headers to a readable string.
+ *
+ * @param sorted Sort the headers by name.
+ * @return A JSON string containing the contents of the headers.
+ */
+ public String toString(boolean sorted) {
+ Map<String,Object> m = (sorted ? new TreeMap<String,Object>() : new LinkedHashMap<String,Object>());
+ for (Map.Entry<String,String[]> e : this.entrySet()) {
+ String[] v = e.getValue();
+ m.put(e.getKey(), v.length == 1 ? v[0] : v);
+ }
+ return JsonSerializer.DEFAULT_LAX.toString(m);
+ }
+
+ @Override /* Object */
+ public String toString() {
+ return toString(false);
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-rest/src/main/java/org/apache/juneau/rest/RequestQuery.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestQuery.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestQuery.java
index bdb9b60..593c900 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestQuery.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestQuery.java
@@ -19,6 +19,7 @@ import javax.servlet.http.*;
import org.apache.juneau.*;
import org.apache.juneau.internal.*;
+import org.apache.juneau.json.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.urlencoding.*;
@@ -90,7 +91,7 @@ public final class RequestQuery extends LinkedHashMap<String,String[]> {
// Fix for behavior difference between Tomcat and WAS.
// getParameter("foo") on "&foo" in Tomcat returns "".
// getParameter("foo") on "&foo" in WAS returns null.
- if (v.length == 1 && v[0] == null)
+ if (v.length == 1 && v[0] == null)
return "";
return v[0];
@@ -304,4 +305,24 @@ public final class RequestQuery extends LinkedHashMap<String,String[]> {
private <T> T parseValue(String val, ClassMeta<T> c) throws ParseException {
return parser.parsePart(val, c);
}
+
+ /**
+ * Converts the query parameters to a readable string.
+ *
+ * @param sorted Sort the query parameters by name.
+ * @return A JSON string containing the contents of the query parameters.
+ */
+ public String toString(boolean sorted) {
+ Map<String,Object> m = (sorted ? new TreeMap<String,Object>() : new LinkedHashMap<String,Object>());
+ for (Map.Entry<String,String[]> e : this.entrySet()) {
+ String[] v = e.getValue();
+ m.put(e.getKey(), v.length == 1 ? v[0] : v);
+ }
+ return JsonSerializer.DEFAULT_LAX.toString(m);
+ }
+
+ @Override /* Object */
+ public String toString() {
+ return toString(false);
+ }
}
[2/3] incubator-juneau git commit: Improvements to
@Query/@FormData/@Header/@Path remoteable annotations.
Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/javadoc/overview.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/javadoc/overview.html b/juneau-core/src/main/javadoc/overview.html
index a4e6885..ef06af5 100644
--- a/juneau-core/src/main/javadoc/overview.html
+++ b/juneau-core/src/main/javadoc/overview.html
@@ -6231,7 +6231,9 @@
<ja>@BeanProperty</ja>(<js>"foo"</js>)
</p>
<li>Fixed a race condition in ClassMeta.
-
+ <li><jsf>URLENC_paramFormat</jsf> has been moved to {@link org.apache.juneau.uon.UonSerializerContext#UON_paramFormat},
+ and the UON/URL-Encoding serializers will now always serialize all values as plain text.
+ <br>This means that arrays and maps are converted to simple comma-delimited lists.
</ul>
<h6 class='topic'>org.apache.juneau.rest</h6>
@@ -6463,11 +6465,11 @@
<br><ja>@Remoteable</ja> annotation has been moved to this package.
<li>Updated doc: <a class='doclink' href='#Remoteable'>6 - Remoteable Services</a>
<li>New doc: <a class='doclink' href='#Remoteable.3rdParty'>6.1 - Interface proxies against 3rd-party REST interfaces</a>
- <li>New URL-encoding serializer setting: {@link org.apache.juneau.urlencoding.UrlEncodingSerializerContext#URLENC_paramFormat}
+ <li>New URL-encoding serializer setting: <code><del>UrlEncodingSerializerContext.URLENC_paramFormat</del></code>.
<li>New methods on {@link org.apache.juneau.urlencoding.UrlEncodingSerializerBuilder}:
<ul>
<li>{@link org.apache.juneau.urlencoding.UrlEncodingSerializerBuilder#paramFormat(String) paramFormat(String)}
- <li>{@link org.apache.juneau.urlencoding.UrlEncodingSerializerBuilder#plainTextParams() plainTextParams()}
+ <li><code><del>UrlEncodingSerializerBuilder.plainTextParams()</del></code>
</ul>
</ul>
@@ -6626,7 +6628,7 @@
<ul>
<li>{@link org.apache.juneau.rest.client.RestClientBuilder#executorService(ExecutorService,boolean) executorService(ExecutorService,boolean)}
<li>{@link org.apache.juneau.rest.client.RestClientBuilder#paramFormat(String) paramFormat(ExecutorService,boolean)}
- <li>{@link org.apache.juneau.rest.client.RestClientBuilder#plainTextParams() plainTextParams()}
+ <li><code><del>RestClientBuilder.plainTextParams()</del></code>
<li>{@link org.apache.juneau.rest.client.RestClientBuilder#noTrace() noTrace()} - Adds a <code>No-Trace: true</code> header on all requests to prevent
the servlet from logging errors.
<br>Useful for testing scenarios when you don't want the console to end up showing errors done on purpose.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
----------------------------------------------------------------------
diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
index 769e5eb..9be6df6 100644
--- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
+++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
@@ -28,6 +28,7 @@ import org.apache.http.client.config.*;
import org.apache.http.client.entity.*;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.*;
+import org.apache.http.entity.*;
import org.apache.http.impl.client.*;
import org.apache.http.util.*;
import org.apache.juneau.*;
@@ -37,6 +38,7 @@ import org.apache.juneau.internal.ObjectUtils;
import org.apache.juneau.parser.*;
import org.apache.juneau.parser.ParseException;
import org.apache.juneau.serializer.*;
+import org.apache.juneau.urlencoding.*;
import org.apache.juneau.utils.*;
/**
@@ -191,16 +193,22 @@ public final class RestCall {
uriBuilder.addParameter(name, partSerializer.serialize(PartType.QUERY, value));
} else if (value instanceof NameValuePairs) {
for (NameValuePair p : (NameValuePairs)value)
- query(p.getName(), p.getValue(), skipIfEmpty, partSerializer);
- } else if (value instanceof String) {
- String s = value.toString();
- if (! isEmpty(s))
- uriBuilder.setCustomQuery(s);
+ query(p.getName(), p.getValue(), skipIfEmpty, UrlEncodingSerializer.DEFAULT_PLAINTEXT);
} else if (value instanceof Map) {
for (Map.Entry<String,Object> p : ((Map<String,Object>) value).entrySet())
query(p.getKey(), p.getValue(), skipIfEmpty, partSerializer);
- } else if (isBean(value)){
+ } else if (isBean(value)) {
return query(name, toBeanMap(value), skipIfEmpty, partSerializer);
+ } else if (value instanceof Reader) {
+ try {
+ uriBuilder.setCustomQuery(IOUtils.read(value));
+ } catch (IOException e) {
+ throw new RestCallException(e);
+ }
+ } else if (value instanceof CharSequence) {
+ String s = value.toString();
+ if (! isEmpty(s))
+ uriBuilder.setCustomQuery(s);
} else {
throw new FormattedRuntimeException("Invalid name ''{0}'' passed to query(name,value,skipIfEmpty) for data type ''{1}''", name, ClassUtils.getReadableClassNameForObject(value));
}
@@ -291,13 +299,21 @@ public final class RestCall {
formData.add(new SerializedNameValuePair(name, value, partSerializer));
} else if (value instanceof NameValuePairs) {
for (NameValuePair p : (NameValuePairs)value)
- if (! (isEmpty(p.getValue()) && skipIfEmpty))
+ if (p.getValue() != null && ! (isEmpty(p.getValue()) && skipIfEmpty))
formData.add(p);
} else if (value instanceof Map) {
for (Map.Entry<String,Object> p : ((Map<String,Object>) value).entrySet())
formData(p.getKey(), p.getValue(), skipIfEmpty, partSerializer);
} else if (isBean(value)) {
return formData(name, toBeanMap(value), skipIfEmpty, partSerializer);
+ } else if (value instanceof Reader) {
+ contentType("application/x-www-form-urlencoded");
+ input(value);
+ } else if (value instanceof CharSequence) {
+ try {
+ contentType("application/x-www-form-urlencoded");
+ input(new StringEntity(value.toString()));
+ } catch (UnsupportedEncodingException e) {}
} else {
throw new FormattedRuntimeException("Invalid name ''{0}'' passed to formData(name,value,skipIfEmpty) for data type ''{1}''", name, ClassUtils.getReadableClassNameForObject(value));
}
@@ -389,13 +405,13 @@ public final class RestCall {
uriBuilder.setPath(newPath);
} else if (value instanceof NameValuePairs) {
for (NameValuePair p : (NameValuePairs)value)
- path(p.getName(), p.getValue());
+ path(p.getName(), p.getValue(), partSerializer);
} else if (value instanceof Map) {
for (Map.Entry<String,Object> p : ((Map<String,Object>) value).entrySet())
- path(p.getKey(), p.getValue());
+ path(p.getKey(), p.getValue(), partSerializer);
} else if (isBean(value)) {
- return path(name, toBeanMap(value));
- } else {
+ return path(name, toBeanMap(value), partSerializer);
+ } else if (value != null) {
throw new FormattedRuntimeException("Invalid name ''{0}'' passed to path(name,value) for data type ''{1}''", name, ClassUtils.getReadableClassNameForObject(value));
}
return this;
@@ -454,6 +470,7 @@ public final class RestCall {
public RestCall input(final Object input) throws RestCallException {
this.input = input;
this.hasInput = true;
+ this.formData = null;
return this;
}
@@ -508,7 +525,7 @@ public final class RestCall {
request.setHeader(name, partSerializer.serialize(PartType.HEADER, value));
} else if (value instanceof NameValuePairs) {
for (NameValuePair p : (NameValuePairs)value)
- header(p.getName(), p.getValue(), skipIfEmpty, partSerializer);
+ header(p.getName(), p.getValue(), skipIfEmpty, UrlEncodingSerializer.DEFAULT_PLAINTEXT);
} else if (value instanceof Map) {
for (Map.Entry<String,Object> p : ((Map<String,Object>) value).entrySet())
header(p.getKey(), p.getValue(), skipIfEmpty, partSerializer);
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
----------------------------------------------------------------------
diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
index 8f26768..910a9fb 100644
--- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
+++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
@@ -567,39 +567,42 @@ public class RestClient extends CoreObject {
if (rmm.getRequestBeanArgs().length > 0) {
BeanSession bs = getBeanContext().createSession();
- for (Integer i : rmm.getRequestBeanArgs()) {
- BeanMap<?> bm = bs.toBeanMap(args[i]);
- for (BeanPropertyValue bpv : bm.getValues(true)) {
+ for (RemoteMethodArg rma : rmm.getRequestBeanArgs()) {
+ BeanMap<?> bm = bs.toBeanMap(args[rma.index]);
+
+ for (BeanPropertyValue bpv : bm.getValues(false)) {
BeanPropertyMeta pMeta = bpv.getMeta();
Object val = bpv.getValue();
Path p = pMeta.getAnnotation(Path.class);
if (p != null)
- rc.path(getName(p.value(), pMeta), val, getPartSerializer(p.serializer()));
+ rc.path(getName(p.name(), p.value(), pMeta), val, getPartSerializer(p.serializer(), rma.serializer));
- Query q1 = pMeta.getAnnotation(Query.class);
- if (q1 != null)
- rc.query(getName(q1.value(), pMeta), val, false, getPartSerializer(q1.serializer()));
+ if (val != null) {
+ Query q1 = pMeta.getAnnotation(Query.class);
+ if (q1 != null)
+ rc.query(getName(q1.name(), q1.value(), pMeta), val, q1.skipIfEmpty(), getPartSerializer(q1.serializer(), rma.serializer));
- QueryIfNE q2 = pMeta.getAnnotation(QueryIfNE.class);
- if (q2 != null)
- rc.query(getName(q2.value(), pMeta), val, true, getPartSerializer(q2.serializer()));
+ QueryIfNE q2 = pMeta.getAnnotation(QueryIfNE.class);
+ if (q2 != null)
+ rc.query(getName(q2.name(), q2.value(), pMeta), val, true, getPartSerializer(q2.serializer(), rma.serializer));
- FormData f1 = pMeta.getAnnotation(FormData.class);
- if (f1 != null)
- rc.formData(getName(f1.value(), pMeta), val, false, getPartSerializer(f1.serializer()));
+ FormData f1 = pMeta.getAnnotation(FormData.class);
+ if (f1 != null)
+ rc.formData(getName(f1.name(), f1.value(), pMeta), val, f1.skipIfEmpty(), getPartSerializer(f1.serializer(), rma.serializer));
- FormDataIfNE f2 = pMeta.getAnnotation(FormDataIfNE.class);
- if (f2 != null)
- rc.formData(getName(f2.value(), pMeta), val, true, getPartSerializer(f2.serializer()));
+ FormDataIfNE f2 = pMeta.getAnnotation(FormDataIfNE.class);
+ if (f2 != null)
+ rc.formData(getName(f2.name(), f2.value(), pMeta), val, true, getPartSerializer(f2.serializer(), rma.serializer));
- org.apache.juneau.remoteable.Header h1 = pMeta.getAnnotation(org.apache.juneau.remoteable.Header.class);
- if (h1 != null)
- rc.header(getName(h1.value(), pMeta), val, false, getPartSerializer(h1.serializer()));
+ org.apache.juneau.remoteable.Header h1 = pMeta.getAnnotation(org.apache.juneau.remoteable.Header.class);
+ if (h1 != null)
+ rc.header(getName(h1.name(), h1.value(), pMeta), val, h1.skipIfEmpty(), getPartSerializer(h1.serializer(), rma.serializer));
- HeaderIfNE h2 = pMeta.getAnnotation(HeaderIfNE.class);
- if (h2 != null)
- rc.header(getName(h2.value(), pMeta), val, true, getPartSerializer(h2.serializer()));
+ HeaderIfNE h2 = pMeta.getAnnotation(HeaderIfNE.class);
+ if (h2 != null)
+ rc.header(getName(h2.name(), h2.value(), pMeta), val, true, getPartSerializer(h2.serializer(), rma.serializer));
+ }
}
}
}
@@ -628,14 +631,20 @@ public class RestClient extends CoreObject {
}
}
- private static String getName(String name, BeanPropertyMeta pMeta) {
- if ("*".equals(name) && ! pMeta.getClassMeta().isMapOrBean())
- name = pMeta.getName();
- return name;
+ private static String getName(String name1, String name2, BeanPropertyMeta pMeta) {
+ String n = name1.isEmpty() ? name2 : name1;
+ ClassMeta<?> cm = pMeta.getClassMeta();
+ if (n.isEmpty() && (cm.isMapOrBean() || cm.isReader() || cm.isInstanceOf(NameValuePairs.class)))
+ n = "*";
+ if (n.isEmpty())
+ n = pMeta.getName();
+ return n;
}
- private static PartSerializer getPartSerializer(Class c) {
- if (c == UrlEncodingSerializer.class)
+ private static PartSerializer getPartSerializer(Class c, PartSerializer c2) {
+ if (c2 != null)
+ return c2;
+ if (c == PartSerializer.class)
return null;
PartSerializer pf = partSerializerCache.get(c);
if (pf == null) {
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
index 463920a..65b4dc8 100644
--- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
+++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
@@ -46,6 +46,7 @@ import org.apache.juneau.internal.*;
import org.apache.juneau.json.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.serializer.*;
+import org.apache.juneau.uon.*;
import org.apache.juneau.urlencoding.*;
/**
@@ -1101,7 +1102,7 @@ public class RestClientBuilder extends CoreObjectBuilder {
}
/**
- * Sets the {@link UrlEncodingSerializerContext#URLENC_paramFormat} property on the URL-encoding serializers in this group.
+ * Sets the {@link UonSerializerContext#UON_paramFormat} property on the URL-encoding serializers in this group.
* <p>
* This overrides the behavior of the URL-encoding serializer to quote and escape characters
* in query names and values that may be confused for UON notation (e.g. <js>"'(foo=123)'"</js>, <js>"'@(1,2,3)'"</js>).
@@ -1109,20 +1110,34 @@ public class RestClientBuilder extends CoreObjectBuilder {
*
* @param value The new value for this property.
* @return This object (for method chaining).
- * @see UrlEncodingSerializerContext#URLENC_paramFormat
+ * @see UonSerializerContext#UON_paramFormat
*/
public RestClientBuilder paramFormat(String value) {
- super.property(UrlEncodingSerializerContext.URLENC_paramFormat, value);
+ super.property(UonSerializerContext.UON_paramFormat, value);
return this;
}
/**
* Shortcut for calling <code>paramFormat(<js>"PLAINTEXT"</js>)</code>.
+ * <p>
+ * The default behavior is to serialize part values (query parameters, form data, headers, path variables) in UON notation.
+ * Calling this method forces plain-text to be used instead.
+ * <p>
+ * Specifially, UON notation has the following effects:
+ * <ul>
+ * <li>Boolean strings (<js>"true"</js>/<js>"false"</js>) and numeric values (<js>"123"</js>) will be
+ * quoted (<js>"'true'"</js>, <js>"'false'"</js>, <js>"'123'"</js>.
+ * <br>This allows them to be differentiated from actual boolean and numeric values.
+ * <li>String such as <js>"(foo='bar')"</js> that mimic UON structures will be quoted and escaped to
+ * <js>"'(foo=bar~'baz~')'"</js>.
+ * </ul>
+ * <p>
+ * The downside to using plain text part serialization is that you cannot serialize arbitrary POJOs.
*
* @return This object (for method chaining).
*/
- public RestClientBuilder plainTextParams() {
- super.property(UrlEncodingSerializerContext.URLENC_paramFormat, "PLAINTEXT");
+ public RestClientBuilder plainTextParts() {
+ super.property(UonSerializerContext.UON_paramFormat, "PLAINTEXT");
return this;
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/RequestBeanProxyResource.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/RequestBeanProxyResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/RequestBeanProxyResource.java
new file mode 100644
index 0000000..eed0679
--- /dev/null
+++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/RequestBeanProxyResource.java
@@ -0,0 +1,50 @@
+// ***************************************************************************************************************************
+// * 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.juneau.rest.test;
+
+
+import java.io.*;
+
+import org.apache.juneau.microservice.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.annotation.*;
+
+/**
+ * Validates the functionality of <ja>@RequestBeans</ja>.
+ */
+@RestResource(
+ path="/testRequestBeanProxy"
+)
+@SuppressWarnings("serial")
+public class RequestBeanProxyResource extends ResourceJena {
+
+ @RestMethod(name="GET", path="/echoQuery")
+ public Reader echoQuery(RestRequest req) throws Exception {
+ return new StringReader(req.getQuery().toString(true));
+ }
+
+ @RestMethod(name="POST", path="/echoFormData")
+ public Reader echoFormData(RestRequest req) throws Exception {
+ return new StringReader(req.getFormData().toString(true));
+ }
+
+ @RestMethod(name="GET", path="/echoHeaders")
+ public Reader echoHeaders(RestRequest req) throws Exception {
+ return new StringReader(req.getHeaders().subset("a,b,c,d,e,f,g,h,i,a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4").toString(true));
+ }
+
+ @RestMethod(name="GET", path="/echoPath/*")
+ public Reader echoPath(RestRequest req) throws Exception {
+ return new StringReader(req.getPathMatch().getRemainder());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java
index f04181b..3bee867 100644
--- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java
+++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java
@@ -60,6 +60,7 @@ import org.apache.juneau.rest.labels.*;
PathVariablesResource.class,
PropertiesResource.class,
QueryResource.class,
+ RequestBeanProxyResource.class,
RestClient2Resource.class,
SerializersResource.class,
StaticFilesResource.class,
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/FormDataTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/FormDataTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/FormDataTest.java
index 9aeff98..d0f1874 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/FormDataTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/FormDataTest.java
@@ -68,7 +68,7 @@ public class FormDataTest extends RestTestcase {
//====================================================================================================
@Test
public void testPlainTextParams() throws Exception {
- RestClient c = TestMicroservice.client(UrlEncodingSerializer.class, UrlEncodingParser.class).plainTextParams().build();
+ RestClient c = TestMicroservice.client(UrlEncodingSerializer.class, UrlEncodingParser.class).plainTextParts().build();
String r;
Map<String,Object> m = new AMap<String,Object>()
[3/3] incubator-juneau git commit: Improvements to
@Query/@FormData/@Header/@Path remoteable annotations.
Posted by ja...@apache.org.
Improvements to @Query/@FormData/@Header/@Path remoteable annotations.
Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/93aadae1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/93aadae1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/93aadae1
Branch: refs/heads/master
Commit: 93aadae1d6c8da0b1ae81df461927ed16744576e
Parents: 13f816f
Author: JamesBognar <ja...@apache.org>
Authored: Thu Jun 1 20:00:25 2017 -0400
Committer: JamesBognar <ja...@apache.org>
Committed: Thu Jun 1 20:00:25 2017 -0400
----------------------------------------------------------------------
.../apache/juneau/annotation/BeanProperty.java | 17 +-
.../java/org/apache/juneau/http/package.html | 41 +
.../org/apache/juneau/internal/ArrayUtils.java | 29 +-
.../org/apache/juneau/internal/IOUtils.java | 30 +
.../java/org/apache/juneau/json/package.html | 4 +-
.../org/apache/juneau/remoteable/FormData.java | 150 +-
.../apache/juneau/remoteable/FormDataIfNE.java | 22 +-
.../org/apache/juneau/remoteable/Header.java | 139 +-
.../apache/juneau/remoteable/HeaderIfNE.java | 22 +-
.../java/org/apache/juneau/remoteable/Path.java | 134 +-
.../org/apache/juneau/remoteable/Query.java | 151 +-
.../org/apache/juneau/remoteable/QueryIfNE.java | 23 +-
.../juneau/remoteable/RemoteMethodArg.java | 9 +-
.../juneau/remoteable/RemoteableMethodMeta.java | 30 +-
.../apache/juneau/remoteable/RequestBean.java | 16 +-
.../juneau/serializer/PartSerializer.java | 1 +
.../org/apache/juneau/uon/UonSerializer.java | 41 +-
.../apache/juneau/uon/UonSerializerContext.java | 40 +-
.../apache/juneau/uon/UonSerializerSession.java | 15 +-
.../java/org/apache/juneau/uon/UonWriter.java | 11 +-
.../java/org/apache/juneau/uon/package.html | 4 +-
.../urlencoding/UrlEncodingSerializer.java | 47 +-
.../UrlEncodingSerializerBuilder.java | 6 +-
.../UrlEncodingSerializerContext.java | 31 +-
.../UrlEncodingSerializerSession.java | 12 +-
.../org/apache/juneau/urlencoding/package.html | 4 +-
.../java/org/apache/juneau/xml/package.html | 4 +-
juneau-core/src/main/javadoc/overview.html | 10 +-
.../org/apache/juneau/rest/client/RestCall.java | 41 +-
.../apache/juneau/rest/client/RestClient.java | 65 +-
.../juneau/rest/client/RestClientBuilder.java | 25 +-
.../rest/test/RequestBeanProxyResource.java | 50 +
.../java/org/apache/juneau/rest/test/Root.java | 1 +
.../apache/juneau/rest/test/FormDataTest.java | 2 +-
.../juneau/rest/test/RequestBeanProxyTest.java | 1988 ++++++++++++++++++
.../apache/juneau/rest/test/RestTestcase.java | 6 +-
.../org/apache/juneau/rest/test/_TestSuite.java | 1 +
.../org/apache/juneau/rest/RequestFormData.java | 23 +-
.../org/apache/juneau/rest/RequestHeaders.java | 43 +
.../org/apache/juneau/rest/RequestQuery.java | 23 +-
40 files changed, 2986 insertions(+), 325 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/annotation/BeanProperty.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/annotation/BeanProperty.java b/juneau-core/src/main/java/org/apache/juneau/annotation/BeanProperty.java
index f2461bb..f6472c0 100644
--- a/juneau-core/src/main/java/org/apache/juneau/annotation/BeanProperty.java
+++ b/juneau-core/src/main/java/org/apache/juneau/annotation/BeanProperty.java
@@ -127,21 +127,14 @@ public @interface BeanProperty {
String name() default "";
/**
- * A synonym for {@link #name()}
+ * A synonym for {@link #name()}.
* <p>
- * If you're only using the <code>BeanProperty</code> annotation to override the property name, this allows you
- * to define it using shortened notation:
- * <p class='bcode'>
- * <ja>@BeanProperty</ja>(<js>"foo"</js>)
- * <jk>public</jk> String getX();
- * }
- * </p>
+ * The following annotations are equivalent:
* <p>
- * This is equivalent to the following notation:
* <p class='bcode'>
- * <ja>@BeanProperty</ja>(name=<js>"foo"</js>)
- * <jk>public</jk> String getX();
- * }
+ * <ja>@BeanProperty</ja>(name=<js>"foo"</js>)
+ *
+ * <ja>@BeanProperty</ja>(<js>"foo"</js>)
* </p>
*/
String value() default "";
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/http/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/package.html b/juneau-core/src/main/java/org/apache/juneau/http/package.html
new file mode 100644
index 0000000..23f63da
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/package.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<!--
+/***************************************************************************************************************************
+ * 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.
+ *
+ ***************************************************************************************************************************/
+ -->
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <style type="text/css">
+ /* For viewing in Page Designer */
+ @IMPORT url("../../../../../../javadoc.css");
+
+ /* For viewing in REST interface */
+ @IMPORT url("../htdocs/javadoc.css");
+ body {
+ margin: 20px;
+ }
+ </style>
+ <script>
+ /* Replace all @code and @link tags. */
+ window.onload = function() {
+ document.body.innerHTML = document.body.innerHTML.replace(/\{\@code ([^\}]+)\}/g, '<code>$1</code>');
+ document.body.innerHTML = document.body.innerHTML.replace(/\{\@link (([^\}]+)\.)?([^\.\}]+)\}/g, '<code>$3</code>');
+ }
+ </script>
+</head>
+<body>
+<p>RFC2616 HTTP Headers</p>
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/internal/ArrayUtils.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/internal/ArrayUtils.java b/juneau-core/src/main/java/org/apache/juneau/internal/ArrayUtils.java
index 5199af1..176dbd5 100644
--- a/juneau-core/src/main/java/org/apache/juneau/internal/ArrayUtils.java
+++ b/juneau-core/src/main/java/org/apache/juneau/internal/ArrayUtils.java
@@ -205,6 +205,31 @@ public final class ArrayUtils {
}
/**
+ * Returns <jk>true</jk> if the specified object is an array.
+ * @param array The array to test.
+ * @return <jk>true</jk> if the specified object is an array.
+ */
+ public static boolean isArray(Object array) {
+ return array != null && array.getClass().isArray();
+ }
+
+ /**
+ * Converts the specified array to an <code>ArrayList</code>
+ *
+ * @param array The array to convert.
+ * @param componentType The type of objects in the array.
+ * It must match the actual component type in the array.
+ * @return A new {@link ArrayList}
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> List<T> toList(Object array, Class<T> componentType) {
+ List<T> l = new ArrayList<T>(Array.getLength(array));
+ for (int i = 0; i < Array.getLength(array); i++)
+ l.add((T)Array.get(array, i));
+ return l;
+ }
+
+ /**
* Shortcut for calling <code>myList.toArray(new T[myList.size()]);</code>
*
* @param c The collection being converted to an array.
@@ -227,14 +252,16 @@ public final class ArrayUtils {
*
* @param array The array to copy into a list.
* @param list The list to copy the values into.
+ * @return The same list passed in.
*/
@SuppressWarnings({"unchecked","rawtypes"})
- public static void copyToList(Object array, List list) {
+ public static List copyToList(Object array, List list) {
if (array != null) {
int length = Array.getLength(array);
for (int i = 0; i < length; i++)
list.add(Array.get(array, i));
}
+ return list;
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/internal/IOUtils.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/internal/IOUtils.java b/juneau-core/src/main/java/org/apache/juneau/internal/IOUtils.java
index 1d0a5cc..516cd2e 100644
--- a/juneau-core/src/main/java/org/apache/juneau/internal/IOUtils.java
+++ b/juneau-core/src/main/java/org/apache/juneau/internal/IOUtils.java
@@ -53,6 +53,36 @@ public final class IOUtils {
}
/**
+ * Reads the specified object to a <code>String</code>.
+ * <p>
+ * Can be any of the following object types:
+ * <ul>
+ * <li>{@link CharSequence}
+ * <li>{@link File}
+ * <li>{@link Reader}
+ * <li>{@link InputStream}
+ * <li><code><jk>byte</jk>[]</code>
+ * </ul>
+ *
+ * @param o The object to read.
+ * @return The object serialized to a string, or <jk>null</jk> if it wasn't a supported type.
+ * @throws IOException
+ */
+ public static String read(Object o) throws IOException {
+ if (o instanceof CharSequence)
+ return o.toString();
+ if (o instanceof File)
+ return read((File)o);
+ if (o instanceof Reader)
+ return read((Reader)o);
+ if (o instanceof InputStream)
+ return read((InputStream)o);
+ if (o instanceof byte[])
+ return read(new ByteArrayInputStream((byte[])o));
+ return null;
+ }
+
+ /**
* Writes the contents of the specified <code>Reader</code> to the specified file.
*
* @param out The file to write the output to.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/json/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/package.html b/juneau-core/src/main/java/org/apache/juneau/json/package.html
index b6decc1..960ea0b 100644
--- a/juneau-core/src/main/java/org/apache/juneau/json/package.html
+++ b/juneau-core/src/main/java/org/apache/juneau/json/package.html
@@ -359,12 +359,12 @@
<p>
Another useful feature is the {@link org.apache.juneau.annotation.Bean#propertyNamer()} annotation that allows you to plug in your own
logic for determining bean property names.<br>
- The {@link org.apache.juneau.PropertyNamerDashedLC} is an example of an alternate property namer.
+ The {@link org.apache.juneau.PropertyNamerDLC} is an example of an alternate property namer.
It converts bean property names to lowercase-dashed format.
</p>
<h6 class='topic'>Example:</h6>
<p class='bcode'>
- <ja>@Bean</ja>(propertyNamer=PropertyNamerDashedLC.<jk>class</jk>)
+ <ja>@Bean</ja>(propertyNamer=PropertyNamerDLC.<jk>class</jk>)
<jk>public class</jk> Person {
...
</p>
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/remoteable/FormData.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/remoteable/FormData.java b/juneau-core/src/main/java/org/apache/juneau/remoteable/FormData.java
index 83389b8..0bd91ad 100644
--- a/juneau-core/src/main/java/org/apache/juneau/remoteable/FormData.java
+++ b/juneau-core/src/main/java/org/apache/juneau/remoteable/FormData.java
@@ -17,7 +17,6 @@ import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.*;
-import org.apache.juneau.annotation.*;
import org.apache.juneau.serializer.*;
import org.apache.juneau.urlencoding.*;
@@ -29,27 +28,39 @@ import org.apache.juneau.urlencoding.*;
* <ja>@Remoteable</ja>(path=<js>"/myproxy"</js>)
* <jk>public interface</jk> MyProxy {
*
+ * <jc>// Explicit names specified for form data parameters.</jc>
+ * <jc>// pojo will be converted to UON notation (unless plain-text parts enabled).</jc>
* <ja>@RemoteMethod</ja>(path=<js>"/mymethod1"</js>)
* String myProxyMethod1(<ja>@FormData</ja>(<js>"foo"</js>)</ja> String foo, <ja>@FormData</ja>(<js>"bar"</js>)</ja> MyPojo pojo);
*
+ * <jc>// Multiple values pulled from a NameValuePairs object.</jc>
+ * <jc>// Same as @FormData("*").</jc>
* <ja>@RemoteMethod</ja>(path=<js>"/mymethod2"</js>)
- * String myProxyMethod2(<ja>@FormData</ja> NameValuePairs form);
+ * String myProxyMethod2(<ja>@FormData</ja> NameValuePairs nameValuePairs);
*
+ * <jc>// Multiple values pulled from a Map.</jc>
+ * <jc>// Same as @FormData("*").</jc>
* <ja>@RemoteMethod</ja>(path=<js>"/mymethod3"</js>)
- * String myProxyMethod2(<ja>@FormData</ja> Map<String,Object> form);
+ * String myProxyMethod3(<ja>@FormData</ja> Map<String,Object> map);
+ *
+ * <jc>// Multiple values pulled from a bean.</jc>
+ * <jc>// Same as @FormData("*").</jc>
+ * <ja>@RemoteMethod</ja>(path=<js>"/mymethod4"</js>)
+ * String myProxyMethod4(<ja>@FormData</ja> MyBean myBean);
+ *
+ * <jc>// An entire form-data HTTP body as a String.</jc>
+ * <jc>// Same as @FormData("*").</jc>
+ * <ja>@RemoteMethod</ja>(path=<js>"/mymethod5"</js>)
+ * String myProxyMethod5(<ja>@FormData</ja> String string);
+ *
+ * <jc>// An entire form-data HTTP body as a Reader.</jc>
+ * <jc>// Sames as @FormData("*").</jc>
+ * <ja>@RemoteMethod</ja>(path=<js>"/mymethod6"</js>)
+ * String myProxyMethod6(<ja>@FormData</ja> Reader reader);
+ *
* }
* </p>
* <p>
- * The argument can be any of the following types:
- * <ul class='spaced-list'>
- * <li>Any serializable POJO - Converted to text using {@link UrlEncodingSerializer#serialize(PartType,Object)}.
- * <li><code>NameValuePairs</code> - Individual name-value pairs.
- * <li><code>Map<String,Object></code> - Individual name-value pairs.
- * Values are converted to text using {@link UrlEncodingSerializer#serialize(PartType,Object)}.
- * <li>A bean - Individual name-value pairs.
- * Values are converted to text using {@link UrlEncodingSerializer#serialize(PartType,Object)}.
- * </ul>
- * <p>
* The annotation can also be applied to a bean property field or getter when the argument is annotated with
* {@link RequestBean @RequestBean}:
* <p>
@@ -63,18 +74,52 @@ import org.apache.juneau.urlencoding.*;
* }
*
* <jk>public interface</jk> MyRequestBean {
+ *
+ * <jc>// Name explicitly specified.</jc>
+ * <ja>@FormData</ja>(<js>"foo"</js>)
+ * String getX();
+ *
+ * <jc>// Name inherited from bean property.</jc>
+ * <jc>// Same as @FormData("bar")</jc>
+ * <ja>@FormData</ja>
+ * String getBar();
+ *
+ * <jc>// Name inherited from bean property.</jc>
+ * <jc>// Same as @FormData("baz")</jc>
+ * <ja>@FormData</ja>
+ * <ja>@BeanProperty</ja>(<js>"baz"</js>)
+ * String getY();
+ *
+ * <jc>// Multiple values pulled from NameValuePairs object.</jc>
+ * <jc>// Same as @FormData("*")</jc>
+ * <ja>@FormData</ja>
+ * NameValuePairs getNameValuePairs();
+ *
+ * <jc>// Multiple values pulled from Map.</jc>
+ * <jc>// Same as @FormData("*")</jc>
+ * <ja>@FormData</ja>
+ * Map<String,Object> getMap();
+ *
+ * <jc>// Multiple values pulled from bean.</jc>
+ * <jc>// Same as @FormData("*")</jc>
* <ja>@FormData</ja>
- * String getFoo();
+ * MyBean getMyBean();
*
+ * <jc>// An entire form-data HTTP body as a Reader.</jc>
+ * <jc>// Same as @FormData("*")</jc>
* <ja>@FormData</ja>
- * MyPojo getBar();
+ * Reader getReader();
* }
* </p>
* <p>
- * When used in a request bean, the {@link #value()} can be used to override the form data parameter name.
- * It can also be overridden via the {@link BeanProperty#name @BeanProperty.name()} annotation.
- * A name of <js>"*"</js> where the bean property value is a map or bean will cause the individual entries in the
- * map or bean to be expanded to form data parameters.
+ * The {@link #name()} and {@link #value()} elements are synonyms for specifying the parameter name. Only one should be used.
+ * <br>The following annotations are fully equivalent:
+ * <p>
+ * <p class='bcode'>
+ * <ja>@FormData</ja>(name=<js>"foo"</js>)
+ *
+ * <ja>@FormData</ja>(<js>"foo"</js>)
+ * </p>
*/
@Documented
@Target({PARAMETER,FIELD,METHOD})
@@ -85,22 +130,71 @@ public @interface FormData {
/**
* The form post parameter name.
* <p>
- * A value of <js>"*"</js> indicates the value should be serialized as name/value pairs and is applicable
- * for the following data types:
- * <ul>
- * <li><code>NameValuePairs</code>
- * <li><code>Map<String,Object></code>
- * <li>A bean
+ * Note that {@link #name()} and {@link #value()} are synonyms.
+ * <p>
+ * The value should be either <js>"*"</js> to represent multiple name/value pairs, or a label that defines the
+ * form data parameter name.
+ * <p>
+ * A blank value (the default) has the following behavior:
+ * <ul class='spaced-list'>
+ * <li>If the data type is <code>NameValuePairs</code>, <code>Map</code>, or a bean,
+ * then it's the equivalent to <js>"*"</js> which will cause the value to be serialized as name/value pairs.
+ * <h6 class='figure'>Example:</h6>
+ * <p class='bcode'>
+ * <jc>// When used on a remote method parameter</jc>
+ * <ja>@Remoteable</ja>(path=<js>"/myproxy"</js>)
+ * <jk>public interface</jk> MyProxy {
+ *
+ * <jc>// Equivalent to @FormData("*")</jc>
+ * <ja>@RemoteMethod</ja>(path=<js>"/mymethod"</js>)
+ * String myProxyMethod1(<ja>@FormData</ja> Map<String,Object> formData);
+ * }
+ *
+ * <jc>// When used on a request bean method</jc>
+ * <jk>public interface</jk> MyRequestBean {
+ *
+ * <jc>// Equivalent to @FormData("*")</jc>
+ * <ja>@FormData</ja>
+ * Map<String,Object> getFoo();
+ * }
+ * </p>
+ * <br>
+ * <li>If used on a request bean method, uses the bean property name.
+ * <h6 class='figure'>Example:</h6>
+ * <p class='bcode'>
+ * <jk>public interface</jk> MyRequestBean {
+ *
+ * <jc>// Equivalent to @FormData("foo")</jc>
+ * <ja>@FormData</ja>
+ * String getFoo();
+ * }
+ * </p>
+ * </ul>
* </ul>
*/
- String value() default "*";
+ String name() default "";
+
+ /**
+ * A synonym for {@link #name()}.
+ * <p>
+ * Allows you to use shortened notation if you're only specifying the name.
+ */
+ String value() default "";
+
+ /**
+ * Skips this value if it's an empty string or empty collection/array.
+ * <p>
+ * Note that <jk>null</jk> values are already ignored.
+ */
+ boolean skipIfEmpty() default false;
/**
* Specifies the {@link PartSerializer} class used for serializing values to strings.
* <p>
- * The default serializer converters values to UON notation.
+ * The default value defaults to the using the part serializer defined on the {@link RequestBean} annotation,
+ * then on the client which by default is {@link UrlEncodingSerializer}.
* <p>
* This annotation is provided to allow values to be custom serialized.
*/
- Class<? extends PartSerializer> serializer() default UrlEncodingSerializer.class;
+ Class<? extends PartSerializer> serializer() default PartSerializer.class;
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/remoteable/FormDataIfNE.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/remoteable/FormDataIfNE.java b/juneau-core/src/main/java/org/apache/juneau/remoteable/FormDataIfNE.java
index 2d0b3ab..494a2cf 100644
--- a/juneau-core/src/main/java/org/apache/juneau/remoteable/FormDataIfNE.java
+++ b/juneau-core/src/main/java/org/apache/juneau/remoteable/FormDataIfNE.java
@@ -31,23 +31,23 @@ public @interface FormDataIfNE {
/**
* The form post parameter name.
- * <p>
- * A value of <js>"*"</js> indicates the value should be serialized as name/value pairs and is applicable
- * for the following data types:
- * <ul>
- * <li><code>NameValuePairs</code>
- * <li><code>Map<String,Object></code>
- * <li>A bean
- * </ul>
+ * @see FormData#name()
+ */
+ String name() default "";
+
+ /**
+ * A synonym for {@link #name()}.
+ * @see FormData#value()
*/
- String value() default "*";
+ String value() default "";
/**
* Specifies the {@link PartSerializer} class used for serializing values to strings.
* <p>
- * The default serializer converters values to UON notation.
+ * The default value defaults to the using the part serializer defined on the {@link RequestBean} annotation,
+ * then on the client which by default is {@link UrlEncodingSerializer}.
* <p>
* This annotation is provided to allow values to be custom serialized.
*/
- Class<? extends PartSerializer> serializer() default UrlEncodingSerializer.class;
+ Class<? extends PartSerializer> serializer() default PartSerializer.class;
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/remoteable/Header.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/remoteable/Header.java b/juneau-core/src/main/java/org/apache/juneau/remoteable/Header.java
index 6eaf870..d733e0d 100644
--- a/juneau-core/src/main/java/org/apache/juneau/remoteable/Header.java
+++ b/juneau-core/src/main/java/org/apache/juneau/remoteable/Header.java
@@ -17,7 +17,6 @@ import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.*;
-import org.apache.juneau.annotation.*;
import org.apache.juneau.serializer.*;
import org.apache.juneau.urlencoding.*;
@@ -29,24 +28,28 @@ import org.apache.juneau.urlencoding.*;
* <ja>@Remoteable</ja>(path=<js>"/myproxy"</js>)
* <jk>public interface</jk> MyProxy {
*
+ * <jc>// Explicit names specified for HTTP headers.</jc>
+ * <jc>// pojo will be converted to UON notation (unless plain-text parts enabled).</jc>
* <ja>@RemoteMethod</ja>(path=<js>"/mymethod1"</js>)
* String myProxyMethod1(<ja>@Header</ja>(<js>"Foo"</js>)</ja> String foo, <ja>@Header</ja>(<js>"Bar"</js>)</ja> MyPojo pojo);
*
+ * <jc>// Multiple values pulled from a NameValuePairs object.</jc>
+ * <jc>// Same as @Header("*").</jc>
* <ja>@RemoteMethod</ja>(path=<js>"/mymethod2"</js>)
- * String myProxyMethod2(<ja>@Header</ja> Map<String,Object> headers);
+ * String myProxyMethod2(<ja>@Header</ja> NameValuePairs nameValuePairs);
+ *
+ * <jc>// Multiple values pulled from a Map.</jc>
+ * <jc>// Same as @Header("*").</jc>
+ * <ja>@RemoteMethod</ja>(path=<js>"/mymethod3"</js>)
+ * String myProxyMethod3(<ja>@Header</ja> Map<String,Object> map);
+ *
+ * <jc>// Multiple values pulled from a bean.</jc>
+ * <jc>// Same as @Header("*").</jc>
+ * <ja>@RemoteMethod</ja>(path=<js>"/mymethod4"</js>)
+ * String myProxyMethod4(<ja>@Header</ja> MyBean myBean);
* }
* </p>
* <p>
- * The argument can be any of the following types:
- * <ul class='spaced-list'>
- * <li><code>NameValuePairs</code> - Individual name-value pairs.
- * <li>Any serializable POJO - Converted to text using {@link UrlEncodingSerializer#serialize(PartType,Object)}.
- * <li><code>Map<String,Object></code> - Individual name-value pairs.
- * Values are converted to text using {@link UrlEncodingSerializer#serialize(PartType,Object)}.
- * <li>A bean - Individual name-value pairs.
- * Values are converted to text using {@link UrlEncodingSerializer#serialize(PartType,Object)}.
- * </ul>
- * <p>
* The annotation can also be applied to a bean property field or getter when the argument is annotated with
* {@link RequestBean @RequestBean}:
* <p>
@@ -60,18 +63,47 @@ import org.apache.juneau.urlencoding.*;
* }
*
* <jk>public interface</jk> MyRequestBean {
+ *
+ * <jc>// Name explicitly specified.</jc>
* <ja>@Header</ja>(<js>"Foo"</js>)
- * String getFoo();
+ * String getX();
+ *
+ * <jc>// Name inherited from bean property.</jc>
+ * <jc>// Same as @Header("bar")</jc>
+ * <ja>@Header</ja>
+ * String getBar();
+ *
+ * <jc>// Name inherited from bean property.</jc>
+ * <jc>// Same as @Header("Baz")</jc>
+ * <ja>@Header</ja>
+ * <ja>@BeanProperty</ja>(<js>"Baz"</js>)
+ * String getY();
*
- * <ja>@Header</ja>(<js>"Bar"</js>)
- * MyPojo getBar();
+ * <jc>// Multiple values pulled from NameValuePairs object.</jc>
+ * <jc>// Same as @Header("*")</jc>
+ * <ja>@Header</ja>
+ * NameValuePairs getNameValuePairs();
+ *
+ * <jc>// Multiple values pulled from Map.</jc>
+ * <jc>// Same as @Header("*")</jc>
+ * <ja>@Header</ja>
+ * Map<String,Object> getMap();
+ *
+ * <jc>// Multiple values pulled from bean.</jc>
+ * <jc>// Same as @Header("*")</jc>
+ * <ja>@Header</ja>
+ * MyBean getBean();
* }
* </p>
* <p>
- * When used in a request bean, the {@link #value()} can be used to override the header name.
- * It can also be overridden via the {@link BeanProperty#name @BeanProperty.name()} annotation.
- * A name of <js>"*"</js> where the bean property value is a map or bean will cause the individual entries in the
- * map or bean to be expanded to headers.
+ * The {@link #name()} and {@link #value()} elements are synonyms for specifying the header name. Only one should be used.
+ * <br>The following annotations are fully equivalent:
+ * <p>
+ * <p class='bcode'>
+ * <ja>@Header</ja>(name=<js>"Foo"</js>)
+ *
+ * <ja>@Header</ja>(<js>"Foo"</js>)
+ * </p>
*/
@Documented
@Target({PARAMETER,FIELD,METHOD})
@@ -82,22 +114,73 @@ public @interface Header {
/**
* The HTTP header name.
* <p>
- * A value of <js>"*"</js> indicates the value should be serialized as name/value pairs and is applicable
- * for the following data types:
- * <ul>
- * <li><code>NameValuePairs</code>
- * <li><code>Map<String,Object></code>
- * <li>A bean
+ * A blank value (the default) indicates to reuse the bean property name when used on a request bean property.
+ * <p>
+ * <p>
+ * The value should be either <js>"*"</js> to represent multiple name/value pairs, or a label that defines the
+ * header name.
+ * <p>
+ * A blank value (the default) has the following behavior:
+ * <ul class='spaced-list'>
+ * <li>If the data type is <code>NameValuePairs</code>, <code>Map</code>, or a bean,
+ * then it's the equivalent to <js>"*"</js> which will cause the value to be serialized as name/value pairs.
+ * <h6 class='figure'>Example:</h6>
+ * <p class='bcode'>
+ * <jc>// When used on a remote method parameter</jc>
+ * <ja>@Remoteable</ja>(path=<js>"/myproxy"</js>)
+ * <jk>public interface</jk> MyProxy {
+ *
+ * <jc>// Equivalent to @Header("*")</jc>
+ * <ja>@RemoteMethod</ja>(path=<js>"/mymethod"</js>)
+ * String myProxyMethod1(<ja>@Header</ja> Map<String,Object> headers);
+ * }
+ *
+ * <jc>// When used on a request bean method</jc>
+ * <jk>public interface</jk> MyRequestBean {
+ *
+ * <jc>// Equivalent to @Header("*")</jc>
+ * <ja>@Header</ja>
+ * Map<String,Object> getFoo();
+ * }
+ * </p>
+ * <br>
+ * <li>If used on a request bean method, uses the bean property name.
+ * <h6 class='figure'>Example:</h6>
+ * <p class='bcode'>
+ * <jk>public interface</jk> MyRequestBean {
+ *
+ * <jc>// Equivalent to @Header("Foo")</jc>
+ * <ja>@Header</ja>
+ * <ja>@BeanProperty</ja>(<js>"Foo"</js>)
+ * String getFoo();
+ * }
+ * </p>
+ * </ul>
* </ul>
*/
- String value() default "*";
+ String name() default "";
+
+ /**
+ * A synonym for {@link #name()}.
+ * <p>
+ * Allows you to use shortened notation if you're only specifying the name.
+ */
+ String value() default "";
+
+ /**
+ * Skips this value if it's an empty string or empty collection/array.
+ * <p>
+ * Note that <jk>null</jk> values are already ignored.
+ */
+ boolean skipIfEmpty() default false;
/**
* Specifies the {@link PartSerializer} class used for serializing values to strings.
* <p>
- * The default serializer converters values to UON notation.
+ * The default value defaults to the using the part serializer defined on the {@link RequestBean} annotation,
+ * then on the client which by default is {@link UrlEncodingSerializer}.
* <p>
* This annotation is provided to allow values to be custom serialized.
*/
- Class<? extends PartSerializer> serializer() default UrlEncodingSerializer.class;
+ Class<? extends PartSerializer> serializer() default PartSerializer.class;
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/remoteable/HeaderIfNE.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/remoteable/HeaderIfNE.java b/juneau-core/src/main/java/org/apache/juneau/remoteable/HeaderIfNE.java
index 4839ff0..eb81015 100644
--- a/juneau-core/src/main/java/org/apache/juneau/remoteable/HeaderIfNE.java
+++ b/juneau-core/src/main/java/org/apache/juneau/remoteable/HeaderIfNE.java
@@ -31,23 +31,23 @@ public @interface HeaderIfNE {
/**
* The HTTP header name.
- * <p>
- * A value of <js>"*"</js> indicates the value should be serialized as name/value pairs and is applicable
- * for the following data types:
- * <ul>
- * <li><code>NameValuePairs</code>
- * <li><code>Map<String,Object></code>
- * <li>A bean
- * </ul>
+ * @see Header#name()
+ */
+ String name() default "";
+
+ /**
+ * A synonym for {@link #name()}.
+ * @see Header#value()
*/
- String value() default "*";
+ String value() default "";
/**
* Specifies the {@link PartSerializer} class used for serializing values to strings.
* <p>
- * The default serializer converters values to UON notation.
+ * The default value defaults to the using the part serializer defined on the {@link RequestBean} annotation,
+ * then on the client which by default is {@link UrlEncodingSerializer}.
* <p>
* This annotation is provided to allow values to be custom serialized.
*/
- Class<? extends PartSerializer> serializer() default UrlEncodingSerializer.class;
+ Class<? extends PartSerializer> serializer() default PartSerializer.class;
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/remoteable/Path.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/remoteable/Path.java b/juneau-core/src/main/java/org/apache/juneau/remoteable/Path.java
index 919615e..3f5874d 100644
--- a/juneau-core/src/main/java/org/apache/juneau/remoteable/Path.java
+++ b/juneau-core/src/main/java/org/apache/juneau/remoteable/Path.java
@@ -17,7 +17,6 @@ import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.*;
-import org.apache.juneau.annotation.*;
import org.apache.juneau.serializer.*;
import org.apache.juneau.urlencoding.*;
@@ -29,21 +28,28 @@ import org.apache.juneau.urlencoding.*;
* <ja>@Remoteable</ja>(path=<js>"/myproxy"</js>)
* <jk>public interface</jk> MyProxy {
*
- * <ja>@RemoteMethod</ja>(path=<js>"/mymethod1/{foo}"</js>)
- * String myProxyMethod1(<ja>@Path</ja>(<js>"foo"</js>)</ja> String foo);
+ * <jc>// Explicit names specified for path parameters.</jc>
+ * <jc>// pojo will be converted to UON notation (unless plain-text parts enabled).</jc>
+ * <ja>@RemoteMethod</ja>(path=<js>"/mymethod1/{foo}/{bar}"</js>)
+ * String myProxyMethod1(<ja>@Path</ja>(<js>"foo"</js>)</ja> String foo, <ja>@Path</ja>(<js>"bar"</js>)</ja> MyPojo pojo);
+ *
+ * <jc>// Multiple values pulled from a NameValuePairs object.</jc>
+ * <jc>// Same as @Path("*").</jc>
+ * <ja>@RemoteMethod</ja>(path=<js>"/mymethod2/{foo}/{bar}/{baz}"</js>)
+ * String myProxyMethod2(<ja>@Path</ja> NameValuePairs nameValuePairs);
+ *
+ * <jc>// Multiple values pulled from a Map.</jc>
+ * <jc>// Same as @Path("*").</jc>
+ * <ja>@RemoteMethod</ja>(path=<js>"/mymethod3/{foo}/{bar}/{baz}"</js>)
+ * String myProxyMethod3(<ja>@Path</ja> Map<String,Object> map);
+ *
+ * <jc>// Multiple values pulled from a bean.</jc>
+ * <jc>// Same as @Path("*").</jc>
+ * <ja>@RemoteMethod</ja>(path=<js>"/mymethod4/{foo}/{bar}/{baz}"</js>)
+ * String myProxyMethod4(<ja>@Path</ja> MyBean myBean);
* }
* </p>
* <p>
- * The argument can be any of the following types:
- * <ul class='spaced-list'>
- * <li><code>NameValuePairs</code> - Individual name-value pairs.
- * <li>Any serializable POJO - Converted to text using {@link UrlEncodingSerializer#serialize(PartType,Object)}.
- * <li><code>Map<String,Object></code> - Individual name-value pairs.
- * Values are converted to text using {@link UrlEncodingSerializer#serialize(PartType,Object)}.
- * <li>A bean - Individual name-value pairs.
- * Values are converted to text using {@link UrlEncodingSerializer#serialize(PartType,Object)}.
- * </ul>
- * <p>
* The annotation can also be applied to a bean property field or getter when the argument is annotated with
* {@link RequestBean @RequestBean}:
* <p>
@@ -52,20 +58,52 @@ import org.apache.juneau.urlencoding.*;
* <ja>@Remoteable</ja>(path=<js>"/myproxy"</js>)
* <jk>public interface</jk> MyProxy {
*
- * <ja>@RemoteMethod</ja>(path=<js>"/mymethod1/{foo}"</js>)
+ * <ja>@RemoteMethod</ja>(path=<js>"/mymethod/{foo}/{bar}/{baz}"</js>)
* String myProxyMethod(<ja>@RequestBean</ja> MyRequestBean bean);
* }
*
* <jk>public interface</jk> MyRequestBean {
+ *
+ * <jc>// Name explicitly specified.</jc>
+ * <ja>@Path</ja>(<js>"foo"</js>)
+ * String getX();
+ *
+ * <jc>// Name inherited from bean property.</jc>
+ * <jc>// Same as @Path("bar")</jc>
+ * <ja>@Path</ja>
+ * String getBar();
+ *
+ * <jc>// Name inherited from bean property.</jc>
+ * <jc>// Same as @Path("baz")</jc>
+ * <ja>@Path</ja>
+ * <ja>@BeanProperty</ja>(<js>"baz"</js>)
+ * String getY();
+ *
+ * <jc>// Multiple values pulled from NameValuePairs object.</jc>
+ * <jc>// Same as @Path("*")</jc>
+ * <ja>@Path</ja>
+ * NameValuePairs getNameValuePairs();
+ *
+ * <jc>// Multiple values pulled from Map.</jc>
+ * <jc>// Same as @Path("*")</jc>
* <ja>@Path</ja>
- * String getFoo();
+ * Map<String,Object> getMap();
+ *
+ * <jc>// Multiple values pulled from bean.</jc>
+ * <jc>// Same as @Path("*")</jc>
+ * <ja>@Path</ja>
+ * MyBean getMyBean();
* }
* </p>
* <p>
- * When used in a request bean, the {@link #value()} can be used to override the path variable name.
- * It can also be overridden via the {@link BeanProperty#name @BeanProperty.name()} annotation.
- * A name of <js>"*"</js> where the bean property value is a map or bean will cause the individual entries in the
- * map or bean to be expanded to path variables.
+ * The {@link #name()} and {@link #value()} elements are synonyms for specifying the path variable name. Only one should be used.
+ * <br>The following annotations are fully equivalent:
+ * <p>
+ * <p class='bcode'>
+ * <ja>@Path</ja>(name=<js>"foo"</js>)
+ *
+ * <ja>@Path</ja>(<js>"foo"</js>)
+ * </p>
*/
@Documented
@Target({PARAMETER,FIELD,METHOD})
@@ -76,22 +114,62 @@ public @interface Path {
/**
* The path parameter name.
* <p>
- * A value of <js>"*"</js> indicates the value should be serialized as name/value pairs and is applicable
- * for the following data types:
- * <ul>
- * <li><code>NameValuePairs</code>
- * <li><code>Map<String,Object></code>
- * <li>A bean
+ * Note that {@link #name()} and {@link #value()} are synonyms.
+ * <p>
+ * The value should be either <js>"*"</js> to represent multiple name/value pairs, or a label that defines the
+ * path variable name.
+ * <p>
+ * A blank value (the default) has the following behavior:
+ * <ul class='spaced-list'>
+ * <li>If the data type is <code>NameValuePairs</code>, <code>Map</code>, or a bean,
+ * then it's the equivalent to <js>"*"</js> which will cause the value to be treated as name/value pairs.
+ * <h6 class='figure'>Example:</h6>
+ * <p class='bcode'>
+ * <jc>// When used on a remote method parameter</jc>
+ * <ja>@Remoteable</ja>(path=<js>"/myproxy"</js>)
+ * <jk>public interface</jk> MyProxy {
+ *
+ * <jc>// Equivalent to @Path("*")</jc>
+ * <ja>@RemoteMethod</ja>(path=<js>"/mymethod/{foo}/{bar}"</js>)
+ * String myProxyMethod1(<ja>@FormData</ja> Map<String,Object> pathVars);
+ * }
+ *
+ * <jc>// When used on a request bean method</jc>
+ * <jk>public interface</jk> MyRequestBean {
+ *
+ * <jc>// Equivalent to @Path("*")</jc>
+ * <ja>@Path</ja>
+ * Map<String,Object> getPathVars();
+ * }
+ * </p>
+ * <br>
+ * <li>If used on a request bean method, uses the bean property name.
+ * <h6 class='figure'>Example:</h6>
+ * <p class='bcode'>
+ * <jk>public interface</jk> MyRequestBean {
+ *
+ * <jc>// Equivalent to @Path("foo")</jc>
+ * <ja>@Path</ja>
+ * String getFoo();
+ * }
* </ul>
*/
- String value() default "*";
+ String name() default "";
+
+ /**
+ * A synonym for {@link #name()}.
+ * <p>
+ * Allows you to use shortened notation if you're only specifying the name.
+ */
+ String value() default "";
/**
* Specifies the {@link PartSerializer} class used for serializing values to strings.
* <p>
- * The default serializer converters values to UON notation.
+ * The default value defaults to the using the part serializer defined on the {@link RequestBean} annotation,
+ * then on the client which by default is {@link UrlEncodingSerializer}.
* <p>
* This annotation is provided to allow values to be custom serialized.
*/
- Class<? extends PartSerializer> serializer() default UrlEncodingSerializer.class;
+ Class<? extends PartSerializer> serializer() default PartSerializer.class;
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/remoteable/Query.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/remoteable/Query.java b/juneau-core/src/main/java/org/apache/juneau/remoteable/Query.java
index 7738468..35540e5 100644
--- a/juneau-core/src/main/java/org/apache/juneau/remoteable/Query.java
+++ b/juneau-core/src/main/java/org/apache/juneau/remoteable/Query.java
@@ -17,7 +17,6 @@ import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.*;
-import org.apache.juneau.annotation.*;
import org.apache.juneau.serializer.*;
import org.apache.juneau.urlencoding.*;
@@ -29,28 +28,38 @@ import org.apache.juneau.urlencoding.*;
* <ja>@Remoteable</ja>(path=<js>"/myproxy"</js>)
* <jk>public interface</jk> MyProxy {
*
+ * <jc>// Explicit names specified for query parameters.</jc>
+ * <jc>// pojo will be converted to UON notation (unless plain-text parts enabled).</jc>
* <ja>@RemoteMethod</ja>(path=<js>"/mymethod1"</js>)
* String myProxyMethod1(<ja>@Query</ja>(<js>"foo"</js>)</ja> String foo, <ja>@Query</ja>(<js>"bar"</js>)</ja> MyPojo pojo);
*
+ * <jc>// Multiple values pulled from a NameValuePairs object.</jc>
+ * <jc>// Same as @Query("*").</jc>
* <ja>@RemoteMethod</ja>(path=<js>"/mymethod2"</js>)
- * String myProxyMethod2(<ja>@Query</ja> Map<String,Object> query);
+ * String myProxyMethod2(<ja>@Query</ja> NameValuePairs nameValuePairs);
*
+ * <jc>// Multiple values pulled from a Map.</jc>
+ * <jc>// Same as @Query("*").</jc>
* <ja>@RemoteMethod</ja>(path=<js>"/mymethod3"</js>)
- * String myProxyMethod2(<ja>@Query</ja> String queryString);
+ * String myProxyMethod3(<ja>@Query</ja> Map<String,Object> map);
+ *
+ * <jc>// Multiple values pulled from a bean.</jc>
+ * <jc>// Same as @Query("*").</jc>
+ * <ja>@RemoteMethod</ja>(path=<js>"/mymethod4"</js>)
+ * String myProxyMethod4(<ja>@Query</ja> MyBean myBean);
+ *
+ * <jc>// An entire query string as a String.</jc>
+ * <jc>// Same as @FQuery("*").</jc>
+ * <ja>@RemoteMethod</ja>(path=<js>"/mymethod5"</js>)
+ * String myProxyMethod5(<ja>@Query</ja> String string);
+ *
+ * <jc>// An entire query string as a Reader.</jc>
+ * <jc>// Same as @Query("*").</jc>
+ * <ja>@RemoteMethod</ja>(path=<js>"/mymethod6"</js>)
+ * String myProxyMethod6(<ja>@Query</ja> Reader reader);
* }
* </p>
* <p>
- * The argument can be any of the following types:
- * <ul class='spaced-list'>
- * <li><code>NameValuePairs</code> - Individual name-value pairs.
- * <li>Any serializable POJO - Converted to text using {@link UrlEncodingSerializer#serialize(PartType,Object)}.
- * <li><code>Map<String,Object></code> - Individual name-value pairs.
- * Values are converted to text using {@link UrlEncodingSerializer#serialize(PartType,Object)}.
- * <li>A bean - Individual name-value pairs.
- * Values are converted to text using {@link UrlEncodingSerializer#serialize(PartType,Object)}.
- * <li>{@link String} - Treated as a query string.
- * </ul>
- * <p>
* The annotation can also be applied to a bean property field or getter when the argument is annotated with
* {@link RequestBean @RequestBean}:
* <p>
@@ -64,18 +73,52 @@ import org.apache.juneau.urlencoding.*;
* }
*
* <jk>public interface</jk> MyRequestBean {
+ *
+ * <jc>// Name explicitly specified.</jc>
+ * <ja>@Query</ja>(<js>"foo"</js>)
+ * String getX();
+ *
+ * <jc>// Name inherited from bean property.</jc>
+ * <jc>// Same as @Query("bar")</jc>
+ * <ja>@Query</ja>
+ * String getBar();
+ *
+ * <jc>// Name inherited from bean property.</jc>
+ * <jc>// Same as @Query("baz")</jc>
+ * <ja>@Query</ja>
+ * <ja>@BeanProperty</ja>(<js>"baz"</js>)
+ * String getY();
+ *
+ * <jc>// Multiple values pulled from NameValuePairs object.</jc>
+ * <jc>// Same as @Query("*")</jc>
+ * <ja>@Query</ja>
+ * NameValuePairs getNameValuePairs();
+ *
+ * <jc>// Multiple values pulled from Map.</jc>
+ * <jc>// Same as @Query("*")</jc>
+ * <ja>@Query</ja>
+ * Map<String,Object> getMap();
+ *
+ * <jc>// Multiple values pulled from bean.</jc>
+ * <jc>// Same as @Query("*")</jc>
* <ja>@Query</ja>
- * String getFoo();
+ * MyBean getMyBean();
*
+ * <jc>// An entire query string as a Reader.</jc>
+ * <jc>// Same as @Query("*")</jc>
* <ja>@Query</ja>
- * MyPojo getBar();
+ * Reader getReader();
* }
* </p>
* <p>
- * When used in a request bean, the {@link #value()} can be used to override the query parameter name.
- * It can also be overridden via the {@link BeanProperty#name @BeanProperty.name()} annotation.
- * A name of <js>"*"</js> where the bean property value is a map or bean will cause the individual entries in the
- * map or bean to be expanded to query parameters.
+ * The {@link #name()} and {@link #value()} elements are synonyms for specifying the parameter name. Only one should be used.
+ * <br>The following annotations are fully equivalent:
+ * <p>
+ * <p class='bcode'>
+ * <ja>@Query</ja>(name=<js>"foo"</js>)
+ *
+ * <ja>@Query</ja>(<js>"foo"</js>)
+ * </p>
*/
@Documented
@Target({PARAMETER,FIELD,METHOD})
@@ -86,23 +129,71 @@ public @interface Query {
/**
* The query parameter name.
* <p>
- * A value of <js>"*"</js> indicates the value should be serialized as name/value pairs and is applicable
- * for the following data types:
- * <ul>
- * <li><code>String</code> - A complete query string.
- * <li><code>NameValuePairs</code>
- * <li><code>Map<String,Object></code>
- * <li>A bean
+ * Note that {@link #name()} and {@link #value()} are synonyms.
+ * <p>
+ * The value should be either <js>"*"</js> to represent multiple name/value pairs, or a label that defines the
+ * query parameter name.
+ * <p>
+ * A blank value (the default) has the following behavior:
+ * <ul class='spaced-list'>
+ * <li>If the data type is <code>NameValuePairs</code>, <code>Map</code>, or a bean,
+ * then it's the equivalent to <js>"*"</js> which will cause the value to be serialized as name/value pairs.
+ * <h6 class='figure'>Example:</h6>
+ * <p class='bcode'>
+ * <jc>// When used on a remote method parameter</jc>
+ * <ja>@Remoteable</ja>(path=<js>"/myproxy"</js>)
+ * <jk>public interface</jk> MyProxy {
+ *
+ * <jc>// Equivalent to @Query("*")</jc>
+ * <ja>@RemoteMethod</ja>(path=<js>"/mymethod"</js>)
+ * String myProxyMethod1(<ja>@Query</ja> Map<String,Object> formData);
+ * }
+ *
+ * <jc>// When used on a request bean method</jc>
+ * <jk>public interface</jk> MyRequestBean {
+ *
+ * <jc>// Equivalent to @Query("*")</jc>
+ * <ja>@Query</ja>
+ * Map<String,Object> getFoo();
+ * }
+ * </p>
+ * <br>
+ * <li>If used on a request bean method, uses the bean property name.
+ * <h6 class='figure'>Example:</h6>
+ * <p class='bcode'>
+ * <jk>public interface</jk> MyRequestBean {
+ *
+ * <jc>// Equivalent to @Query("foo")</jc>
+ * <ja>@Query</ja>
+ * String getFoo();
+ * }
+ * </p>
+ * </ul>
* </ul>
*/
- String value() default "*";
+ String name() default "";
+
+ /**
+ * A synonym for {@link #name()}.
+ * <p>
+ * Allows you to use shortened notation if you're only specifying the name.
+ */
+ String value() default "";
+
+ /**
+ * Skips this value if it's an empty string or empty collection/array.
+ * <p>
+ * Note that <jk>null</jk> values are already ignored.
+ */
+ boolean skipIfEmpty() default false;
/**
* Specifies the {@link PartSerializer} class used for serializing values to strings.
* <p>
- * The default serializer converters values to UON notation.
+ * The default value defaults to the using the part serializer defined on the {@link RequestBean} annotation,
+ * then on the client which by default is {@link UrlEncodingSerializer}.
* <p>
* This annotation is provided to allow values to be custom serialized.
*/
- Class<? extends PartSerializer> serializer() default UrlEncodingSerializer.class;
+ Class<? extends PartSerializer> serializer() default PartSerializer.class;
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/remoteable/QueryIfNE.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/remoteable/QueryIfNE.java b/juneau-core/src/main/java/org/apache/juneau/remoteable/QueryIfNE.java
index 8d38510..968c974 100644
--- a/juneau-core/src/main/java/org/apache/juneau/remoteable/QueryIfNE.java
+++ b/juneau-core/src/main/java/org/apache/juneau/remoteable/QueryIfNE.java
@@ -31,24 +31,23 @@ public @interface QueryIfNE {
/**
* The query parameter name.
- * <p>
- * A value of <js>"*"</js> indicates the value should be serialized as name/value pairs and is applicable
- * for the following data types:
- * <ul>
- * <li><code>String</code> - A complete query string.
- * <li><code>NameValuePairs</code>
- * <li><code>Map<String,Object></code>
- * <li>A bean
- * </ul>
+ * @see Query#name()
+ */
+ String name() default "";
+
+ /**
+ * A synonym for {@link #name()}.
+ * @see Query#value()
*/
- String value() default "*";
+ String value() default "";
/**
* Specifies the {@link PartSerializer} class used for serializing values to strings.
* <p>
- * The default serializer converters values to UON notation.
+ * The default value defaults to the using the part serializer defined on the {@link RequestBean} annotation,
+ * then on the client which by default is {@link UrlEncodingSerializer}.
* <p>
* This annotation is provided to allow values to be custom serialized.
*/
- Class<? extends PartSerializer> serializer() default UrlEncodingSerializer.class;
+ Class<? extends PartSerializer> serializer() default PartSerializer.class;
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/remoteable/RemoteMethodArg.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/remoteable/RemoteMethodArg.java b/juneau-core/src/main/java/org/apache/juneau/remoteable/RemoteMethodArg.java
index ab9a44c..97a4af3 100644
--- a/juneau-core/src/main/java/org/apache/juneau/remoteable/RemoteMethodArg.java
+++ b/juneau-core/src/main/java/org/apache/juneau/remoteable/RemoteMethodArg.java
@@ -35,19 +35,20 @@ public class RemoteMethodArg {
/**
* Constructor.
*
- * @param name The argument name. Can be blank.
+ * @param name The argument name pulled from name().
+ * @param name2 The argument name pulled from value().
* @param index The zero-based index of the argument on the Java method.
* @param skipIfNE The value is skipped if it's null/empty.
* @param serializer The class to use for serializing headers, query paramters, form-data parameters, and
* path variables.
* If {@link UrlEncodingSerializer}, then the url-encoding serializer defined on the client will be used.
*/
- protected RemoteMethodArg(String name, int index, boolean skipIfNE, Class<? extends PartSerializer> serializer) {
- this.name = name;
+ protected RemoteMethodArg(String name, String name2, int index, boolean skipIfNE, Class<? extends PartSerializer> serializer) {
+ this.name = name.isEmpty() ? name2 : name;
this.index = index;
this.skipIfNE = skipIfNE;
try {
- this.serializer = (serializer == UrlEncodingSerializer.class ? null : serializer.newInstance());
+ this.serializer = (serializer == PartSerializer.class ? null : serializer.newInstance());
} catch (Exception e) {
throw new RuntimeException(e);
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/remoteable/RemoteableMethodMeta.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/remoteable/RemoteableMethodMeta.java b/juneau-core/src/main/java/org/apache/juneau/remoteable/RemoteableMethodMeta.java
index 13b96b4..772cb4f 100644
--- a/juneau-core/src/main/java/org/apache/juneau/remoteable/RemoteableMethodMeta.java
+++ b/juneau-core/src/main/java/org/apache/juneau/remoteable/RemoteableMethodMeta.java
@@ -29,8 +29,8 @@ public class RemoteableMethodMeta {
private final String httpMethod;
private final String url;
- private final RemoteMethodArg[] pathArgs, queryArgs, headerArgs, formDataArgs;
- private final Integer[] requestBeanArgs, otherArgs;
+ private final RemoteMethodArg[] pathArgs, queryArgs, headerArgs, formDataArgs, requestBeanArgs;
+ private final Integer[] otherArgs;
private final Integer bodyArg;
/**
@@ -47,7 +47,7 @@ public class RemoteableMethodMeta {
this.queryArgs = b.queryArgs.toArray(new RemoteMethodArg[b.queryArgs.size()]);
this.formDataArgs = b.formDataArgs.toArray(new RemoteMethodArg[b.formDataArgs.size()]);
this.headerArgs = b.headerArgs.toArray(new RemoteMethodArg[b.headerArgs.size()]);
- this.requestBeanArgs = b.requestBeanArgs.toArray(new Integer[b.requestBeanArgs.size()]);
+ this.requestBeanArgs = b.requestBeanArgs.toArray(new RemoteMethodArg[b.requestBeanArgs.size()]);
this.otherArgs = b.otherArgs.toArray(new Integer[b.otherArgs.size()]);
this.bodyArg = b.bodyArg;
}
@@ -58,9 +58,9 @@ public class RemoteableMethodMeta {
pathArgs = new LinkedList<RemoteMethodArg>(),
queryArgs = new LinkedList<RemoteMethodArg>(),
headerArgs = new LinkedList<RemoteMethodArg>(),
- formDataArgs = new LinkedList<RemoteMethodArg>();
+ formDataArgs = new LinkedList<RemoteMethodArg>(),
+ requestBeanArgs = new LinkedList<RemoteMethodArg>();
private List<Integer>
- requestBeanArgs = new LinkedList<Integer>(),
otherArgs = new LinkedList<Integer>();
private Integer bodyArg;
@@ -90,28 +90,28 @@ public class RemoteableMethodMeta {
Class<?> ca = a.annotationType();
if (ca == Path.class) {
Path p = (Path)a;
- annotated = pathArgs.add(new RemoteMethodArg(p.value(), index, false, p.serializer()));
+ annotated = pathArgs.add(new RemoteMethodArg(p.name(), p.value(), index, false, p.serializer()));
} else if (ca == Query.class) {
Query q = (Query)a;
- annotated = queryArgs.add(new RemoteMethodArg(q.value(), index, false, q.serializer()));
+ annotated = queryArgs.add(new RemoteMethodArg(q.name(), q.value(), index, q.skipIfEmpty(), q.serializer()));
} else if (ca == QueryIfNE.class) {
QueryIfNE q = (QueryIfNE)a;
- annotated = queryArgs.add(new RemoteMethodArg(q.value(), index, true, q.serializer()));
+ annotated = queryArgs.add(new RemoteMethodArg(q.name(), q.value(), index, true, q.serializer()));
} else if (ca == FormData.class) {
FormData f = (FormData)a;
- annotated = formDataArgs.add(new RemoteMethodArg(f.value(), index, false, f.serializer()));
+ annotated = formDataArgs.add(new RemoteMethodArg(f.name(), f.value(), index, f.skipIfEmpty(), f.serializer()));
} else if (ca == FormDataIfNE.class) {
FormDataIfNE f = (FormDataIfNE)a;
- annotated = formDataArgs.add(new RemoteMethodArg(f.value(), index, true, f.serializer()));
+ annotated = formDataArgs.add(new RemoteMethodArg(f.name(), f.value(), index, true, f.serializer()));
} else if (ca == Header.class) {
Header h = (Header)a;
- annotated = headerArgs.add(new RemoteMethodArg(h.value(), index, false, h.serializer()));
+ annotated = headerArgs.add(new RemoteMethodArg(h.name(), h.value(), index, h.skipIfEmpty(), h.serializer()));
} else if (ca == HeaderIfNE.class) {
HeaderIfNE h = (HeaderIfNE)a;
- annotated = headerArgs.add(new RemoteMethodArg(h.value(), index, true, h.serializer()));
+ annotated = headerArgs.add(new RemoteMethodArg(h.name(), h.value(), index, true, h.serializer()));
} else if (ca == RequestBean.class) {
- annotated = true;
- requestBeanArgs.add(index);
+ RequestBean rb = (RequestBean)a;
+ annotated = requestBeanArgs.add(new RemoteMethodArg("", "", index, false, rb.serializer()));
} else if (ca == Body.class) {
annotated = true;
if (bodyArg == null)
@@ -182,7 +182,7 @@ public class RemoteableMethodMeta {
* Returns the {@link RequestBean @RequestBean} annotated arguments on this Java method.
* @return A list of zero-indexed argument indices.
*/
- public Integer[] getRequestBeanArgs() {
+ public RemoteMethodArg[] getRequestBeanArgs() {
return requestBeanArgs;
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/remoteable/RequestBean.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/remoteable/RequestBean.java b/juneau-core/src/main/java/org/apache/juneau/remoteable/RequestBean.java
index 3da7f6c..0c18874 100644
--- a/juneau-core/src/main/java/org/apache/juneau/remoteable/RequestBean.java
+++ b/juneau-core/src/main/java/org/apache/juneau/remoteable/RequestBean.java
@@ -17,6 +17,9 @@ import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.urlencoding.*;
+
/**
* Annotation applied to Java method arguments of interface proxies to denote a bean with remoteable annotations.
* <p>
@@ -82,4 +85,15 @@ import java.lang.annotation.*;
@Target(PARAMETER)
@Retention(RUNTIME)
@Inherited
-public @interface RequestBean {}
+public @interface RequestBean {
+
+ /**
+ * Specifies the {@link PartSerializer} class used for serializing values to strings.
+ * <p>
+ * The default value defaults to the using the part serializer defined on the client which by default is
+ * {@link UrlEncodingSerializer}.
+ * <p>
+ * This annotation is provided to allow values to be custom serialized.
+ */
+ Class<? extends PartSerializer> serializer() default PartSerializer.class;
+}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/serializer/PartSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/PartSerializer.java b/juneau-core/src/main/java/org/apache/juneau/serializer/PartSerializer.java
index 0063b9e..37d0fc5 100644
--- a/juneau-core/src/main/java/org/apache/juneau/serializer/PartSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/serializer/PartSerializer.java
@@ -31,6 +31,7 @@ import org.apache.juneau.urlencoding.*;
* <li>{@link Header#serializer()}
* <li>{@link HeaderIfNE#serializer()}
* <li>{@link Path#serializer()}
+ * <li>{@link RequestBean#serializer()}
* <li><code>RestClientBuilder.partSerializer(Class)</code>
* </ul>
* <p>
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializer.java b/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializer.java
index b358920..8eed75b 100644
--- a/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializer.java
@@ -204,17 +204,16 @@ public class UonSerializer extends WriterSerializer {
* @param eType The expected type of the object if this is a bean property.
* @param attrName The bean property name if this is a bean property. <jk>null</jk> if this isn't a bean property being serialized.
* @param pMeta The bean property metadata.
- * @param plainTextParams <jk>true</jk> if this is a top level parameter key or value and paramFormat is PLAINTEXT.
*
* @return The same writer passed in.
* @throws Exception
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
protected SerializerWriter serializeAnything(UonSerializerSession session, UonWriter out, Object o, ClassMeta<?> eType,
- String attrName, BeanPropertyMeta pMeta, boolean plainTextParams) throws Exception {
+ String attrName, BeanPropertyMeta pMeta) throws Exception {
if (o == null) {
- out.appendObject(null, false, plainTextParams);
+ out.appendObject(null, false);
return out;
}
@@ -249,7 +248,7 @@ public class UonSerializer extends WriterSerializer {
// '\0' characters are considered null.
if (o == null || (sType.isChar() && ((Character)o).charValue() == 0))
- out.appendObject(null, false, plainTextParams);
+ out.appendObject(null, false);
else if (sType.isBoolean())
out.appendBoolean(o);
else if (sType.isNumber())
@@ -271,7 +270,7 @@ public class UonSerializer extends WriterSerializer {
serializeCollection(session, out, toList(sType.getInnerClass(), o), eType);
}
else {
- out.appendObject(o, false, plainTextParams);
+ out.appendObject(o, false);
}
if (! isRecursion)
@@ -287,7 +286,9 @@ public class UonSerializer extends WriterSerializer {
ClassMeta<?> keyType = type.getKeyType(), valueType = type.getValueType();
int depth = session.getIndent();
- out.append('(');
+
+ if (! session.isPlainTextParams())
+ out.append('(');
Iterator mapEntries = m.entrySet().iterator();
@@ -295,15 +296,17 @@ public class UonSerializer extends WriterSerializer {
Map.Entry e = (Map.Entry) mapEntries.next();
Object value = e.getValue();
Object key = session.generalize(e.getKey(), keyType);
- out.cr(depth).appendObject(key, false, false).append('=');
- serializeAnything(session, out, value, valueType, (key == null ? null : session.toString(key)), null, false);
+ out.cr(depth).appendObject(key, false).append('=');
+ serializeAnything(session, out, value, valueType, (key == null ? null : session.toString(key)), null);
if (mapEntries.hasNext())
out.append(',');
}
if (m.size() > 0)
out.cr(depth-1);
- out.append(')');
+
+ if (! session.isPlainTextParams())
+ out.append(')');
return out;
}
@@ -311,7 +314,8 @@ public class UonSerializer extends WriterSerializer {
private SerializerWriter serializeBeanMap(UonSerializerSession session, UonWriter out, BeanMap<?> m, String typeName) throws Exception {
int depth = session.getIndent();
- out.append('(');
+ if (! session.isPlainTextParams())
+ out.append('(');
boolean addComma = false;
@@ -331,16 +335,17 @@ public class UonSerializer extends WriterSerializer {
if (addComma)
out.append(',');
- out.cr(depth).appendObject(key, false, false).append('=');
+ out.cr(depth).appendObject(key, false).append('=');
- serializeAnything(session, out, value, cMeta, key, pMeta, false);
+ serializeAnything(session, out, value, cMeta, key, pMeta);
addComma = true;
}
if (m.size() > 0)
out.cr(depth-1);
- out.append(')');
+ if (! session.isPlainTextParams())
+ out.append(')');
return out;
}
@@ -352,20 +357,22 @@ public class UonSerializer extends WriterSerializer {
c = session.sort(c);
- out.append('@').append('(');
+ if (! session.isPlainTextParams())
+ out.append('@').append('(');
int depth = session.getIndent();
for (Iterator i = c.iterator(); i.hasNext();) {
out.cr(depth);
- serializeAnything(session, out, i.next(), elementType, "<iterator>", null, false);
+ serializeAnything(session, out, i.next(), elementType, "<iterator>", null);
if (i.hasNext())
out.append(',');
}
if (c.size() > 0)
out.cr(depth-1);
- out.append(')');
+ if (! session.isPlainTextParams())
+ out.append(')');
return out;
}
@@ -383,6 +390,6 @@ public class UonSerializer extends WriterSerializer {
@Override /* Serializer */
protected void doSerialize(SerializerSession session, Object o) throws Exception {
UonSerializerSession s = (UonSerializerSession)session;
- serializeAnything(s, s.getWriter(), o, s.getExpectedRootType(o), "root", null, false);
+ serializeAnything(s, s.getWriter(), o, s.getExpectedRootType(o), "root", null);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerContext.java b/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerContext.java
index b9ce464..ab2f931 100644
--- a/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerContext.java
@@ -71,10 +71,38 @@ public class UonSerializerContext extends SerializerContext {
*/
public static final String UON_addBeanTypeProperties = "UonSerializer.addBeanTypeProperties";
+ /**
+ * <b>Configuration property:</b> Format to use for query/form-data/header values.
+ * <p>
+ * <ul>
+ * <li><b>Name:</b> <js>"UrlEncodingSerializer.paramFormat"</js>
+ * <li><b>Data type:</b> <code>String</code>
+ * <li><b>Default:</b> <js>"UON"</js>
+ * <li><b>Session-overridable:</b> <jk>true</jk>
+ * </ul>
+ * <p>
+ * Specifies the format to use for URL GET parameter keys and values.
+ * <p>
+ * The possible values are:
+ * <ul>
+ * <li><js>"UON"</js> (default) - Use UON notation for values.
+ * <br>String values such as <js>"(foo='bar')"</js> will end up being quoted and escaped to <js>"'(foo=bar~'baz~')'"</js>.
+ * <br>Boolean strings (<js>"true"</js>/<js>"false"</js>) and numeric values (<js>"123"</js>) will also end up
+ * quoted (<js>"'true'"</js>, <js>"'false'"</js>, <js>"'123'"</js>.
+ * <li><js>"PLAINTEXT"</js> (default) - Serialize as plain text.
+ * <br>Strings will never be quoted or escaped.
+ * <br>Note that this can cause errors during parsing if you're using the URL-encoding parser to parse
+ * the results since UON constructs won't be differentiatable.
+ * <br>However, this is not an issue if you're simply creating queries or form posts against 3rd-party interfaces.
+ * </ul>
+ */
+ public static final String UON_paramFormat = "UonSerializer.paramFormat";
+
final boolean
encodeChars,
- addBeanTypeProperties;
+ addBeanTypeProperties,
+ plainTextParams;
/**
* Constructor.
@@ -87,6 +115,7 @@ public class UonSerializerContext extends SerializerContext {
super(ps);
encodeChars = ps.getProperty(UON_encodeChars, boolean.class, false);
addBeanTypeProperties = ps.getProperty(UON_addBeanTypeProperties, boolean.class, ps.getProperty(SERIALIZER_addBeanTypeProperties, boolean.class, true));
+ plainTextParams = ps.getProperty(UON_paramFormat, String.class, "UON").equals("PLAINTEXT");
}
@Override /* Context */
@@ -95,6 +124,15 @@ public class UonSerializerContext extends SerializerContext {
.append("UonSerializerContext", new ObjectMap()
.append("encodeChars", encodeChars)
.append("addBeanTypeProperties", addBeanTypeProperties)
+ .append("plainTextParams", plainTextParams)
);
}
+
+ /**
+ * Returns <jk>true</jk> if the {@link UonSerializerContext#UON_paramFormat} is <js>"PLAINTEXT"</js>.
+ * @return <jk>true</jk> if the {@link UonSerializerContext#UON_paramFormat} is <js>"PLAINTEXT"</js>.
+ */
+ public boolean plainTextParams() {
+ return plainTextParams;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
index e9f9659..b7c6c66 100644
--- a/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
@@ -32,7 +32,8 @@ public class UonSerializerSession extends SerializerSession {
private final boolean
encodeChars,
- addBeanTypeProperties;
+ addBeanTypeProperties,
+ plainTextParams;
/**
* Create a new session using properties specified in the context.
@@ -57,9 +58,11 @@ public class UonSerializerSession extends SerializerSession {
if (op == null || op.isEmpty()) {
encodeChars = encode == null ? ctx.encodeChars : encode;
addBeanTypeProperties = ctx.addBeanTypeProperties;
+ plainTextParams = ctx.plainTextParams;
} else {
encodeChars = encode == null ? op.getBoolean(UON_encodeChars, ctx.encodeChars) : encode;
addBeanTypeProperties = op.getBoolean(MSGPACK_addBeanTypeProperties, ctx.addBeanTypeProperties);
+ plainTextParams = op.getString(UonSerializerContext.UON_paramFormat, "UON").equals("PLAINTEXT");
}
}
@@ -82,11 +85,19 @@ public class UonSerializerSession extends SerializerSession {
return addBeanTypeProperties;
}
+ /**
+ * Returns <jk>true</jk> if the {@link UonSerializerContext#UON_paramFormat} is <js>"PLAINTEXT"</js>.
+ * @return <jk>true</jk> if the {@link UonSerializerContext#UON_paramFormat} is <js>"PLAINTEXT"</js>.
+ */
+ public boolean isPlainTextParams() {
+ return plainTextParams;
+ }
+
@Override /* SerializerSession */
public final UonWriter getWriter() throws Exception {
Object output = getOutput();
if (output instanceof UonWriter)
return (UonWriter)output;
- return new UonWriter(this, super.getWriter(), isUseWhitespace(), isEncodeChars(), isTrimStrings(), getUriResolver());
+ return new UonWriter(this, super.getWriter(), isUseWhitespace(), isEncodeChars(), isTrimStrings(), isPlainTextParams(), getUriResolver());
}
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/uon/UonWriter.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/UonWriter.java b/juneau-core/src/main/java/org/apache/juneau/uon/UonWriter.java
index 2844e62..1aafc74 100644
--- a/juneau-core/src/main/java/org/apache/juneau/uon/UonWriter.java
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/UonWriter.java
@@ -29,7 +29,7 @@ import org.apache.juneau.serializer.*;
public final class UonWriter extends SerializerWriter {
private final UonSerializerSession session;
- private final boolean encodeChars;
+ private final boolean encodeChars, plainTextParams;
// Characters that do not need to be URL-encoded in strings.
private static final AsciiSet unencodedChars = new AsciiSet("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789;/?:@-_.!*'$(),~=");
@@ -53,12 +53,14 @@ public final class UonWriter extends SerializerWriter {
* @param useWhitespace If <jk>true</jk>, tabs will be used in output.
* @param encodeChars If <jk>true</jk>, special characters should be encoded.
* @param trimStrings If <jk>true</jk>, strings should be trimmed before they're serialized.
+ * @param plainTextParams If <jk>true</jk>, don't use UON notation for values.
* @param uriResolver The URI resolver for resolving URIs to absolute or root-relative form.
*/
- protected UonWriter(UonSerializerSession session, Writer out, boolean useWhitespace, boolean encodeChars, boolean trimStrings, UriResolver uriResolver) {
+ protected UonWriter(UonSerializerSession session, Writer out, boolean useWhitespace, boolean encodeChars, boolean trimStrings, boolean plainTextParams, UriResolver uriResolver) {
super(out, useWhitespace, trimStrings, '\'', uriResolver);
this.session = session;
this.encodeChars = encodeChars;
+ this.plainTextParams = plainTextParams;
}
/**
@@ -66,11 +68,10 @@ public final class UonWriter extends SerializerWriter {
*
* @param o The object being serialized.
* @param isTopAttrName If this is a top-level attribute name we're serializing.
- * @param plainTextParams This is a top-level name or parameter we're serializing and the parameter format is PLAINTEXT.
* @return This object (for method chaining).
* @throws IOException Should never happen.
*/
- public final UonWriter appendObject(Object o, boolean isTopAttrName, boolean plainTextParams) throws IOException {
+ public final UonWriter appendObject(Object o, boolean isTopAttrName) throws IOException {
if (o instanceof Boolean)
return appendBoolean(o);
@@ -164,7 +165,7 @@ public final class UonWriter extends SerializerWriter {
*/
@Override
public SerializerWriter appendUri(Object uri) throws IOException {
- return appendObject(uriResolver.resolve(uri), false, false);
+ return appendObject(uriResolver.resolve(uri), false);
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/uon/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/package.html b/juneau-core/src/main/java/org/apache/juneau/uon/package.html
index 1794466..440f5b2 100644
--- a/juneau-core/src/main/java/org/apache/juneau/uon/package.html
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/package.html
@@ -467,12 +467,12 @@
<p>
Another useful feature is the {@link org.apache.juneau.annotation.Bean#propertyNamer()} annotation that allows you to plug in your own
logic for determining bean property names.<br>
- The {@link org.apache.juneau.PropertyNamerDashedLC} is an example of an alternate property namer.
+ The {@link org.apache.juneau.PropertyNamerDLC} is an example of an alternate property namer.
It converts bean property names to lowercase-dashed format.
</p>
<h6 class='figure'>Example:</h6>
<p class='bcode'>
- <ja>@Bean</ja>(propertyNamer=PropertyNamerDashedLC.<jk>class</jk>)
+ <ja>@Bean</ja>(propertyNamer=PropertyNamerDLC.<jk>class</jk>)
<jk>public class</jk> Person {
...
</p>
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
index 2ab697a..df35f9a 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
@@ -137,6 +137,9 @@ public class UrlEncodingSerializer extends UonSerializer implements PartSerializ
/** Reusable instance of {@link UrlEncodingSerializer}, all default settings. */
public static final UrlEncodingSerializer DEFAULT = new UrlEncodingSerializer(PropertyStore.create());
+ /** Reusable instance of {@link UrlEncodingSerializer.PlainText}. */
+ public static final UrlEncodingSerializer DEFAULT_PLAINTEXT = new PlainText(PropertyStore.create());
+
/** Reusable instance of {@link UrlEncodingSerializer.Expanded}. */
public static final UrlEncodingSerializer DEFAULT_EXPANDED = new Expanded(PropertyStore.create());
@@ -182,6 +185,24 @@ public class UrlEncodingSerializer extends UonSerializer implements PartSerializ
}
}
+ /**
+ * Equivalent to <code><jk>new</jk> UrlEncodingSerializerBuilder().plainTextParts().build();</code>.
+ */
+ public static class PlainText extends UrlEncodingSerializer {
+
+ /**
+ * Constructor.
+ * @param propertyStore The property store containing all the settings for this object.
+ */
+ public PlainText(PropertyStore propertyStore) {
+ super(propertyStore);
+ }
+
+ @Override /* CoreObject */
+ protected ObjectMap getOverrideProperties() {
+ return super.getOverrideProperties().append(UonSerializerContext.UON_paramFormat, "PLAINTEXT");
+ }
+ }
private final UrlEncodingSerializerContext ctx;
@@ -247,7 +268,7 @@ public class UrlEncodingSerializer extends UonSerializer implements PartSerializ
// All other types can't be serialized as key/value pairs, so we create a
// mock key/value pair with a "_value" key.
out.append("_value=");
- super.serializeAnything(session, out, o, null, null, null, session.plainTextParams());
+ super.serializeAnything(session, out, o, null, null, null);
}
session.pop();
@@ -278,7 +299,6 @@ public class UrlEncodingSerializer extends UonSerializer implements PartSerializ
@SuppressWarnings({ "rawtypes", "unchecked" })
private SerializerWriter serializeMap(UrlEncodingSerializerSession session, UonWriter out, Map m, ClassMeta<?> type) throws Exception {
- boolean plainTextParams = session.plainTextParams();
m = session.sort(m);
ClassMeta<?> keyType = type.getKeyType(), valueType = type.getValueType();
@@ -295,15 +315,15 @@ public class UrlEncodingSerializer extends UonSerializer implements PartSerializ
while (i.hasNext()) {
if (addAmp)
out.cr(depth).append('&');
- out.appendObject(key, true, plainTextParams).append('=');
- super.serializeAnything(session, out, i.next(), null, (key == null ? null : key.toString()), null, plainTextParams);
+ out.appendObject(key, true).append('=');
+ super.serializeAnything(session, out, i.next(), null, (key == null ? null : key.toString()), null);
addAmp = true;
}
} else {
if (addAmp)
out.cr(depth).append('&');
- out.appendObject(key, true, plainTextParams).append('=');
- super.serializeAnything(session, out, value, valueType, (key == null ? null : key.toString()), null, plainTextParams);
+ out.appendObject(key, true).append('=');
+ super.serializeAnything(session, out, value, valueType, (key == null ? null : key.toString()), null);
addAmp = true;
}
}
@@ -323,7 +343,7 @@ public class UrlEncodingSerializer extends UonSerializer implements PartSerializ
if (addAmp)
out.cr(depth).append('&');
out.append(e.getKey()).append('=');
- super.serializeAnything(session, out, e.getValue(), valueType, null, null, session.plainTextParams());
+ super.serializeAnything(session, out, e.getValue(), valueType, null, null);
addAmp = true;
}
@@ -333,7 +353,6 @@ public class UrlEncodingSerializer extends UonSerializer implements PartSerializ
@SuppressWarnings({ "rawtypes" })
private SerializerWriter serializeBeanMap(UrlEncodingSerializerSession session, UonWriter out, BeanMap<?> m, String typeName) throws Exception {
int depth = session.getIndent();
- boolean plainTextParams = session.plainTextParams();
boolean addAmp = false;
@@ -358,9 +377,9 @@ public class UrlEncodingSerializer extends UonSerializer implements PartSerializ
if (addAmp)
out.cr(depth).append('&');
- out.appendObject(key, true, plainTextParams).append('=');
+ out.appendObject(key, true).append('=');
- super.serializeAnything(session, out, i.next(), cMeta.getElementType(), key, pMeta, plainTextParams);
+ super.serializeAnything(session, out, i.next(), cMeta.getElementType(), key, pMeta);
addAmp = true;
}
@@ -368,9 +387,9 @@ public class UrlEncodingSerializer extends UonSerializer implements PartSerializ
if (addAmp)
out.cr(depth).append('&');
- out.appendObject(key, true, plainTextParams).append('=');
+ out.appendObject(key, true).append('=');
- super.serializeAnything(session, out, value, cMeta, key, pMeta, plainTextParams);
+ super.serializeAnything(session, out, value, cMeta, key, pMeta);
addAmp = true;
}
@@ -405,8 +424,8 @@ public class UrlEncodingSerializer extends UonSerializer implements PartSerializ
return o.toString();
if (cm.isCharSequence()) {
String s = o.toString();
- boolean ptt = (plainTextParams != null ? plainTextParams : ctx.plainTextParams);
- if (ptt || ! UonUtils.needsQuotes(s))
+ boolean ptt = (plainTextParams != null ? plainTextParams : ctx.plainTextParams());
+ if (ptt || s.isEmpty() || ! UonUtils.needsQuotes(s))
return (urlEncode ? StringUtils.urlEncode(s) : s);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerBuilder.java
index 7c79631..e7ff61e 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerBuilder.java
@@ -124,17 +124,17 @@ public class UrlEncodingSerializerBuilder extends UonSerializerBuilder {
*
* @param paramFormat The new value for this property.
* @return This object (for method chaining).
- * @see UrlEncodingSerializerContext#URLENC_paramFormat
+ * @see UonSerializerContext#UON_paramFormat
*/
public UrlEncodingSerializerBuilder paramFormat(String paramFormat) {
- return property(UrlEncodingSerializerContext.URLENC_paramFormat, paramFormat);
+ return property(UonSerializerContext.UON_paramFormat, paramFormat);
}
/**
* Shortcut for calling <code>paramFormat(<js>"PLAINTEXT"</js>)</code>.
*
* @return This object (for method chaining).
- * @see UrlEncodingSerializerContext#URLENC_paramFormat
+ * @see UonSerializerContext#UON_paramFormat
*/
public UrlEncodingSerializerBuilder plainTextParams() {
return paramFormat("PLAINTEXT");
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerContext.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerContext.java
index 1894b0a..d7ff160 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerContext.java
@@ -25,36 +25,9 @@ import org.apache.juneau.uon.*;
*/
public class UrlEncodingSerializerContext extends UonSerializerContext {
- /**
- * <b>Configuration property:</b> Format to use for top-level query names and simple parameters.
- * <p>
- * <ul>
- * <li><b>Name:</b> <js>"UrlEncodingSerializer.paramFormat"</js>
- * <li><b>Data type:</b> <code>String</code>
- * <li><b>Default:</b> <js>"UON"</js>
- * <li><b>Session-overridable:</b> <jk>true</jk>
- * </ul>
- * <p>
- * Specifies the format to use for URL GET parameter keys and values.
- * <p>
- * The possible values are:
- * <ul>
- * <li><js>"UON"</js> (default) - Use UON notation for values.
- * <br>String values such as <js>"(foo='bar')"</js> will end up being quoted and escaped to <js>"'(foo=bar~'baz~')'"</js>.
- * <br>Similarly, boolean and numeric values will also end up quoted.
- * <li><js>"PLAINTEXT"</js> (default) - Serialize as plain text.
- * <br>Strings will never be quoted or escaped.
- * <br>Note that this can cause errors during parsing if you're using the URL-encoding parser to parse
- * the results since UON constructs won't be differentiatable.
- * <br>However, this is not an issue if you're simply creating queries or form posts against 3rd-party interfaces.
- * </ul>
- */
- public static final String URLENC_paramFormat = "UrlEncodingSerializer.paramFormat";
-
final boolean
- expandedParams,
- plainTextParams;
+ expandedParams;
/**
* Constructor.
@@ -66,7 +39,6 @@ public class UrlEncodingSerializerContext extends UonSerializerContext {
public UrlEncodingSerializerContext(PropertyStore ps) {
super(ps);
this.expandedParams = ps.getProperty(UrlEncodingContext.URLENC_expandedParams, boolean.class, false);
- this.plainTextParams = ps.getProperty(UrlEncodingSerializerContext.URLENC_paramFormat, String.class, "UON").equals("PLAINTEXT");
}
@Override /* Context */
@@ -74,7 +46,6 @@ public class UrlEncodingSerializerContext extends UonSerializerContext {
return super.asMap()
.append("UrlEncodingSerializerContext", new ObjectMap()
.append("expandedParams", expandedParams)
- .append("plainTextParams", plainTextParams)
);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
index a7a93e3..d9c39d9 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
@@ -27,7 +27,7 @@ import org.apache.juneau.uon.*;
*/
public class UrlEncodingSerializerSession extends UonSerializerSession {
- private final boolean expandedParams, plainTextParams;
+ private final boolean expandedParams;
/**
* Create a new session using properties specified in the context.
@@ -51,10 +51,8 @@ public class UrlEncodingSerializerSession extends UonSerializerSession {
super(ctx, encode, op, output, javaMethod, locale, timeZone, mediaType, uriContext);
if (op == null || op.isEmpty()) {
expandedParams = ctx.expandedParams;
- plainTextParams = ctx.plainTextParams;
} else {
expandedParams = op.getBoolean(UrlEncodingContext.URLENC_expandedParams, false);
- plainTextParams = op.getString(UrlEncodingSerializerContext.URLENC_paramFormat, "UON").equals("PLAINTEXT");
}
}
@@ -91,12 +89,4 @@ public class UrlEncodingSerializerSession extends UonSerializerSession {
}
return false;
}
-
- /**
- * Returns <jk>true</jk> if the {@link UrlEncodingSerializerContext#URLENC_paramFormat} is <js>"PLAINTEXT"</js>.
- * @return <jk>true</jk> if the {@link UrlEncodingSerializerContext#URLENC_paramFormat} is <js>"PLAINTEXT"</js>.
- */
- protected boolean plainTextParams() {
- return plainTextParams;
- }
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/urlencoding/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/package.html b/juneau-core/src/main/java/org/apache/juneau/urlencoding/package.html
index ce7f90e..88349fc 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/package.html
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/package.html
@@ -467,12 +467,12 @@
<p>
Another useful feature is the {@link org.apache.juneau.annotation.Bean#propertyNamer()} annotation that allows you to plug in your own
logic for determining bean property names.<br>
- The {@link org.apache.juneau.PropertyNamerDashedLC} is an example of an alternate property namer.
+ The {@link org.apache.juneau.PropertyNamerDLC} is an example of an alternate property namer.
It converts bean property names to lowercase-dashed format.
</p>
<h6 class='figure'>Example:</h6>
<p class='bcode'>
- <ja>@Bean</ja>(propertyNamer=PropertyNamerDashedLC.<jk>class</jk>)
+ <ja>@Bean</ja>(propertyNamer=PropertyNamerDLC.<jk>class</jk>)
<jk>public class</jk> Person {
...
</p>
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/java/org/apache/juneau/xml/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/package.html b/juneau-core/src/main/java/org/apache/juneau/xml/package.html
index 3b2647e..68257e9 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/package.html
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/package.html
@@ -2178,13 +2178,13 @@
<p>
Another useful feature is the {@link org.apache.juneau.annotation.Bean#propertyNamer()} annotation that allows you to plug in your own
logic for determining bean property names.<br>
- The {@link org.apache.juneau.PropertyNamerDashedLC} is an example of an alternate property namer.
+ The {@link org.apache.juneau.PropertyNamerDLC} is an example of an alternate property namer.
It converts bean property names to lowercase-dashed format.
</p>
<h6 class='figure'>Example</h6>
<p class='bcode'>
<ja>@Xml</ja>(prefix=<js>"per"</js>)
- <ja>@Bean</ja>(typeName=<js>"person"</js>,propertyNamer=PropertyNamerDashedLC.<jk>class</jk>)
+ <ja>@Bean</ja>(typeName=<js>"person"</js>,propertyNamer=PropertyNamerDLC.<jk>class</jk>)
<jk>public class</jk> Person {
...
</p>