http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-test/src/test/java/org/apache/juneau/ini/ConfigMgrTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-test/src/test/java/org/apache/juneau/ini/ConfigMgrTest.java 
b/juneau-core-test/src/test/java/org/apache/juneau/ini/ConfigMgrTest.java
new file mode 100755
index 0000000..4039fcb
--- /dev/null
+++ b/juneau-core-test/src/test/java/org/apache/juneau/ini/ConfigMgrTest.java
@@ -0,0 +1,204 @@
+// 
***************************************************************************************************************************
+// * 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.ini;
+
+import static org.apache.juneau.TestUtils.*;
+import static org.junit.Assert.*;
+
+import java.io.*;
+import java.nio.charset.*;
+
+import org.apache.juneau.internal.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.svl.*;
+import org.junit.*;
+
+@SuppressWarnings("javadoc")
+public class ConfigMgrTest {
+
+       private static File tempDir;
+
+       @BeforeClass
+       public static void setup() {
+               tempDir = new File(System.getProperty("java.io.tmpdir"), 
StringUtils.generateUUID(12));
+               FileUtils.mkdirs(tempDir, true);
+       }
+
+       @AfterClass
+       public static void teardown() {
+               FileUtils.delete(tempDir);
+       }
+
+       
//====================================================================================================
+       // get(String path)
+       // get(String path, boolean create)
+       
//====================================================================================================
+       @Test
+       public void testGet() throws Exception {
+               File f;
+               ConfigMgr cm = new ConfigMgr(false, new XorEncoder(), 
JsonSerializer.DEFAULT, JsonParser.DEFAULT, Charset.defaultCharset(), new 
String[]{tempDir.getAbsolutePath()});
+
+               ConfigFile cf = cm.get("TestGet.cfg", true);
+               cf.put("Test/A", "a");
+
+               f = new File(tempDir, "TestGet.cfg");
+               assertTrue(f.exists());
+
+               cf.save();
+               assertTextEquals("[Test]|A = a|", IOUtils.read(f));
+
+               cf = cm.get("TestGet.cfg");
+               assertObjectEquals("{'default':{},Test:{A:'a'}}", cf);
+
+               ConfigFile cf2 = cm.get(tempDir.getAbsolutePath() + 
"/TestGet.cfg");
+               assertObjectEquals("{'default':{},Test:{A:'a'}}", cf2);
+               assertTrue(cf == cf2);  // Relative and absolute paths must 
resolve to same config file.
+
+               try { cm.get("TestGet2.cfg"); fail(); } catch 
(FileNotFoundException e) {}
+               try { cm.get(tempDir.getAbsolutePath() + "TestGet2.cfg"); 
fail(); } catch (FileNotFoundException e) {}
+
+               cm.get(tempDir.getAbsolutePath() + "TestGet2.cfg", true);
+
+               ConfigMgr cm2 = new ConfigMgr(false, new XorEncoder(), 
JsonSerializer.DEFAULT, JsonParser.DEFAULT, Charset.defaultCharset(), new 
String[]{tempDir.getAbsolutePath()});
+               cf = cm2.get("TestGet.cfg");
+               assertObjectEquals("{'default':{},Test:{A:'a'}}", cf);
+
+               cm2 = new ConfigMgr(false, new XorEncoder(), 
JsonSerializer.DEFAULT, JsonParser.DEFAULT, Charset.defaultCharset(), null);
+               try { cf = cm2.get("TestGet.cfg"); fail(); } catch 
(FileNotFoundException e) {}
+
+               String NL = System.getProperty("line.separator");
+               cf = cm2.create(new StringReader(("[Test]"+NL+"A = a"+NL)));
+               assertObjectEquals("{'default':{},Test:{A:'a'}}", cf);
+
+               ConfigMgr cm3 = new ConfigMgr(false, new XorEncoder(), 
JsonSerializer.DEFAULT, JsonParser.DEFAULT, IOUtils.UTF8, new 
String[]{tempDir.getAbsolutePath()});
+               cf = cm3.get("TestGet.cfg");
+               assertObjectEquals("{'default':{},Test:{A:'a'}}", cf);
+
+               cm.deleteAll();
+               cm2.deleteAll();
+               cm3.deleteAll();
+       }
+
+       
//====================================================================================================
+       // loadIfModified()
+       
//====================================================================================================
+       @Test
+       public void testLoadIfModified() throws Exception {
+               ConfigMgr cm = new ConfigMgr(false, new XorEncoder(), 
JsonSerializer.DEFAULT, JsonParser.DEFAULT, Charset.defaultCharset(), new 
String[]{tempDir.getAbsolutePath()});
+               File f;
+               ConfigFile cf = cm.get("TestGet.cfg", true);
+               cf.put("Test/A", "a");
+
+               f = new File(tempDir, "TestGet.cfg");
+               String NL = System.getProperty("line.separator");
+               IOUtils.write(f, new StringReader("[Test]"+NL+"A = b"+NL));
+               FileUtils.modifyTimestamp(f);
+
+               cm.loadIfModified();
+               assertEquals("b", cf.getString("Test/A"));
+               cm.loadIfModified();
+               assertEquals("b", cf.getString("Test/A"));
+
+               // Config file with no backing file.
+               cf = cm.create();
+               cf.put("Test/B", "b");
+               cm.loadIfModified();
+               cf.loadIfModified();
+               assertEquals("b", cf.getString("Test/B"));
+
+               cm.deleteAll();
+       }
+
+       
//====================================================================================================
+       // read only
+       
//====================================================================================================
+       @Test
+       public void testReadOnly() throws Exception {
+               ConfigMgr cm = new ConfigMgr(true, new XorEncoder(), 
JsonSerializer.DEFAULT, JsonParser.DEFAULT, Charset.defaultCharset(), new 
String[]{tempDir.getAbsolutePath()});
+               ConfigFile cf = cm.get("TestGet.cfg", true);
+
+               // All these should fail.
+               try { cf.loadIfModified(); fail(); } catch 
(UnsupportedOperationException e) {}
+               try { cf.load(); fail(); } catch (UnsupportedOperationException 
e) {}
+               try { cf.load(new StringReader("")); fail(); } catch 
(UnsupportedOperationException e) {}
+               try { cf.put("A","b"); fail(); } catch 
(UnsupportedOperationException e) {}
+               try { cf.put("A","b",true); fail(); } catch 
(UnsupportedOperationException e) {}
+               try { cf.put("A","b"); fail(); } catch 
(UnsupportedOperationException e) {}
+               try { cf.put("A","b",true); fail(); } catch 
(UnsupportedOperationException e) {}
+               try { cf.removeString("A"); fail(); } catch 
(UnsupportedOperationException e) {}
+               try { cf.addLines("A","b=c"); fail(); } catch 
(UnsupportedOperationException e) {}
+               try { cf.addHeaderComments("A", "b=c"); fail(); } catch 
(UnsupportedOperationException e) {}
+               try { cf.clearHeaderComments("A"); fail(); } catch 
(UnsupportedOperationException e) {}
+               try { cf.addSection("A"); fail(); } catch 
(UnsupportedOperationException e) {}
+               try { cf.setSection("A",null); fail(); } catch 
(UnsupportedOperationException e) {}
+               try { cf.removeSection("A"); fail(); } catch 
(UnsupportedOperationException e) {}
+               try { cf.save(); fail(); } catch (UnsupportedOperationException 
e) {}
+               try { cf.merge(cf); fail(); } catch 
(UnsupportedOperationException e) {}
+               try { cf.addListener(new ConfigFileListener(){}); fail(); } 
catch (UnsupportedOperationException e) {}
+
+               // All these should succeed.
+               cf.getObject(String.class, "A");
+               cf.getObject(String.class, "A", "a");
+               cf.getString("A");
+               cf.getString("A","a");
+               cf.getObject(String.class, "A");
+               cf.getObject(String.class, "A", "a");
+               cf.getObject(String[].class, "A");
+               cf.getStringArray("A");
+               cf.getStringArray("A", null);
+               cf.getInt("A");
+               cf.getInt("A", 0);
+               cf.getBoolean("A");
+               cf.getBoolean("A", true);
+               cf.containsNonEmptyValue("A");
+               cf.getSectionMap("A");
+               cf.serializeTo(new StringWriter());
+               cf.serializeTo(new StringWriter(), ConfigFileFormat.INI);
+               cf.getResolving(VarResolver.DEFAULT);
+               cf.toWritable();
+       }
+
+       
//====================================================================================================
+       // main(String[] args)
+       
//====================================================================================================
+       @Test
+       public void testMain() throws Exception {
+               System.setProperty("exit.2", "0");
+               ConfigMgr cm = new ConfigMgr(false, new XorEncoder(), 
JsonSerializer.DEFAULT, JsonParser.DEFAULT, Charset.defaultCharset(), new 
String[]{tempDir.getAbsolutePath()});
+
+               ConfigFile cf = cm.get("Test.cfg", true)
+                       .addLines(null, "# c1", "\t# c2", " c3 ", "  ", "x1=1", 
"x2=true", "x3=null")
+                       .addLines("s1", "#c4", "k1=1", "#c5 foo=bar", "k2 = 
true", "k3  = \tnull");
+               cf.save();
+
+               File configFile = new File(tempDir, "Test.cfg");
+               File envFile = new File(tempDir, "Test.bat");
+
+               ConfigMgr.main(new String[]{"createBatchEnvFile", 
"-configFile", configFile.getAbsolutePath(), "-envFile", 
envFile.getAbsolutePath()});
+               String expected = "rem c1|rem c2|rem c3||set x1 = 1|set x2 = 
true|set x3 = null|rem c4|set s1_k1 = 1|rem c5 foo=bar|set s1_k2 = true|set 
s1_k3 = null|";
+               String actual = IOUtils.read(envFile);
+               assertTextEquals(expected, actual);
+
+               ConfigMgr.main(new String[]{"createShellEnvFile", 
"-configFile", configFile.getAbsolutePath(), "-envFile", 
envFile.getAbsolutePath()});
+               expected = "# c1|# c2|# c3||export x1=\"1\"|export 
x2=\"true\"|export x3=\"null\"|# c4|export s1_k1=\"1\"|# c5 foo=bar|export 
s1_k2=\"true\"|export s1_k3=\"null\"|";
+               actual = IOUtils.read(envFile);
+               assertTextEquals(expected, actual);
+
+               ConfigMgr.main(new String[]{"setVals", "-configFile", 
configFile.getAbsolutePath(), "-vals", "x1=2", "s1/k1=2", "s2/k1=3"});
+               FileUtils.modifyTimestamp(configFile);
+               cf.loadIfModified();
+               
assertObjectEquals("{'default':{x1:'2',x2:'true',x3:'null'},s1:{k1:'2',k2:'true',k3:'null'},s2:{k1:'3'}}",
 cf);
+
+               ConfigMgr.main(new String[]{});
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-test/src/test/java/org/apache/juneau/internal/VersionRangeTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-test/src/test/java/org/apache/juneau/internal/VersionRangeTest.java
 
b/juneau-core-test/src/test/java/org/apache/juneau/internal/VersionRangeTest.java
new file mode 100755
index 0000000..baa07c6
--- /dev/null
+++ 
b/juneau-core-test/src/test/java/org/apache/juneau/internal/VersionRangeTest.java
@@ -0,0 +1,70 @@
+// 
***************************************************************************************************************************
+// * 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.internal;
+
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.junit.*;
+import org.junit.runner.*;
+import org.junit.runners.*;
+
+@RunWith(Parameterized.class)
+@SuppressWarnings("javadoc")
+public class VersionRangeTest {
+
+       @Parameterized.Parameters
+       public static Collection<Object[]> getPairs() {
+               return Arrays.asList(new Object[][] {
+                       // {range, version, shouldMatch }
+                       /* 00 */ {"1.1", "1.1.3", true},
+                       /* 01 */ {"1.1", "1.1", true},
+                       /* 02 */ {"1.1", "1.1.0", true},
+                       /* 03 */ {"1.1", "1.0", false},
+                       /* 04 */ {"1.1", "1.0.9", false},
+                       /* 05 */ {"[1.0,2.0)", ".9", false},
+                       /* 06 */ {"[1.0,2.0)", "1", true},
+                       /* 07 */ {"[1.0,2.0)", "1.0", true},
+                       /* 08 */ {"[1.0,2.0)", "1.0.0", true},
+                       /* 09 */ {"[1.0,2.0)", "1.1", true},
+                       /* 10 */ {"[1.0,2.0)", "2.0", false},
+                       /* 11 */ {"[1.0,2.0)", "2", false},
+                       /* 12 */ {"(1.0,2.0]", "2", true},
+                       /* 13 */ {"(1.0,2.0]", "2.0", true},
+                       /* 14 */ {"(1.0,2.0]", "2.0.1", true},
+                       /* 15 */ {"(1.0,2.0]", "2.1", false},
+                       /* 16 */ {"(.5.0,.6]", ".5", false},
+                       /* 17 */ {"(.5.0,.6]", ".5.1", true},
+                       /* 18 */ {"(.5.0,.6]", ".6", true},
+                       /* 19 */ {"(.5.0,.6]", ".6.1", true},
+                       /* 20 */ {"(.5.0,.6]", ".7", false},
+                       /* 21 */ {"[1.1,2.0)", "1", false},
+               });
+       }
+
+       private VersionRange range;
+       private String version;
+       private boolean shouldMatch;
+
+       public VersionRangeTest(String range, String version, boolean 
shouldMatch) {
+               this.version = version;
+               this.range = new VersionRange(range);
+               this.shouldMatch = shouldMatch;
+       }
+
+       @Test
+       public void test() throws Exception {
+               assertEquals(shouldMatch, range.matches(version));
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonParserTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonParserTest.java 
b/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonParserTest.java
new file mode 100755
index 0000000..04a7f67
--- /dev/null
+++ 
b/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonParserTest.java
@@ -0,0 +1,207 @@
+// 
***************************************************************************************************************************
+// * 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.jena;
+
+import static org.apache.juneau.BeanContext.*;
+import static org.apache.juneau.jena.RdfCommonContext.*;
+import static org.apache.juneau.jena.RdfSerializerContext.*;
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.junit.*;
+
+@SuppressWarnings({"rawtypes","serial","javadoc"})
+public class CommonParserTest {
+
+       private String wrap(String in) {
+               return ""
+                       + "<rdf:RDF"
+                   + " xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'"
+                   + " xmlns:j='http://www.apache.org/juneau/'"
+                   + " xmlns:jp='http://www.apache.org/juneaubp/'>"
+                   + in
+                   + "</rdf:RDF>";
+       }
+
+       private String strip(String s) {
+               return s.replaceFirst("<rdf:RDF[^>]+>\\s*", 
"").replaceAll("</rdf:RDF>$", "").trim().replaceAll("[\\r\\n]", "");
+       }
+
+       private RdfSerializer getBasicSerializer() {
+               return new RdfSerializer()
+                       .setProperty(SERIALIZER_quoteChar, '\'')
+                       .setProperty(RDF_addLiteralTypes, true)
+                       .setProperty(SERIALIZER_useIndentation, false)
+                       .setProperty(RDF_rdfxml_allowBadUris, true)
+                       .setProperty(RDF_rdfxml_showDoctypeDeclaration, false)
+                       .setProperty(RDF_rdfxml_showXmlDeclaration, false);
+       }
+
+       
//====================================================================================================
+       // testBasicFromSerializer
+       
//====================================================================================================
+       @Test
+       public void testFromSerializer() throws Exception {
+               WriterSerializer s = getBasicSerializer();
+               ReaderParser p = new 
RdfParser.Xml().setProperty(RdfParserContext.RDF_trimWhitespace, 
true).setClassLoader(getClass().getClassLoader());
+               Map m = null;
+               String in;
+               Integer one = Integer.valueOf(1);
+
+               in = wrap("<rdf:Description><jp:a 
rdf:datatype='http://www.w3.org/2001/XMLSchema#int'>1</jp:a></rdf:Description>");
+               m = (Map)p.parse(in, Object.class);
+               assertEquals(one, m.get("a"));
+
+               in = wrap("<rdf:Description><jp:a 
rdf:datatype='http://www.w3.org/2001/XMLSchema#int'>1</jp:a><jp:b>foo 
bar</jp:b><jp:c 
rdf:datatype='http://www.w3.org/2001/XMLSchema#boolean'>false</jp:c></rdf:Description>");
+               m = (Map)p.parse(in, Object.class);
+               assertEquals(one, m.get("a"));
+               assertEquals("foo bar", m.get("b"));
+               in = wrap("<rdf:Description><jp:a 
rdf:datatype='http://www.w3.org/2001/XMLSchema#int'> 1 </jp:a><jp:b> foo bar 
</jp:b><jp:c rdf:datatype='http://www.w3.org/2001/XMLSchema#boolean'> false 
</jp:c></rdf:Description>");
+               m = (Map)p.parse(in, Object.class);
+               assertEquals(one, m.get("a"));
+               assertEquals("foo bar", m.get("b"));
+               assertEquals(false, m.get("c"));
+
+               in = 
wrap("<rdf:Description><jp:x>org.apache.juneau.test.Person</jp:x><jp:addresses><rdf:Seq><rdf:li
 
rdf:parseType='Resource'><jp:x>org.apache.juneau.test.Address</jp:x><jp:city>city
 A</jp:city><jp:state>state A</jp:state><jp:street>street A</jp:street><jp:zip 
rdf:datatype='http://www.w3.org/2001/XMLSchema#int'>12345</jp:zip></rdf:li></rdf:Seq></jp:addresses></rdf:Description>");
+               m = (Map)p.parse(in, Object.class);
+               assertEquals("org.apache.juneau.test.Person", m.get("x"));
+               List l = (List)m.get("addresses");
+               assertNotNull(l);
+               m = (Map)l.get(0);
+               assertNotNull(m);
+               assertEquals("org.apache.juneau.test.Address", m.get("x"));
+               assertEquals("city A", m.get("city"));
+               assertEquals("state A", m.get("state"));
+               assertEquals("street A", m.get("street"));
+               assertEquals(12345, m.get("zip"));
+
+               in = wrap("<rdf:Seq><rdf:li 
rdf:parseType='Resource'><jp:attribute>value</jp:attribute></rdf:li><rdf:li 
rdf:parseType='Resource'><jp:attribute>value</jp:attribute></rdf:li></rdf:Seq>");
+               ObjectList jl = (ObjectList)p.parse(in, Object.class);
+               assertEquals("value", 
jl.getObjectMap(0).getString("attribute"));
+               assertEquals("value", 
jl.getObjectMap(1).getString("attribute"));
+
+               // Verify that all the following return null.
+               assertNull(p.parse((CharSequence)null, Object.class));
+               assertNull(p.parse(wrap(""), Object.class));
+               assertNull(p.parse(wrap("   "), Object.class));
+               assertNull(p.parse(wrap("   \t"), Object.class));
+               assertNull(p.parse(wrap("   <!--foo-->"), Object.class));
+               assertNull(p.parse(wrap("   <!--foo-->   "), Object.class));
+               assertNull(p.parse(wrap("   //foo   "), Object.class));
+
+
+               A1 t1 = new A1();
+               A2 t2 = new A2();
+               t2.add(new A3("name0","value0"));
+               t2.add(new A3("name1","value1"));
+               t1.list = t2;
+
+               s.setProperty(SERIALIZER_addBeanTypeProperties, true);
+               in = strip(s.serialize(t1));
+               
assertEquals("<rdf:Description><j:class>"+A1.class.getName()+"</j:class><jp:list><rdf:Seq><rdf:li
 
rdf:parseType='Resource'><jp:name>name0</jp:name><jp:value>value0</jp:value></rdf:li><rdf:li
 
rdf:parseType='Resource'><jp:name>name1</jp:name><jp:value>value1</jp:value></rdf:li></rdf:Seq></jp:list></rdf:Description>",
 in);
+               in = wrap(in);
+               t1 = (A1)p.parse(in, Object.class);
+               assertEquals("value1", t1.list.get(1).value);
+               t1 = p.parse(in, A1.class);
+               assertEquals("value1", t1.list.get(1).value);
+       }
+
+       public static class A1 {
+               public A2 list;
+       }
+
+       public static class A2 extends LinkedList<A3> {
+       }
+
+       public static class A3 {
+               public String name, value;
+               public A3(){}
+               public A3(String name, String value) {
+                       this.name = name;
+                       this.value = value;
+               }
+       }
+
+       
//====================================================================================================
+       // Correct handling of unknown properties.
+       
//====================================================================================================
+       @Test
+       public void testCorrectHandlingOfUnknownProperties() throws Exception {
+               ReaderParser p = new 
RdfParser.Xml().setProperty(BEAN_ignoreUnknownBeanProperties, true);
+               B t;
+
+               String in = wrap("<rdf:Description><jp:a 
rdf:datatype='http://www.w3.org/2001/XMLSchema#int'>1</jp:a><jp:unknownProperty>foo</jp:unknownProperty><jp:b
 
rdf:datatype='http://www.w3.org/2001/XMLSchema#int'>2</jp:b></rdf:Description>");
+               t = p.parse(in, B.class);
+               assertEquals(t.a, 1);
+               assertEquals(t.b, 2);
+
+               try {
+                       p = new RdfParser.Xml();
+                       p.parse(in, B.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {}
+       }
+
+       public static class B {
+               public int a, b;
+       }
+
+       
//====================================================================================================
+       // Writing to Collection properties with no setters.
+       
//====================================================================================================
+       @Test
+       public void testCollectionPropertiesWithNoSetters() throws Exception {
+               RdfParser p = new RdfParser.Xml();
+               String in = 
wrap("<rdf:Description><jp:ints><rdf:Seq><rdf:li>1</rdf:li><rdf:li>2</rdf:li></rdf:Seq></jp:ints><jp:beans><rdf:Seq><rdf:li
 
rdf:parseType='Resource'><jp:a>1</jp:a><jp:b>2</jp:b></rdf:li></rdf:Seq></jp:beans></rdf:Description>");
+               C t = p.parse(in, C.class);
+               assertEquals(t.getInts().size(), 2);
+               assertEquals(t.getBeans().get(0).b, 2);
+       }
+
+       public static class C {
+               private Collection<Integer> ints = new LinkedList<Integer>();
+               private List<B> beans = new LinkedList<B>();
+               public Collection<Integer> getInts() {
+                       return ints;
+               }
+               public List<B> getBeans() {
+                       return beans;
+               }
+       }
+
+       
//====================================================================================================
+       // Parser listeners.
+       
//====================================================================================================
+       @Test
+       public void testParserListeners() throws Exception {
+               final List<String> events = new LinkedList<String>();
+               RdfParser p = new 
RdfParser.Xml().setProperty(BEAN_ignoreUnknownBeanProperties, true);
+               p.addListener(
+                       new ParserListener() {
+                               @Override /* ParserListener */
+                               public <T> void onUnknownProperty(String 
propertyName, Class<T> beanClass, T bean, int line, int col) {
+                                       events.add(propertyName + "," + line + 
"," + col);
+                               }
+                       }
+               );
+
+               String in = wrap("<rdf:Description><jp:a 
rdf:datatype='http://www.w3.org/2001/XMLSchema#int'>1</jp:a><jp:unknownProperty>foo</jp:unknownProperty><jp:b
 
rdf:datatype='http://www.w3.org/2001/XMLSchema#int'>2</jp:b></rdf:Description>");
+               p.parse(in, B.class);
+               assertEquals(1, events.size());
+               assertEquals("unknownProperty,-1,-1", events.get(0));
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonTest.java 
b/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonTest.java
new file mode 100755
index 0000000..c2085a2
--- /dev/null
+++ b/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonTest.java
@@ -0,0 +1,514 @@
+// 
***************************************************************************************************************************
+// * 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.jena;
+
+import static org.apache.juneau.TestUtils.*;
+import static org.apache.juneau.jena.RdfCommonContext.*;
+import static org.apache.juneau.serializer.SerializerContext.*;
+import static org.junit.Assert.*;
+
+import java.net.*;
+import java.net.URI;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.jena.annotation.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.testbeans.*;
+import org.apache.juneau.xml.*;
+import org.junit.*;
+
+@SuppressWarnings({"unchecked","serial","javadoc"})
+public class CommonTest {
+
+       private RdfSerializer getBasicSerializer() {
+               return new RdfSerializer()
+                       .setProperty(SERIALIZER_quoteChar, '\'')
+                       .setProperty(SERIALIZER_useIndentation, false)
+                       .setProperty(RDF_rdfxml_allowBadUris, true)
+                       .setProperty(RDF_rdfxml_showDoctypeDeclaration, false)
+                       .setProperty(RDF_rdfxml_showXmlDeclaration, false);
+       }
+
+       private String strip(String s) {
+               return s.replaceFirst("<rdf:RDF[^>]+>\\s*", 
"").replaceAll("</rdf:RDF>$", "").trim().replaceAll("[\\r\\n]", "");
+       }
+
+       
//====================================================================================================
+       // Trim nulls from beans
+       
//====================================================================================================
+       @Test
+       public void testTrimNullsFromBeans() throws Exception {
+               RdfSerializer s = getBasicSerializer();
+               RdfParser p = RdfParser.DEFAULT_XML;
+               A t1 = A.create(), t2;
+
+               s.setProperty(SERIALIZER_trimNullProperties, false);
+               String r = s.serialize(t1);
+               assertEquals("<rdf:Description><jp:s1 
rdf:resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/><jp:s2>s2</jp:s2></rdf:Description>",
 strip(r));
+               t2 = p.parse(r, A.class);
+               assertEqualObjects(t1, t2);
+
+               s.setProperty(SERIALIZER_trimNullProperties, true);
+               r = s.serialize(t1);
+               
assertEquals("<rdf:Description><jp:s2>s2</jp:s2></rdf:Description>", strip(r));
+               t2 = p.parse(r, A.class);
+               assertEqualObjects(t1, t2);
+       }
+
+       public static class A {
+               public String s1, s2;
+
+               public static A create() {
+                       A t = new A();
+                       t.s2 = "s2";
+                       return t;
+               }
+       }
+
+       
//====================================================================================================
+       // Trim empty maps
+       
//====================================================================================================
+       @Test
+       public void testTrimEmptyMaps() throws Exception {
+               RdfSerializer s = getBasicSerializer();
+               RdfParser p = RdfParser.DEFAULT_XML;
+               B t1 = B.create(), t2;
+               String r;
+
+               s.setProperty(SERIALIZER_trimEmptyMaps, false);
+               r = s.serialize(t1);
+               assertEquals("<rdf:Description><jp:f1 
rdf:parseType='Resource'></jp:f1><jp:f2 rdf:parseType='Resource'><jp:f2a 
rdf:resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/><jp:f2b 
rdf:parseType='Resource'><jp:s2>s2</jp:s2></jp:f2b></jp:f2></rdf:Description>", 
strip(r));
+               t2 = p.parse(r, B.class);
+               assertEqualObjects(t1, t2);
+
+               s.setProperty(SERIALIZER_trimEmptyMaps, true);
+               r = s.serialize(t1);
+               assertEquals("<rdf:Description><jp:f2 
rdf:parseType='Resource'><jp:f2a 
rdf:resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/><jp:f2b 
rdf:parseType='Resource'><jp:s2>s2</jp:s2></jp:f2b></jp:f2></rdf:Description>", 
strip(r));
+               t2 = p.parse(r, B.class);
+               assertNull(t2.f1);
+       }
+
+       public static class B {
+               public TreeMap<String,A> f1, f2;
+
+               public static B create() {
+                       B t = new B();
+                       t.f1 = new TreeMap<String,A>();
+                       t.f2 = new 
TreeMap<String,A>(){{put("f2a",null);put("f2b",A.create());}};
+                       return t;
+               }
+       }
+
+       
//====================================================================================================
+       // Trim empty lists
+       
//====================================================================================================
+       @Test
+       public void testTrimEmptyLists() throws Exception {
+               RdfSerializer s = getBasicSerializer();
+               RdfParser p = RdfParser.DEFAULT_XML;
+               C t1 = C.create(), t2;
+               String r;
+
+               s.setProperty(SERIALIZER_trimEmptyCollections, false);
+               r = s.serialize(t1);
+               
assertEquals("<rdf:Description><jp:f1><rdf:Seq/></jp:f1><jp:f2><rdf:Seq><rdf:li 
rdf:resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/><rdf:li 
rdf:parseType='Resource'><jp:s2>s2</jp:s2></rdf:li></rdf:Seq></jp:f2></rdf:Description>",
 strip(r));
+               t2 = p.parse(r, C.class);
+               assertEqualObjects(t1, t2);
+
+               s.setProperty(SERIALIZER_trimEmptyCollections, true);
+               r = s.serialize(t1);
+               assertEquals("<rdf:Description><jp:f2><rdf:Seq><rdf:li 
rdf:resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/><rdf:li 
rdf:parseType='Resource'><jp:s2>s2</jp:s2></rdf:li></rdf:Seq></jp:f2></rdf:Description>",
 strip(r));
+               t2 = p.parse(r, C.class);
+               assertNull(t2.f1);
+               t2 = p.parse(r, C.class);
+       }
+
+       public static class C {
+               public List<A> f1, f2;
+
+               public static C create() {
+                       C t = new C();
+                       t.f1 = new LinkedList<A>();
+                       t.f2 = new 
LinkedList<A>(){{add(null);add(A.create());}};
+                       return t;
+               }
+       }
+
+       
//====================================================================================================
+       // Trim empty arrays
+       
//====================================================================================================
+       @Test
+       public void testTrimEmptyArrays() throws Exception {
+               RdfSerializer s = getBasicSerializer();
+               RdfParser p = RdfParser.DEFAULT_XML;
+               D t1 = D.create(), t2;
+               String r;
+
+               s.setProperty(SERIALIZER_trimEmptyCollections, false);
+               r = s.serialize(t1);
+               
assertEquals("<rdf:Description><jp:f1><rdf:Seq/></jp:f1><jp:f2><rdf:Seq><rdf:li 
rdf:resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/><rdf:li 
rdf:parseType='Resource'><jp:s2>s2</jp:s2></rdf:li></rdf:Seq></jp:f2></rdf:Description>",
 strip(r));
+               t2 = p.parse(r, D.class);
+               assertEqualObjects(t1, t2);
+
+               s.setProperty(SERIALIZER_trimEmptyCollections, true);
+               r = s.serialize(t1);
+               assertEquals("<rdf:Description><jp:f2><rdf:Seq><rdf:li 
rdf:resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/><rdf:li 
rdf:parseType='Resource'><jp:s2>s2</jp:s2></rdf:li></rdf:Seq></jp:f2></rdf:Description>",
 strip(r));
+               t2 = p.parse(r, D.class);
+               assertNull(t2.f1);
+       }
+
+       public static class D {
+               public A[] f1, f2;
+
+               public static D create() {
+                       D t = new D();
+                       t.f1 = new A[]{};
+                       t.f2 = new A[]{null, A.create()};
+                       return t;
+               }
+       }
+
+       
//====================================================================================================
+       // @BeanProperty.properties annotation.
+       
//====================================================================================================
+       @Test
+       public void testBeanPropertyProperties() throws Exception {
+               RdfSerializer s = getBasicSerializer();
+               RdfParser p = RdfParser.DEFAULT_XML;
+               E1 t1 = E1.create(), t2;
+               String r;
+
+               r = s.serialize(t1);
+               assertEquals("<rdf:Description><jp:x1 
rdf:parseType='Resource'><jp:f1>1</jp:f1></jp:x1><jp:x2 
rdf:parseType='Resource'><jp:f1>1</jp:f1></jp:x2><jp:x3><rdf:Seq><rdf:li 
rdf:parseType='Resource'><jp:f1>1</jp:f1></rdf:li></rdf:Seq></jp:x3><jp:x4><rdf:Seq><rdf:li
 
rdf:parseType='Resource'><jp:f1>1</jp:f1></rdf:li></rdf:Seq></jp:x4><jp:x5><rdf:Seq><rdf:li
 
rdf:parseType='Resource'><jp:f1>1</jp:f1></rdf:li></rdf:Seq></jp:x5><jp:x6><rdf:Seq><rdf:li
 
rdf:parseType='Resource'><jp:f1>1</jp:f1></rdf:li></rdf:Seq></jp:x6></rdf:Description>",
 strip(r));
+               t2 = p.parse(r, E1.class);
+               assertEqualObjects(t1, t2);
+       }
+
+       public static class E1 {
+               @BeanProperty(properties="f1") public E2 x1;
+               @BeanProperty(properties="f1") public Map<String,Integer> x2;
+               @BeanProperty(properties="f1") public E2[] x3;
+               @BeanProperty(properties="f1") public List<E2> x4;
+               @BeanProperty(properties="f1") public ObjectMap[] x5;
+               @BeanProperty(properties="f1") public List<ObjectMap> x6;
+
+               public static E1 create() {
+                       E1 t = new E1();
+                       t.x1 = new E2();
+                       t.x2 = new LinkedHashMap<String,Integer>() {{ 
put("f1",1); put("f2",2); }};
+                       t.x3 = new E2[] {new E2()};
+                       t.x4 = new LinkedList<E2>() {{ add(new E2()); }};
+                       t.x5 = new ObjectMap[] {new 
ObjectMap().append("f1","1").append("f2","2")};
+                       t.x6 = new LinkedList<ObjectMap>() {{ add(new 
ObjectMap().append("f1","1").append("f2","2")); }};
+                       return t;
+               }
+       }
+
+       public static class E2 {
+               public int f1 = 1;
+               public int f2 = 2;
+       }
+
+       
//====================================================================================================
+       // @BeanProperty.properties annotation on list of beans.
+       
//====================================================================================================
+       @Test
+       public void testBeanPropertyProperiesOnListOfBeans() throws Exception {
+               RdfSerializer s = getBasicSerializer();
+               RdfParser p = RdfParser.DEFAULT_XML;
+               List<F> l1 = new LinkedList<F>(), l2;
+               F t = F.create();
+               t.x1.add(F.create());
+               l1.add(t);
+
+               String r = s.serialize(l1);
+               assertEquals("<rdf:Seq><rdf:li 
rdf:parseType='Resource'><jp:x1><rdf:Seq><rdf:li 
rdf:parseType='Resource'><jp:x2>2</jp:x2></rdf:li></rdf:Seq></jp:x1><jp:x2>2</jp:x2></rdf:li></rdf:Seq>",
 strip(r));
+               ClassMeta<LinkedList<F>> cm = 
p.getBeanContext().getCollectionClassMeta(LinkedList.class, F.class);
+               l2 = p.parse(r, cm);
+               assertEqualObjects(l1, l2);
+       }
+
+       public static class F {
+               @BeanProperty(properties="x2") public List<F> x1;
+               public int x2;
+
+               public static F create() {
+                       F t = new F();
+                       t.x1 = new LinkedList<F>();
+                       t.x2 = 2;
+                       return t;
+               }
+       }
+
+       
//====================================================================================================
+       // Test URIAttr - Test that URLs and URIs are serialized and parsed 
correctly.
+       
//====================================================================================================
+       @Test
+       public void testURIAttr() throws Exception {
+               RdfSerializer s = getBasicSerializer();
+               RdfParser p = RdfParser.DEFAULT_XML;
+
+               G t = new G();
+               t.uri = new URI("http://uri";);
+               t.f1 = new URI("http://f1";);
+               t.f2 = new URL("http://f2";);
+
+               String xml = s.serialize(t);
+               t = p.parse(xml, G.class);
+               assertEquals("http://uri";, t.uri.toString());
+               assertEquals("http://f1";, t.f1.toString());
+               assertEquals("http://f2";, t.f2.toString());
+       }
+
+       public static class G {
+               @Rdf(beanUri=true) public URI uri;
+               public URI f1;
+               public URL f2;
+       }
+
+       
//====================================================================================================
+       // Test URIs with URI_CONTEXT and URI_AUTHORITY
+       
//====================================================================================================
+       @Test
+       public void testUris() throws Exception {
+               WriterSerializer s = getBasicSerializer();
+               TestURI t = new TestURI();
+               String r;
+               String expected = "";
+
+               s.setProperty(SERIALIZER_relativeUriBase, null);
+               r = stripAndSort(s.serialize(t));
+               expected = ""
+                       +"</rdf:Description>>"
+                       +"\n<<rdf:Description rdf:about='f0/x0'>"
+                       +"\n<jp:f1 rdf:resource='f1/x1'/>"
+                       +"\n<jp:f2 rdf:resource='/f2/x2'/>"
+                       +"\n<jp:f3 rdf:resource='http://www.apache.org/f3/x3'/>"
+                       +"\n<jp:f4 rdf:resource='f4/x4'/>"
+                       +"\n<jp:f5 rdf:resource='/f5/x5'/>"
+                       +"\n<jp:f6 rdf:resource='http://www.apache.org/f6/x6'/>"
+                       +"\n<jp:f7 rdf:resource='http://www.apache.org/f7/x7'/>"
+                       +"\n<jp:f8 rdf:resource='f8/x8'/>"
+                       +"\n<jp:f9 rdf:resource='f9/x9'/>"
+                       +"\n<jp:fa>http://www.apache.org/fa/xa#MY_LABEL</jp:fa>"
+                       
+"\n<jp:fb>http://www.apache.org/fb/xb?label=MY_LABEL&amp;foo=bar</jp:fb>"
+                       
+"\n<jp:fc>http://www.apache.org/fc/xc?foo=bar&amp;label=MY_LABEL</jp:fc>"
+                       
+"\n<jp:fd>http://www.apache.org/fd/xd?label2=MY_LABEL&amp;foo=bar</jp:fd>"
+                       
+"\n<jp:fe>http://www.apache.org/fe/xe?foo=bar&amp;label2=MY_LABEL</jp:fe>"
+               ;
+               assertEquals(expected, r);
+
+               s.setProperty(SERIALIZER_relativeUriBase, "");  // Same as null.
+               r = stripAndSort(s.serialize(t));
+               assertEquals(expected, r);
+
+               s.setProperty(SERIALIZER_relativeUriBase, "/cr");
+               r = stripAndSort(s.serialize(t));
+               expected = ""
+                       +"</rdf:Description>>"
+                       +"\n<<rdf:Description rdf:about='/cr/f0/x0'>"
+                       +"\n<jp:f1 rdf:resource='/cr/f1/x1'/>"
+                       +"\n<jp:f2 rdf:resource='/f2/x2'/>"
+                       +"\n<jp:f3 rdf:resource='http://www.apache.org/f3/x3'/>"
+                       +"\n<jp:f4 rdf:resource='/cr/f4/x4'/>"
+                       +"\n<jp:f5 rdf:resource='/f5/x5'/>"
+                       +"\n<jp:f6 rdf:resource='http://www.apache.org/f6/x6'/>"
+                       +"\n<jp:f7 rdf:resource='http://www.apache.org/f7/x7'/>"
+                       +"\n<jp:f8 rdf:resource='/cr/f8/x8'/>"
+                       +"\n<jp:f9 rdf:resource='/cr/f9/x9'/>"
+                       +"\n<jp:fa>http://www.apache.org/fa/xa#MY_LABEL</jp:fa>"
+                       
+"\n<jp:fb>http://www.apache.org/fb/xb?label=MY_LABEL&amp;foo=bar</jp:fb>"
+                       
+"\n<jp:fc>http://www.apache.org/fc/xc?foo=bar&amp;label=MY_LABEL</jp:fc>"
+                       
+"\n<jp:fd>http://www.apache.org/fd/xd?label2=MY_LABEL&amp;foo=bar</jp:fd>"
+                       
+"\n<jp:fe>http://www.apache.org/fe/xe?foo=bar&amp;label2=MY_LABEL</jp:fe>"
+               ;
+               assertEquals(expected, r);
+
+               s.setProperty(SERIALIZER_relativeUriBase, "/cr/");  // Same as 
above
+               r = stripAndSort(s.serialize(t));
+               assertEquals(expected, r);
+
+               s.setProperty(SERIALIZER_relativeUriBase, "/");
+               r = stripAndSort(s.serialize(t));
+               expected = ""
+                       +"</rdf:Description>>"
+                       +"\n<<rdf:Description rdf:about='/f0/x0'>"
+                       +"\n<jp:f1 rdf:resource='/f1/x1'/>"
+                       +"\n<jp:f2 rdf:resource='/f2/x2'/>"
+                       +"\n<jp:f3 rdf:resource='http://www.apache.org/f3/x3'/>"
+                       +"\n<jp:f4 rdf:resource='/f4/x4'/>"
+                       +"\n<jp:f5 rdf:resource='/f5/x5'/>"
+                       +"\n<jp:f6 rdf:resource='http://www.apache.org/f6/x6'/>"
+                       +"\n<jp:f7 rdf:resource='http://www.apache.org/f7/x7'/>"
+                       +"\n<jp:f8 rdf:resource='/f8/x8'/>"
+                       +"\n<jp:f9 rdf:resource='/f9/x9'/>"
+                       +"\n<jp:fa>http://www.apache.org/fa/xa#MY_LABEL</jp:fa>"
+                       
+"\n<jp:fb>http://www.apache.org/fb/xb?label=MY_LABEL&amp;foo=bar</jp:fb>"
+                       
+"\n<jp:fc>http://www.apache.org/fc/xc?foo=bar&amp;label=MY_LABEL</jp:fc>"
+                       
+"\n<jp:fd>http://www.apache.org/fd/xd?label2=MY_LABEL&amp;foo=bar</jp:fd>"
+                       
+"\n<jp:fe>http://www.apache.org/fe/xe?foo=bar&amp;label2=MY_LABEL</jp:fe>"
+               ;
+               assertEquals(expected, r);
+
+               s.setProperty(SERIALIZER_relativeUriBase, null);
+
+               s.setProperty(SERIALIZER_absolutePathUriBase, "http://foo";);
+               r = stripAndSort(s.serialize(t));
+               expected = ""
+                       +"</rdf:Description>>"
+                       +"\n<<rdf:Description rdf:about='f0/x0'>"
+                       +"\n<jp:f1 rdf:resource='f1/x1'/>"
+                       +"\n<jp:f2 rdf:resource='http://foo/f2/x2'/>"
+                       +"\n<jp:f3 rdf:resource='http://www.apache.org/f3/x3'/>"
+                       +"\n<jp:f4 rdf:resource='f4/x4'/>"
+                       +"\n<jp:f5 rdf:resource='http://foo/f5/x5'/>"
+                       +"\n<jp:f6 rdf:resource='http://www.apache.org/f6/x6'/>"
+                       +"\n<jp:f7 rdf:resource='http://www.apache.org/f7/x7'/>"
+                       +"\n<jp:f8 rdf:resource='f8/x8'/>"
+                       +"\n<jp:f9 rdf:resource='f9/x9'/>"
+                       +"\n<jp:fa>http://www.apache.org/fa/xa#MY_LABEL</jp:fa>"
+                       
+"\n<jp:fb>http://www.apache.org/fb/xb?label=MY_LABEL&amp;foo=bar</jp:fb>"
+                       
+"\n<jp:fc>http://www.apache.org/fc/xc?foo=bar&amp;label=MY_LABEL</jp:fc>"
+                       
+"\n<jp:fd>http://www.apache.org/fd/xd?label2=MY_LABEL&amp;foo=bar</jp:fd>"
+                       
+"\n<jp:fe>http://www.apache.org/fe/xe?foo=bar&amp;label2=MY_LABEL</jp:fe>"
+               ;
+               assertEquals(expected, r);
+
+               s.setProperty(SERIALIZER_absolutePathUriBase, "http://foo/";);
+               r = stripAndSort(s.serialize(t));
+               assertEquals(expected, r);
+
+               s.setProperty(SERIALIZER_absolutePathUriBase, "");  // Same as 
null.
+               r = stripAndSort(s.serialize(t));
+               expected = ""
+                       +"</rdf:Description>>"
+                       +"\n<<rdf:Description rdf:about='f0/x0'>"
+                       +"\n<jp:f1 rdf:resource='f1/x1'/>"
+                       +"\n<jp:f2 rdf:resource='/f2/x2'/>"
+                       +"\n<jp:f3 rdf:resource='http://www.apache.org/f3/x3'/>"
+                       +"\n<jp:f4 rdf:resource='f4/x4'/>"
+                       +"\n<jp:f5 rdf:resource='/f5/x5'/>"
+                       +"\n<jp:f6 rdf:resource='http://www.apache.org/f6/x6'/>"
+                       +"\n<jp:f7 rdf:resource='http://www.apache.org/f7/x7'/>"
+                       +"\n<jp:f8 rdf:resource='f8/x8'/>"
+                       +"\n<jp:f9 rdf:resource='f9/x9'/>"
+                       +"\n<jp:fa>http://www.apache.org/fa/xa#MY_LABEL</jp:fa>"
+                       
+"\n<jp:fb>http://www.apache.org/fb/xb?label=MY_LABEL&amp;foo=bar</jp:fb>"
+                       
+"\n<jp:fc>http://www.apache.org/fc/xc?foo=bar&amp;label=MY_LABEL</jp:fc>"
+                       
+"\n<jp:fd>http://www.apache.org/fd/xd?label2=MY_LABEL&amp;foo=bar</jp:fd>"
+                       
+"\n<jp:fe>http://www.apache.org/fe/xe?foo=bar&amp;label2=MY_LABEL</jp:fe>"
+               ;
+               assertEquals(expected, r);
+       }
+
+       private String stripAndSort(String s) {
+               s = strip(s);
+               Set<String> set = new TreeSet<String>();
+               for (String s2 : s.split("><"))
+                       set.add('<' + s2 + '>');
+               return StringUtils.join(set, "\n");
+       }
+
+       
//====================================================================================================
+       // Validate that you cannot update properties on locked serializer.
+       
//====================================================================================================
+       @Test
+       public void testLockedSerializer() throws Exception {
+               RdfSerializer s = getBasicSerializer().lock();
+               try {
+                       
s.setProperty(XmlSerializerContext.XML_enableNamespaces, true);
+                       fail("Locked exception not thrown");
+               } catch (LockedException e) {}
+               try {
+                       
s.setProperty(SerializerContext.SERIALIZER_addBeanTypeProperties, true);
+                       fail("Locked exception not thrown");
+               } catch (LockedException e) {}
+               try {
+                       
s.setProperty(BeanContext.BEAN_beanMapPutReturnsOldValue, true);
+                       fail("Locked exception not thrown");
+               } catch (LockedException e) {}
+       }
+
+       
//====================================================================================================
+       // Recursion
+       
//====================================================================================================
+       @Test
+       public void testRecursion() throws Exception {
+               WriterSerializer s = new 
RdfSerializer.XmlAbbrev().setProperty(SERIALIZER_quoteChar, '\'');
+
+               R1 r1 = new R1();
+               R2 r2 = new R2();
+               R3 r3 = new R3();
+               r1.r2 = r2;
+               r2.r3 = r3;
+               r3.r1 = r1;
+
+               // No recursion detection
+               try {
+                       s.serialize(r1);
+                       fail("Exception expected!");
+               } catch (Exception e) {
+                       String msg = e.getLocalizedMessage();
+                       assertTrue(msg.contains("It's recommended you use the 
SerializerContext.SERIALIZER_detectRecursions setting to help locate the 
loop."));
+               }
+
+               // Recursion detection, no ignore
+               s.setProperty(SERIALIZER_detectRecursions, true);
+               try {
+                       s.serialize(r1);
+                       fail("Exception expected!");
+               } catch (Exception e) {
+                       String msg = e.getLocalizedMessage();
+                       
assertTrue(msg.contains("[0]root:org.apache.juneau.jena.CommonTest$R1"));
+                       
assertTrue(msg.contains("->[1]r2:org.apache.juneau.jena.CommonTest$R2"));
+                       
assertTrue(msg.contains("->[2]r3:org.apache.juneau.jena.CommonTest$R3"));
+                       
assertTrue(msg.contains("->[3]r1:org.apache.juneau.jena.CommonTest$R1"));
+               }
+
+               s.setProperty(SERIALIZER_ignoreRecursions, true);
+               String r = s.serialize(r1).replace("\r", "");
+               // Note...the order of the namespaces is not always the same 
depending on the JVM.
+               // The Jena libraries appear to use a hashmap for these.
+               assertTrue(r.contains(
+                       "<rdf:Description>\n"+
+                       "<jp:name>foo</jp:name>\n"+
+                       "<jp:r2 rdf:parseType='Resource'>\n"+
+                       "<jp:name>bar</jp:name>\n"+
+                       "<jp:r3 rdf:parseType='Resource'>\n"+
+                       "<jp:name>baz</jp:name>\n"+
+                       "</jp:r3>\n"+
+                       "</jp:r2>\n"+
+                       "</rdf:Description>\n"+
+                       "</rdf:RDF>\n"
+               ));
+               
assertTrue(r.contains("xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#";));
+               
assertTrue(r.contains("xmlns:j='http://www.apache.org/juneau/";));
+               
assertTrue(r.contains("xmlns:jp='http://www.apache.org/juneaubp/";));
+       }
+
+       public static class R1 {
+               public String name = "foo";
+               public R2 r2;
+       }
+       public static class R2 {
+               public String name = "bar";
+               public R3 r3;
+       }
+       public static class R3 {
+               public String name = "baz";
+               public R1 r1;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonXmlTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonXmlTest.java 
b/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonXmlTest.java
new file mode 100755
index 0000000..90c9966
--- /dev/null
+++ b/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonXmlTest.java
@@ -0,0 +1,97 @@
+// 
***************************************************************************************************************************
+// * 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.jena;
+
+import static org.apache.juneau.TestUtils.*;
+import static org.apache.juneau.jena.RdfCommonContext.*;
+import static org.apache.juneau.serializer.SerializerContext.*;
+import static org.junit.Assert.*;
+
+import java.net.*;
+
+import org.apache.juneau.jena.annotation.*;
+import org.apache.juneau.xml.annotation.*;
+import org.junit.*;
+
+@SuppressWarnings("javadoc")
+public class CommonXmlTest {
+
+       private RdfSerializer getBasicSerializer() {
+               return new RdfSerializer()
+                       .setProperty(SERIALIZER_quoteChar, '\'')
+                       .setProperty(SERIALIZER_useIndentation, false)
+                       .setProperty(RDF_rdfxml_allowBadUris, true)
+                       .setProperty(RDF_rdfxml_showDoctypeDeclaration, false)
+                       .setProperty(RDF_rdfxml_showXmlDeclaration, false);
+       }
+
+       private String strip(String s) {
+               return s.replaceFirst("<rdf:RDF[^>]+>\\s*", 
"").replaceAll("</rdf:RDF>$", "").trim().replaceAll("[\\r\\n]", "");
+       }
+
+       
//====================================================================================================
+       // Bean.uri annotation
+       
//====================================================================================================
+       @Test
+       public void testBeanUriAnnotation() throws Exception {
+               RdfSerializer s = getBasicSerializer();
+               RdfParser p = RdfParser.DEFAULT_XML;
+               A t1 = A.create(), t2;
+               String r;
+
+               r = s.serialize(t1);
+               assertEquals("<rdf:Description 
rdf:about='http://foo'><jp:name>bar</jp:name></rdf:Description>", strip(r));
+               t2 = p.parse(r, A.class);
+               assertEqualObjects(t1, t2);
+       }
+
+       public static class A {
+               @Rdf(beanUri=true) @Xml(format=XmlFormat.ATTR) public URL url;
+               public String name;
+
+               public static A create() throws Exception {
+                       A t = new A();
+                       t.url = new URL("http://foo";);
+                       t.name = "bar";
+                       return t;
+               }
+       }
+
+       
//====================================================================================================
+       // Bean.uri annotation, only uri property
+       
//====================================================================================================
+       @Test
+       public void testBeanUriAnnotationOnlyUriProperty() throws Exception {
+               RdfSerializer s = getBasicSerializer();
+               RdfParser p = RdfParser.DEFAULT_XML;
+               B t1 = B.create(), t2;
+               String r;
+
+               r = s.serialize(t1);
+               assertEquals("<rdf:Description rdf:about='http://foo'><jp:url2 
rdf:resource='http://foo/2'/></rdf:Description>", strip(r));
+               t2 = p.parse(r, B.class);
+               assertEqualObjects(t1, t2);
+       }
+
+       public static class B {
+               @Rdf(beanUri=true) @Xml(format=XmlFormat.ATTR) public URL url;
+               public URL url2;
+
+               public static B create() throws Exception {
+                       B t = new B();
+                       t.url = new URL("http://foo";);
+                       t.url2 = new URL("http://foo/2";);
+                       return t;
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-test/src/test/java/org/apache/juneau/jena/RdfParserTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-test/src/test/java/org/apache/juneau/jena/RdfParserTest.java 
b/juneau-core-test/src/test/java/org/apache/juneau/jena/RdfParserTest.java
new file mode 100755
index 0000000..8eaef41
--- /dev/null
+++ b/juneau-core-test/src/test/java/org/apache/juneau/jena/RdfParserTest.java
@@ -0,0 +1,159 @@
+// 
***************************************************************************************************************************
+// * 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.jena;
+
+import static org.apache.juneau.TestUtils.*;
+import static org.apache.juneau.jena.RdfCommonContext.*;
+import static org.apache.juneau.jena.RdfSerializerContext.*;
+import static org.junit.Assert.*;
+
+import java.net.URI;
+import java.text.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.jena.annotation.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.transforms.*;
+import org.junit.*;
+
+@SuppressWarnings("javadoc")
+public class RdfParserTest {
+
+       @Before
+       public void beforeTest() {
+               TestUtils.setLocale(Locale.US);
+       }
+
+       @After
+       public void afterTest() {
+               TestUtils.unsetLocale();
+       }
+
+       @Test
+       public void testParseIntoGenericPojos() throws Exception {
+               A a = new A().init();
+
+               // Create a new serializer with readable output.
+               RdfSerializer s = new RdfSerializer.XmlAbbrev()
+                  .setProperty(RDF_rdfxml_tab, 3)
+                  .setProperty(SERIALIZER_quoteChar, '\'')
+                  .setProperty(RDF_addRootProperty, true);
+
+               String expected =
+                        "<rdf:RDF a='http://ns/' a1='http://ns2/' 
j='http://www.apache.org/juneau/' jp='http://www.apache.org/juneaubp/' 
rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"
+                        + "\n   <rdf:Description about='http://test/a'>"
+                        + "\n      <a:f1>1</a:f1>"
+                        + "\n      <a:f2>f2</a:f2>"
+                        + "\n      <a:f4a rdf:resource='http://test/a'/>"
+                        + "\n      <a:f4b 
rdf:resource='http://test/external'/>"
+                        + "\n      <a:f5>1999-01-01T00:00:00Z</a:f5>"
+                        + "\n      <a:f6>"
+                        + "\n         <rdf:Seq>"
+                        + "\n            <rdf:li>"
+                        + "\n               <rdf:Description 
about='http://test/a/a1'>"
+                        + "\n                  <a1:f1>1</a1:f1>"
+                        + "\n                  <a1:f2>f2</a1:f2>"
+                        + "\n                  <a1:f4a 
rdf:resource='http://test/a'/>"
+                        + "\n                  <a1:f4b 
rdf:resource='http://test/external'/>"
+                        + "\n                  
<a1:f5>1999-01-01T00:00:00Z</a1:f5>"
+                        + "\n               </rdf:Description>"
+                        + "\n            </rdf:li>"
+                        + "\n         </rdf:Seq>"
+                        + "\n      </a:f6>"
+                        + "\n      <j:root>true</j:root>"
+                        + "\n   </rdf:Description>"
+                        + "\n</rdf:RDF>";
+
+               String rdfXml = s.serialize(a);
+               assertXmlEquals(expected, rdfXml);
+
+               A a2 = RdfParser.DEFAULT_XML.parse(rdfXml, A.class);
+
+               assertEqualObjects(a, a2);
+
+               ObjectMap m = RdfParser.DEFAULT_XML.parse(rdfXml, 
ObjectMap.class);
+               String json = JsonSerializer.DEFAULT_LAX_READABLE.serialize(m);
+
+               String e = ""
+                       + "{\n"
+                       + "     uri: 'http://test/a', \n"
+                       + "     f6: [\n"
+                       + "             {\n"
+                       + "                     uri: 'http://test/a/a1', \n"
+                       + "                     f5: '1999-01-01T00:00:00Z', \n"
+                       + "                     f4b: 'http://test/external', \n"
+                       + "                     f4a: 'http://test/a', \n"
+                       + "                     f2: 'f2', \n"
+                       + "                     f1: '1'\n"
+                       + "             }\n"
+                       + "     ], \n"
+                       + "     f5: '1999-01-01T00:00:00Z', \n"
+                       + "     f4b: 'http://test/external', \n"
+                       + "     f4a: 'http://test/a', \n"
+                       + "     f2: 'f2', \n"
+                       + "     f1: '1', \n"
+                       + "     root: 'true'\n"
+                       + "}";
+               assertEquals(e, json.replace("\r", ""));
+
+       }
+
+       @Rdf(prefix="a", namespace="http://ns/";)
+       public static class A {
+               public int f1;
+               public String f2;
+               @Rdf(beanUri=true) public URI f3;
+               public URI f4a, f4b;
+               @BeanProperty(swap=CalendarSwap.ISO8601DTZ.class) public 
Calendar f5;
+               public LinkedList<A1> f6 = new LinkedList<A1>();
+
+               public A init() throws Exception {
+                       f1 = 1;
+                       f2 = "f2";
+                       f3 = new URI("http://test/a";); // Bean URI.
+                       f4a = new URI("http://test/a";); // Points to itself.
+                       f4b = new URI("http://test/external";);
+                       f5 = new GregorianCalendar();
+                       DateFormat df = 
DateFormat.getDateInstance(DateFormat.MEDIUM);
+                       df.setTimeZone(TimeZone.getTimeZone("GMT"));
+                       f5.setTime(df.parse("Jan 1, 1999"));
+                       f6 = new LinkedList<A1>();
+                       f6.add(new A1().init());
+                       return this;
+               }
+       }
+
+       @Rdf(prefix="a1", namespace="http://ns2/";)
+       public static class A1 {
+               public int f1;
+               public String f2;
+               @Rdf(beanUri=true) public URI f3;
+               public URI f4a, f4b;
+               @BeanProperty(swap=CalendarSwap.ISO8601DTZ.class) public 
Calendar f5;
+
+               public A1 init() throws Exception {
+                       f1 = 1;
+                       f2 = "f2";
+                       f3 = new URI("http://test/a/a1";);
+                       f4a = new URI("http://test/a";);
+                       f4b = new URI("http://test/external";);
+                       f5 = new GregorianCalendar();
+                       DateFormat df = 
DateFormat.getDateInstance(DateFormat.MEDIUM);
+                       df.setTimeZone(TimeZone.getTimeZone("GMT"));
+                       f5.setTime(df.parse("Jan 1, 1999"));
+                       return this;
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-test/src/test/java/org/apache/juneau/jena/RdfTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/jena/RdfTest.java 
b/juneau-core-test/src/test/java/org/apache/juneau/jena/RdfTest.java
new file mode 100755
index 0000000..6becb22
--- /dev/null
+++ b/juneau-core-test/src/test/java/org/apache/juneau/jena/RdfTest.java
@@ -0,0 +1,595 @@
+// 
***************************************************************************************************************************
+// * 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.jena;
+
+import static org.apache.juneau.TestUtils.*;
+import static org.apache.juneau.jena.RdfCommonContext.*;
+import static org.apache.juneau.jena.RdfSerializerContext.*;
+
+import java.net.URI;
+import java.util.*;
+
+import org.apache.juneau.jena.annotation.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.junit.*;
+
+@SuppressWarnings({"serial","javadoc"})
+public class RdfTest {
+
+       @Test
+       public void testCollectionFormatProperties() throws Exception {
+               A a = new A().init(), a2;
+               String rdfXml;
+               String expected;
+
+               RdfSerializer s = new RdfSerializer.XmlAbbrev()
+                  .setProperty(RDF_rdfxml_tab, 3)
+                  .setProperty(SERIALIZER_quoteChar, '\'')
+                  .setProperty(RDF_addRootProperty, true);
+               RdfParser p = RdfParser.DEFAULT_XML.clone();
+
+               
//--------------------------------------------------------------------------------
+               // Normal format - Sequence
+               
//--------------------------------------------------------------------------------
+               expected =
+                       "<rdf:RDF a='http://ns/' 
j='http://www.apache.org/juneau/' jp='http://www.apache.org/juneaubp/' 
rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"
+                       + "\n   <rdf:Description about='http://test/a'>"
+                       + "\n      <a:f2>"
+                       + "\n         <rdf:Seq>"
+                       + "\n            <rdf:li>f2a</rdf:li>"
+                       + "\n            <rdf:li>f2b</rdf:li>"
+                       + "\n         </rdf:Seq>"
+                       + "\n      </a:f2>"
+                       + "\n      <a:f3>"
+                       + "\n         <rdf:Seq>"
+                       + "\n            <rdf:li>1</rdf:li>"
+                       + "\n            <rdf:li>2</rdf:li>"
+                       + "\n         </rdf:Seq>"
+                       + "\n      </a:f3>"
+                       + "\n      <j:root>true</j:root>"
+                       + "\n   </rdf:Description>"
+                       + "\n</rdf:RDF>";
+               rdfXml = s.serialize(a);
+               assertXmlEquals(expected, rdfXml);
+
+               a2 = p.parse(rdfXml, A.class);
+               assertEqualObjects(a, a2);
+
+               
//--------------------------------------------------------------------------------
+               // Explicit sequence
+               
//--------------------------------------------------------------------------------
+               s.setProperty(RDF_collectionFormat, RdfCollectionFormat.SEQ);
+               expected =
+                       "<rdf:RDF a='http://ns/' 
j='http://www.apache.org/juneau/' jp='http://www.apache.org/juneaubp/' 
rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"
+                       + "\n   <rdf:Description about='http://test/a'>"
+                       + "\n      <a:f2>"
+                       + "\n         <rdf:Seq>"
+                       + "\n            <rdf:li>f2a</rdf:li>"
+                       + "\n            <rdf:li>f2b</rdf:li>"
+                       + "\n         </rdf:Seq>"
+                       + "\n      </a:f2>"
+                       + "\n      <a:f3>"
+                       + "\n         <rdf:Seq>"
+                       + "\n            <rdf:li>1</rdf:li>"
+                       + "\n            <rdf:li>2</rdf:li>"
+                       + "\n         </rdf:Seq>"
+                       + "\n      </a:f3>"
+                       + "\n      <j:root>true</j:root>"
+                       + "\n   </rdf:Description>"
+                       + "\n</rdf:RDF>";
+               rdfXml = s.serialize(a);
+               assertXmlEquals(expected, rdfXml);
+
+               a2 = p.parse(rdfXml, A.class);
+               assertEqualObjects(a, a2);
+
+               
//--------------------------------------------------------------------------------
+               // Bag
+               
//--------------------------------------------------------------------------------
+               s.setProperty(RDF_collectionFormat, RdfCollectionFormat.BAG);
+               expected =
+                       "<rdf:RDF a='http://ns/' 
j='http://www.apache.org/juneau/' jp='http://www.apache.org/juneaubp/' 
rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"
+                       + "\n   <rdf:Description about='http://test/a'>"
+                       + "\n      <a:f2>"
+                       + "\n         <rdf:Bag>"
+                       + "\n            <rdf:li>f2a</rdf:li>"
+                       + "\n            <rdf:li>f2b</rdf:li>"
+                       + "\n         </rdf:Bag>"
+                       + "\n      </a:f2>"
+                       + "\n      <a:f3>"
+                       + "\n         <rdf:Bag>"
+                       + "\n            <rdf:li>1</rdf:li>"
+                       + "\n            <rdf:li>2</rdf:li>"
+                       + "\n         </rdf:Bag>"
+                       + "\n      </a:f3>"
+                       + "\n      <j:root>true</j:root>"
+                       + "\n   </rdf:Description>"
+                       + "\n</rdf:RDF>";
+               rdfXml = s.serialize(a);
+               assertXmlEquals(expected, rdfXml);
+
+               a2 = p.parse(rdfXml, A.class);
+               assertEqualObjects(a, a2);
+
+               
//--------------------------------------------------------------------------------
+               // List
+               
//--------------------------------------------------------------------------------
+               s.setProperty(RDF_collectionFormat, RdfCollectionFormat.LIST);
+               expected =
+                          "<rdf:RDF a='http://ns/' 
j='http://www.apache.org/juneau/' jp='http://www.apache.org/juneaubp/' 
rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"
+                        + "\n   <rdf:Description about='http://test/a'>"
+                        + "\n      <a:f2 parseType='Resource'>"
+                        + "\n         <rdf:first>f2a</rdf:first>"
+                        + "\n         <rdf:rest parseType='Resource'>"
+                        + "\n            <rdf:first>f2b</rdf:first>"
+                        + "\n            <rdf:rest 
resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/>"
+                        + "\n         </rdf:rest>"
+                        + "\n      </a:f2>"
+                        + "\n      <a:f3 parseType='Resource'>"
+                        + "\n         <rdf:first>1</rdf:first>"
+                        + "\n         <rdf:rest parseType='Resource'>"
+                        + "\n            <rdf:first>2</rdf:first>"
+                        + "\n            <rdf:rest 
resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/>"
+                        + "\n         </rdf:rest>"
+                        + "\n      </a:f3>"
+                        + "\n      <j:root>true</j:root>"
+                        + "\n   </rdf:Description>"
+                        + "\n</rdf:RDF>";
+               rdfXml = s.serialize(a);
+               assertXmlEquals(expected, rdfXml);
+
+               a2 = p.parse(rdfXml, A.class);
+               assertEqualObjects(a, a2);
+
+               
//--------------------------------------------------------------------------------
+               // Multi-properties
+               
//--------------------------------------------------------------------------------
+               s.setProperty(RDF_collectionFormat, 
RdfCollectionFormat.MULTI_VALUED);
+               expected =
+                       "<rdf:RDF a='http://ns/' 
j='http://www.apache.org/juneau/' jp='http://www.apache.org/juneaubp/' 
rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"
+                       + "\n   <rdf:Description about='http://test/a'>"
+                        + "\n      <a:f2>f2a</a:f2>"
+                        + "\n      <a:f2>f2b</a:f2>"
+                        + "\n      <a:f3>1</a:f3>"
+                        + "\n      <a:f3>2</a:f3>"
+                        + "\n      <j:root>true</j:root>"
+                        + "\n   </rdf:Description>"
+                       + "\n</rdf:RDF>";
+               rdfXml = s.serialize(a);
+               assertXmlEquals(expected, rdfXml);
+
+               // Note - Must specify collection format on parser for it to be 
able to understand this layout.
+               p.setProperty(RDF_collectionFormat, 
RdfCollectionFormat.MULTI_VALUED);
+               a2 = p.parse(rdfXml, A.class);
+               assertEqualObjects(a, a2);
+       }
+
+       @Rdf(prefix="a", namespace="http://ns/";)
+       public static class A {
+               @Rdf(beanUri=true) public URI f1;
+      public String[] f2;
+      public List<Integer> f3;
+
+      public A init() throws Exception {
+         f1 = new URI("http://test/a";);
+         f2 = new String[]{"f2a","f2b"};
+         f3 = Arrays.asList(new Integer[]{1,2});
+         return this;
+      }
+   }
+
+       @Test
+       public void testCollectionFormatAnnotations() throws Exception {
+               B b = new B().init(), b2;
+               String rdfXml, expected;
+               RdfSerializer s = new RdfSerializer.XmlAbbrev()
+                  .setProperty(RDF_rdfxml_tab, 3)
+                  .setProperty(SERIALIZER_quoteChar, '\'')
+                  .setProperty(RDF_addRootProperty, true);
+               RdfParser p = RdfParser.DEFAULT_XML.clone();
+
+               
//--------------------------------------------------------------------------------
+               // Normal format - Sequence
+               
//--------------------------------------------------------------------------------
+
+               expected =
+                        "<rdf:RDF b='http://ns/' 
j='http://www.apache.org/juneau/' jp='http://www.apache.org/juneaubp/' 
rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"
+                        + "\n   <rdf:Description about='http://test/b'>"
+                        + "\n      <b:f2>"
+                        + "\n         <rdf:Seq>"
+                        + "\n            <rdf:li>f2a</rdf:li>"
+                        + "\n            <rdf:li>f2b</rdf:li>"
+                        + "\n         </rdf:Seq>"
+                        + "\n      </b:f2>"
+                        + "\n      <b:f3>"
+                        + "\n         <rdf:Bag>"
+                        + "\n            <rdf:li>f3a</rdf:li>"
+                        + "\n            <rdf:li>f3b</rdf:li>"
+                        + "\n         </rdf:Bag>"
+                        + "\n      </b:f3>"
+                        + "\n      <b:f4 parseType='Resource'>"
+                        + "\n         <rdf:first>f4a</rdf:first>"
+                        + "\n         <rdf:rest parseType='Resource'>"
+                        + "\n            <rdf:first>f4b</rdf:first>"
+                        + "\n            <rdf:rest 
resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/>"
+                        + "\n         </rdf:rest>"
+                        + "\n      </b:f4>"
+                        + "\n      <b:f5>f5a</b:f5>"
+                        + "\n      <b:f5>f5b</b:f5>"
+                        + "\n      <b:f6>"
+                        + "\n         <rdf:Seq>"
+                        + "\n            <rdf:li>f6a</rdf:li>"
+                        + "\n            <rdf:li>f6b</rdf:li>"
+                        + "\n         </rdf:Seq>"
+                        + "\n      </b:f6>"
+                        + "\n      <b:f7>"
+                        + "\n         <rdf:Seq>"
+                        + "\n            <rdf:li>f7a</rdf:li>"
+                        + "\n            <rdf:li>f7b</rdf:li>"
+                        + "\n         </rdf:Seq>"
+                        + "\n      </b:f7>"
+                        + "\n      <b:f8>"
+                        + "\n         <rdf:Bag>"
+                        + "\n            <rdf:li>f8a</rdf:li>"
+                        + "\n            <rdf:li>f8b</rdf:li>"
+                        + "\n         </rdf:Bag>"
+                        + "\n      </b:f8>"
+                        + "\n      <b:f9 parseType='Resource'>"
+                        + "\n         <rdf:first>f9a</rdf:first>"
+                        + "\n         <rdf:rest parseType='Resource'>"
+                        + "\n            <rdf:first>f9b</rdf:first>"
+                        + "\n            <rdf:rest 
resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/>"
+                        + "\n         </rdf:rest>"
+                        + "\n      </b:f9>"
+                        + "\n      <b:fa>faa</b:fa>"
+                        + "\n      <b:fa>fab</b:fa>"
+                        + "\n      <b:fb>"
+                        + "\n         <rdf:Seq>"
+                        + "\n            <rdf:li>fba</rdf:li>"
+                        + "\n            <rdf:li>fbb</rdf:li>"
+                        + "\n         </rdf:Seq>"
+                        + "\n      </b:fb>"
+                        + "\n      <j:root>true</j:root>"
+                        + "\n   </rdf:Description>"
+                        + "\n</rdf:RDF>";
+               rdfXml = s.serialize(b);
+               assertXmlEquals(expected, rdfXml);
+
+               b2 = p.parse(rdfXml, B.class);
+               assertEqualObjects(b, b2, true);
+
+               
//--------------------------------------------------------------------------------
+               // Default is Bag - Should only affect DEFAULT properties.
+               
//--------------------------------------------------------------------------------
+               s.setProperty(RDF_collectionFormat, RdfCollectionFormat.BAG);
+               expected =
+                        "<rdf:RDF b='http://ns/' 
j='http://www.apache.org/juneau/' jp='http://www.apache.org/juneaubp/' 
rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"
+                        + "\n   <rdf:Description about='http://test/b'>"
+                        + "\n      <b:f2>"
+                        + "\n         <rdf:Seq>"
+                        + "\n            <rdf:li>f2a</rdf:li>"
+                        + "\n            <rdf:li>f2b</rdf:li>"
+                        + "\n         </rdf:Seq>"
+                        + "\n      </b:f2>"
+                        + "\n      <b:f3>"
+                        + "\n         <rdf:Bag>"
+                        + "\n            <rdf:li>f3a</rdf:li>"
+                        + "\n            <rdf:li>f3b</rdf:li>"
+                        + "\n         </rdf:Bag>"
+                        + "\n      </b:f3>"
+                        + "\n      <b:f4 parseType='Resource'>"
+                        + "\n         <rdf:first>f4a</rdf:first>"
+                        + "\n         <rdf:rest parseType='Resource'>"
+                        + "\n            <rdf:first>f4b</rdf:first>"
+                        + "\n            <rdf:rest 
resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/>"
+                        + "\n         </rdf:rest>"
+                        + "\n      </b:f4>"
+                        + "\n      <b:f5>f5a</b:f5>"
+                        + "\n      <b:f5>f5b</b:f5>"
+                        + "\n      <b:f6>"
+                        + "\n         <rdf:Bag>"
+                        + "\n            <rdf:li>f6a</rdf:li>"
+                        + "\n            <rdf:li>f6b</rdf:li>"
+                        + "\n         </rdf:Bag>"
+                        + "\n      </b:f6>"
+                        + "\n      <b:f7>"
+                        + "\n         <rdf:Seq>"
+                        + "\n            <rdf:li>f7a</rdf:li>"
+                        + "\n            <rdf:li>f7b</rdf:li>"
+                        + "\n         </rdf:Seq>"
+                        + "\n      </b:f7>"
+                        + "\n      <b:f8>"
+                        + "\n         <rdf:Bag>"
+                        + "\n            <rdf:li>f8a</rdf:li>"
+                        + "\n            <rdf:li>f8b</rdf:li>"
+                        + "\n         </rdf:Bag>"
+                        + "\n      </b:f8>"
+                        + "\n      <b:f9 parseType='Resource'>"
+                        + "\n         <rdf:first>f9a</rdf:first>"
+                        + "\n         <rdf:rest parseType='Resource'>"
+                        + "\n            <rdf:first>f9b</rdf:first>"
+                        + "\n            <rdf:rest 
resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/>"
+                        + "\n         </rdf:rest>"
+                        + "\n      </b:f9>"
+                        + "\n      <b:fa>faa</b:fa>"
+                        + "\n      <b:fa>fab</b:fa>"
+                        + "\n      <b:fb>"
+                        + "\n         <rdf:Bag>"
+                        + "\n            <rdf:li>fba</rdf:li>"
+                        + "\n            <rdf:li>fbb</rdf:li>"
+                        + "\n         </rdf:Bag>"
+                        + "\n      </b:fb>"
+                        + "\n      <j:root>true</j:root>"
+                        + "\n   </rdf:Description>"
+                        + "\n</rdf:RDF>";
+
+               rdfXml = s.serialize(b);
+               assertXmlEquals(expected, rdfXml);
+
+               b2 = p.parse(rdfXml, B.class);
+               assertEqualObjects(b, b2, true);
+       }
+
+       @Rdf(prefix="b", namespace="http://ns/";)
+       public static class B {
+               @Rdf(beanUri=true) public URI f1;
+
+               @Rdf(collectionFormat=RdfCollectionFormat.SEQ)
+               public String[] f2;
+
+               @Rdf(collectionFormat=RdfCollectionFormat.BAG)
+               public String[] f3;
+
+               @Rdf(collectionFormat=RdfCollectionFormat.LIST)
+               public String[] f4;
+
+               @Rdf(collectionFormat=RdfCollectionFormat.MULTI_VALUED)
+               public String[] f5;
+
+               @Rdf(collectionFormat=RdfCollectionFormat.DEFAULT)
+               public String[] f6;
+
+               public BA f7;
+               public BB f8;
+               public BC f9;
+               public BD fa;
+               public BE fb;
+
+               public B init() throws Exception {
+         f1 = new URI("http://test/b";);
+         f2 = new String[]{"f2a","f2b"};
+         f3 = new String[]{"f3a","f3b"};
+         f4 = new String[]{"f4a","f4b"};
+         f5 = new String[]{"f5a","f5b"};
+         f6 = new String[]{"f6a","f6b"};
+         f7 = new BA().append("f7a","f7b");
+         f8 = new BB().append("f8a","f8b");
+         f9 = new BC().append("f9a","f9b");
+         fa = new BD().append("faa","fab");
+         fb = new BE().append("fba","fbb");
+         return this;
+      }
+   }
+
+       @Rdf(prefix="ba", namespace="http://ns/";, 
collectionFormat=RdfCollectionFormat.SEQ)
+       public static class BA extends ArrayList<String> {
+               public BA append(String...s) {
+                       this.addAll(Arrays.asList(s));
+                       return this;
+               }
+       }
+
+       @Rdf(prefix="bb", namespace="http://ns/";, 
collectionFormat=RdfCollectionFormat.BAG)
+       public static class BB extends ArrayList<String> {
+               public BB append(String...s) {
+                       this.addAll(Arrays.asList(s));
+                       return this;
+               }
+       }
+
+       @Rdf(prefix="bc", namespace="http://ns/";, 
collectionFormat=RdfCollectionFormat.LIST)
+       public static class BC extends ArrayList<String> {
+               public BC append(String...s) {
+                       this.addAll(Arrays.asList(s));
+                       return this;
+               }
+       }
+
+       @Rdf(prefix="bd", namespace="http://ns/";, 
collectionFormat=RdfCollectionFormat.MULTI_VALUED)
+       public static class BD extends ArrayList<String> {
+               public BD append(String...s) {
+                       this.addAll(Arrays.asList(s));
+                       return this;
+               }
+       }
+
+       @Rdf(prefix="bd", namespace="http://ns/";, 
collectionFormat=RdfCollectionFormat.DEFAULT)
+       public static class BE extends ArrayList<String> {
+               public BE append(String...s) {
+                       this.addAll(Arrays.asList(s));
+                       return this;
+               }
+       }
+
+       @Test
+       public void testCollectionFormatAnnotationOnClass() throws Exception {
+               C c = new C().init(), c2;
+               String rdfXml, expected;
+               RdfSerializer s = new RdfSerializer.XmlAbbrev()
+                  .setProperty(RDF_rdfxml_tab, 3)
+                  .setProperty(SERIALIZER_quoteChar, '\'')
+                  .setProperty(RDF_addRootProperty, true);
+               RdfParser p = RdfParser.DEFAULT_XML.clone();
+
+               
//--------------------------------------------------------------------------------
+               // Default on class is Bag - Should only affect DEFAULT 
properties.
+               
//--------------------------------------------------------------------------------
+               s.setProperty(RDF_collectionFormat, RdfCollectionFormat.BAG);
+               expected =
+                        "<rdf:RDF b='http://ns/' 
j='http://www.apache.org/juneau/' jp='http://www.apache.org/juneaubp/' 
rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"
+                        + "\n   <rdf:Description about='http://test/b'>"
+                        + "\n      <b:f2>"
+                        + "\n         <rdf:Seq>"
+                        + "\n            <rdf:li>f2a</rdf:li>"
+                        + "\n            <rdf:li>f2b</rdf:li>"
+                        + "\n         </rdf:Seq>"
+                        + "\n      </b:f2>"
+                        + "\n      <b:f3>"
+                        + "\n         <rdf:Bag>"
+                        + "\n            <rdf:li>f3a</rdf:li>"
+                        + "\n            <rdf:li>f3b</rdf:li>"
+                        + "\n         </rdf:Bag>"
+                        + "\n      </b:f3>"
+                        + "\n      <b:f4 parseType='Resource'>"
+                        + "\n         <rdf:first>f4a</rdf:first>"
+                        + "\n         <rdf:rest parseType='Resource'>"
+                        + "\n            <rdf:first>f4b</rdf:first>"
+                        + "\n            <rdf:rest 
resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/>"
+                        + "\n         </rdf:rest>"
+                        + "\n      </b:f4>"
+                        + "\n      <b:f5>f5a</b:f5>"
+                        + "\n      <b:f5>f5b</b:f5>"
+                        + "\n      <b:f6>"
+                        + "\n         <rdf:Bag>"
+                        + "\n            <rdf:li>f6a</rdf:li>"
+                        + "\n            <rdf:li>f6b</rdf:li>"
+                        + "\n         </rdf:Bag>"
+                        + "\n      </b:f6>"
+                        + "\n      <b:f7>"
+                        + "\n         <rdf:Seq>"
+                        + "\n            <rdf:li>f7a</rdf:li>"
+                        + "\n            <rdf:li>f7b</rdf:li>"
+                        + "\n         </rdf:Seq>"
+                        + "\n      </b:f7>"
+                        + "\n      <b:f8>"
+                        + "\n         <rdf:Bag>"
+                        + "\n            <rdf:li>f8a</rdf:li>"
+                        + "\n            <rdf:li>f8b</rdf:li>"
+                        + "\n         </rdf:Bag>"
+                        + "\n      </b:f8>"
+                        + "\n      <b:f9 parseType='Resource'>"
+                        + "\n         <rdf:first>f9a</rdf:first>"
+                        + "\n         <rdf:rest parseType='Resource'>"
+                        + "\n            <rdf:first>f9b</rdf:first>"
+                        + "\n            <rdf:rest 
resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/>"
+                        + "\n         </rdf:rest>"
+                        + "\n      </b:f9>"
+                        + "\n      <b:fa>faa</b:fa>"
+                        + "\n      <b:fa>fab</b:fa>"
+                        + "\n      <b:fb>"
+                        + "\n         <rdf:Bag>"
+                        + "\n            <rdf:li>fba</rdf:li>"
+                        + "\n            <rdf:li>fbb</rdf:li>"
+                        + "\n         </rdf:Bag>"
+                        + "\n      </b:fb>"
+                        + "\n      <j:root>true</j:root>"
+                        + "\n   </rdf:Description>"
+                        + "\n</rdf:RDF>";
+
+               rdfXml = s.serialize(c);
+               assertXmlEquals(expected, rdfXml);
+
+               c2 = p.parse(rdfXml, C.class);
+               assertEqualObjects(c, c2, true);
+       }
+
+       @Rdf(collectionFormat=RdfCollectionFormat.BAG)
+       public static class C extends B {
+               @Override /* B */
+               public C init() throws Exception {
+         f1 = new URI("http://test/b";);
+         f2 = new String[]{"f2a","f2b"};
+         f3 = new String[]{"f3a","f3b"};
+         f4 = new String[]{"f4a","f4b"};
+         f5 = new String[]{"f5a","f5b"};
+         f6 = new String[]{"f6a","f6b"};
+         f7 = new BA().append("f7a","f7b");
+         f8 = new BB().append("f8a","f8b");
+         f9 = new BC().append("f9a","f9b");
+         fa = new BD().append("faa","fab");
+         fb = new BE().append("fba","fbb");
+         return this;
+      }
+       }
+
+       @Test
+       @SuppressWarnings("unchecked")
+       public void testLooseCollectionsOfBeans() throws Exception {
+               WriterSerializer s = new 
RdfSerializer.XmlAbbrev().setProperty(RDF_looseCollections, true);
+               ReaderParser p = new 
RdfParser.Xml().setProperty(RDF_looseCollections, true);
+               String rdfXml, expected;
+
+               List<D> l = new LinkedList<D>();
+               l.add(new D().init(1));
+               l.add(new D().init(2));
+
+               rdfXml = s.serialize(l);
+               expected =
+                       "<rdf:RDF j='http://www.apache.org/juneau/' 
jp='http://www.apache.org/juneaubp/' 
rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"
+                               + "\n   <rdf:Description 
about='http://localhost/f1/2'>"
+                               + "\n      <jp:f2>f2</jp:f2>"
+                               + "\n      <jp:f3 
resource='http://localhost/f3/2'/>"
+                               + "\n   </rdf:Description>"
+                               + "\n   <rdf:Description 
about='http://localhost/f1/1'>"
+                               + "\n      <jp:f2>f2</jp:f2>"
+                               + "\n      <jp:f3 
resource='http://localhost/f3/1'/>"
+                               + "\n   </rdf:Description>"
+                               + "\n</rdf:RDF>";
+               assertXmlEquals(expected, rdfXml);
+
+               l = p.parseCollection(rdfXml, LinkedList.class, D.class);
+               D[] da = l.toArray(new D[l.size()]);
+               rdfXml = s.serialize(da);
+               expected =
+                       "<rdf:RDF j='http://www.apache.org/juneau/' 
jp='http://www.apache.org/juneaubp/' 
rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"
+                               + "\n   <rdf:Description 
about='http://localhost/f1/2'>"
+                               + "\n      <jp:f2>f2</jp:f2>"
+                               + "\n      <jp:f3 
resource='http://localhost/f3/2'/>"
+                               + "\n   </rdf:Description>"
+                               + "\n   <rdf:Description 
about='http://localhost/f1/1'>"
+                               + "\n      <jp:f2>f2</jp:f2>"
+                               + "\n      <jp:f3 
resource='http://localhost/f3/1'/>"
+                               + "\n   </rdf:Description>"
+                               + "\n</rdf:RDF>";
+               assertXmlEquals(expected, rdfXml);
+
+               da = p.parse(rdfXml, D[].class);
+               rdfXml = s.serialize(da);
+               expected =
+                       "<rdf:RDF j='http://www.apache.org/juneau/' 
jp='http://www.apache.org/juneaubp/' 
rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"
+                               + "\n   <rdf:Description 
about='http://localhost/f1/2'>"
+                               + "\n      <jp:f2>f2</jp:f2>"
+                               + "\n      <jp:f3 
resource='http://localhost/f3/2'/>"
+                               + "\n   </rdf:Description>"
+                               + "\n   <rdf:Description 
about='http://localhost/f1/1'>"
+                               + "\n      <jp:f2>f2</jp:f2>"
+                               + "\n      <jp:f3 
resource='http://localhost/f3/1'/>"
+                               + "\n   </rdf:Description>"
+                               + "\n</rdf:RDF>";
+               assertXmlEquals(expected, rdfXml);
+       }
+
+       public static class D {
+               @Rdf(beanUri=true) public URI f1;
+               public String f2;
+               public URI f3;
+
+               public D init(int num) throws Exception {
+                       f1 = new URI("http://localhost/f1/"; + num);
+                       f2 = "f2";
+                       f3 = new URI("http://localhost/f3/"; + num);
+                       return this;
+               }
+       }
+}

Reply via email to