http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingSerializerTest.java ---------------------------------------------------------------------- diff --git a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingSerializerTest.java b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingSerializerTest.java index 3366856..84f240b 100755 --- a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingSerializerTest.java +++ b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingSerializerTest.java @@ -17,13 +17,13 @@ import static org.junit.Assert.*; import java.util.*; import org.apache.juneau.*; +import org.apache.juneau.json.JsonSerializer; import org.junit.*; @SuppressWarnings("javadoc") public class UrlEncodingSerializerTest { static UrlEncodingSerializer s = UrlEncodingSerializer.DEFAULT; - static UrlEncodingSerializer ss = UrlEncodingSerializer.DEFAULT_SIMPLE; static UrlEncodingSerializer sr = UrlEncodingSerializer.DEFAULT_READABLE; @@ -43,253 +43,214 @@ public class UrlEncodingSerializerTest { // 2nd level t = new ObjectMap("{a:'a'}"); assertEquals("a=a", s.serialize(t)); - assertEquals("a=a", ss.serialize(t)); assertEquals("a=a", sr.serialize(t)); // Simple map // Top level t = new ObjectMap("{a:'b',c:123,d:false,e:true,f:null}"); - assertEquals("a=b&c=$n(123)&d=$b(false)&e=$b(true)&f=%00", s.serialize(t)); - assertEquals("a=b&c=123&d=false&e=true&f=%00", ss.serialize(t)); - assertEquals("a=b\n&c=$n(123)\n&d=$b(false)\n&e=$b(true)\n&f=%00", sr.serialize(t)); + assertEquals("a=b&c=123&d=false&e=true&f=null", s.serialize(t)); + assertEquals("a=b\n&c=123\n&d=false\n&e=true\n&f=null", sr.serialize(t)); // 2nd level t = new ObjectMap("{a:{a:'b',c:123,d:false,e:true,f:null}}"); - assertEquals("a=$o(a=b,c=$n(123),d=$b(false),e=$b(true),f=%00)", s.serialize(t)); - assertEquals("a=(a=b,c=123,d=false,e=true,f=%00)", ss.serialize(t)); - assertEquals("a=$o(\n\ta=b,\n\tc=$n(123),\n\td=$b(false),\n\te=$b(true),\n\tf=%00\n)", sr.serialize(t)); + assertEquals("a=(a=b,c=123,d=false,e=true,f=null)", s.serialize(t)); + assertEquals("a=(\n\ta=b,\n\tc=123,\n\td=false,\n\te=true,\n\tf=null\n)", sr.serialize(t)); // Simple map with primitives as literals t = new ObjectMap("{a:'b',c:'123',d:'false',e:'true',f:'null'}"); - assertEquals("a=b&c=123&d=false&e=true&f=null", s.serialize(t)); - assertEquals("a=b&c=123&d=false&e=true&f=null", ss.serialize(t)); - assertEquals("a=b\n&c=123\n&d=false\n&e=true\n&f=null", sr.serialize(t)); + assertEquals("a=b&c='123'&d='false'&e='true'&f='null'", s.serialize(t)); + assertEquals("a=b\n&c='123'\n&d='false'\n&e='true'\n&f='null'", sr.serialize(t)); // null // Note that serializeParams is always encoded. // Top level t = null; - assertEquals("_value=%00", s.serialize(t)); - assertEquals("_value=%00", ss.serialize(t)); - assertEquals("_value=%00", sr.serialize(t)); + assertEquals("_value=null", s.serialize(t)); + assertEquals("_value=null", sr.serialize(t)); // 2nd level t = new ObjectMap("{null:null}"); - assertEquals("%00=%00", s.serialize(t)); - assertEquals("%00=%00", ss.serialize(t)); - assertEquals("%00=%00", sr.serialize(t)); + assertEquals("null=null", s.serialize(t)); + assertEquals("null=null", sr.serialize(t)); // 3rd level t = new ObjectMap("{null:{null:null}}"); - assertEquals("%00=$o(%00=%00)", s.serialize(t)); - assertEquals("%00=(%00=%00)", ss.serialize(t)); - assertEquals("%00=$o(\n\t%00=%00\n)", sr.serialize(t)); + assertEquals("null=(null=null)", s.serialize(t)); + assertEquals("null=(\n\tnull=null\n)", sr.serialize(t)); // Empty array // Top level t = new String[0]; - assertEquals("_value=$a()", s.serialize(t)); - assertEquals("_value=()", ss.serialize(t)); - assertEquals("_value=$a()", sr.serialize(t)); + assertEquals("_value=@()", s.serialize(t)); + assertEquals("_value=@()", sr.serialize(t)); // 2nd level in map t = new ObjectMap("{x:[]}"); - assertEquals("x=$a()", s.serialize(t)); - assertEquals("x=()", ss.serialize(t)); - assertEquals("x=$a()", sr.serialize(t)); + assertEquals("x=@()", s.serialize(t)); + assertEquals("x=@()", sr.serialize(t)); // Empty 2 dimensional array t = new String[1][0]; - assertEquals("_value=$a($a())", s.serialize(t)); - assertEquals("_value=(())", ss.serialize(t)); - assertEquals("_value=$a(\n\t$a()\n)", sr.serialize(t)); + assertEquals("_value=@(@())", s.serialize(t)); + assertEquals("_value=@(\n\t@()\n)", sr.serialize(t)); // Array containing empty string // Top level t = new String[]{""}; - assertEquals("_value=$a(())", s.serialize(t)); - assertEquals("_value=(())", ss.serialize(t)); - assertEquals("_value=$a(\n\t()\n)", sr.serialize(t)); + assertEquals("_value=@('')", s.serialize(t)); + assertEquals("_value=@(\n\t''\n)", sr.serialize(t)); // 2nd level t = new ObjectMap("{x:['']}"); - assertEquals("x=$a(())", s.serialize(t)); - assertEquals("x=(())", ss.serialize(t)); - assertEquals("x=$a(\n\t()\n)", sr.serialize(t)); + assertEquals("x=@('')", s.serialize(t)); + assertEquals("x=@(\n\t''\n)", sr.serialize(t)); // Array containing 3 empty strings t = new String[]{"","",""}; - assertEquals("_value=$a(,,)", s.serialize(t)); - assertEquals("_value=(,,)", ss.serialize(t)); - assertEquals("_value=$a(\n\t(),\n\t(),\n\t()\n)", sr.serialize(t)); + assertEquals("_value=@('','','')", s.serialize(t)); + assertEquals("_value=@(\n\t'',\n\t'',\n\t''\n)", sr.serialize(t)); // String containing \u0000 // Top level t = "\u0000"; - assertEquals("_value=(%00)", s.serialize(t)); - assertEquals("_value=(%00)", ss.serialize(t)); - assertEquals("_value=(%00)", sr.serialize(t)); + assertEquals("_value=%00", s.serialize(t)); + assertEquals("_value=%00", sr.serialize(t)); // 2nd level t = new ObjectMap("{'\u0000':'\u0000'}"); - assertEquals("(%00)=(%00)", s.serialize(t)); - assertEquals("(%00)=(%00)", ss.serialize(t)); - assertEquals("(%00)=(%00)", sr.serialize(t)); + assertEquals("%00=%00", s.serialize(t)); + assertEquals("%00=%00", sr.serialize(t)); // Boolean // Top level t = false; - assertEquals("_value=$b(false)", s.serialize(t)); - assertEquals("_value=false", ss.serialize(t)); - assertEquals("_value=$b(false)", sr.serialize(t)); + assertEquals("_value=false", s.serialize(t)); + assertEquals("_value=false", sr.serialize(t)); // 2nd level t = new ObjectMap("{x:false}"); - assertEquals("x=$b(false)", s.serialize(t)); - assertEquals("x=false", ss.serialize(t)); - assertEquals("x=$b(false)", sr.serialize(t)); + assertEquals("x=false", s.serialize(t)); + assertEquals("x=false", sr.serialize(t)); // Number // Top level t = 123; - assertEquals("_value=$n(123)", s.serialize(t)); - assertEquals("_value=123", ss.serialize(t)); - assertEquals("_value=$n(123)", sr.serialize(t)); + assertEquals("_value=123", s.serialize(t)); + assertEquals("_value=123", sr.serialize(t)); // 2nd level t = new ObjectMap("{x:123}"); - assertEquals("x=$n(123)", s.serialize(t)); - assertEquals("x=123", ss.serialize(t)); - assertEquals("x=$n(123)", sr.serialize(t)); + assertEquals("x=123", s.serialize(t)); + assertEquals("x=123", sr.serialize(t)); // Unencoded chars // Top level t = "x;/?:@-_.!*'"; - assertEquals("_value=x;/?:@-_.!*'", s.serialize(t)); - assertEquals("_value=x;/?:@-_.!*'", ss.serialize(t)); - assertEquals("_value=x;/?:@-_.!*'", sr.serialize(t)); + assertEquals("_value=x;/?:@-_.!*~'", s.serialize(t)); + assertEquals("_value=x;/?:@-_.!*~'", sr.serialize(t)); // 2nd level t = new ObjectMap("{x:'x;/?:@-_.!*\\''}"); - assertEquals("x=x;/?:@-_.!*'", s.serialize(t)); - assertEquals("x=x;/?:@-_.!*'", ss.serialize(t)); - assertEquals("x=x;/?:@-_.!*'", sr.serialize(t)); + assertEquals("x=x;/?:@-_.!*~'", s.serialize(t)); + assertEquals("x=x;/?:@-_.!*~'", sr.serialize(t)); // Encoded chars // Top level t = "x{}|\\^[]`<>#%\"&+"; assertEquals("_value=x%7B%7D%7C%5C%5E%5B%5D%60%3C%3E%23%25%22%26%2B", s.serialize(t)); - assertEquals("_value=x%7B%7D%7C%5C%5E%5B%5D%60%3C%3E%23%25%22%26%2B", ss.serialize(t)); assertEquals("_value=x%7B%7D%7C%5C%5E%5B%5D%60%3C%3E%23%25%22%26%2B", sr.serialize(t)); // 2nd level t = new ObjectMap("{'x{}|\\\\^[]`<>#%\"&+':'x{}|\\\\^[]`<>#%\"&+'}"); assertEquals("x%7B%7D%7C%5C%5E%5B%5D%60%3C%3E%23%25%22%26%2B=x%7B%7D%7C%5C%5E%5B%5D%60%3C%3E%23%25%22%26%2B", s.serialize(t)); - assertEquals("x%7B%7D%7C%5C%5E%5B%5D%60%3C%3E%23%25%22%26%2B=x%7B%7D%7C%5C%5E%5B%5D%60%3C%3E%23%25%22%26%2B", ss.serialize(t)); assertEquals("x%7B%7D%7C%5C%5E%5B%5D%60%3C%3E%23%25%22%26%2B=x%7B%7D%7C%5C%5E%5B%5D%60%3C%3E%23%25%22%26%2B", sr.serialize(t)); // Escaped chars // Top level t = "x$,()~"; - assertEquals("_value=x$,()~", s.serialize(t)); - assertEquals("_value=x$,()~", ss.serialize(t)); - assertEquals("_value=x$,()~", sr.serialize(t)); + assertEquals("_value='x$,()~~'", s.serialize(t)); + assertEquals("_value='x$,()~~'", sr.serialize(t)); // 2nd level t = new ObjectMap("{'x$,()~':'x$,()~'}"); - assertEquals("x$,()~=x$,()~", s.serialize(t)); - assertEquals("x$,()~=x$,()~", ss.serialize(t)); - assertEquals("x$,()~=x$,()~", sr.serialize(t)); + assertEquals("'x$,()~~'='x$,()~~'", s.serialize(t)); + assertEquals("'x$,()~~'='x$,()~~'", sr.serialize(t)); // 3rd level t = new ObjectMap("{'x$,()~':{'x$,()~':'x$,()~'}}"); - assertEquals("x$,()~=$o(x$~,~(~)~~=x$~,~(~)~~)", s.serialize(t)); - assertEquals("x$,()~=(x$~,~(~)~~=x$~,~(~)~~)", ss.serialize(t)); - assertEquals("x$,()~=$o(\n\tx$~,~(~)~~=x$~,~(~)~~\n)", sr.serialize(t)); + assertEquals("'x$,()~~'=('x$,()~~'='x$,()~~')", s.serialize(t)); + assertEquals("'x$,()~~'=(\n\t'x$,()~~'='x$,()~~'\n)", sr.serialize(t)); // Equals sign // Gets encoded at top level, and encoded+escaped at 2nd level. // Top level t = "x="; - assertEquals("_value=x=", s.serialize(t)); - assertEquals("_value=x=", ss.serialize(t)); - assertEquals("_value=x=", sr.serialize(t)); + assertEquals("_value='x='", s.serialize(t)); + assertEquals("_value='x='", sr.serialize(t)); // 2nd level t = new ObjectMap("{'x=':'x='}"); - assertEquals("x%3D=x=", s.serialize(t)); - assertEquals("x%3D=x=", ss.serialize(t)); - assertEquals("x%3D=x=", sr.serialize(t)); + assertEquals("'x%3D'='x='", s.serialize(t)); + assertEquals("'x%3D'='x='", sr.serialize(t)); // 3rd level t = new ObjectMap("{'x=':{'x=':'x='}}"); - assertEquals("x%3D=$o(x~==x~=)", s.serialize(t)); - assertEquals("x%3D=(x~==x~=)", ss.serialize(t)); - assertEquals("x%3D=$o(\n\tx~==x~=\n)", sr.serialize(t)); + assertEquals("'x%3D'=('x='='x=')", s.serialize(t)); + assertEquals("'x%3D'=(\n\t'x='='x='\n)", sr.serialize(t)); // String starting with parenthesis // Top level t = "()"; - assertEquals("_value=(~(~))", s.serialize(t)); - assertEquals("_value=(~(~))", ss.serialize(t)); - assertEquals("_value=(~(~))", sr.serialize(t)); + assertEquals("_value='()'", s.serialize(t)); + assertEquals("_value='()'", sr.serialize(t)); // 2nd level t = new ObjectMap("{'()':'()'}"); - assertEquals("(~(~))=(~(~))", s.serialize(t)); - assertEquals("(~(~))=(~(~))", ss.serialize(t)); - assertEquals("(~(~))=(~(~))", sr.serialize(t)); + assertEquals("'()'='()'", s.serialize(t)); + assertEquals("'()'='()'", sr.serialize(t)); // String starting with $ // Top level t = "$a"; - assertEquals("_value=($a)", s.serialize(t)); - assertEquals("_value=($a)", ss.serialize(t)); - assertEquals("_value=($a)", sr.serialize(t)); + assertEquals("_value=$a", s.serialize(t)); + assertEquals("_value=$a", sr.serialize(t)); // 2nd level t = new ObjectMap("{$a:'$a'}"); - assertEquals("($a)=($a)", s.serialize(t)); - assertEquals("($a)=($a)", ss.serialize(t)); - assertEquals("($a)=($a)", sr.serialize(t)); + assertEquals("$a=$a", s.serialize(t)); + assertEquals("$a=$a", sr.serialize(t)); // Blank string // Top level t = ""; - assertEquals("_value=", s.serialize(t)); - assertEquals("_value=", ss.serialize(t)); - assertEquals("_value=", sr.serialize(t)); + assertEquals("_value=''", s.serialize(t)); + assertEquals("_value=''", sr.serialize(t)); // 2nd level t = new ObjectMap("{'':''}"); - assertEquals("=", s.serialize(t)); - assertEquals("=", ss.serialize(t)); - assertEquals("=", sr.serialize(t)); + assertEquals("''=''", s.serialize(t)); + assertEquals("''=''", sr.serialize(t)); // 3rd level t = new ObjectMap("{'':{'':''}}"); - assertEquals("=$o(=)", s.serialize(t)); - assertEquals("=(=)", ss.serialize(t)); - assertEquals("=$o(\n\t()=()\n)", sr.serialize(t)); + assertEquals("''=(''='')", s.serialize(t)); + assertEquals("''=(\n\t''=''\n)", sr.serialize(t)); // Newline character // Top level t = "\n"; - assertEquals("_value=%0A", s.serialize(t)); - assertEquals("_value=%0A", ss.serialize(t)); - assertEquals("_value=(%0A)", sr.serialize(t)); + assertEquals("_value='%0A'", s.serialize(t)); + assertEquals("_value='%0A'", sr.serialize(t)); // 2nd level t = new ObjectMap("{'\n':'\n'}"); - assertEquals("%0A=%0A", s.serialize(t)); - assertEquals("%0A=%0A", ss.serialize(t)); - assertEquals("(%0A)=(%0A)", sr.serialize(t)); + assertEquals("'%0A'='%0A'", s.serialize(t)); + assertEquals("'%0A'='%0A'", sr.serialize(t)); // 3rd level t = new ObjectMap("{'\n':{'\n':'\n'}}"); - assertEquals("%0A=$o(%0A=%0A)", s.serialize(t)); - assertEquals("%0A=(%0A=%0A)", ss.serialize(t)); - assertEquals("(%0A)=$o(\n\t(%0A)=(%0A)\n)", sr.serialize(t)); + assertEquals("'%0A'=('%0A'='%0A')", s.serialize(t)); + assertEquals("'%0A'=(\n\t'%0A'='%0A'\n)", sr.serialize(t)); } //==================================================================================================== @@ -303,58 +264,49 @@ public class UrlEncodingSerializerTest { // Top level t = "¢"; assertEquals("_value=%C2%A2", s.serialize(t)); - assertEquals("_value=%C2%A2", ss.serialize(t)); assertEquals("_value=%C2%A2", sr.serialize(t)); // 2nd level t = new ObjectMap("{'¢':'¢'}"); assertEquals("%C2%A2=%C2%A2", s.serialize(t)); - assertEquals("%C2%A2=%C2%A2", ss.serialize(t)); assertEquals("%C2%A2=%C2%A2", sr.serialize(t)); // 3rd level t = new ObjectMap("{'¢':{'¢':'¢'}}"); - assertEquals("%C2%A2=$o(%C2%A2=%C2%A2)", s.serialize(t)); - assertEquals("%C2%A2=(%C2%A2=%C2%A2)", ss.serialize(t)); - assertEquals("%C2%A2=$o(\n\t%C2%A2=%C2%A2\n)", sr.serialize(t)); + assertEquals("%C2%A2=(%C2%A2=%C2%A2)", s.serialize(t)); + assertEquals("%C2%A2=(\n\t%C2%A2=%C2%A2\n)", sr.serialize(t)); // 3-byte UTF-8 character // Top level t = "â¬"; assertEquals("_value=%E2%82%AC", s.serialize(t)); - assertEquals("_value=%E2%82%AC", ss.serialize(t)); assertEquals("_value=%E2%82%AC", sr.serialize(t)); // 2nd level t = new ObjectMap("{'â¬':'â¬'}"); assertEquals("%E2%82%AC=%E2%82%AC", s.serialize(t)); - assertEquals("%E2%82%AC=%E2%82%AC", ss.serialize(t)); assertEquals("%E2%82%AC=%E2%82%AC", sr.serialize(t)); // 3rd level t = new ObjectMap("{'â¬':{'â¬':'â¬'}}"); - assertEquals("%E2%82%AC=$o(%E2%82%AC=%E2%82%AC)", s.serialize(t)); - assertEquals("%E2%82%AC=(%E2%82%AC=%E2%82%AC)", ss.serialize(t)); - assertEquals("%E2%82%AC=$o(\n\t%E2%82%AC=%E2%82%AC\n)", sr.serialize(t)); + assertEquals("%E2%82%AC=(%E2%82%AC=%E2%82%AC)", s.serialize(t)); + assertEquals("%E2%82%AC=(\n\t%E2%82%AC=%E2%82%AC\n)", sr.serialize(t)); // 4-byte UTF-8 character // Top level t = "ð¤¢"; assertEquals("_value=%F0%A4%AD%A2", s.serialize(t)); - assertEquals("_value=%F0%A4%AD%A2", ss.serialize(t)); assertEquals("_value=%F0%A4%AD%A2", sr.serialize(t)); // 2nd level t = new ObjectMap("{'ð¤¢':'ð¤¢'}"); assertEquals("%F0%A4%AD%A2=%F0%A4%AD%A2", s.serialize(t)); - assertEquals("%F0%A4%AD%A2=%F0%A4%AD%A2", ss.serialize(t)); assertEquals("%F0%A4%AD%A2=%F0%A4%AD%A2", sr.serialize(t)); // 3rd level t = new ObjectMap("{'ð¤¢':{'ð¤¢':'ð¤¢'}}"); - assertEquals("%F0%A4%AD%A2=$o(%F0%A4%AD%A2=%F0%A4%AD%A2)", s.serialize(t)); - assertEquals("%F0%A4%AD%A2=(%F0%A4%AD%A2=%F0%A4%AD%A2)", ss.serialize(t)); - assertEquals("%F0%A4%AD%A2=$o(\n\t%F0%A4%AD%A2=%F0%A4%AD%A2\n)", sr.serialize(t)); + assertEquals("%F0%A4%AD%A2=(%F0%A4%AD%A2=%F0%A4%AD%A2)", s.serialize(t)); + assertEquals("%F0%A4%AD%A2=(\n\t%F0%A4%AD%A2=%F0%A4%AD%A2\n)", sr.serialize(t)); } //==================================================================================================== @@ -366,54 +318,54 @@ public class UrlEncodingSerializerTest { DTOs.B t = DTOs.B.create(); String r; - s = UrlEncodingSerializer.DEFAULT_SIMPLE; + s = UrlEncodingSerializer.DEFAULT; r = s.serialize(t); String e = "" - + "f01=(a,b)" - + "&f02=(c,d)" - + "&f03=(1,2)" - + "&f04=(3,4)" - + "&f05=((e,f),(g,h))" - + "&f06=((i,j),(k,l))" - + "&f07=((a=a,b=1,c=true),(a=a,b=1,c=true))" - + "&f08=((a=a,b=1,c=true),(a=a,b=1,c=true))" - + "&f09=(((a=a,b=1,c=true)),((a=a,b=1,c=true)))" - + "&f10=(((a=a,b=1,c=true)),((a=a,b=1,c=true)))" - + "&f11=(a,b)" - + "&f12=(c,d)" - + "&f13=(1,2)" - + "&f14=(3,4)" - + "&f15=((e,f),(g,h))" - + "&f16=((i,j),(k,l))" - + "&f17=((a=a,b=1,c=true),(a=a,b=1,c=true))" - + "&f18=((a=a,b=1,c=true),(a=a,b=1,c=true))" - + "&f19=(((a=a,b=1,c=true)),((a=a,b=1,c=true)))" - + "&f20=(((a=a,b=1,c=true)),((a=a,b=1,c=true)))"; + + "f01=@(a,b)" + + "&f02=@(c,d)" + + "&f03=@(1,2)" + + "&f04=@(3,4)" + + "&f05=@(@(e,f),@(g,h))" + + "&f06=@(@(i,j),@(k,l))" + + "&f07=@((a=a,b=1,c=true),(a=a,b=1,c=true))" + + "&f08=@((a=a,b=1,c=true),(a=a,b=1,c=true))" + + "&f09=@(@((a=a,b=1,c=true)),@((a=a,b=1,c=true)))" + + "&f10=@(@((a=a,b=1,c=true)),@((a=a,b=1,c=true)))" + + "&f11=@(a,b)" + + "&f12=@(c,d)" + + "&f13=@(1,2)" + + "&f14=@(3,4)" + + "&f15=@(@(e,f),@(g,h))" + + "&f16=@(@(i,j),@(k,l))" + + "&f17=@((a=a,b=1,c=true),(a=a,b=1,c=true))" + + "&f18=@((a=a,b=1,c=true),(a=a,b=1,c=true))" + + "&f19=@(@((a=a,b=1,c=true)),@((a=a,b=1,c=true)))" + + "&f20=@(@((a=a,b=1,c=true)),@((a=a,b=1,c=true)))"; assertEquals(e, r); - s = UrlEncodingSerializer.DEFAULT_SIMPLE.clone().setExpandedParams(true); + s = UrlEncodingSerializer.DEFAULT.clone().setExpandedParams(true); r = s.serialize(t); e = "" + "f01=a&f01=b" + "&f02=c&f02=d" + "&f03=1&f03=2" + "&f04=3&f04=4" - + "&f05=(e,f)&f05=(g,h)" - + "&f06=(i,j)&f06=(k,l)" + + "&f05=@(e,f)&f05=@(g,h)" + + "&f06=@(i,j)&f06=@(k,l)" + "&f07=(a=a,b=1,c=true)&f07=(a=a,b=1,c=true)" + "&f08=(a=a,b=1,c=true)&f08=(a=a,b=1,c=true)" - + "&f09=((a=a,b=1,c=true))&f09=((a=a,b=1,c=true))" - + "&f10=((a=a,b=1,c=true))&f10=((a=a,b=1,c=true))" + + "&f09=@((a=a,b=1,c=true))&f09=@((a=a,b=1,c=true))" + + "&f10=@((a=a,b=1,c=true))&f10=@((a=a,b=1,c=true))" + "&f11=a&f11=b" + "&f12=c&f12=d" + "&f13=1&f13=2" + "&f14=3&f14=4" - + "&f15=(e,f)&f15=(g,h)" - + "&f16=(i,j)&f16=(k,l)" + + "&f15=@(e,f)&f15=@(g,h)" + + "&f16=@(i,j)&f16=@(k,l)" + "&f17=(a=a,b=1,c=true)&f17=(a=a,b=1,c=true)" + "&f18=(a=a,b=1,c=true)&f18=(a=a,b=1,c=true)" - + "&f19=((a=a,b=1,c=true))&f19=((a=a,b=1,c=true))" - + "&f20=((a=a,b=1,c=true))&f20=((a=a,b=1,c=true))"; + + "&f19=@((a=a,b=1,c=true))&f19=@((a=a,b=1,c=true))" + + "&f20=@((a=a,b=1,c=true))&f20=@((a=a,b=1,c=true))"; assertEquals(e, r); } @@ -427,54 +379,54 @@ public class UrlEncodingSerializerTest { DTOs.C t = DTOs.C.create(); String r; - s = UrlEncodingSerializer.DEFAULT_SIMPLE; + s = UrlEncodingSerializer.DEFAULT; r = s.serialize(t); String e = "" + "f01=a&f01=b" + "&f02=c&f02=d" + "&f03=1&f03=2" + "&f04=3&f04=4" - + "&f05=(e,f)&f05=(g,h)" - + "&f06=(i,j)&f06=(k,l)" + + "&f05=@(e,f)&f05=@(g,h)" + + "&f06=@(i,j)&f06=@(k,l)" + "&f07=(a=a,b=1,c=true)&f07=(a=a,b=1,c=true)" + "&f08=(a=a,b=1,c=true)&f08=(a=a,b=1,c=true)" - + "&f09=((a=a,b=1,c=true))&f09=((a=a,b=1,c=true))" - + "&f10=((a=a,b=1,c=true))&f10=((a=a,b=1,c=true))" + + "&f09=@((a=a,b=1,c=true))&f09=@((a=a,b=1,c=true))" + + "&f10=@((a=a,b=1,c=true))&f10=@((a=a,b=1,c=true))" + "&f11=a&f11=b" + "&f12=c&f12=d" + "&f13=1&f13=2" + "&f14=3&f14=4" - + "&f15=(e,f)&f15=(g,h)" - + "&f16=(i,j)&f16=(k,l)" + + "&f15=@(e,f)&f15=@(g,h)" + + "&f16=@(i,j)&f16=@(k,l)" + "&f17=(a=a,b=1,c=true)&f17=(a=a,b=1,c=true)" + "&f18=(a=a,b=1,c=true)&f18=(a=a,b=1,c=true)" - + "&f19=((a=a,b=1,c=true))&f19=((a=a,b=1,c=true))" - + "&f20=((a=a,b=1,c=true))&f20=((a=a,b=1,c=true))"; + + "&f19=@((a=a,b=1,c=true))&f19=@((a=a,b=1,c=true))" + + "&f20=@((a=a,b=1,c=true))&f20=@((a=a,b=1,c=true))"; assertEquals(e, r); - s = UrlEncodingSerializer.DEFAULT_SIMPLE.clone().setExpandedParams(true); + s = UrlEncodingSerializer.DEFAULT.clone().setExpandedParams(true); r = s.serialize(t); e = "" + "f01=a&f01=b" + "&f02=c&f02=d" + "&f03=1&f03=2" + "&f04=3&f04=4" - + "&f05=(e,f)&f05=(g,h)" - + "&f06=(i,j)&f06=(k,l)" + + "&f05=@(e,f)&f05=@(g,h)" + + "&f06=@(i,j)&f06=@(k,l)" + "&f07=(a=a,b=1,c=true)&f07=(a=a,b=1,c=true)" + "&f08=(a=a,b=1,c=true)&f08=(a=a,b=1,c=true)" - + "&f09=((a=a,b=1,c=true))&f09=((a=a,b=1,c=true))" - + "&f10=((a=a,b=1,c=true))&f10=((a=a,b=1,c=true))" + + "&f09=@((a=a,b=1,c=true))&f09=@((a=a,b=1,c=true))" + + "&f10=@((a=a,b=1,c=true))&f10=@((a=a,b=1,c=true))" + "&f11=a&f11=b" + "&f12=c&f12=d" + "&f13=1&f13=2" + "&f14=3&f14=4" - + "&f15=(e,f)&f15=(g,h)" - + "&f16=(i,j)&f16=(k,l)" + + "&f15=@(e,f)&f15=@(g,h)" + + "&f16=@(i,j)&f16=@(k,l)" + "&f17=(a=a,b=1,c=true)&f17=(a=a,b=1,c=true)" + "&f18=(a=a,b=1,c=true)&f18=(a=a,b=1,c=true)" - + "&f19=((a=a,b=1,c=true))&f19=((a=a,b=1,c=true))" - + "&f20=((a=a,b=1,c=true))&f20=((a=a,b=1,c=true))"; + + "&f19=@((a=a,b=1,c=true))&f19=@((a=a,b=1,c=true))" + + "&f20=@((a=a,b=1,c=true))&f20=@((a=a,b=1,c=true))"; assertEquals(e, r); } @@ -487,9 +439,18 @@ public class UrlEncodingSerializerTest { t.put("f1", new String[]{"bar"}); t.put("f2", new String[]{"bar","baz"}); t.put("f3", new String[]{}); - s = UrlEncodingSerializer.DEFAULT_SIMPLE_EXPANDED; + s = UrlEncodingSerializer.DEFAULT_EXPANDED; r = s.serialize(t); String e = "f1=bar&f2=bar&f2=baz"; assertEquals(e, r); } + + @Test + public void testParseParameterObjectMap() throws Exception { + String in = "(name='foo bar')"; + + ObjectMap r = UrlEncodingParser.DEFAULT.parseParameter(in, ObjectMap.class); + + assertEquals("{name:'foo bar'}", JsonSerializer.DEFAULT_LAX.toString(r)); + } } \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core-test/src/test/java/org/apache/juneau/utils/PojoRestTest.java ---------------------------------------------------------------------- diff --git a/juneau-core-test/src/test/java/org/apache/juneau/utils/PojoRestTest.java b/juneau-core-test/src/test/java/org/apache/juneau/utils/PojoRestTest.java index 5450e2d..be25076 100755 --- a/juneau-core-test/src/test/java/org/apache/juneau/utils/PojoRestTest.java +++ b/juneau-core-test/src/test/java/org/apache/juneau/utils/PojoRestTest.java @@ -71,7 +71,7 @@ public class PojoRestTest { model.put("/person1", p); // Make sure it got stored correctly. - JsonSerializer serializer = JsonSerializer.DEFAULT_LAX; + JsonSerializer serializer = JsonSerializer.DEFAULT_LAX.clone().setAddBeanTypeProperties(false); assertEquals("{person1:{name:'some name',age:123,addresses:[{street:'street A',city:'city A',state:'state A',zip:12345,isCurrent:true},{street:'street B',city:'city B',state:'state B',zip:12345,isCurrent:false}]}}", serializer.serialize(model.getRootObject())); // Get the original Person object back. @@ -82,7 +82,7 @@ public class PojoRestTest { Address a3 = (Address)model.get("/person1/addresses/1"); assertEquals("city B", a3.city); - serializer = new JsonSerializer.Simple().setAddBeanTypeProperties(true); + serializer = new JsonSerializer.Simple(); p = new Person("some name", 123, new Address("street A", "city A", "state A", 12345, true), new Address("street B", "city B", "state B", 12345, false) @@ -115,7 +115,7 @@ public class PojoRestTest { model.put("addresses/0", new Address("street D", "city D", "state D", 12345, false)); model.put("addresses/1", new Address("street E", "city E", "state E", 12345, false)); model.put("addresses/2", new Address("street F", "city F", "state F", 12345, false)); - serializer = JsonSerializer.DEFAULT_LAX; + serializer = JsonSerializer.DEFAULT_LAX.clone().setAddBeanTypeProperties(false); s = serializer.serialize(p); expectedValue = "{name:'some name',age:123,addresses:[{street:'street D',city:'city D',state:'state D',zip:12345,isCurrent:false},{street:'street E',city:'city E',state:'state E',zip:12345,isCurrent:false},{street:'street F',city:'city F',state:'state F',zip:12345,isCurrent:false}]}"; assertEquals(expectedValue, s); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlContentTest.java ---------------------------------------------------------------------- diff --git a/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlContentTest.java b/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlContentTest.java index d695969..e11fe18 100755 --- a/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlContentTest.java +++ b/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlContentTest.java @@ -34,7 +34,7 @@ public class XmlContentTest { public void testContentFormat() throws Exception { A t = A.newInstance(), t2; XmlSerializer s1 = XmlSerializer.DEFAULT_SQ, - s2 = new XmlSerializer().setQuoteChar('\'').setUseIndentation(true).setEnableNamespaces(false); + s2 = new XmlSerializer().setQuoteChar('\'').setUseWhitespace(true).setEnableNamespaces(false); XmlParser p = XmlParser.DEFAULT; XmlSerializerSession session; String r; @@ -142,7 +142,7 @@ public class XmlContentTest { public void testXmlMixed() throws Exception { B t = B.newInstance(), t2; XmlSerializer s1 = XmlSerializer.DEFAULT_SQ, - s2 = new XmlSerializer().setQuoteChar('\'').setUseIndentation(true).setEnableNamespaces(false); + s2 = new XmlSerializer().setQuoteChar('\'').setUseWhitespace(true).setEnableNamespaces(false); XmlParser p = XmlParser.DEFAULT; XmlSerializerSession session; String r; http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/.project ---------------------------------------------------------------------- diff --git a/juneau-core/.project b/juneau-core/.project index fe1874b..cd59d79 100644 --- a/juneau-core/.project +++ b/juneau-core/.project @@ -1,28 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- - *************************************************************************************************************************** - * 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. * - *************************************************************************************************************************** ---> <projectDescription> - <name>juneau-core</name> - <comment>Base toolkit for serializers, parsers, and bean contexts. NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse.</comment> - <projects/> - <buildSpec> - <buildCommand> - <name>org.eclipse.jdt.core.javabuilder</name> - </buildCommand> - </buildSpec> - <natures> - <nature>org.eclipse.jdt.core.javanature</nature> - </natures> -</projectDescription> \ No newline at end of file + <name>juneau-core</name> + <comment>Base toolkit for serializers, parsers, and bean contexts. NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse.</comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>edu.umd.cs.findbugs.plugin.eclipse.findbugsBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>edu.umd.cs.findbugs.plugin.eclipse.findbugsNature</nature> + </natures> +</projectDescription> http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/BeanContext.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanContext.java b/juneau-core/src/main/java/org/apache/juneau/BeanContext.java index 116d6e9..881ccf3 100644 --- a/juneau-core/src/main/java/org/apache/juneau/BeanContext.java +++ b/juneau-core/src/main/java/org/apache/juneau/BeanContext.java @@ -917,8 +917,8 @@ public class BeanContext extends Context { if (! cmCacheCache.containsKey(hashCode)) { ConcurrentHashMap<Class,ClassMeta> cm = new ConcurrentHashMap<Class,ClassMeta>(); - cm.put(String.class, new ClassMeta(String.class, this, null, null, findPojoSwap(String.class), findChildPojoSwaps(String.class))); - cm.put(Object.class, new ClassMeta(Object.class, this, null, null, findPojoSwap(Object.class), findChildPojoSwaps(Object.class))); + cm.putIfAbsent(String.class, new ClassMeta(String.class, this, null, null, findPojoSwap(String.class), findChildPojoSwaps(String.class))); + cm.putIfAbsent(Object.class, new ClassMeta(Object.class, this, null, null, findPojoSwap(Object.class), findChildPojoSwaps(Object.class))); cmCacheCache.putIfAbsent(hashCode, cm); } this.cmCache = cmCacheCache.get(hashCode); @@ -1006,7 +1006,7 @@ public class BeanContext extends Context { int ctCount = 0; for (Map<Class,ClassMeta> cm : cmCacheCache.values()) ctCount += cm.size(); - System.out.println(MessageFormat.format("ClassMeta cache: {0} instances in {1} caches", ctCount, cmCacheCache.size())); + System.out.println(MessageFormat.format("ClassMeta cache: {0} instances in {1} caches", ctCount, cmCacheCache.size())); // NOT DEBUG } catch (Exception e) { e.printStackTrace(); } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/BeanMap.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanMap.java b/juneau-core/src/main/java/org/apache/juneau/BeanMap.java index 4e1bad6..48fbd40 100644 --- a/juneau-core/src/main/java/org/apache/juneau/BeanMap.java +++ b/juneau-core/src/main/java/org/apache/juneau/BeanMap.java @@ -203,15 +203,6 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T if (meta.ctx.ignoreUnknownBeanProperties) return null; - // If this bean has subtypes, and we haven't set the subtype yet, - // store the property in a temporary cache until the bean can be instantiated. - // This eliminates the need for requiring that the sub type attribute be provided first. - if (meta.subTypeProperty != null) { - if (propertyCache == null) - propertyCache = new TreeMap<String,Object>(); - return propertyCache.put(property, value); - } - if (property.equals(session.getBeanTypePropertyName())) return null; http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java b/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java index 40f1346..a98677c 100644 --- a/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java +++ b/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java @@ -19,7 +19,6 @@ import java.beans.*; import java.io.*; import java.lang.reflect.*; import java.util.*; -import java.util.Map.*; import org.apache.juneau.annotation.*; import org.apache.juneau.internal.*; @@ -88,7 +87,6 @@ public class BeanMeta<T> { private final MetadataMap extMeta; // Extended metadata // Other fields - final BeanPropertyMeta subTypeProperty; // The property indentified as the sub type differentiator property (identified by @Bean.subTypeProperty annotation). private final BeanPropertyMeta typeProperty; // "_type" mock bean property. private final String dictionaryName; // The @Bean.typeName() annotation defined on this bean class. final String notABeanReason; // Readable string explaining why this class wasn't a bean. @@ -111,7 +109,7 @@ public class BeanMeta<T> { this.notABeanReason = b.init(this); this.beanFilter = beanFilter; - this.dictionaryName = beanFilter == null ? null : beanFilter.getTypeName(); + this.dictionaryName = b.dictionaryName; this.properties = b.properties == null ? null : Collections.unmodifiableMap(b.properties); this.getterProps = Collections.unmodifiableMap(b.getterProps); this.setterProps = Collections.unmodifiableMap(b.setterProps); @@ -119,7 +117,6 @@ public class BeanMeta<T> { this.constructor = b.constructor; this.constructorArgs = b.constructorArgs; this.extMeta = b.extMeta; - this.subTypeProperty = b.subTypeIdProperty == null ? null : b.subTypeIdProperty.build(); this.beanRegistry = b.beanRegistry; this.typeProperty = new BeanPropertyMeta.Builder(this, ctx.getBeanTypePropertyName(), ctx.string(), beanRegistry).build(); } @@ -136,9 +133,9 @@ public class BeanMeta<T> { Constructor<T> constructor; String[] constructorArgs = new String[0]; MetadataMap extMeta = new MetadataMap(); - BeanPropertyMeta.Builder subTypeIdProperty; PropertyNamer propertyNamer; BeanRegistry beanRegistry; + String dictionaryName; private Builder(ClassMeta<T> classMeta, BeanContext ctx, BeanFilter beanFilter, String[] pNames) { this.classMeta = classMeta; @@ -159,9 +156,10 @@ public class BeanMeta<T> { fVis = ctx.beanFieldVisibility; List<Class<?>> bdClasses = new ArrayList<Class<?>>(); + if (beanFilter != null && beanFilter.getBeanDictionary() != null) + bdClasses.addAll(Arrays.asList(beanFilter.getBeanDictionary())); Bean bean = classMeta.innerClass.getAnnotation(Bean.class); if (bean != null) { - bdClasses.addAll(Arrays.asList(bean.beanDictionary())); if (! bean.typeName().isEmpty()) bdClasses.add(classMeta.innerClass); } @@ -335,12 +333,10 @@ public class BeanMeta<T> { properties = sortProperties ? new TreeMap<String,BeanPropertyMeta>() : new LinkedHashMap<String,BeanPropertyMeta>(); - if (beanFilter != null && beanFilter.getSubTypeProperty() != null) { - String subTypeProperty = beanFilter.getSubTypeProperty(); - BeanPropertyMeta.Builder stp = normalProps.remove(subTypeProperty); - this.subTypeIdProperty = new SubTypePropertyMeta.Builder(beanMeta, subTypeProperty, beanFilter.getSubTypes(), stp == null ? null : stp.build(), beanRegistry); - properties.put(subTypeProperty, this.subTypeIdProperty.build()); - } + if (beanFilter != null && beanFilter.getTypeName() != null) + dictionaryName = beanFilter.getTypeName(); + if (dictionaryName == null) + dictionaryName = findDictionaryName(this.classMeta); for (Map.Entry<String,BeanPropertyMeta.Builder> e : normalProps.entrySet()) properties.put(e.getKey(), e.getValue().build()); @@ -385,6 +381,27 @@ public class BeanMeta<T> { return null; } + private String findDictionaryName(ClassMeta<?> cm) { + BeanRegistry br = cm.getBeanRegistry(); + if (br != null) { + String s = br.getTypeName(this.classMeta); + if (s != null) + return s; + } + Class<?> pcm = cm.innerClass.getSuperclass(); + if (pcm != null) { + String s = findDictionaryName(ctx.getClassMeta(pcm)); + if (s != null) + return s; + } + for (Class<?> icm : cm.innerClass.getInterfaces()) { + String s = findDictionaryName(ctx.getClassMeta(icm)); + if (s != null) + return s; + } + return null; + } + /* * Returns the property name of the specified field if it's a valid property. * Returns null if the field isn't a valid property. @@ -402,10 +419,8 @@ public class BeanMeta<T> { return name; return null; } - } - /** * Returns the {@link ClassMeta} of this bean. * @@ -426,27 +441,6 @@ public class BeanMeta<T> { } /** - * Returns the subtype property of this bean if it has one. - * <p> - * The subtype is specified using the {@link Bean#subTypeProperty()} annotation. - * - * @return The meta property for the sub type property, or <jk>null</jk> if no subtype is defined for this bean. - */ - public BeanPropertyMeta getSubTypeProperty() { - return subTypeProperty; - } - - /** - * Returns <jk>true</jk> if this bean has subtypes associated with it. - * Subtypes are defined using the {@link Bean#subTypes()} annotation. - * - * @return <jk>true</jk> if this bean has subtypes associated with it. - */ - public boolean isSubTyped() { - return subTypeProperty != null; - } - - /** * Returns a mock bean property that resolves to the name <js>"_type"</js> and whose value always resolves * to the dictionary name of the bean. * @@ -738,75 +732,6 @@ public class BeanMeta<T> { } } - /* - * Bean property for getting and setting bean subtype. - */ - @SuppressWarnings({"rawtypes","unchecked"}) - private static class SubTypePropertyMeta extends BeanPropertyMeta { - - private final Map<Class<?>,String> subTypes; - private final BeanPropertyMeta realProperty; // Bean property if bean actually has a real subtype field. - - static class Builder extends BeanPropertyMeta.Builder { - Map<Class<?>,String> subTypes; - BeanPropertyMeta realProperty; - - Builder(BeanMeta beanMeta, String subTypeAttr, Map<Class<?>,String> subTypes, BeanPropertyMeta realProperty, BeanRegistry beanRegistry) { - super(beanMeta, subTypeAttr, beanMeta.ctx.string(), beanRegistry); - this.subTypes = subTypes; - this.realProperty = realProperty; - } - - @Override - public SubTypePropertyMeta build() { - return new SubTypePropertyMeta(this); - } - } - - SubTypePropertyMeta(Builder b) { - super(b); - this.subTypes = b.subTypes; - this.realProperty = b.realProperty; - } - - /* - * Setting this bean property causes the inner bean to be set to the subtype implementation. - */ - @Override /* BeanPropertyMeta */ - public Object set(BeanMap<?> m, Object value) throws BeanRuntimeException { - if (value == null) - throw new BeanRuntimeException("Attempting to set bean subtype property to null."); - String subTypeId = value.toString(); - for (Entry<Class<?>,String> e : subTypes.entrySet()) { - if (e.getValue().equals(subTypeId)) { - Class subTypeClass = e.getKey(); - m.meta = beanMeta.ctx.getBeanMeta(subTypeClass); - try { - m.setBean(subTypeClass.newInstance()); - if (realProperty != null) - realProperty.set(m, value); - // If subtype attribute wasn't specified first, set them again from the temporary cache. - if (m.propertyCache != null) - for (Map.Entry<String,Object> me : m.propertyCache.entrySet()) - m.put(me.getKey(), me.getValue()); - } catch (Exception e1) { - throw new BeanRuntimeException(e1); - } - return null; - } - } - throw new BeanRuntimeException(beanMeta.c, "Unknown subtype ID ''{0}''", subTypeId); - } - - @Override /* BeanPropertyMeta */ - public Object get(BeanMap<?> m) throws BeanRuntimeException { - String subTypeId = beanMeta.beanFilter.getSubTypes().get(beanMeta.c); - if (subTypeId == null) - throw new BeanRuntimeException(beanMeta.c, "Unmapped sub type class"); - return subTypeId; - } - } - @Override /* Object */ public String toString() { StringBuilder sb = new StringBuilder(c.getName()); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java b/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java index 516d3d4..ba6f2df 100644 --- a/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java +++ b/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java @@ -451,11 +451,6 @@ public class BeanPropertyMeta { if (m.bean == null) { - // If this bean has subtypes, and we haven't set the subtype yet, - // store the property in a temporary cache until the bean can be instantiated. - if (m.meta.subTypeProperty != null && m.propertyCache == null) - m.propertyCache = new TreeMap<String,Object>(); - // Read-only beans get their properties stored in a cache. if (m.propertyCache != null) return m.propertyCache.put(name, value); @@ -612,10 +607,10 @@ public class BeanPropertyMeta { } else { if (swap != null && value != null && isParentClass(swap.getSwapClass(), value.getClass())) { - value = swap.unswap(session, value, rawTypeMeta); + value = swap.unswap(session, value, rawTypeMeta); } else { - value = session.convertToType(value, rawTypeMeta); - } + value = session.convertToType(value, rawTypeMeta); + } if (setter != null) setter.invoke(bean, new Object[] { value }); else if (field != null) http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/BeanRegistry.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanRegistry.java b/juneau-core/src/main/java/org/apache/juneau/BeanRegistry.java index 13f9657..090fd91 100644 --- a/juneau-core/src/main/java/org/apache/juneau/BeanRegistry.java +++ b/juneau-core/src/main/java/org/apache/juneau/BeanRegistry.java @@ -36,18 +36,19 @@ import org.apache.juneau.internal.*; public class BeanRegistry { private final Map<String,ClassMeta<?>> map; + private final Map<Class<?>,String> reverseMap; private final BeanContext beanContext; - private final String beanTypePropertyName; private final boolean isEmpty; BeanRegistry(BeanContext beanContext, BeanRegistry parent, Class<?>...classes) { this.beanContext = beanContext; - this.beanTypePropertyName = beanContext.getBeanTypePropertyName(); this.map = new ConcurrentHashMap<String,ClassMeta<?>>(); + this.reverseMap = new ConcurrentHashMap<Class<?>,String>(); for (Class<?> c : beanContext.beanDictionaryClasses) addClass(c); if (parent != null) - this.map.putAll(parent.map); + for (Map.Entry<String,ClassMeta<?>> e : parent.map.entrySet()) + addToMap(e.getKey(), e.getValue()); for (Class<?> c : classes) addClass(c); isEmpty = map.isEmpty(); @@ -77,13 +78,13 @@ public class BeanRegistry { val = getTypedClassMeta(v); else throw new BeanRuntimeException("Class ''{0}'' was passed to BeanRegistry but value of type ''{1}'' found in map is not a Type object.", c.getName(), v.getClass().getName()); - map.put(typeName, val); + addToMap(typeName, val); } } else { Bean b = c.getAnnotation(Bean.class); if (b == null || b.typeName().isEmpty()) throw new BeanRuntimeException("Class ''{0}'' was passed to BeanRegistry but it doesn't have a @Bean.typeName() annotation defined.", c.getName()); - map.put(b.typeName(), beanContext.getClassMeta(c)); + addToMap(b.typeName(), beanContext.getClassMeta(c)); } } } catch (BeanRuntimeException e) { @@ -104,34 +105,9 @@ public class BeanRegistry { return beanContext.getClassMeta(type, args); } - /** - * Converts the specified object map into a bean if it contains a <js>"_type"</js> entry in it. - * - * @param m The object map to convert to a bean if possible. - * @return The new bean, or the original <code>ObjectMap</code> if no <js>"_type"</js> entry was found. - */ - public Object cast(ObjectMap m) { - if (isEmpty) - return m; - Object o = m.get(beanTypePropertyName); - if (o == null) - return m; - String typeName = o.toString(); - ClassMeta<?> cm = getClassMeta(typeName); - BeanMap<?> bm = m.getBeanSession().newBeanMap(cm.getInnerClass()); - - // Iterate through all the entries in the map and set the individual field values. - for (Map.Entry<String,Object> e : m.entrySet()) { - String k = e.getKey(); - Object v = e.getValue(); - if (! k.equals(beanTypePropertyName)) { - // Attempt to recursively cast child maps. - if (v instanceof ObjectMap) - v = cast((ObjectMap)v); - bm.put(k, v); - } - } - return bm.getBean(); + private void addToMap(String typeName, ClassMeta<?> cm) { + map.put(typeName, cm); + reverseMap.put(cm.innerClass, typeName); } /** @@ -151,15 +127,28 @@ public class BeanRegistry { return cm; if (typeName.charAt(typeName.length()-1) == '^') { cm = getClassMeta(typeName.substring(0, typeName.length()-1)); - if (cm != null) + if (cm != null) { cm = beanContext.getClassMeta(Array.newInstance(cm.innerClass, 1).getClass()); - map.put(typeName, cm); + map.put(typeName, cm); + } return cm; } return null; } /** + * Given the specified class, return the dictionary name for it. + * + * @param c The class to lookup in this registry. + * @return The dictionary name for the specified class in this registry, or <jk>null</jk> if not found. + */ + public String getTypeName(ClassMeta<?> c) { + if (isEmpty) + return null; + return reverseMap.get(c.innerClass); + } + + /** * Returns <jk>true</jk> if this dictionary has an entry for the specified type name. * * @param typeName The bean type name. @@ -168,4 +157,14 @@ public class BeanRegistry { public boolean hasName(String typeName) { return getClassMeta(typeName) != null; } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append('{'); + for (Map.Entry<String,ClassMeta<?>> e : map.entrySet()) + sb.append(e.getKey()).append(":").append(e.getValue().toString(true)).append(", "); + sb.append('}'); + return sb.toString(); + } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/BeanSession.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanSession.java b/juneau-core/src/main/java/org/apache/juneau/BeanSession.java index 540329b..abc9959 100644 --- a/juneau-core/src/main/java/org/apache/juneau/BeanSession.java +++ b/juneau-core/src/main/java/org/apache/juneau/BeanSession.java @@ -551,8 +551,18 @@ public class BeanSession extends Session { } // It's a bean being initialized with a Map - if (type.isBean() && value instanceof Map) + if (type.isBean() && value instanceof Map) { + if (value instanceof ObjectMap) { + ObjectMap m2 = (ObjectMap)value; + String typeName = m2.getString(getBeanTypePropertyName()); + if (typeName != null) { + ClassMeta cm = type.getBeanRegistry().getClassMeta(typeName); + if (cm != null && ClassUtils.isParentClass(type.innerClass, cm.innerClass)) + return (T)m2.cast(cm); + } + } return newBeanMap(tc).load((Map<?,?>) value).getBean(); + } if (type.canCreateNewInstanceFromNumber(outer) && value instanceof Number) return type.newInstanceFromNumber(this, outer, (Number)value); @@ -722,12 +732,8 @@ public class BeanSession extends Session { if (m == null) return null; T bean = null; - if (m.constructorArgs.length == 0) { + if (m.constructorArgs.length == 0) bean = newBean(outer, c); - // Beans with subtypes won't be instantiated until the sub type property is specified. - if (bean == null && ! m.getClassMeta().hasSubTypes()) - return null; - } return new BeanMap<T>(this, bean, m); } @@ -768,12 +774,8 @@ public class BeanSession extends Session { return null; try { T o = (T)m.newBean(outer); - if (o == null) { - // Beans with subtypes won't be instantiated until the sub type property is specified. - if (cm.hasSubTypes()) - return null; + if (o == null) throw new BeanRuntimeException(c, "Class does not have a no-arg constructor."); - } return o; } catch (BeanRuntimeException e) { throw e; http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java b/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java index fdcbd2a..c1c2e72 100644 --- a/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java +++ b/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java @@ -104,6 +104,7 @@ public final class ClassMeta<T> implements Type { resolvedDictionaryName; // The name if this is an array type (e.g. "X^^"). private final Throwable initException; // Any exceptions thrown in the init() method. private final InvocationHandler invocationHandler; // The invocation handler for this class (if it has one). + private final BeanRegistry beanRegistry; // The bean registry of this class meta (if it has one). private static final Boolean BOOLEAN_DEFAULT = false; private static final Character CHARACTER_DEFAULT = (char)0; @@ -179,6 +180,7 @@ public final class ClassMeta<T> implements Type { BeanMeta _beanMeta = null; PojoSwap _pojoSwap = null; InvocationHandler _invocationHandler = null; + BeanRegistry _beanRegistry = null; if (c.isPrimitive()) { if (c == Boolean.TYPE) @@ -462,6 +464,7 @@ public final class ClassMeta<T> implements Type { try { newMeta = new BeanMeta(this, beanContext, beanFilter, null); _notABeanReason = newMeta.notABeanReason; + _beanRegistry = newMeta.beanRegistry; // Always get the bean registry even if it's not a bean. } catch (RuntimeException e) { _notABeanReason = e.getMessage(); throw e; @@ -493,6 +496,10 @@ public final class ClassMeta<T> implements Type { if (_beanMeta != null && beanContext != null && beanContext.useInterfaceProxies && innerClass.isInterface()) _invocationHandler = new BeanProxyInvocationHandler<T>(_beanMeta); + Bean b = c.getAnnotation(Bean.class); + if (b != null && b.beanDictionary().length != 0) + _beanRegistry = new BeanRegistry(beanContext, null, b.beanDictionary()); + this.cc = _cc; this.isDelegate = _isDelegate; this.fromStringMethod = _fromStringMethod; @@ -522,6 +529,7 @@ public final class ClassMeta<T> implements Type { this.resolvedDictionaryName = _resolvedDictionaryName; this.serializedClassMeta = _serializedClassMeta; this.invocationHandler = _invocationHandler; + this.beanRegistry = _beanRegistry; } /** @@ -566,6 +574,7 @@ public final class ClassMeta<T> implements Type { this.beanFilter = mainType.beanFilter; this.extMeta = mainType.extMeta; this.initException = mainType.initException; + this.beanRegistry = mainType.beanRegistry; } private ClassMeta<?> findClassMeta(Class<?> c) { @@ -578,7 +587,7 @@ public final class ClassMeta<T> implements Type { private BeanFilter findBeanFilter() { try { - List<Bean> ba = ReflectionUtils.findAnnotations(Bean.class, innerClass); + Map<Class<?>,Bean> ba = ReflectionUtils.findAnnotationsMap(Bean.class, innerClass); if (! ba.isEmpty()) return new AnnotationBeanFilterBuilder(innerClass, ba).build(); } catch (Exception e) { @@ -629,6 +638,19 @@ public final class ClassMeta<T> implements Type { } /** + * Returns the bean registry for this class. + * <p> + * This bean registry contains names specified in the {@link Bean#beanDictionary()} annotation defined + * on the class, regardless of whether the class is an actual bean. + * This allows interfaces to define subclasses with type names. + * + * @return The bean registry for this class, or <jk>null</jk> if no bean registry is associated with it. + */ + public BeanRegistry getBeanRegistry() { + return beanRegistry; + } + + /** * Returns the category of this class. * * @return The category of this class. @@ -648,15 +670,6 @@ public final class ClassMeta<T> implements Type { } /** - * Returns <jk>true</jk> if this class as subtypes defined through {@link Bean#subTypes}. - * - * @return <jk>true</jk> if this class has subtypes. - */ - public boolean hasSubTypes() { - return beanFilter != null && beanFilter.getSubTypeProperty() != null; - } - - /** * Returns <jk>true</jk> if this class is a subclass of or the same as the specified class. * * @param c The comparison class. @@ -694,7 +707,9 @@ public final class ClassMeta<T> implements Type { s = f; if (s == null) s = PojoSwap.NULL; - childSwapMap.putIfAbsent(normalClass, s); + PojoSwap<?,?> s2 = childSwapMap.putIfAbsent(normalClass, s); + if (s2 != null) + s = s2; } if (s == PojoSwap.NULL) return null; @@ -719,7 +734,9 @@ public final class ClassMeta<T> implements Type { s = f; if (s == null) s = PojoSwap.NULL; - childUnswapMap.putIfAbsent(swapClass, s); + PojoSwap<?,?> s2 = childUnswapMap.putIfAbsent(swapClass, s); + if (s2 != null) + s = s2; } if (s == PojoSwap.NULL) return null; @@ -1155,9 +1172,6 @@ public final class ClassMeta<T> implements Type { public boolean canCreateNewBean(Object outer) { if (beanMeta == null) return false; - // Beans with transforms with subtype properties are assumed to be constructable. - if (beanFilter != null && beanFilter.getSubTypeProperty() != null) - return true; if (beanMeta.constructor == null) return false; if (isMemberClass) http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/CoreApi.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/CoreApi.java b/juneau-core/src/main/java/org/apache/juneau/CoreApi.java index 1bb1979..f93b180 100644 --- a/juneau-core/src/main/java/org/apache/juneau/CoreApi.java +++ b/juneau-core/src/main/java/org/apache/juneau/CoreApi.java @@ -1364,7 +1364,7 @@ public abstract class CoreApi extends Lockable { * @see BeanContext#BEAN_beanTypePropertyName */ public CoreApi setBeanTypePropertyName(String value) throws LockedException { - return addToProperty(BEAN_beanTypePropertyName, value); + return setProperty(BEAN_beanTypePropertyName, value); } /** @@ -1390,7 +1390,7 @@ public abstract class CoreApi extends Lockable { * @see BeanContext#BEAN_defaultParser */ public CoreApi setDefaultParser(Class<?> value) throws LockedException { - return addToProperty(BEAN_defaultParser, value); + return setProperty(BEAN_defaultParser, value); } /** @@ -1414,7 +1414,7 @@ public abstract class CoreApi extends Lockable { * @see BeanContext#BEAN_locale */ public CoreApi setLocale(Locale value) throws LockedException { - return addToProperty(BEAN_locale, value); + return setProperty(BEAN_locale, value); } /** @@ -1464,7 +1464,7 @@ public abstract class CoreApi extends Lockable { * @see BeanContext#BEAN_mediaType */ public CoreApi setMediaType(MediaType value) throws LockedException { - return addToProperty(BEAN_mediaType, value); + return setProperty(BEAN_mediaType, value); } /** @@ -1501,7 +1501,7 @@ public abstract class CoreApi extends Lockable { * @see BeanContext#BEAN_debug */ public CoreApi setDebug(boolean value) throws LockedException { - return addToProperty(BEAN_debug, value); + return setProperty(BEAN_debug, value); } /** http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/LockedException.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/LockedException.java b/juneau-core/src/main/java/org/apache/juneau/LockedException.java index 9ba5063..4ad8303 100644 --- a/juneau-core/src/main/java/org/apache/juneau/LockedException.java +++ b/juneau-core/src/main/java/org/apache/juneau/LockedException.java @@ -25,6 +25,6 @@ public final class LockedException extends RuntimeException { private static final long serialVersionUID = 1L; LockedException() { - super("Object is locked and object settings cannot be modified."); + super("Object is locked and object settings cannot be modified. Try cloning the object."); } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/annotation/Bean.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/annotation/Bean.java b/juneau-core/src/main/java/org/apache/juneau/annotation/Bean.java index 63ae64f..983588d 100644 --- a/juneau-core/src/main/java/org/apache/juneau/annotation/Bean.java +++ b/juneau-core/src/main/java/org/apache/juneau/annotation/Bean.java @@ -164,59 +164,6 @@ public @interface Bean { Class<? extends PropertyNamer> propertyNamer() default PropertyNamerDefault.class; /** - * Defines a virtual property on a superclass that identifies bean subtype classes. - * <p> - * In the following example, the abstract class has two subclasses that are differentiated - * by a property called <code>subType</code> - * <p class='bcode'> - * <jc>// Abstract superclass</jc> - * <ja>@Bean</ja>( - * subTypeProperty=<js>"subType"</js>, - * subTypes={A1.class, A2.class} - * ) - * <jk>public class</jk> A { - * <jk>public</jk> String <jf>f0</jf> = <js>"f0"</js>; - * } - * - * <jc>// Subclass 1</jc> - * <ja>@Bean</ja>(typeName=<js>"A1"</js>) - * <jk>public class</jk> A1 <jk>extends</jk> A { - * <jk>public</jk> String <jf>f1</jf>; - * } - * - * <jc>// Subclass 2</jc> - * <ja>@Bean</ja>(typeName=<js>"A2"</js>) - * <jk>public class</jk> A2 <jk>extends</jk> A { - * <jk>public</jk> String <jf>f2</jf>; - * } - * <p> - * The following shows what happens when serializing a subclassed object to JSON: - * <p class='bcode'> - * JsonSerializer s = JsonSerializer.<jsf>DEFAULT_LAX</jsf>; - * A1 a1 = <jk>new</jk> A1(); - * a1.<jf>f1</jf> = <js>"f1"</js>; - * String r = s.serialize(a1); - * <jsm>assertEquals</jsm>(<js>"{subType:'A1',f1:'f1',f0:'f0'}"</js>, r); - * </p> - * <p> - * The following shows what happens when parsing back into the original object. - * <p> - * <p class='bcode'> - * JsonParser p = JsonParser.<jsf>DEFAULT</jsf>; - * A a = p.parse(r, A.<jk>class</jk>); - * <jsm>assertTrue</jsm>(a <jk>instanceof</jk> A1); - * </p> - * <p> - * This annotation is an alternative to using the {@link BeanFilter} class with an implemented {@link BeanFilter#getSubTypeProperty()} method. - */ - String subTypeProperty() default "_subtype"; - - /** - * Used in conjunction with {@link #subTypeProperty()} to set up bean subtypes. - */ - Class<?>[] subTypes() default {}; - - /** * Identifies a class to be used as the interface class for this and all subclasses. * <p> * When specified, only the list of properties defined on the interface class will be used during serialization. @@ -273,7 +220,8 @@ public @interface Bean { /** - * The list of classes that make up the bean dictionary for all properties of this bean. + * The list of classes that make up the bean dictionary for all properties of this bean + * or for subclasses of this bean. * <p> * This is a shorthand for setting the {@link BeanProperty#beanDictionary()} on all properties of the bean. * <p> http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/dto/atom/AtomBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/atom/AtomBuilder.java b/juneau-core/src/main/java/org/apache/juneau/dto/atom/AtomBuilder.java index 60d578a..623d79e 100644 --- a/juneau-core/src/main/java/org/apache/juneau/dto/atom/AtomBuilder.java +++ b/juneau-core/src/main/java/org/apache/juneau/dto/atom/AtomBuilder.java @@ -129,7 +129,7 @@ public class AtomBuilder { * @return The new element. */ public static final Icon icon(String uri) { - return icon(uri); + return new Icon(uri); } /** @@ -171,7 +171,7 @@ public class AtomBuilder { * @return The new element. */ public static final Logo logo(String uri) { - return logo(uri); + return new Logo(uri); } /** @@ -181,7 +181,7 @@ public class AtomBuilder { * @return The new element. */ public static final Logo logo(URI uri) { - return logo(uri); + return new Logo(uri); } /** http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElement.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElement.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElement.java index d105866..e3539ec 100644 --- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElement.java +++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElement.java @@ -16,6 +16,7 @@ import static org.apache.juneau.xml.annotation.XmlFormat.*; import java.util.*; +import org.apache.juneau.annotation.*; import org.apache.juneau.html.*; import org.apache.juneau.utils.*; import org.apache.juneau.xml.annotation.*; @@ -35,6 +36,7 @@ public abstract class HtmlElement { * @return The attributes of this element. */ @Xml(format=ATTRS) + @BeanProperty(name="a") public LinkedHashMap<String,Object> getAttrs() { return attrs; } @@ -44,6 +46,7 @@ public abstract class HtmlElement { * @param attrs The new attributes for this element. * @return This object (for method chaining). */ + @BeanProperty(name="a") public HtmlElement setAttrs(LinkedHashMap<String,Object> attrs) { this.attrs = attrs; return this; http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementContainer.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementContainer.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementContainer.java index 9878c40..1b8269e 100644 --- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementContainer.java +++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementContainer.java @@ -33,7 +33,7 @@ public class HtmlElementContainer extends HtmlElement { * @return The children of this element. */ @Xml(format=ELEMENTS) - @BeanProperty(beanDictionary=HtmlBeanDictionary.class) + @BeanProperty(beanDictionary=HtmlBeanDictionary.class, name="c") public LinkedList<Object> getChildren() { return children; } @@ -43,6 +43,7 @@ public class HtmlElementContainer extends HtmlElement { * @param children The new children for this container. * @return This object (for method chaining). */ + @BeanProperty(name="c") public HtmlElementContainer setChildren(LinkedList<Object> children) { this.children = children; return this; http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementMixed.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementMixed.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementMixed.java index 0890bc9..65b779e 100644 --- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementMixed.java +++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementMixed.java @@ -33,7 +33,7 @@ public class HtmlElementMixed extends HtmlElement { * @return The children of this element. */ @Xml(format=MIXED) - @BeanProperty(beanDictionary=HtmlBeanDictionary.class) + @BeanProperty(beanDictionary=HtmlBeanDictionary.class, name="c") public LinkedList<Object> getChildren() { return children; } @@ -44,6 +44,7 @@ public class HtmlElementMixed extends HtmlElement { * @param children The new children of this element. * @return This object (for method chaining). */ + @BeanProperty(name="c") public HtmlElement setChildren(LinkedList<Object> children) { this.children = children; return this; http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementText.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementText.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementText.java index 5c66b7e..a27cef2 100644 --- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementText.java +++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementText.java @@ -12,6 +12,7 @@ // *************************************************************************************************************************** package org.apache.juneau.dto.html5; +import org.apache.juneau.annotation.*; import org.apache.juneau.xml.annotation.*; /** @@ -28,6 +29,7 @@ public class HtmlElementText extends HtmlElement { * @return The inner text of this element, or <jk>null</jk> if no text is set. */ @Xml(format=XmlFormat.TEXT) + @BeanProperty(name="c") public Object getText() { return text; } @@ -38,6 +40,7 @@ public class HtmlElementText extends HtmlElement { * @param text The inner text of this element, or <jk>null</jk> if no text is set. * @return This object (for method chaining). */ + @BeanProperty(name="c") public HtmlElement setText(Object text) { this.text = text; return this; http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/dto/html5/Pre.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Pre.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Pre.java index 7d1f553..4f97bd6 100644 --- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Pre.java +++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Pre.java @@ -31,7 +31,7 @@ public class Pre extends HtmlElementMixed { //-------------------------------------------------------------------------------- @Xml(format=MIXED_PWS) - @BeanProperty(beanDictionary=HtmlBeanDictionary.class) + @BeanProperty(beanDictionary=HtmlBeanDictionary.class, name="c") @Override public LinkedList<Object> getChildren() { return super.getChildren(); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/dto/html5/Script.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Script.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Script.java index 4992a5c..8e5d4c9 100644 --- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Script.java +++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Script.java @@ -99,6 +99,7 @@ public class Script extends HtmlElementText { //-------------------------------------------------------------------------------- @Xml(format=XmlFormat.TEXT_PWS) + @BeanProperty(name="c") @Override public Object getText() { return super.getText(); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/dto/html5/Style.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Style.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Style.java index 174c1f5..5c8516a 100644 --- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/Style.java +++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/Style.java @@ -50,6 +50,7 @@ public class Style extends HtmlElementText { //-------------------------------------------------------------------------------- @Xml(format=XmlFormat.TEXT_PWS) + @BeanProperty(name="c") @Override /* HtmlElementText */ public Object getText() { return super.getText(); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/dto/jsonschema/Sample.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/jsonschema/Sample.java b/juneau-core/src/main/java/org/apache/juneau/dto/jsonschema/Sample.java index 8e37172..a9aa605 100644 --- a/juneau-core/src/main/java/org/apache/juneau/dto/jsonschema/Sample.java +++ b/juneau-core/src/main/java/org/apache/juneau/dto/jsonschema/Sample.java @@ -53,7 +53,7 @@ class Sample { .getProperty("address",true) // Get "address" property, resolved to Address schema. .getProperty("street") // Get "street" property. .getTypeAsJsonType(); // Get data type. - System.err.println("streetType=" + streetType); // Prints "streetType=string" + System.err.println("streetType=" + streetType); // Prints "streetType=string" // NOT DEBUG JsonType productIdType = purchaseOrderSchema .getProperty("product") // Get "product" property @@ -62,6 +62,6 @@ class Sample { .resolve() // Resolve to Product schema. .getProperty("productId") // Get "productId" property. .getTypeAsJsonType(); // Get data type. - System.err.println("productIdType=" + productIdType); // Prints "productIdType=number" + System.err.println("productIdType=" + productIdType); // Prints "productIdType=number" // NOT DEBUG } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroup.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroup.java b/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroup.java index 5f148d2..4f437c4 100644 --- a/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroup.java +++ b/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroup.java @@ -69,7 +69,7 @@ public final class EncoderGroup extends Lockable { */ public EncoderGroup append(Encoder e) { checkLock(); - synchronized(encoders) { + synchronized(this) { cache.clear(); encoders.add(0, e); } @@ -101,7 +101,7 @@ public final class EncoderGroup extends Lockable { append(e.newInstance()); } catch (NoClassDefFoundError x) { // Ignore if dependent library not found (e.g. Jena). - System.err.println(e); + System.err.println(e); // NOT DEBUG } return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java index 692357d..ac79d08 100644 --- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java +++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java @@ -225,8 +225,8 @@ public class HtmlDocSerializer extends HtmlStrippedDocSerializer { } @Override /* Serializer */ - public HtmlDocSerializer setUseIndentation(boolean value) throws LockedException { - super.setUseIndentation(value); + public HtmlDocSerializer setUseWhitespace(boolean value) throws LockedException { + super.setUseWhitespace(value); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java index de55239..f270030 100644 --- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java +++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java @@ -132,6 +132,6 @@ public final class HtmlDocSerializerSession extends HtmlSerializerSession { Object output = getOutput(); if (output instanceof HtmlWriter) return (HtmlWriter)output; - return new HtmlWriter(super.getWriter(), isUseIndentation(), isTrimStrings(), getQuoteChar(), getRelativeUriBase(), getAbsolutePathUriBase()); + return new HtmlWriter(super.getWriter(), isUseWhitespace(), isTrimStrings(), getQuoteChar(), getRelativeUriBase(), getAbsolutePathUriBase()); } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java index decdaad..39705ca 100644 --- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java +++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java @@ -69,7 +69,6 @@ public final class HtmlParser extends XmlParser { PojoSwap<T,Object> transform = (PojoSwap<T,Object>)eType.getPojoSwap(); ClassMeta<?> sType = eType.getSerializedClassMeta(); session.setCurrentClass(sType); - BeanRegistry breg = (pMeta == null ? session.getBeanRegistry() : pMeta.getBeanRegistry()); int event = r.getEventType(); if (event != START_ELEMENT) @@ -160,9 +159,10 @@ public final class HtmlParser extends XmlParser { } else if (tag == TABLE) { String typeName = getAttribute(r, session.getBeanTypePropertyName(), "object"); + ClassMeta cm = session.getClassMeta(typeName, pMeta, eType); - if (breg.hasName(typeName)) { - sType = eType = (ClassMeta<T>)breg.getClassMeta(typeName); + if (cm != null) { + sType = eType = cm; typeName = sType.isArray() ? "array" : "object"; } else if (! "array".equals(typeName)) { // Type name could be a subtype name. @@ -201,9 +201,9 @@ public final class HtmlParser extends XmlParser { } else if (tag == UL) { String typeName = getAttribute(r, session.getBeanTypePropertyName(), "array"); - - if (breg.hasName(typeName)) - sType = eType = (ClassMeta<T>)breg.getClassMeta(typeName); + ClassMeta cm = session.getClassMeta(typeName, pMeta, eType); + if (cm != null) + sType = eType = cm; if (sType.isObject()) o = parseIntoCollection(session, r, (Collection)new ObjectList(session), sType.getElementType(), pMeta); @@ -332,7 +332,6 @@ public final class HtmlParser extends XmlParser { if (elementType == null) elementType = (ClassMeta<E>)object(); - BeanRegistry breg = (pMeta == null ? session.getBeanRegistry() : pMeta.getBeanRegistry()); HtmlTag tag = nextTag(r, TR); List<String> keys = new ArrayList<String>(); @@ -350,9 +349,9 @@ public final class HtmlParser extends XmlParser { break; String type = getAttribute(r, session.getBeanTypePropertyName(), null); - if (breg.hasName(type)) { - elementType = (ClassMeta)breg.getClassMeta(type); - } + ClassMeta elementType2 = session.getClassMeta(type, pMeta, null); + if (elementType2 != null) + elementType = elementType2; if (elementType.canCreateNewBean(l)) { BeanMap m = session.newBeanMap(l, elementType.getInnerClass()); @@ -398,7 +397,7 @@ public final class HtmlParser extends XmlParser { if (m != null && c != null) { ObjectMap m2 = (m instanceof ObjectMap ? (ObjectMap)m : new ObjectMap(m).setBeanSession(session)); m2.put(session.getBeanTypePropertyName(), c); - l.add((E)breg.cast(m2)); + l.add((E)session.cast(m2, pMeta, null)); } else { l.add((E)m); } @@ -429,13 +428,8 @@ public final class HtmlParser extends XmlParser { nextTag(r, TD); BeanPropertyMeta pMeta = m.getPropertyMeta(key); if (pMeta == null) { - if (m.getMeta().isSubTyped()) { - Object value = parseAnything(session, object(), r, m.getBean(false), false, null); - m.put(key, value); - } else { - onUnknownProperty(session, key, m, -1, -1); - parseAnything(session, object(), r, null, false, null); - } + onUnknownProperty(session, key, m, -1, -1); + parseAnything(session, object(), r, null, false, null); } else { ClassMeta<?> cm = pMeta.getClassMeta(); Object value = parseAnything(session, cm, r, m.getBean(false), false, pMeta); @@ -448,8 +442,6 @@ public final class HtmlParser extends XmlParser { return m; } - - /* * Reads the next tag. Advances past anything that's not a start or end tag. Throws an exception if * it's not one of the expected tags. http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserSession.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserSession.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserSession.java index 80645af..f885578 100644 --- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserSession.java +++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserSession.java @@ -32,7 +32,6 @@ import org.apache.juneau.xml.*; */ public final class HtmlParserSession extends XmlParserSession { - private XMLEventReader xmlEventReader; private static final Set<String> whitespaceElements = new HashSet<String>( Arrays.asList( new String[]{"br","bs","sp","ff"} @@ -203,19 +202,4 @@ public final class HtmlParserSession extends XmlParserSession { throw new XMLStreamException("Invalid tag found in parseWhitespaceElement(): " + tag); } } - - @Override /* ParserSession */ - public boolean close() { - if (super.close()) { - if (xmlEventReader != null) { - try { - xmlEventReader.close(); - } catch (XMLStreamException e) { - throw new BeanRuntimeException(e); - } - } - return true; - } - return false; - } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java index d462732..e5d4589 100644 --- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java +++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java @@ -152,7 +152,7 @@ public class HtmlSerializer extends XmlSerializer { public static class SqReadable extends Sq { /** Constructor */ public SqReadable() { - setUseIndentation(true); + setUseWhitespace(true); } } @@ -831,8 +831,8 @@ public class HtmlSerializer extends XmlSerializer { } @Override /* Serializer */ - public HtmlSerializer setUseIndentation(boolean value) throws LockedException { - super.setUseIndentation(value); + public HtmlSerializer setUseWhitespace(boolean value) throws LockedException { + super.setUseWhitespace(value); return this; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java index b97bb9e..3d67924 100644 --- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java +++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java @@ -83,7 +83,7 @@ public class HtmlSerializerSession extends XmlSerializerSession { Object output = getOutput(); if (output instanceof HtmlWriter) return (HtmlWriter)output; - return new HtmlWriter(super.getWriter(), isUseIndentation(), isTrimStrings(), getQuoteChar(), getRelativeUriBase(), getAbsolutePathUriBase()); + return new HtmlWriter(super.getWriter(), isUseWhitespace(), isTrimStrings(), getQuoteChar(), getRelativeUriBase(), getAbsolutePathUriBase()); } /** http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/html/HtmlWriter.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlWriter.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlWriter.java index 3a2a810..95b6092 100644 --- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlWriter.java +++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlWriter.java @@ -26,14 +26,14 @@ public class HtmlWriter extends XmlWriter { * Constructor. * * @param out The writer being wrapped. - * @param useIndentation If <jk>true</jk>, tabs will be used in output. + * @param useWhitespace If <jk>true</jk>, tabs will be used in output. * @param trimStrings If <jk>true</jk>, strings should be trimmed before they're serialized. * @param quoteChar The quote character to use (i.e. <js>'\''</js> or <js>'"'</js>) * @param uriContext The web application context path (e.g. "/contextRoot"). * @param uriAuthority The web application URI authority (e.g. "http://hostname:9080") */ - public HtmlWriter(Writer out, boolean useIndentation, boolean trimStrings, char quoteChar, String uriContext, String uriAuthority) { - super(out, useIndentation, trimStrings, quoteChar, uriContext, uriAuthority, false, null); + public HtmlWriter(Writer out, boolean useWhitespace, boolean trimStrings, char quoteChar, String uriContext, String uriAuthority) { + super(out, useWhitespace, trimStrings, quoteChar, uriContext, uriAuthority, false, null); } /** http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/ini/ConfigMgr.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/ini/ConfigMgr.java b/juneau-core/src/main/java/org/apache/juneau/ini/ConfigMgr.java index 7188624..0ebf523 100644 --- a/juneau-core/src/main/java/org/apache/juneau/ini/ConfigMgr.java +++ b/juneau-core/src/main/java/org/apache/juneau/ini/ConfigMgr.java @@ -303,10 +303,10 @@ public class ConfigMgr { } private static void printUsageAndExit() { - System.err.println("---Usage---"); - System.err.println("java -cp juneau.jar org.apache.juneau.ini.ConfigFile createBatchEnvFile -configFile <configFile> -envFile <envFile> [-verbose]"); - System.err.println("java -cp juneau.jar org.apache.juneau.ini.ConfigFile createShellEnvFile -configFile <configFile> -envFile <envFile> [-verbose]"); - System.err.println("java -cp juneau.jar org.apache.juneau.ini.ConfigFile setVals -configFile <configFile> -vals [var1 val1 [var2 val2...]] [-verbose]"); + System.err.println("---Usage---"); // NOT DEBUG + System.err.println("java -cp juneau.jar org.apache.juneau.ini.ConfigFile createBatchEnvFile -configFile <configFile> -envFile <envFile> [-verbose]"); // NOT DEBUG + System.err.println("java -cp juneau.jar org.apache.juneau.ini.ConfigFile createShellEnvFile -configFile <configFile> -envFile <envFile> [-verbose]"); // NOT DEBUG + System.err.println("java -cp juneau.jar org.apache.juneau.ini.ConfigFile setVals -configFile <configFile> -vals [var1 val1 [var2 val2...]] [-verbose]"); // NOT DEBUG int rc = Integer.getInteger("exit.2", 2); if (rc != 0) System.exit(rc); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/internal/AsciiSet.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/internal/AsciiSet.java b/juneau-core/src/main/java/org/apache/juneau/internal/AsciiSet.java index 999de00..7f84418 100644 --- a/juneau-core/src/main/java/org/apache/juneau/internal/AsciiSet.java +++ b/juneau-core/src/main/java/org/apache/juneau/internal/AsciiSet.java @@ -54,4 +54,19 @@ public final class AsciiSet { return false; return store[c]; } + + /** + * Returns <jk>true</jk> if the specified string contains at least one character in this set. + * + * @param s The string to test. + * @return <jk>true</jk> if the string is not null and contains at least one character in this set. + */ + public boolean contains(CharSequence s) { + if (s == null) + return false; + for (int i = 0; i < s.length(); i++) + if (contains(s.charAt(i))) + return true; + return false; + } }
