You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2017/07/28 18:22:27 UTC

[12/12] incubator-juneau git commit: Allow serializer and parser sessions to be reused.

Allow serializer and parser sessions to be reused.

Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/2a37f310
Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/2a37f310
Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/2a37f310

Branch: refs/heads/master
Commit: 2a37f31039f08cbdd1badcfe86e69461ac8b2299
Parents: 8879750c
Author: JamesBognar <ja...@apache.org>
Authored: Fri Jul 28 14:22:08 2017 -0400
Committer: JamesBognar <ja...@apache.org>
Committed: Fri Jul 28 14:22:08 2017 -0400

----------------------------------------------------------------------
 .../java/org/apache/juneau/jena/RdfParser.java  | 370 +--------
 .../apache/juneau/jena/RdfParserSession.java    | 480 ++++++++----
 .../org/apache/juneau/jena/RdfSerializer.java   | 314 +-------
 .../juneau/jena/RdfSerializerSession.java       | 450 ++++++-----
 .../org/apache/juneau/ParserReaderTest.java     |  26 +-
 .../org/apache/juneau/XmlValidatorParser.java   |  30 +-
 .../apache/juneau/html/CommonParserTest.java    |   2 +-
 .../apache/juneau/jena/CommonParserTest.java    |   2 +-
 .../apache/juneau/json/CommonParserTest.java    |   2 +-
 .../juneau/transforms/LocalizedDatesTest.java   |   2 +-
 .../urlencoding/CommonParser_UonTest.java       |   2 +-
 .../CommonParser_UrlEncodingTest.java           |   2 +-
 .../juneau/urlencoding/UonParserReaderTest.java |   7 +-
 .../apache/juneau/utils/ParserReaderTest.java   |   2 +-
 .../apache/juneau/utils/StringUtilsTest.java    |   2 +-
 .../org/apache/juneau/xml/CommonParserTest.java |   2 +-
 .../org/apache/juneau/xml/XmlContentTest.java   |  24 +-
 .../java/org/apache/juneau/BeanContext.java     |  24 +-
 .../java/org/apache/juneau/BeanSession.java     |  33 +-
 .../java/org/apache/juneau/BeanSessionArgs.java |  51 ++
 .../main/java/org/apache/juneau/Context.java    |   2 +-
 .../main/java/org/apache/juneau/CoreObject.java |  24 +-
 .../org/apache/juneau/CoreObjectBuilder.java    |   2 +-
 .../java/org/apache/juneau/PropertyStore.java   |  41 +-
 .../main/java/org/apache/juneau/Session.java    |  37 +-
 .../java/org/apache/juneau/SessionArgs.java     |  33 +
 .../java/org/apache/juneau/csv/CsvParser.java   |  20 +-
 .../org/apache/juneau/csv/CsvParserSession.java |  98 +--
 .../org/apache/juneau/csv/CsvSerializer.java    |  63 +-
 .../apache/juneau/csv/CsvSerializerSession.java |  86 ++-
 .../apache/juneau/html/HtmlDocSerializer.java   |  44 +-
 .../juneau/html/HtmlDocSerializerSession.java   |  85 ++-
 .../org/apache/juneau/html/HtmlDocTemplate.java |  27 +-
 .../juneau/html/HtmlDocTemplateBasic.java       |  35 +-
 .../java/org/apache/juneau/html/HtmlParser.java | 538 +------------
 .../apache/juneau/html/HtmlParserSession.java   | 562 +++++++++++++-
 .../juneau/html/HtmlSchemaDocSerializer.java    | 108 +--
 .../html/HtmlSchemaDocSerializerSession.java    | 124 +++
 .../org/apache/juneau/html/HtmlSerializer.java  | 614 +--------------
 .../juneau/html/HtmlSerializerSession.java      | 633 ++++++++++++++-
 .../juneau/html/HtmlStrippedDocSerializer.java  |  18 +-
 .../html/HtmlStrippedDocSerializerSession.java  |  51 ++
 .../java/org/apache/juneau/html/HtmlTag.java    |   2 -
 .../org/apache/juneau/internal/IOUtils.java     |  55 +-
 .../java/org/apache/juneau/jso/JsoParser.java   |  13 +-
 .../org/apache/juneau/jso/JsoParserSession.java |  45 ++
 .../org/apache/juneau/jso/JsoSerializer.java    |  15 +-
 .../apache/juneau/jso/JsoSerializerSession.java |  52 ++
 .../java/org/apache/juneau/json/JsonParser.java | 695 +----------------
 .../apache/juneau/json/JsonParserSession.java   | 730 ++++++++++++++++--
 .../juneau/json/JsonSchemaSerializer.java       | 126 +--
 .../json/JsonSchemaSerializerSession.java       | 129 ++++
 .../org/apache/juneau/json/JsonSerializer.java  | 241 +-----
 .../juneau/json/JsonSerializerSession.java      | 229 +++++-
 .../juneau/msgpack/MsgPackInputStream.java      |  20 +-
 .../apache/juneau/msgpack/MsgPackParser.java    | 174 +----
 .../juneau/msgpack/MsgPackParserSession.java    | 204 ++++-
 .../juneau/msgpack/MsgPackSerializer.java       | 170 +----
 .../msgpack/MsgPackSerializerSession.java       | 201 ++++-
 .../apache/juneau/parser/InputStreamParser.java |   2 +-
 .../juneau/parser/InputStreamParserSession.java |  50 ++
 .../apache/juneau/parser/ParseException.java    |  22 +-
 .../java/org/apache/juneau/parser/Parser.java   | 269 +------
 .../org/apache/juneau/parser/ParserContext.java |   6 +
 .../org/apache/juneau/parser/ParserGroup.java   |   4 +-
 .../org/apache/juneau/parser/ParserInput.java   | 230 ------
 .../apache/juneau/parser/ParserListener.java    |  19 +-
 .../org/apache/juneau/parser/ParserPipe.java    | 278 +++++++
 .../org/apache/juneau/parser/ParserReader.java  |  65 +-
 .../org/apache/juneau/parser/ParserSession.java | 595 ++++++++++++---
 .../apache/juneau/parser/ParserSessionArgs.java |  61 ++
 .../org/apache/juneau/parser/ReaderParser.java  |   2 +-
 .../juneau/parser/ReaderParserSession.java      |  51 ++
 .../juneau/plaintext/PlainTextParser.java       |  11 +-
 .../plaintext/PlainTextParserSession.java       |  43 ++
 .../juneau/plaintext/PlainTextSerializer.java   |  11 +-
 .../plaintext/PlainTextSerializerSession.java   |  47 ++
 .../serializer/OutputStreamSerializer.java      |  36 +-
 .../OutputStreamSerializerSession.java          |  75 ++
 .../apache/juneau/serializer/Serializer.java    | 211 ++---
 .../juneau/serializer/SerializerContext.java    |   6 +
 .../juneau/serializer/SerializerGroup.java      |   4 +-
 .../juneau/serializer/SerializerOutput.java     | 174 -----
 .../juneau/serializer/SerializerPipe.java       | 172 +++++
 .../juneau/serializer/SerializerSession.java    | 316 +++++---
 .../serializer/SerializerSessionArgs.java       |  65 ++
 .../juneau/serializer/WriterSerializer.java     |  44 +-
 .../serializer/WriterSerializerSession.java     |  80 ++
 .../apache/juneau/soap/SoapXmlSerializer.java   |  34 +-
 .../juneau/soap/SoapXmlSerializerContext.java   |  16 +-
 .../juneau/soap/SoapXmlSerializerSession.java   |  75 ++
 .../java/org/apache/juneau/uon/UonParser.java   | 708 +----------------
 .../org/apache/juneau/uon/UonParserSession.java | 760 +++++++++++++++++--
 .../java/org/apache/juneau/uon/UonReader.java   |  48 +-
 .../org/apache/juneau/uon/UonSerializer.java    | 213 +-----
 .../apache/juneau/uon/UonSerializerSession.java | 250 ++++--
 .../juneau/urlencoding/UrlEncodingParser.java   | 300 +-------
 .../urlencoding/UrlEncodingParserSession.java   | 310 +++++++-
 .../urlencoding/UrlEncodingSerializer.java      | 222 +-----
 .../UrlEncodingSerializerSession.java           | 226 +++++-
 .../org/apache/juneau/xml/XmlDocSerializer.java |  22 +-
 .../juneau/xml/XmlDocSerializerSession.java     |  53 ++
 .../java/org/apache/juneau/xml/XmlParser.java   | 468 +-----------
 .../org/apache/juneau/xml/XmlParserSession.java | 645 ++++++++++++----
 .../java/org/apache/juneau/xml/XmlReader.java   | 301 ++++++++
 .../juneau/xml/XmlSchemaDocSerializer.java      |  13 +-
 .../xml/XmlSchemaDocSerializerSession.java      |  53 ++
 .../apache/juneau/xml/XmlSchemaSerializer.java  | 546 +------------
 .../juneau/xml/XmlSchemaSerializerSession.java  | 551 ++++++++++++++
 .../org/apache/juneau/xml/XmlSerializer.java    | 630 +--------------
 .../apache/juneau/xml/XmlSerializerSession.java | 693 ++++++++++++++---
 juneau-core/src/main/javadoc/overview.html      |  24 +-
 .../juneau/examples/rest/PhotosResource.java    |  30 +-
 .../juneau/rest/client/RestCallLogger.java      |   2 +-
 .../juneau/rest/client/RestRequestEntity.java   |  21 +-
 .../apache/juneau/rest/jaxrs/BaseProvider.java  |  37 +-
 .../juneau/rest/test/AcceptCharsetResource.java |  27 +-
 .../rest/test/CharsetEncodingsResource.java     |  22 +-
 .../rest/test/DefaultContentTypesResource.java  |  22 +-
 .../apache/juneau/rest/test/GroupsResource.java |  22 +-
 .../juneau/rest/test/InheritanceResource.java   |  20 +-
 .../juneau/rest/test/NlsPropertyResource.java   |  10 +-
 .../juneau/rest/test/OnPostCallResource.java    |  28 +-
 .../juneau/rest/test/OnPreCallResource.java     |  14 +-
 .../juneau/rest/test/ParsersResource.java       |  48 +-
 .../juneau/rest/test/PropertiesResource.java    |  24 +-
 .../juneau/rest/test/SerializersResource.java   |  40 +-
 .../org/apache/juneau/rest/RequestBody.java     |  11 +-
 .../java/org/apache/juneau/rest/RestConfig.java |   6 +-
 .../org/apache/juneau/rest/RestRequest.java     |   3 +
 .../juneau/rest/RestResourceResolver.java       |  44 --
 .../juneau/rest/RestResourceResolverSimple.java |  59 ++
 .../juneau/rest/annotation/RestResource.java    |   2 +-
 .../juneau/rest/response/DefaultHandler.java    |  35 +-
 .../org/apache/juneau/rest/vars/FileVar.java    |   5 +-
 .../org/apache/juneau/rest/vars/RequestVar.java |   3 +-
 .../org/apache/juneau/rest/vars/UrlVar.java     |   5 +-
 .../org/apache/juneau/rest/vars/WidgetVar.java  |   2 +-
 .../juneau/rest/widget/MenuItemWidget.java      |  17 +-
 139 files changed, 9703 insertions(+), 9139 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/2a37f310/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
----------------------------------------------------------------------
diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
index e2b58d5..d68c70a 100644
--- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
@@ -12,21 +12,12 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.jena;
 
-import static org.apache.juneau.internal.StringUtils.*;
 import static org.apache.juneau.jena.Constants.*;
 import static org.apache.juneau.jena.RdfCommonContext.*;
 
-import java.lang.reflect.*;
-import java.util.*;
-
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
-import org.apache.juneau.http.*;
 import org.apache.juneau.parser.*;
-import org.apache.juneau.transform.*;
-
-import com.hp.hpl.jena.rdf.model.*;
-import com.hp.hpl.jena.util.iterator.*;
 
 /**
  * Parses RDF into POJOs.
@@ -80,12 +71,7 @@ public class RdfParser extends ReaderParser {
 		 * @param propertyStore The property store containing all the settings for this object.
 		 */
 		public Xml(PropertyStore propertyStore) {
-			super(propertyStore);
-		}
-
-		@Override
-		protected ObjectMap getOverrideProperties() {
-			return super.getOverrideProperties().append(RDF_language, LANG_RDF_XML);
+			super(propertyStore.copy().append(RDF_language, LANG_RDF_XML));
 		}
 	}
 
@@ -99,12 +85,7 @@ public class RdfParser extends ReaderParser {
 		 * @param propertyStore The property store containing all the settings for this object.
 		 */
 		public NTriple(PropertyStore propertyStore) {
-			super(propertyStore);
-		}
-
-		@Override
-		protected ObjectMap getOverrideProperties() {
-			return super.getOverrideProperties().append(RDF_language, LANG_NTRIPLE);
+			super(propertyStore.copy().append(RDF_language, LANG_NTRIPLE));
 		}
 	}
 
@@ -118,12 +99,7 @@ public class RdfParser extends ReaderParser {
 		 * @param propertyStore The property store containing all the settings for this object.
 		 */
 		public Turtle(PropertyStore propertyStore) {
-			super(propertyStore);
-		}
-
-		@Override
-		protected ObjectMap getOverrideProperties() {
-			return super.getOverrideProperties().append(RDF_language, LANG_TURTLE);
+			super(propertyStore.copy().append(RDF_language, LANG_TURTLE));
 		}
 	}
 
@@ -137,12 +113,7 @@ public class RdfParser extends ReaderParser {
 		 * @param propertyStore The property store containing all the settings for this object.
 		 */
 		public N3(PropertyStore propertyStore) {
-			super(propertyStore);
-		}
-
-		@Override
-		protected ObjectMap getOverrideProperties() {
-			return super.getOverrideProperties().append(RDF_language, LANG_N3);
+			super(propertyStore.copy().append(RDF_language, LANG_N3));
 		}
 	}
 
@@ -164,337 +135,8 @@ public class RdfParser extends ReaderParser {
 		return new RdfParserBuilder(propertyStore);
 	}
 
-	@SuppressWarnings({"unchecked", "rawtypes"})
-	@Override /* ReaderParser */
-	protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception {
-
-		RdfParserSession s = (RdfParserSession)session;
-
-		Model model = s.getModel();
-		RDFReader r = s.getRdfReader();
-		r.read(model, session.getReader(), null);
-
-		List<Resource> roots = getRoots(s, model);
-
-		// Special case where we're parsing a loose collection of resources.
-		if (s.isLooseCollections() && type.isCollectionOrArray()) {
-			Collection c = null;
-			if (type.isArray() || type.isArgs())
-				c = new ArrayList();
-			else
-				c = (
-					type.canCreateNewInstance(session.getOuter()) 
-					? (Collection<?>)type.newInstance(session.getOuter()) 
-					: new ObjectList(session)
-				);
-
-			int argIndex = 0;
-			for (Resource resource : roots)
-				c.add(parseAnything(s, type.isArgs() ? type.getArg(argIndex++) : type.getElementType(), resource, 
-					session.getOuter(), null));
-
-			if (type.isArray() || type.isArgs())
-				return (T)session.toArray(type, c);
-			return (T)c;
-		}
-
-		if (roots.isEmpty())
-			return null;
-		if (roots.size() > 1)
-			throw new ParseException(session, "Too many root nodes found in model:  {0}", roots.size());
-		Resource resource = roots.get(0);
-
-		return parseAnything(s, type, resource, session.getOuter(), null);
-	}
-
-	/*
-	 * Finds the roots in the model using either the "root" property to identify it,
-	 * 	or by resorting to scanning the model for all nodes with no incoming predicates.
-	 */
-	private static List<Resource> getRoots(RdfParserSession session, Model m) {
-		List<Resource> l = new LinkedList<Resource>();
-
-		// First try to find the root using the "http://www.apache.org/juneau/root" property.
-		Property root = m.createProperty(session.getJuneauNsUri(), RDF_juneauNs_ROOT);
-		for (ResIterator i  = m.listResourcesWithProperty(root); i.hasNext();)
-			l.add(i.next());
-
-		if (! l.isEmpty())
-			return l;
-
-		// Otherwise, we need to find all resources that aren't objects.
-		// We want to explicitly ignore statements where the subject
-		// and object are the same node.
-		Set<RDFNode> objects = new HashSet<RDFNode>();
-		for (StmtIterator i = m.listStatements(); i.hasNext();) {
-			Statement st = i.next();
-			RDFNode subject = st.getSubject();
-			RDFNode object = st.getObject();
-			if (object.isResource() && ! object.equals(subject))
-				objects.add(object);
-		}
-		for (ResIterator i = m.listSubjects(); i.hasNext();) {
-			Resource r = i.next();
-			if (! objects.contains(r))
-				l.add(r);
-		}
-		return l;
-	}
-
-	private <T> BeanMap<T> parseIntoBeanMap(RdfParserSession session, Resource r2, BeanMap<T> m) throws Exception {
-		BeanMeta<T> bm = m.getMeta();
-		RdfBeanMeta rbm = bm.getExtendedMeta(RdfBeanMeta.class);
-		if (rbm.hasBeanUri() && r2.getURI() != null)
-			rbm.getBeanUriProperty().set(m, null, r2.getURI());
-		for (StmtIterator i = r2.listProperties(); i.hasNext();) {
-			Statement st = i.next();
-			Property p = st.getPredicate();
-			String key = session.decodeString(p.getLocalName());
-			BeanPropertyMeta pMeta = m.getPropertyMeta(key);
-			session.setCurrentProperty(pMeta);
-			if (pMeta != null) {
-				RDFNode o = st.getObject();
-				ClassMeta<?> cm = pMeta.getClassMeta();
-				if (cm.isCollectionOrArray() && isMultiValuedCollections(session, pMeta)) {
-					ClassMeta<?> et = cm.getElementType();
-					Object value = parseAnything(session, et, o, m.getBean(false), pMeta);
-					setName(et, value, key);
-					pMeta.add(m, key, value);
-				} else {
-					Object value = parseAnything(session, cm, o, m.getBean(false), pMeta);
-					setName(cm, value, key);
-					pMeta.set(m, key, value);
-				}
-			} else if (! (p.equals(session.getRootProperty()) || p.equals(session.getTypeProperty()))) {
-				session.onUnknownProperty(key, m, -1, -1);
-			}
-			session.setCurrentProperty(null);
-		}
-		return m;
-	}
-
-	private static boolean isMultiValuedCollections(RdfParserSession session, BeanPropertyMeta pMeta) {
-		if (pMeta != null && pMeta.getExtendedMeta(RdfBeanPropertyMeta.class).getCollectionFormat() != RdfCollectionFormat.DEFAULT)
-			return pMeta.getExtendedMeta(RdfBeanPropertyMeta.class).getCollectionFormat() == RdfCollectionFormat.MULTI_VALUED;
-		return session.getCollectionFormat() == RdfCollectionFormat.MULTI_VALUED;
-	}
-
-	@SuppressWarnings({ "unchecked", "rawtypes" })
-	private <T> T parseAnything(RdfParserSession session, ClassMeta<T> eType, RDFNode n, Object outer, 
-			BeanPropertyMeta pMeta) throws Exception {
-
-		if (eType == null)
-			eType = (ClassMeta<T>)object();
-		PojoSwap<T,Object> transform = (PojoSwap<T,Object>)eType.getPojoSwap();
-		ClassMeta<?> sType = eType.getSerializedClassMeta();
-		session.setCurrentClass(sType);
-
-		if (! sType.canCreateNewInstance(outer)) {
-			if (n.isResource()) {
-				Statement st = n.asResource().getProperty(session.getTypeProperty());
-				if (st != null) {
-					String c = st.getLiteral().getString();
-					ClassMeta tcm = session.getClassMeta(c, pMeta, eType);
-					if (tcm != null)
-						sType = eType = tcm;
-				}
-			}
-		}
-
-		Object o = null;
-		if (n.isResource() && n.asResource().getURI() != null && n.asResource().getURI().equals(RDF_NIL)) {
-			// Do nothing.  Leave o == null.
-		} else if (sType.isObject()) {
-			if (n.isLiteral()) {
-				o = n.asLiteral().getValue();
-				if (o instanceof String) {
-					o = session.decodeString(o);
-				}
-			}
-			else if (n.isResource()) {
-				Resource r = n.asResource();
-				if (session.wasAlreadyProcessed(r))
-					o = r.getURI();
-				else if (r.getProperty(session.getValueProperty()) != null) {
-					o = parseAnything(session, object(), n.asResource().getProperty(session.getValueProperty()).getObject(), outer, null);
-				} else if (isSeq(session, r)) {
-					o = new ObjectList(session);
-					parseIntoCollection(session, r.as(Seq.class), (Collection)o, sType, pMeta);
-				} else if (isBag(session, r)) {
-					o = new ObjectList(session);
-					parseIntoCollection(session, r.as(Bag.class), (Collection)o, sType, pMeta);
-				} else if (r.canAs(RDFList.class)) {
-					o = new ObjectList(session);
-					parseIntoCollection(session, r.as(RDFList.class), (Collection)o, sType, pMeta);
-				} else {
-					// If it has a URI and no child properties, we interpret this as an
-					// external resource, and convert it to just a URL.
-					String uri = r.getURI();
-					if (uri != null && ! r.listProperties().hasNext()) {
-						o = r.getURI();
-					} else {
-						ObjectMap m2 = new ObjectMap(session);
-						parseIntoMap(session, r, m2, null, null, pMeta);
-						o = session.cast(m2, pMeta, eType);
-					}
-				}
-			} else {
-				throw new ParseException(session, "Unrecognized node type ''{0}'' for object", n);
-			}
-		} else if (sType.isBoolean()) {
-			o = session.convertToType(getValue(session, n, outer), boolean.class);
-		} else if (sType.isCharSequence()) {
-			o = session.decodeString(getValue(session, n, outer));
-		} else if (sType.isChar()) {
-			o = session.decodeString(getValue(session, n, outer)).charAt(0);
-		} else if (sType.isNumber()) {
-			o = parseNumber(getValue(session, n, outer).toString(), (Class<? extends Number>)sType.getInnerClass());
-		} else if (sType.isMap()) {
-			Resource r = n.asResource();
-			if (session.wasAlreadyProcessed(r))
-				return null;
-			Map m = (sType.canCreateNewInstance(outer) ? (Map)sType.newInstance(outer) : new ObjectMap(session));
-			o = parseIntoMap(session, r, m, eType.getKeyType(), eType.getValueType(), pMeta);
-		} else if (sType.isCollectionOrArray() || sType.isArgs()) {
-			if (sType.isArray() || sType.isArgs())
-				o = new ArrayList();
-			else
-				o = (sType.canCreateNewInstance(outer) ? (Collection<?>)sType.newInstance(outer) : new ObjectList(session));
-			Resource r = n.asResource();
-			if (session.wasAlreadyProcessed(r))
-				return null;
-			if (isSeq(session, r)) {
-				parseIntoCollection(session, r.as(Seq.class), (Collection)o, sType, pMeta);
-			} else if (isBag(session, r)) {
-				parseIntoCollection(session, r.as(Bag.class), (Collection)o, sType, pMeta);
-			} else if (r.canAs(RDFList.class)) {
-				parseIntoCollection(session, r.as(RDFList.class), (Collection)o, sType, pMeta);
-			} else {
-				throw new ParseException("Unrecognized node type ''{0}'' for collection", n);
-			}
-			if (sType.isArray() || sType.isArgs())
-				o = session.toArray(sType, (Collection)o);
-		} else if (sType.canCreateNewBean(outer)) {
-			Resource r = n.asResource();
-			if (session.wasAlreadyProcessed(r))
-				return null;
-			BeanMap<?> bm = session.newBeanMap(outer, sType.getInnerClass());
-			o = parseIntoBeanMap(session, r, bm).getBean();
-		} else if (sType.isUri() && n.isResource()) {
-			o = sType.newInstanceFromString(outer, session.decodeString(n.asResource().getURI()));
-		} else if (sType.canCreateNewInstanceFromString(outer)) {
-			o = sType.newInstanceFromString(outer, session.decodeString(getValue(session, n, outer)));
-		} else if (sType.canCreateNewInstanceFromNumber(outer)) {
-			o = sType.newInstanceFromNumber(session, outer, parseNumber(getValue(session, n, outer).toString(), sType.getNewInstanceFromNumberClass()));
-		} else if (n.isResource()) {
-			Resource r = n.asResource();
-			Map m = new ObjectMap(session);
-			parseIntoMap(session, r, m, sType.getKeyType(), sType.getValueType(), pMeta);
-			if (m.containsKey(session.getBeanTypePropertyName(eType)))
-				o = session.cast((ObjectMap)m, pMeta, eType);
-			else
-				throw new ParseException(session, "Class ''{0}'' could not be instantiated.  Reason: ''{1}''", sType.getInnerClass().getName(), sType.getNotABeanReason());
-		} else {
-			throw new ParseException("Class ''{0}'' could not be instantiated.  Reason: ''{1}''", sType.getInnerClass().getName(), sType.getNotABeanReason());
-		}
-
-		if (transform != null && o != null)
-			o = transform.unswap(session, o, eType);
-
-		if (outer != null)
-			setParent(eType, o, outer);
-
-		return (T)o;
-	}
-
-	private static boolean isSeq(RdfParserSession session, RDFNode n) {
-		if (n.isResource()) {
-			Statement st = n.asResource().getProperty(session.getRdfTypeProperty());
-			if (st != null)
-				return RDF_SEQ.equals(st.getResource().getURI());
-		}
-		return false;
-	}
-
-	private static boolean isBag(RdfParserSession session, RDFNode n) {
-		if (n.isResource()) {
-			Statement st = n.asResource().getProperty(session.getRdfTypeProperty());
-			if (st != null)
-				return RDF_BAG.equals(st.getResource().getURI());
-		}
-		return false;
-	}
-
-	private Object getValue(RdfParserSession session, RDFNode n, Object outer) throws Exception {
-		if (n.isLiteral())
-			return n.asLiteral().getValue();
-		if (n.isResource()) {
-			Statement st = n.asResource().getProperty(session.getValueProperty());
-			if (st != null) {
-				n = st.getObject();
-				if (n.isLiteral())
-					return n.asLiteral().getValue();
-				return parseAnything(session, object(), st.getObject(), outer, null);
-			}
-		}
-		throw new ParseException(session, "Unknown value type for node ''{0}''", n);
-	}
-
-	private <K,V> Map<K,V> parseIntoMap(RdfParserSession session, Resource r, Map<K,V> m, ClassMeta<K> keyType, 
-			ClassMeta<V> valueType, BeanPropertyMeta pMeta) throws Exception {
-		// Add URI as "uri" to generic maps.
-		if (r.getURI() != null) {
-			K uri = convertAttrToType(session, m, "uri", keyType);
-			V value = convertAttrToType(session, m, r.getURI(), valueType);
-			m.put(uri, value);
-		}
-		for (StmtIterator i = r.listProperties(); i.hasNext();) {
-			Statement st = i.next();
-			Property p = st.getPredicate();
-			String key = p.getLocalName();
-			if (! (key.equals("root") && p.getURI().equals(session.getJuneauNsUri()))) {
-				key = session.decodeString(key);
-				RDFNode o = st.getObject();
-				K key2 = convertAttrToType(session, m, key, keyType);
-				V value = parseAnything(session, valueType, o, m, pMeta);
-				setName(valueType, value, key);
-				m.put(key2, value);
-			}
-
-		}
-		return m;
-	}
-
-	@SuppressWarnings("unchecked")
-	private <E> Collection<E> parseIntoCollection(RdfParserSession session, Container c, Collection<E> l, 
-			ClassMeta<?> type, BeanPropertyMeta pMeta) throws Exception {
-		int argIndex = 0;
-		for (NodeIterator ni = c.iterator(); ni.hasNext();) {
-			E e = (E)parseAnything(session, type.isArgs() ? type.getArg(argIndex++) : type.getElementType(), ni.next(), l, pMeta);
-			l.add(e);
-		}
-		return l;
-	}
-
-	@SuppressWarnings("unchecked")
-	private <E> Collection<E> parseIntoCollection(RdfParserSession session, RDFList list, Collection<E> l, 
-			ClassMeta<?> type, BeanPropertyMeta pMeta) throws Exception {
-		int argIndex = 0;
-		for (ExtendedIterator<RDFNode> ni = list.iterator(); ni.hasNext();) {
-			E e = (E)parseAnything(session, type.isArgs() ? type.getArg(argIndex++) : type.getElementType(), ni.next(), l, pMeta);
-			l.add(e);
-		}
-		return l;
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Entry point methods
-	//--------------------------------------------------------------------------------
-
 	@Override /* Parser */
-	public RdfParserSession createSession(Object input, ObjectMap op, Method javaMethod, Object outer, Locale locale, 
-			TimeZone timeZone, MediaType mediaType) {
-		return new RdfParserSession(ctx, op, input, javaMethod, outer, locale, timeZone, mediaType);
+	public ReaderParserSession createSession(ParserSessionArgs args) {
+		return new RdfParserSession(ctx, args);
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/2a37f310/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
----------------------------------------------------------------------
diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
index 63a5eca..267d06f 100644
--- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
@@ -12,27 +12,29 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.jena;
 
+import static org.apache.juneau.internal.StringUtils.*;
 import static org.apache.juneau.jena.Constants.*;
 import static org.apache.juneau.jena.RdfCommonContext.*;
 
-import java.io.*;
-import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.*;
-import org.apache.juneau.http.*;
 import org.apache.juneau.parser.*;
+import org.apache.juneau.transform.*;
 import org.apache.juneau.xml.*;
 
 import com.hp.hpl.jena.rdf.model.*;
+import com.hp.hpl.jena.util.iterator.*;
 
 /**
  * Session object that lives for the duration of a single use of {@link RdfParser}.
- * 
+ *
  * <p>
- * This class is NOT thread safe.  It is meant to be discarded after one-time use.
+ * This class is NOT thread safe.  
+ * It is typically discarded after one-time use although it can be reused against multiple inputs.
  */
-public class RdfParserSession extends ParserSession {
+@SuppressWarnings({"unchecked", "rawtypes"})
+public class RdfParserSession extends ReaderParserSession {
 
 	private final String rdfLanguage;
 	private final Namespace juneauNs, juneauBpNs;
@@ -46,38 +48,18 @@ public class RdfParserSession extends ParserSession {
 	/**
 	 * Create a new session using properties specified in the context.
 	 *
-	 * @param ctx 
+	 * @param ctx
 	 * 	The context creating this session object.
 	 * 	The context contains all the configuration settings for this object.
-	 * @param input 
-	 * 	The input. 
-	 * 	Can be any of the following types:
-	 * 	<ul>
-	 * 		<li><jk>null</jk>
-	 * 		<li>{@link Reader}
-	 * 		<li>{@link CharSequence}
-	 * 		<li>{@link InputStream} containing UTF-8 encoded text.
-	 * 		<li>{@link File} containing system encoded text.
-	 * 	</ul>
-	 * @param op 
-	 * 	The override properties.
-	 * 	These override any context properties defined in the context.
-	 * @param javaMethod The java method that called this parser, usually the method in a REST servlet.
-	 * @param outer The outer object for instantiating top-level non-static inner classes.
-	 * @param locale 
-	 * 	The session locale.
-	 * 	If <jk>null</jk>, then the locale defined on the context is used.
-	 * @param timeZone 
-	 * 	The session timezone.
-	 * 	If <jk>null</jk>, then the timezone defined on the context is used.
-	 * @param mediaType The session media type (e.g. <js>"application/json"</js>).
+	 * @param args
+	 * 	Runtime session arguments.
 	 */
-	protected RdfParserSession(RdfParserContext ctx, ObjectMap op, Object input, Method javaMethod, Object outer, 
-			Locale locale, TimeZone timeZone, MediaType mediaType) {
-		super(ctx, op, input, javaMethod, outer, locale, timeZone, mediaType);
+	protected RdfParserSession(RdfParserContext ctx, ParserSessionArgs args) {
+		super(ctx, args);
 		ObjectMap jenaSettings = new ObjectMap();
 		jenaSettings.putAll(ctx.jenaSettings);
-		if (op == null || op.isEmpty()) {
+		ObjectMap p = getProperties();
+		if (p.isEmpty()) {
 			this.rdfLanguage = ctx.rdfLanguage;
 			this.juneauNs = ctx.juneauNs;
 			this.juneauBpNs = ctx.juneauBpNs;
@@ -85,12 +67,12 @@ public class RdfParserSession extends ParserSession {
 			this.collectionFormat = ctx.collectionFormat;
 			this.looseCollections = ctx.looseCollections;
 		} else {
-			this.rdfLanguage = op.getString(RDF_language, ctx.rdfLanguage);
-			this.juneauNs = (op.containsKey(RDF_juneauNs) ? NamespaceFactory.parseNamespace(op.get(RDF_juneauNs)) : ctx.juneauNs);
-			this.juneauBpNs = (op.containsKey(RDF_juneauBpNs) ? NamespaceFactory.parseNamespace(op.get(RDF_juneauBpNs)) : ctx.juneauBpNs);
-			this.trimWhitespace = op.getBoolean(RdfParserContext.RDF_trimWhitespace, ctx.trimWhitespace);
-			this.collectionFormat = RdfCollectionFormat.valueOf(op.getString(RDF_collectionFormat, "DEFAULT"));
-			this.looseCollections = op.getBoolean(RDF_looseCollections, ctx.looseCollections);
+			this.rdfLanguage = p.getString(RDF_language, ctx.rdfLanguage);
+			this.juneauNs = (p.containsKey(RDF_juneauNs) ? NamespaceFactory.parseNamespace(p.get(RDF_juneauNs)) : ctx.juneauNs);
+			this.juneauBpNs = (p.containsKey(RDF_juneauBpNs) ? NamespaceFactory.parseNamespace(p.get(RDF_juneauBpNs)) : ctx.juneauBpNs);
+			this.trimWhitespace = p.getBoolean(RdfParserContext.RDF_trimWhitespace, ctx.trimWhitespace);
+			this.collectionFormat = RdfCollectionFormat.valueOf(p.getString(RDF_collectionFormat, "DEFAULT"));
+			this.looseCollections = p.getBoolean(RDF_looseCollections, ctx.looseCollections);
 		}
 		this.model = ModelFactory.createDefaultModel();
 		addModelPrefix(juneauNs);
@@ -108,129 +90,55 @@ public class RdfParserSession extends ParserSession {
 		}
 	}
 
-	/**
-	 * Returns <jk>true</jk> if this resource was already visited.
-	 *
-	 * @param r The resource to check.
-	 * @return <jk>true</jk> if this resource was already visited.
-	 */
-	public final boolean wasAlreadyProcessed(Resource r) {
-		return ! urisVisited.add(r);
-	}
+	@Override /* ReaderParserSession */
+	protected <T> T doParse(ParserPipe pipe, ClassMeta<T> type) throws Exception {
 
-	/**
-	 * Returns the root property.
-	 *
-	 * @return The root property.
-	 */
-	public final Property getRootProperty() {
-		return pRoot;
-	}
+		RDFReader r = rdfReader;
+		r.read(model, pipe.getBufferedReader(), null);
 
-	/**
-	 * Returns the RDF property identifier <js>"value"</js>.
-	 *
-	 * @return The RDF property identifier <js>"value"</js>.
-	 */
-	public final Property getValueProperty() {
-		return pValue;
-	}
+		List<Resource> roots = getRoots(model);
 
-	/**
-	 * Returns the RDF property identifier <js>"_type"</js>.
-	 *
-	 * @return The RDF property identifier <js>"_type"</js>.
-	 */
-	public final Property getTypeProperty() {
-		return pType;
-	}
-
-	/**
-	 * Returns the RDF property identifier <js>"type"</js>.
-	 *
-	 * @return The RDF property identifier <js>"type"</js>.
-	 */
-	public final Property getRdfTypeProperty() {
-		return pRdfType;
-	}
+		// Special case where we're parsing a loose collection of resources.
+		if (looseCollections && type.isCollectionOrArray()) {
+			Collection c = null;
+			if (type.isArray() || type.isArgs())
+				c = new ArrayList();
+			else
+				c = (
+					type.canCreateNewInstance(getOuter()) 
+					? (Collection<?>)type.newInstance(getOuter()) 
+					: new ObjectList(this)
+				);
 
-	/**
-	 * Returns the RDF model being parsed into.
-	 *
-	 * @return The RDF model being parsed into.
-	 */
-	public final Model getModel() {
-		return model;
-	}
+			int argIndex = 0;
+			for (Resource resource : roots)
+				c.add(parseAnything(type.isArgs() ? type.getArg(argIndex++) : type.getElementType(), resource, 
+					getOuter(), null));
 
-	/**
-	 * Returns the RDF reader that's reading the model.
-	 *
-	 * @return The RDF reader that's reading the model.
-	 */
-	public final RDFReader getRdfReader() {
-		return rdfReader;
-	}
-
-	/**
-	 * Returns the {@link RdfCommonContext#RDF_collectionFormat} setting value for this session.
-	 *
-	 * @return The {@link RdfCommonContext#RDF_collectionFormat} setting value for this session.
-	 */
-	public final RdfCollectionFormat getCollectionFormat() {
-		return collectionFormat;
-	}
+			if (type.isArray() || type.isArgs())
+				return (T)toArray(type, c);
+			return (T)c;
+		}
 
-	/**
-	 * Returns the {@link RdfCommonContext#RDF_looseCollections} setting value for this session.
-	 *
-	 * @return The {@link RdfCommonContext#RDF_looseCollections} setting value for this session.
-	 */
-	public final boolean isLooseCollections() {
-		return looseCollections;
-	}
+		if (roots.isEmpty())
+			return null;
+		if (roots.size() > 1)
+			throw new ParseException(loc(), "Too many root nodes found in model:  {0}", roots.size());
+		Resource resource = roots.get(0);
 
-	/**
-	 * Returns the Juneau namespace URI.
-	 *
-	 * @return The Juneau namespace URI.
-	 */
-	public final String getJuneauNsUri() {
-		return juneauNs.getUri();
+		return parseAnything(type, resource, getOuter(), null);
 	}
 
-	/**
-	 * Adds the specified namespace as a model prefix.
-	 *
-	 * @param ns The XML namespace.
-	 */
-	public final void addModelPrefix(Namespace ns) {
+	private final void addModelPrefix(Namespace ns) {
 		model.setNsPrefix(ns.getName(), ns.getUri());
 	}
 
-	/**
-	 * Constructs a <code>Property</code> in the Juneau Bean namespace in this mode.
-	 *
-	 * @param name The property name.
-	 * @return The new property object.
-	 */
-	public final Property getRdfProperty(String name) {
-		return model.createProperty(juneauBpNs.getUri(), name);
-	}
-
-	/**
+	/*
 	 * Decodes the specified string.
-	 * 
-	 * <p>
 	 * If {@link RdfParserContext#RDF_trimWhitespace} is <jk>true</jk>, the resulting string is trimmed before decoding.
-	 * 
-	 * <p>
 	 * If {@link #isTrimStrings()} is <jk>true</jk>, the resulting string is trimmed after decoding.
-	 *
-	 * @param o The string to trim.
-	 * @return The trimmed string, or <jk>null</jk> if the string was <jk>null</jk>.
 	 */
-	public final String decodeString(Object o) {
+	private String decodeString(Object o) {
 		if (o == null)
 			return null;
 		String s = o.toString();
@@ -243,4 +151,284 @@ public class RdfParserSession extends ParserSession {
 			s = s.trim();
 		return s;
 	}
+	
+	/*
+	 * Finds the roots in the model using either the "root" property to identify it,
+	 * 	or by resorting to scanning the model for all nodes with no incoming predicates.
+	 */
+	private List<Resource> getRoots(Model m) {
+		List<Resource> l = new LinkedList<Resource>();
+
+		// First try to find the root using the "http://www.apache.org/juneau/root" property.
+		Property root = m.createProperty(juneauNs.getUri(), RDF_juneauNs_ROOT);
+		for (ResIterator i  = m.listResourcesWithProperty(root); i.hasNext();)
+			l.add(i.next());
+
+		if (! l.isEmpty())
+			return l;
+
+		// Otherwise, we need to find all resources that aren't objects.
+		// We want to explicitly ignore statements where the subject
+		// and object are the same node.
+		Set<RDFNode> objects = new HashSet<RDFNode>();
+		for (StmtIterator i = m.listStatements(); i.hasNext();) {
+			Statement st = i.next();
+			RDFNode subject = st.getSubject();
+			RDFNode object = st.getObject();
+			if (object.isResource() && ! object.equals(subject))
+				objects.add(object);
+		}
+		for (ResIterator i = m.listSubjects(); i.hasNext();) {
+			Resource r = i.next();
+			if (! objects.contains(r))
+				l.add(r);
+		}
+		return l;
+	}
+
+	private <T> BeanMap<T> parseIntoBeanMap(Resource r2, BeanMap<T> m) throws Exception {
+		BeanMeta<T> bm = m.getMeta();
+		RdfBeanMeta rbm = bm.getExtendedMeta(RdfBeanMeta.class);
+		if (rbm.hasBeanUri() && r2.getURI() != null)
+			rbm.getBeanUriProperty().set(m, null, r2.getURI());
+		for (StmtIterator i = r2.listProperties(); i.hasNext();) {
+			Statement st = i.next();
+			Property p = st.getPredicate();
+			String key = decodeString(p.getLocalName());
+			BeanPropertyMeta pMeta = m.getPropertyMeta(key);
+			setCurrentProperty(pMeta);
+			if (pMeta != null) {
+				RDFNode o = st.getObject();
+				ClassMeta<?> cm = pMeta.getClassMeta();
+				if (cm.isCollectionOrArray() && isMultiValuedCollections(pMeta)) {
+					ClassMeta<?> et = cm.getElementType();
+					Object value = parseAnything(et, o, m.getBean(false), pMeta);
+					setName(et, value, key);
+					pMeta.add(m, key, value);
+				} else {
+					Object value = parseAnything(cm, o, m.getBean(false), pMeta);
+					setName(cm, value, key);
+					pMeta.set(m, key, value);
+				}
+			} else if (! (p.equals(pRoot) || p.equals(pType))) {
+				onUnknownProperty(null, key, m, -1, -1);
+			}
+			setCurrentProperty(null);
+		}
+		return m;
+	}
+
+	private boolean isMultiValuedCollections(BeanPropertyMeta pMeta) {
+		if (pMeta != null && pMeta.getExtendedMeta(RdfBeanPropertyMeta.class).getCollectionFormat() != RdfCollectionFormat.DEFAULT)
+			return pMeta.getExtendedMeta(RdfBeanPropertyMeta.class).getCollectionFormat() == RdfCollectionFormat.MULTI_VALUED;
+		return collectionFormat == RdfCollectionFormat.MULTI_VALUED;
+	}
+
+	private <T> T parseAnything(ClassMeta<T> eType, RDFNode n, Object outer, BeanPropertyMeta pMeta) throws Exception {
+
+		if (eType == null)
+			eType = (ClassMeta<T>)object();
+		PojoSwap<T,Object> transform = (PojoSwap<T,Object>)eType.getPojoSwap();
+		ClassMeta<?> sType = eType.getSerializedClassMeta();
+		setCurrentClass(sType);
+
+		if (! sType.canCreateNewInstance(outer)) {
+			if (n.isResource()) {
+				Statement st = n.asResource().getProperty(pType);
+				if (st != null) {
+					String c = st.getLiteral().getString();
+					ClassMeta tcm = getClassMeta(c, pMeta, eType);
+					if (tcm != null)
+						sType = eType = tcm;
+				}
+			}
+		}
+
+		Object o = null;
+		if (n.isResource() && n.asResource().getURI() != null && n.asResource().getURI().equals(RDF_NIL)) {
+			// Do nothing.  Leave o == null.
+		} else if (sType.isObject()) {
+			if (n.isLiteral()) {
+				o = n.asLiteral().getValue();
+				if (o instanceof String) {
+					o = decodeString(o);
+				}
+			}
+			else if (n.isResource()) {
+				Resource r = n.asResource();
+				if (! urisVisited.add(r))
+					o = r.getURI();
+				else if (r.getProperty(pValue) != null) {
+					o = parseAnything(object(), n.asResource().getProperty(pValue).getObject(), outer, null);
+				} else if (isSeq(r)) {
+					o = new ObjectList(this);
+					parseIntoCollection(r.as(Seq.class), (Collection)o, sType, pMeta);
+				} else if (isBag(r)) {
+					o = new ObjectList(this);
+					parseIntoCollection(r.as(Bag.class), (Collection)o, sType, pMeta);
+				} else if (r.canAs(RDFList.class)) {
+					o = new ObjectList(this);
+					parseIntoCollection(r.as(RDFList.class), (Collection)o, sType, pMeta);
+				} else {
+					// If it has a URI and no child properties, we interpret this as an
+					// external resource, and convert it to just a URL.
+					String uri = r.getURI();
+					if (uri != null && ! r.listProperties().hasNext()) {
+						o = r.getURI();
+					} else {
+						ObjectMap m2 = new ObjectMap(this);
+						parseIntoMap(r, m2, null, null, pMeta);
+						o = cast(m2, pMeta, eType);
+					}
+				}
+			} else {
+				throw new ParseException(loc(), "Unrecognized node type ''{0}'' for object", n);
+			}
+		} else if (sType.isBoolean()) {
+			o = convertToType(getValue(n, outer), boolean.class);
+		} else if (sType.isCharSequence()) {
+			o = decodeString(getValue(n, outer));
+		} else if (sType.isChar()) {
+			o = decodeString(getValue(n, outer)).charAt(0);
+		} else if (sType.isNumber()) {
+			o = parseNumber(getValue(n, outer).toString(), (Class<? extends Number>)sType.getInnerClass());
+		} else if (sType.isMap()) {
+			Resource r = n.asResource();
+			if (! urisVisited.add(r))
+				return null;
+			Map m = (sType.canCreateNewInstance(outer) ? (Map)sType.newInstance(outer) : new ObjectMap(this));
+			o = parseIntoMap(r, m, eType.getKeyType(), eType.getValueType(), pMeta);
+		} else if (sType.isCollectionOrArray() || sType.isArgs()) {
+			if (sType.isArray() || sType.isArgs())
+				o = new ArrayList();
+			else
+				o = (sType.canCreateNewInstance(outer) ? (Collection<?>)sType.newInstance(outer) : new ObjectList(this));
+			Resource r = n.asResource();
+			if (! urisVisited.add(r))
+				return null;
+			if (isSeq(r)) {
+				parseIntoCollection(r.as(Seq.class), (Collection)o, sType, pMeta);
+			} else if (isBag(r)) {
+				parseIntoCollection(r.as(Bag.class), (Collection)o, sType, pMeta);
+			} else if (r.canAs(RDFList.class)) {
+				parseIntoCollection(r.as(RDFList.class), (Collection)o, sType, pMeta);
+			} else {
+				throw new ParseException("Unrecognized node type ''{0}'' for collection", n);
+			}
+			if (sType.isArray() || sType.isArgs())
+				o = toArray(sType, (Collection)o);
+		} else if (sType.canCreateNewBean(outer)) {
+			Resource r = n.asResource();
+			if (! urisVisited.add(r))
+				return null;
+			BeanMap<?> bm = newBeanMap(outer, sType.getInnerClass());
+			o = parseIntoBeanMap(r, bm).getBean();
+		} else if (sType.isUri() && n.isResource()) {
+			o = sType.newInstanceFromString(outer, decodeString(n.asResource().getURI()));
+		} else if (sType.canCreateNewInstanceFromString(outer)) {
+			o = sType.newInstanceFromString(outer, decodeString(getValue(n, outer)));
+		} else if (sType.canCreateNewInstanceFromNumber(outer)) {
+			o = sType.newInstanceFromNumber(this, outer, parseNumber(getValue(n, outer).toString(), sType.getNewInstanceFromNumberClass()));
+		} else if (n.isResource()) {
+			Resource r = n.asResource();
+			Map m = new ObjectMap(this);
+			parseIntoMap(r, m, sType.getKeyType(), sType.getValueType(), pMeta);
+			if (m.containsKey(getBeanTypePropertyName(eType)))
+				o = cast((ObjectMap)m, pMeta, eType);
+			else
+				throw new ParseException(loc(), "Class ''{0}'' could not be instantiated.  Reason: ''{1}''", sType.getInnerClass().getName(), sType.getNotABeanReason());
+		} else {
+			throw new ParseException("Class ''{0}'' could not be instantiated.  Reason: ''{1}''", sType.getInnerClass().getName(), sType.getNotABeanReason());
+		}
+
+		if (transform != null && o != null)
+			o = transform.unswap(this, o, eType);
+
+		if (outer != null)
+			setParent(eType, o, outer);
+
+		return (T)o;
+	}
+
+	private ObjectMap loc() {
+		return getLastLocation();
+	}
+
+	private boolean isSeq(RDFNode n) {
+		if (n.isResource()) {
+			Statement st = n.asResource().getProperty(pRdfType);
+			if (st != null)
+				return RDF_SEQ.equals(st.getResource().getURI());
+		}
+		return false;
+	}
+
+	private boolean isBag(RDFNode n) {
+		if (n.isResource()) {
+			Statement st = n.asResource().getProperty(pRdfType);
+			if (st != null)
+				return RDF_BAG.equals(st.getResource().getURI());
+		}
+		return false;
+	}
+
+	private Object getValue(RDFNode n, Object outer) throws Exception {
+		if (n.isLiteral())
+			return n.asLiteral().getValue();
+		if (n.isResource()) {
+			Statement st = n.asResource().getProperty(pValue);
+			if (st != null) {
+				n = st.getObject();
+				if (n.isLiteral())
+					return n.asLiteral().getValue();
+				return parseAnything(object(), st.getObject(), outer, null);
+			}
+		}
+		throw new ParseException(loc(), "Unknown value type for node ''{0}''", n);
+	}
+
+	private <K,V> Map<K,V> parseIntoMap(Resource r, Map<K,V> m, ClassMeta<K> keyType, 
+			ClassMeta<V> valueType, BeanPropertyMeta pMeta) throws Exception {
+		// Add URI as "uri" to generic maps.
+		if (r.getURI() != null) {
+			K uri = convertAttrToType(m, "uri", keyType);
+			V value = convertAttrToType(m, r.getURI(), valueType);
+			m.put(uri, value);
+		}
+		for (StmtIterator i = r.listProperties(); i.hasNext();) {
+			Statement st = i.next();
+			Property p = st.getPredicate();
+			String key = p.getLocalName();
+			if (! (key.equals("root") && p.getURI().equals(juneauNs.getUri()))) {
+				key = decodeString(key);
+				RDFNode o = st.getObject();
+				K key2 = convertAttrToType(m, key, keyType);
+				V value = parseAnything(valueType, o, m, pMeta);
+				setName(valueType, value, key);
+				m.put(key2, value);
+			}
+
+		}
+		return m;
+	}
+
+	private <E> Collection<E> parseIntoCollection(Container c, Collection<E> l, 
+			ClassMeta<?> type, BeanPropertyMeta pMeta) throws Exception {
+		int argIndex = 0;
+		for (NodeIterator ni = c.iterator(); ni.hasNext();) {
+			E e = (E)parseAnything(type.isArgs() ? type.getArg(argIndex++) : type.getElementType(), ni.next(), l, pMeta);
+			l.add(e);
+		}
+		return l;
+	}
+
+	private <E> Collection<E> parseIntoCollection(RDFList list, Collection<E> l, 
+			ClassMeta<?> type, BeanPropertyMeta pMeta) throws Exception {
+		int argIndex = 0;
+		for (ExtendedIterator<RDFNode> ni = list.iterator(); ni.hasNext();) {
+			E e = (E)parseAnything(type.isArgs() ? type.getArg(argIndex++) : type.getElementType(), ni.next(), l, pMeta);
+			l.add(e);
+		}
+		return l;
+	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/2a37f310/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
index 30c5163..e19d8b2 100644
--- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
@@ -15,18 +15,9 @@ package org.apache.juneau.jena;
 import static org.apache.juneau.jena.Constants.*;
 import static org.apache.juneau.jena.RdfCommonContext.*;
 
-import java.lang.reflect.*;
-import java.util.*;
-
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
-import org.apache.juneau.http.*;
-import org.apache.juneau.internal.*;
 import org.apache.juneau.serializer.*;
-import org.apache.juneau.transform.*;
-import org.apache.juneau.xml.*;
-
-import com.hp.hpl.jena.rdf.model.*;
 
 /**
  * Serializes POJOs to RDF.
@@ -51,7 +42,6 @@ import com.hp.hpl.jena.rdf.model.*;
  * 
  * See <a class="doclink" href="package-summary.html#TOC">RDF Overview</a> for an overview of RDF support in Juneau.
  */
-@SuppressWarnings({ "rawtypes", "unchecked" })
 @Produces(value="text/xml+rdf+abbrev", contentType="text/xml+rdf")
 public class RdfSerializer extends WriterSerializer {
 
@@ -81,12 +71,7 @@ public class RdfSerializer extends WriterSerializer {
 		 * @param propertyStore The property store containing all the settings for this object.
 		 */
 		public Xml(PropertyStore propertyStore) {
-			super(propertyStore);
-		}
-
-		@Override /* CoreObject */
-		protected ObjectMap getOverrideProperties() {
-			return super.getOverrideProperties().append(RDF_language, LANG_RDF_XML);
+			super(propertyStore.copy().append(RDF_language, LANG_RDF_XML));
 		}
 	}
 
@@ -100,12 +85,7 @@ public class RdfSerializer extends WriterSerializer {
 		 * @param propertyStore The property store containing all the settings for this object.
 		 */
 		public XmlAbbrev(PropertyStore propertyStore) {
-			super(propertyStore);
-		}
-
-		@Override /* CoreObject */
-		protected ObjectMap getOverrideProperties() {
-			return super.getOverrideProperties().append(RDF_language, LANG_RDF_XML_ABBREV);
+			super(propertyStore.copy().append(RDF_language, LANG_RDF_XML_ABBREV));
 		}
 	}
 
@@ -119,12 +99,7 @@ public class RdfSerializer extends WriterSerializer {
 		 * @param propertyStore The property store containing all the settings for this object.
 		 */
 		public NTriple(PropertyStore propertyStore) {
-			super(propertyStore);
-		}
-
-		@Override /* CoreObject */
-		protected ObjectMap getOverrideProperties() {
-			return super.getOverrideProperties().append(RDF_language, LANG_NTRIPLE);
+			super(propertyStore.copy().append(RDF_language, LANG_NTRIPLE));
 		}
 	}
 
@@ -138,12 +113,7 @@ public class RdfSerializer extends WriterSerializer {
 		 * @param propertyStore The property store containing all the settings for this object.
 		 */
 		public Turtle(PropertyStore propertyStore) {
-			super(propertyStore);
-		}
-
-		@Override /* CoreObject */
-		protected ObjectMap getOverrideProperties() {
-			return super.getOverrideProperties().append(RDF_language, LANG_TURTLE);
+			super(propertyStore.copy().append(RDF_language, LANG_TURTLE));
 		}
 	}
 
@@ -157,12 +127,7 @@ public class RdfSerializer extends WriterSerializer {
 		 * @param propertyStore The property store containing all the settings for this object.
 		 */
 		public N3(PropertyStore propertyStore) {
-			super(propertyStore);
-		}
-
-		@Override /* CoreObject */
-		protected ObjectMap getOverrideProperties() {
-			return super.getOverrideProperties().append(RDF_language, LANG_N3);
+			super(propertyStore.copy().append(RDF_language, LANG_N3));
 		}
 	}
 
@@ -185,272 +150,7 @@ public class RdfSerializer extends WriterSerializer {
 	}
 
 	@Override /* Serializer */
-	protected void doSerialize(SerializerSession session, SerializerOutput out, Object o) throws Exception {
-
-		RdfSerializerSession s = (RdfSerializerSession)session;
-
-		Model model = s.getModel();
-		Resource r = null;
-
-		ClassMeta<?> cm = session.getClassMetaForObject(o);
-		if (s.isLooseCollections() && cm != null && cm.isCollectionOrArray()) {
-			Collection c = s.sort(cm.isCollection() ? (Collection)o : toList(cm.getInnerClass(), o));
-			for (Object o2 : c)
-				serializeAnything(s, o2, false, object(), "root", null, null);
-		} else {
-			RDFNode n = serializeAnything(s, o, false, s.getExpectedRootType(o), "root", null, null);
-			if (n.isLiteral()) {
-				r = model.createResource();
-				r.addProperty(s.getValueProperty(), n);
-			} else {
-				r = n.asResource();
-			}
-
-			if (s.isAddRootProp())
-				r.addProperty(s.getRootProp(), "true");
-		}
-
-		s.getRdfWriter().write(model, out.getWriter(), "http://unknown/");
-	}
-
-	private RDFNode serializeAnything(RdfSerializerSession session, Object o, boolean isURI, ClassMeta<?> eType, 
-			String attrName, BeanPropertyMeta bpm, Resource parentResource) throws SerializeException {
-		Model m = session.getModel();
-
-		ClassMeta<?> aType = null;       // The actual type
-		ClassMeta<?> wType = null;       // The wrapped type
-		ClassMeta<?> sType = object();   // The serialized type
-
-		aType = session.push(attrName, o, eType);
-
-		if (eType == null)
-			eType = object();
-
-		// Handle recursion
-		if (aType == null) {
-			o = null;
-			aType = object();
-		}
-
-		if (o != null) {
-
-			if (aType.isDelegate()) {
-				wType = aType;
-				aType = ((Delegate)o).getClassMeta();
-			}
-
-			sType = aType.getSerializedClassMeta();
-
-			// Swap if necessary
-			PojoSwap swap = aType.getPojoSwap();
-			if (swap != null) {
-				o = swap.swap(session, o);
-
-				// If the getSwapClass() method returns Object, we need to figure out
-				// the actual type now.
-				if (sType.isObject())
-					sType = session.getClassMetaForObject(o);
-			}
-		} else {
-			sType = eType.getSerializedClassMeta();
-		}
-
-		String typeName = session.getBeanTypeName(eType, aType, bpm);
-
-		RDFNode n = null;
-
-		if (o == null || sType.isChar() && ((Character)o).charValue() == 0) {
-			if (bpm != null) {
-				if (! session.isTrimNulls()) {
-					n = m.createResource(RDF_NIL);
-				}
-			} else {
-				n = m.createResource(RDF_NIL);
-			}
-
-		} else if (sType.isUri() || isURI) {
-			// Note that RDF URIs must be absolute to be valid!
-			String uri = getUri(session, o, null);
-			if (StringUtils.isAbsoluteUri(uri))
-				n = m.createResource(uri);
-			else
-				n = m.createLiteral(session.encodeTextInvalidChars(uri));
-
-		} else if (sType.isCharSequence() || sType.isChar()) {
-			n = m.createLiteral(session.encodeTextInvalidChars(o));
-
-		} else if (sType.isNumber() || sType.isBoolean()) {
-			if (! session.isAddLiteralTypes())
-				n = m.createLiteral(o.toString());
-			else
-				n = m.createTypedLiteral(o);
-
-		} else if (sType.isMap() || (wType != null && wType.isMap())) {
-			if (o instanceof BeanMap) {
-				BeanMap bm = (BeanMap)o;
-				Object uri = null;
-				RdfBeanMeta rbm = (RdfBeanMeta)bm.getMeta().getExtendedMeta(RdfBeanMeta.class);
-				if (rbm.hasBeanUri())
-					uri = rbm.getBeanUriProperty().get(bm, null);
-				String uri2 = getUri(session, uri, null);
-				n = m.createResource(uri2);
-				serializeBeanMap(session, bm, (Resource)n, typeName);
-			} else {
-				Map m2 = (Map)o;
-				n = m.createResource();
-				serializeMap(session, m2, (Resource)n, sType);
-			}
-
-		} else if (sType.isBean()) {
-			BeanMap bm = session.toBeanMap(o);
-			Object uri = null;
-			RdfBeanMeta rbm = (RdfBeanMeta)bm.getMeta().getExtendedMeta(RdfBeanMeta.class);
-			if (rbm.hasBeanUri())
-				uri = rbm.getBeanUriProperty().get(bm, null);
-			String uri2 = getUri(session, uri, null);
-			n = m.createResource(uri2);
-			serializeBeanMap(session, bm, (Resource)n, typeName);
-
-		} else if (sType.isCollectionOrArray() || (wType != null && wType.isCollection())) {
-			Collection c = session.sort(sType.isCollection() ? (Collection)o : toList(sType.getInnerClass(), o));
-			RdfCollectionFormat f = session.getCollectionFormat();
-			RdfClassMeta rcm = sType.getExtendedMeta(RdfClassMeta.class);
-			if (rcm.getCollectionFormat() != RdfCollectionFormat.DEFAULT)
-				f = rcm.getCollectionFormat();
-			if (bpm != null && bpm.getExtendedMeta(RdfBeanPropertyMeta.class).getCollectionFormat() != RdfCollectionFormat.DEFAULT)
-				f = bpm.getExtendedMeta(RdfBeanPropertyMeta.class).getCollectionFormat();
-			switch (f) {
-				case BAG: n = serializeToContainer(session, c, eType, m.createBag()); break;
-				case LIST: n = serializeToList(session, c, eType); break;
-				case MULTI_VALUED: serializeToMultiProperties(session, c, eType, bpm, attrName, parentResource); break;
-				default: n = serializeToContainer(session, c, eType, m.createSeq());
-			}
-		} else {
-			n = m.createLiteral(session.encodeTextInvalidChars(session.toString(o)));
-		}
-
-		session.pop();
-
-		return n;
-	}
-
-	private static String getUri(RdfSerializerSession session, Object uri, Object uri2) {
-		String s = null;
-		if (uri != null)
-			s = uri.toString();
-		if ((s == null || s.isEmpty()) && uri2 != null)
-			s = uri2.toString();
-		if (s == null)
-			return null;
-		return session.getUriResolver().resolve(s);
-	}
-
-	private void serializeMap(RdfSerializerSession session, Map m, Resource r, ClassMeta<?> type) throws SerializeException {
-
-		m = session.sort(m);
-
-		ClassMeta<?> keyType = type.getKeyType(), valueType = type.getValueType();
-
-		ArrayList<Map.Entry<Object,Object>> l = new ArrayList<Map.Entry<Object,Object>>(m.entrySet());
-		Collections.reverse(l);
-		for (Map.Entry<Object,Object> me : l) {
-			Object value = me.getValue();
-
-			Object key = session.generalize(me.getKey(), keyType);
-
-			Namespace ns = session.getJuneauBpNs();
-			Model model = session.getModel();
-			Property p = model.createProperty(ns.getUri(), session.encodeElementName(session.toString(key)));
-			RDFNode n = serializeAnything(session, value, false, valueType, key == null ? null : session.toString(key), null, r);
-			if (n != null)
-				r.addProperty(p, n);
-		}
-	}
-
-	private void serializeBeanMap(RdfSerializerSession session, BeanMap<?> m, Resource r, String typeName) throws SerializeException {
-		List<BeanPropertyValue> l = m.getValues(session.isTrimNulls(), typeName != null ? session.createBeanTypeNameProperty(m, typeName) : null);
-		Collections.reverse(l);
-		for (BeanPropertyValue bpv : l) {
-			BeanPropertyMeta pMeta = bpv.getMeta();
-			ClassMeta<?> cMeta = pMeta.getClassMeta();
-
-			if (pMeta.getExtendedMeta(RdfBeanPropertyMeta.class).isBeanUri())
-				continue;
-
-			String key = bpv.getName();
-			Object value = bpv.getValue();
-			Throwable t = bpv.getThrown();
-			if (t != null)
-				session.onBeanGetterException(pMeta, t);
-
-			if (session.canIgnoreValue(cMeta, key, value))
-				continue;
-
-			BeanPropertyMeta bpm = bpv.getMeta();
-			Namespace ns = bpm.getExtendedMeta(RdfBeanPropertyMeta.class).getNamespace();
-			if (ns == null && session.isUseXmlNamespaces())
-				ns = bpm.getExtendedMeta(XmlBeanPropertyMeta.class).getNamespace();
-			if (ns == null)
-				ns = session.getJuneauBpNs();
-			else if (session.isAutoDetectNamespaces())
-				session.addModelPrefix(ns);
-
-			Property p = session.getModel().createProperty(ns.getUri(), session.encodeElementName(key));
-			RDFNode n = serializeAnything(session, value, pMeta.isUri(), cMeta, key, pMeta, r);
-			if (n != null)
-				r.addProperty(p, n);
-		}
-	}
-
-
-	private Container serializeToContainer(RdfSerializerSession session, Collection c, ClassMeta<?> type, Container list) throws SerializeException {
-
-		ClassMeta<?> elementType = type.getElementType();
-		for (Object e : c) {
-			RDFNode n = serializeAnything(session, e, false, elementType, null, null, null);
-			list = list.add(n);
-		}
-		return list;
-	}
-
-	private RDFList serializeToList(RdfSerializerSession session, Collection c, ClassMeta<?> type) throws SerializeException {
-		ClassMeta<?> elementType = type.getElementType();
-		List<RDFNode> l = new ArrayList<RDFNode>(c.size());
-		for (Object e : c) {
-			l.add(serializeAnything(session, e, false, elementType, null, null, null));
-		}
-		return session.getModel().createList(l.iterator());
-	}
-
-	private void serializeToMultiProperties(RdfSerializerSession session, Collection c, ClassMeta<?> sType, 
-			BeanPropertyMeta bpm, String attrName, Resource parentResource) throws SerializeException {
-		ClassMeta<?> elementType = sType.getElementType();
-		for (Object e : c) {
-			Namespace ns = null;
-			if (bpm != null) {
-				ns = bpm.getExtendedMeta(RdfBeanPropertyMeta.class).getNamespace();
-				if (ns == null && session.isUseXmlNamespaces())
-					ns = bpm.getExtendedMeta(XmlBeanPropertyMeta.class).getNamespace();
-			}
-			if (ns == null)
-				ns = session.getJuneauBpNs();
-			else if (session.isAutoDetectNamespaces())
-				session.addModelPrefix(ns);
-			RDFNode n2 = serializeAnything(session, e, false, elementType, null, null, null);
-			Property p = session.getModel().createProperty(ns.getUri(), session.encodeElementName(attrName));
-			parentResource.addProperty(p, n2);
-		}
-
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Entry point methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* Serializer */
-	public RdfSerializerSession createSession(ObjectMap op, Method javaMethod, Locale locale, 
-			TimeZone timeZone, MediaType mediaType, UriContext uriContext) {
-		return new RdfSerializerSession(ctx, op, javaMethod, locale, timeZone, mediaType, uriContext);
+	public WriterSerializerSession createSession(SerializerSessionArgs args) {
+		return new RdfSerializerSession(ctx, args);
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/2a37f310/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
index d7dabb8..3e8f1ba 100644
--- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
@@ -16,24 +16,26 @@ import static org.apache.juneau.jena.Constants.*;
 import static org.apache.juneau.jena.RdfCommonContext.*;
 import static org.apache.juneau.jena.RdfSerializerContext.*;
 
-import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.*;
-import org.apache.juneau.http.*;
+import org.apache.juneau.internal.*;
 import org.apache.juneau.msgpack.*;
 import org.apache.juneau.serializer.*;
+import org.apache.juneau.transform.*;
 import org.apache.juneau.xml.*;
 
 import com.hp.hpl.jena.rdf.model.*;
 
 /**
  * Session object that lives for the duration of a single use of {@link RdfSerializer}.
- * 
+ *
  * <p>
- * This class is NOT thread safe.  It is meant to be discarded after one-time use.
+ * This class is NOT thread safe.  
+ * It is typically discarded after one-time use although it can be reused within the same thread.
  */
-public final class RdfSerializerSession extends SerializerSession {
+@SuppressWarnings({ "rawtypes", "unchecked" })
+public final class RdfSerializerSession extends WriterSerializerSession {
 
 	private final String rdfLanguage;
 	private final Namespace juneauNs, juneauBpNs;
@@ -44,7 +46,7 @@ public final class RdfSerializerSession extends SerializerSession {
 		looseCollections,
 		autoDetectNamespaces,
 		addBeanTypeProperties;
-	private final Property pRoot, pValue, pType;
+	private final Property pRoot, pValue;
 	private final Model model;
 	private final RDFWriter writer;
 	private final RdfCollectionFormat collectionFormat;
@@ -53,32 +55,24 @@ public final class RdfSerializerSession extends SerializerSession {
 	/**
 	 * Create a new session using properties specified in the context.
 	 *
-	 * @param ctx 
+	 * @param ctx
 	 * 	The context creating this session object.
 	 * 	The context contains all the configuration settings for this object.
-	 * @param op 
-	 * 	The override properties.
-	 * 	These override any context properties defined in the context.
-	 * @param javaMethod The java method that called this serializer, usually the method in a REST servlet.
-	 * @param locale 
-	 * 	The session locale.
-	 * 	If <jk>null</jk>, then the locale defined on the context is used.
-	 * @param timeZone 
-	 * 	The session timezone.
-	 * 	If <jk>null</jk>, then the timezone defined on the context is used.
-	 * @param mediaType The session media type (e.g. <js>"application/json"</js>).
-	 * @param uriContext 
-	 * 	The URI context.
-	 * 	Identifies the current request URI used for resolution of URIs to absolute or root-relative form.
+	 * @param args
+	 * 	Runtime arguments.
+	 * 	These specify session-level information such as locale and URI context.
+	 * 	It also include session-level properties that override the properties defined on the bean and
+	 * 	serializer contexts.
+	 * 	<br>If <jk>null</jk>, defaults to {@link SerializerSessionArgs#DEFAULT}.
 	 */
-	protected RdfSerializerSession(RdfSerializerContext ctx, ObjectMap op, Method javaMethod, 
-			Locale locale, TimeZone timeZone, MediaType mediaType, UriContext uriContext) {
-		super(ctx, op, javaMethod, locale, timeZone, mediaType, uriContext);
+	protected RdfSerializerSession(RdfSerializerContext ctx, SerializerSessionArgs args) {
+		super(ctx, args);
 		ObjectMap jenaSettings = new ObjectMap();
 		jenaSettings.put("rdfXml.tab", isUseWhitespace() ? 2 : 0);
 		jenaSettings.put("rdfXml.attributeQuoteChar", Character.toString(getQuoteChar()));
 		jenaSettings.putAll(ctx.jenaSettings);
-		if (op == null || op.isEmpty()) {
+		ObjectMap p = getProperties();
+		if (p.isEmpty()) {
 			this.rdfLanguage = ctx.rdfLanguage;
 			this.juneauNs = ctx.juneauNs;
 			this.juneauBpNs = ctx.juneauBpNs;
@@ -91,22 +85,22 @@ public final class RdfSerializerSession extends SerializerSession {
 			this.namespaces = ctx.namespaces;
 			addBeanTypeProperties = ctx.addBeanTypeProperties;
 		} else {
-			this.rdfLanguage = op.getString(RDF_language, ctx.rdfLanguage);
-			this.juneauNs = (op.containsKey(RDF_juneauNs) ? NamespaceFactory.parseNamespace(op.get(RDF_juneauNs)) : ctx.juneauNs);
-			this.juneauBpNs = (op.containsKey(RDF_juneauBpNs) ? NamespaceFactory.parseNamespace(op.get(RDF_juneauBpNs)) : ctx.juneauBpNs);
-			this.addLiteralTypes = op.getBoolean(RDF_addLiteralTypes, ctx.addLiteralTypes);
-			this.addRootProperty = op.getBoolean(RDF_addRootProperty, ctx.addRootProperty);
-			for (Map.Entry<String,Object> e : op.entrySet()) {
+			this.rdfLanguage = p.getString(RDF_language, ctx.rdfLanguage);
+			this.juneauNs = (p.containsKey(RDF_juneauNs) ? NamespaceFactory.parseNamespace(p.get(RDF_juneauNs)) : ctx.juneauNs);
+			this.juneauBpNs = (p.containsKey(RDF_juneauBpNs) ? NamespaceFactory.parseNamespace(p.get(RDF_juneauBpNs)) : ctx.juneauBpNs);
+			this.addLiteralTypes = p.getBoolean(RDF_addLiteralTypes, ctx.addLiteralTypes);
+			this.addRootProperty = p.getBoolean(RDF_addRootProperty, ctx.addRootProperty);
+			for (Map.Entry<String,Object> e : p.entrySet()) {
 				String key = e.getKey();
 				if (key.startsWith("Rdf.jena."))
 					jenaSettings.put(key.substring(9), e.getValue());
 			}
-			this.collectionFormat = RdfCollectionFormat.valueOf(op.getString(RDF_collectionFormat, "DEFAULT"));
-			this.looseCollections = op.getBoolean(RDF_looseCollections, ctx.looseCollections);
-			this.useXmlNamespaces = op.getBoolean(RDF_useXmlNamespaces, ctx.useXmlNamespaces);
-			this.autoDetectNamespaces = op.getBoolean(RDF_autoDetectNamespaces, ctx.autoDetectNamespaces);
-			this.namespaces = op.get(Namespace[].class, RDF_namespaces, ctx.namespaces);
-			addBeanTypeProperties = op.getBoolean(RDF_addBeanTypeProperties, ctx.addBeanTypeProperties);
+			this.collectionFormat = RdfCollectionFormat.valueOf(p.getString(RDF_collectionFormat, "DEFAULT"));
+			this.looseCollections = p.getBoolean(RDF_looseCollections, ctx.looseCollections);
+			this.useXmlNamespaces = p.getBoolean(RDF_useXmlNamespaces, ctx.useXmlNamespaces);
+			this.autoDetectNamespaces = p.getBoolean(RDF_autoDetectNamespaces, ctx.autoDetectNamespaces);
+			this.namespaces = p.get(Namespace[].class, RDF_namespaces, ctx.namespaces);
+			addBeanTypeProperties = p.getBoolean(RDF_addBeanTypeProperties, ctx.addBeanTypeProperties);
 		}
 		this.model = ModelFactory.createDefaultModel();
 		addModelPrefix(juneauNs);
@@ -115,7 +109,6 @@ public final class RdfSerializerSession extends SerializerSession {
 			addModelPrefix(ns);
 		this.pRoot = model.createProperty(juneauNs.getUri(), RDF_juneauNs_ROOT);
 		this.pValue = model.createProperty(juneauNs.getUri(), RDF_juneauNs_VALUE);
-		this.pType = model.createProperty(juneauNs.getUri(), RDF_juneauNs_TYPE);
 		writer = model.getWriter(rdfLanguage);
 
 		// Only apply properties with this prefix!
@@ -128,172 +121,291 @@ public final class RdfSerializerSession extends SerializerSession {
 				writer.setProperty(e.getKey().substring(propPrefix.length()), e.getValue());
 	}
 
-	/**
+	/*
 	 * Adds the specified namespace as a model prefix.
-	 *
-	 * @param ns The XML namespace.
 	 */
-	public void addModelPrefix(Namespace ns) {
+	private void addModelPrefix(Namespace ns) {
 		model.setNsPrefix(ns.getName(), ns.getUri());
 	}
 
 	/**
-	 * Returns the {@link RdfCommonContext#RDF_collectionFormat} setting value for this session.
+	 * Returns the {@link MsgPackSerializerContext#MSGPACK_addBeanTypeProperties} setting value for this session.
 	 *
-	 * @return The {@link RdfCommonContext#RDF_collectionFormat} setting value for this session.
+	 * @return The {@link MsgPackSerializerContext#MSGPACK_addBeanTypeProperties} setting value for this session.
 	 */
-	public final RdfCollectionFormat getCollectionFormat() {
-		return collectionFormat;
+	@Override /* SerializerSession */
+	public final boolean isAddBeanTypeProperties() {
+		return addBeanTypeProperties;
 	}
 
-	/**
-	 * Returns the {@link RdfCommonContext#RDF_useXmlNamespaces} setting value for this session.
-	 *
-	 * @return The {@link RdfCommonContext#RDF_useXmlNamespaces} setting value for this session.
+	/*
+	 * XML-encodes the specified string using the {@link XmlUtils#escapeText(Object)} method.
 	 */
-	public final boolean isUseXmlNamespaces() {
-		return useXmlNamespaces;
+	private String encodeTextInvalidChars(Object o) {
+		if (o == null)
+			return null;
+		String s = toString(o);
+		return XmlUtils.escapeText(s);
 	}
 
-	/**
-	 * Returns the {@link RdfCommonContext#RDF_looseCollections} setting value for this session.
-	 *
-	 * @return The {@link RdfCommonContext#RDF_looseCollections} setting value for this session.
+	/*
+	 * XML-encoded the specified element name using the {@link XmlUtils#encodeElementName(Object)} method.
 	 */
-	public final boolean isLooseCollections() {
-		return looseCollections;
+	private String encodeElementName(Object o) {
+		return XmlUtils.encodeElementName(toString(o));
 	}
+	
+	@Override /* Serializer */
+	protected void doSerialize(SerializerPipe out, Object o) throws Exception {
 
-	/**
-	 * Returns the {@link RdfCommonContext#RDF_language} setting value for this session.
-	 *
-	 * @return The {@link RdfCommonContext#RDF_language} setting value for this session.
-	 */
-	public final String getRdfLanguage() {
-		return rdfLanguage;
-	}
+		Resource r = null;
 
-	/**
-	 * Returns the {@link RdfCommonContext#RDF_juneauNs} setting value for this session.
-	 *
-	 * @return The {@link RdfCommonContext#RDF_juneauNs} setting value for this session.
-	 */
-	public final Namespace getJuneauNs() {
-		return juneauNs;
-	}
+		ClassMeta<?> cm = getClassMetaForObject(o);
+		if (looseCollections && cm != null && cm.isCollectionOrArray()) {
+			Collection c = sort(cm.isCollection() ? (Collection)o : toList(cm.getInnerClass(), o));
+			for (Object o2 : c)
+				serializeAnything(o2, false, object(), "root", null, null);
+		} else {
+			RDFNode n = serializeAnything(o, false, getExpectedRootType(o), "root", null, null);
+			if (n.isLiteral()) {
+				r = model.createResource();
+				r.addProperty(pValue, n);
+			} else {
+				r = n.asResource();
+			}
 
-	/**
-	 * Returns the {@link RdfCommonContext#RDF_juneauBpNs} setting value for this session.
-	 *
-	 * @return The {@link RdfCommonContext#RDF_juneauBpNs} setting value for this session.
-	 */
-	public final Namespace getJuneauBpNs() {
-		return juneauBpNs;
-	}
+			if (addRootProperty)
+				r.addProperty(pRoot, "true");
+		}
 
-	/**
-	 * Returns the {@link RdfSerializerContext#RDF_addLiteralTypes} setting value for this session.
-	 *
-	 * @return The {@link RdfSerializerContext#RDF_addLiteralTypes} setting value for this session.
-	 */
-	public final boolean isAddLiteralTypes() {
-		return addLiteralTypes;
+		writer.write(model, out.getWriter(), "http://unknown/");
 	}
 
-	/**
-	 * Returns the {@link RdfSerializerContext#RDF_addRootProperty} setting value for this session.
-	 *
-	 * @return The {@link RdfSerializerContext#RDF_addRootProperty} setting value for this session.
-	 */
-	public final boolean isAddRootProp() {
-		return addRootProperty;
-	}
+	private RDFNode serializeAnything(Object o, boolean isURI, ClassMeta<?> eType, 
+			String attrName, BeanPropertyMeta bpm, Resource parentResource) throws SerializeException {
+		Model m = model;
 
-	/**
-	 * Returns the {@link RdfSerializerContext#RDF_autoDetectNamespaces} setting value for this session.
-	 *
-	 * @return The {@link RdfSerializerContext#RDF_autoDetectNamespaces} setting value for this session.
-	 */
-	public final boolean isAutoDetectNamespaces() {
-		return autoDetectNamespaces;
-	}
+		ClassMeta<?> aType = null;       // The actual type
+		ClassMeta<?> wType = null;       // The wrapped type
+		ClassMeta<?> sType = object();   // The serialized type
 
-	/**
-	 * Returns the {@link MsgPackSerializerContext#MSGPACK_addBeanTypeProperties} setting value for this session.
-	 *
-	 * @return The {@link MsgPackSerializerContext#MSGPACK_addBeanTypeProperties} setting value for this session.
-	 */
-	@Override /* SerializerSession */
-	public final boolean isAddBeanTypeProperties() {
-		return addBeanTypeProperties;
-	}
+		aType = push(attrName, o, eType);
 
-	/**
-	 * Returns the RDF property that identifies the root node in the RDF model.
-	 *
-	 * @return The RDF property that identifies the root node in the RDF model.
-	 */
-	public final Property getRootProp() {
-		return pRoot;
+		if (eType == null)
+			eType = object();
+
+		// Handle recursion
+		if (aType == null) {
+			o = null;
+			aType = object();
+		}
+
+		if (o != null) {
+
+			if (aType.isDelegate()) {
+				wType = aType;
+				aType = ((Delegate)o).getClassMeta();
+			}
+
+			sType = aType.getSerializedClassMeta();
+
+			// Swap if necessary
+			PojoSwap swap = aType.getPojoSwap();
+			if (swap != null) {
+				o = swap.swap(this, o);
+
+				// If the getSwapClass() method returns Object, we need to figure out
+				// the actual type now.
+				if (sType.isObject())
+					sType = getClassMetaForObject(o);
+			}
+		} else {
+			sType = eType.getSerializedClassMeta();
+		}
+
+		String typeName = getBeanTypeName(eType, aType, bpm);
+
+		RDFNode n = null;
+
+		if (o == null || sType.isChar() && ((Character)o).charValue() == 0) {
+			if (bpm != null) {
+				if (! isTrimNulls()) {
+					n = m.createResource(RDF_NIL);
+				}
+			} else {
+				n = m.createResource(RDF_NIL);
+			}
+
+		} else if (sType.isUri() || isURI) {
+			// Note that RDF URIs must be absolute to be valid!
+			String uri = getUri(o, null);
+			if (StringUtils.isAbsoluteUri(uri))
+				n = m.createResource(uri);
+			else
+				n = m.createLiteral(encodeTextInvalidChars(uri));
+
+		} else if (sType.isCharSequence() || sType.isChar()) {
+			n = m.createLiteral(encodeTextInvalidChars(o));
+
+		} else if (sType.isNumber() || sType.isBoolean()) {
+			if (! addLiteralTypes)
+				n = m.createLiteral(o.toString());
+			else
+				n = m.createTypedLiteral(o);
+
+		} else if (sType.isMap() || (wType != null && wType.isMap())) {
+			if (o instanceof BeanMap) {
+				BeanMap bm = (BeanMap)o;
+				Object uri = null;
+				RdfBeanMeta rbm = (RdfBeanMeta)bm.getMeta().getExtendedMeta(RdfBeanMeta.class);
+				if (rbm.hasBeanUri())
+					uri = rbm.getBeanUriProperty().get(bm, null);
+				String uri2 = getUri(uri, null);
+				n = m.createResource(uri2);
+				serializeBeanMap(bm, (Resource)n, typeName);
+			} else {
+				Map m2 = (Map)o;
+				n = m.createResource();
+				serializeMap(m2, (Resource)n, sType);
+			}
+
+		} else if (sType.isBean()) {
+			BeanMap bm = toBeanMap(o);
+			Object uri = null;
+			RdfBeanMeta rbm = (RdfBeanMeta)bm.getMeta().getExtendedMeta(RdfBeanMeta.class);
+			if (rbm.hasBeanUri())
+				uri = rbm.getBeanUriProperty().get(bm, null);
+			String uri2 = getUri(uri, null);
+			n = m.createResource(uri2);
+			serializeBeanMap(bm, (Resource)n, typeName);
+
+		} else if (sType.isCollectionOrArray() || (wType != null && wType.isCollection())) {
+			Collection c = sort(sType.isCollection() ? (Collection)o : toList(sType.getInnerClass(), o));
+			RdfCollectionFormat f = collectionFormat;
+			RdfClassMeta rcm = sType.getExtendedMeta(RdfClassMeta.class);
+			if (rcm.getCollectionFormat() != RdfCollectionFormat.DEFAULT)
+				f = rcm.getCollectionFormat();
+			if (bpm != null && bpm.getExtendedMeta(RdfBeanPropertyMeta.class).getCollectionFormat() != RdfCollectionFormat.DEFAULT)
+				f = bpm.getExtendedMeta(RdfBeanPropertyMeta.class).getCollectionFormat();
+			switch (f) {
+				case BAG: n = serializeToContainer(c, eType, m.createBag()); break;
+				case LIST: n = serializeToList(c, eType); break;
+				case MULTI_VALUED: serializeToMultiProperties(c, eType, bpm, attrName, parentResource); break;
+				default: n = serializeToContainer(c, eType, m.createSeq());
+			}
+		} else {
+			n = m.createLiteral(encodeTextInvalidChars(toString(o)));
+		}
+
+		pop();
+
+		return n;
 	}
 
-	/**
-	 * Returns the RDF property that represents a value in the RDF model.
-	 *
-	 * @return The RDF property that represents a value in the RDF model.
-	 */
-	public final Property getValueProperty() {
-		return pValue;
+	private String getUri(Object uri, Object uri2) {
+		String s = null;
+		if (uri != null)
+			s = uri.toString();
+		if ((s == null || s.isEmpty()) && uri2 != null)
+			s = uri2.toString();
+		if (s == null)
+			return null;
+		return getUriResolver().resolve(s);
 	}
 
-	/**
-	 * Returns the RDF property that represents a class in the RDF model.
-	 *
-	 * @return The RDF property that represents a class in the RDF model.
-	 */
-	public final Property getTypeProperty() {
-		return pType;
+	private void serializeMap(Map m, Resource r, ClassMeta<?> type) throws SerializeException {
+
+		m = sort(m);
+
+		ClassMeta<?> keyType = type.getKeyType(), valueType = type.getValueType();
+
+		ArrayList<Map.Entry<Object,Object>> l = new ArrayList<Map.Entry<Object,Object>>(m.entrySet());
+		Collections.reverse(l);
+		for (Map.Entry<Object,Object> me : l) {
+			Object value = me.getValue();
+
+			Object key = generalize(me.getKey(), keyType);
+
+			Namespace ns = juneauBpNs;
+			Property p = model.createProperty(ns.getUri(), encodeElementName(toString(key)));
+			RDFNode n = serializeAnything(value, false, valueType, key == null ? null : toString(key), null, r);
+			if (n != null)
+				r.addProperty(p, n);
+		}
 	}
 
-	/**
-	 * Returns the RDF model being serialized.
-	 *
-	 * @return The RDF model being serialized.
-	 */
-	public final Model getModel() {
-		return model;
+	private void serializeBeanMap(BeanMap<?> m, Resource r, String typeName) throws SerializeException {
+		List<BeanPropertyValue> l = m.getValues(isTrimNulls(), typeName != null ? createBeanTypeNameProperty(m, typeName) : null);
+		Collections.reverse(l);
+		for (BeanPropertyValue bpv : l) {
+			BeanPropertyMeta pMeta = bpv.getMeta();
+			ClassMeta<?> cMeta = pMeta.getClassMeta();
+
+			if (pMeta.getExtendedMeta(RdfBeanPropertyMeta.class).isBeanUri())
+				continue;
+
+			String key = bpv.getName();
+			Object value = bpv.getValue();
+			Throwable t = bpv.getThrown();
+			if (t != null)
+				onBeanGetterException(pMeta, t);
+
+			if (canIgnoreValue(cMeta, key, value))
+				continue;
+
+			BeanPropertyMeta bpm = bpv.getMeta();
+			Namespace ns = bpm.getExtendedMeta(RdfBeanPropertyMeta.class).getNamespace();
+			if (ns == null && useXmlNamespaces)
+				ns = bpm.getExtendedMeta(XmlBeanPropertyMeta.class).getNamespace();
+			if (ns == null)
+				ns = juneauBpNs;
+			else if (autoDetectNamespaces)
+				addModelPrefix(ns);
+
+			Property p = model.createProperty(ns.getUri(), encodeElementName(key));
+			RDFNode n = serializeAnything(value, pMeta.isUri(), cMeta, key, pMeta, r);
+			if (n != null)
+				r.addProperty(p, n);
+		}
 	}
 
-	/**
-	 * Returns the RDF writer that's being serialized to.
-	 *
-	 * @return The RDF writer that's being serialized to.
-	 */
-	public final RDFWriter getRdfWriter() {
-		return writer;
+
+	private Container serializeToContainer(Collection c, ClassMeta<?> type, Container list) throws SerializeException {
+
+		ClassMeta<?> elementType = type.getElementType();
+		for (Object e : c) {
+			RDFNode n = serializeAnything(e, false, elementType, null, null, null);
+			list = list.add(n);
+		}
+		return list;
 	}
 
-	/**
-	 * XML-encodes the specified string using the {@link XmlUtils#escapeText(Object)} method.
-	 *
-	 * @param o The string being encoded.
-	 * @return The encoded string, or <jk>null</jk> if the input was <jk>null</jk>.
-	 */
-	public final String encodeTextInvalidChars(Object o) {
-		if (o == null)
-			return null;
-		String s = toString(o);
-		return XmlUtils.escapeText(s);
+	private RDFList serializeToList(Collection c, ClassMeta<?> type) throws SerializeException {
+		ClassMeta<?> elementType = type.getElementType();
+		List<RDFNode> l = new ArrayList<RDFNode>(c.size());
+		for (Object e : c) {
+			l.add(serializeAnything(e, false, elementType, null, null, null));
+		}
+		return model.createList(l.iterator());
 	}
 
-	/**
-	 * XML-encoded the specified element name using the {@link XmlUtils#encodeElementName(Object)} method.
-	 *
-	 * @param o The string being encoded.
-	 * @return The encoded string.
-	 */
-	public final String encodeElementName(Object o) {
-		String s = toString(o);
-		return XmlUtils.encodeElementName(s);
+	private void serializeToMultiProperties(Collection c, ClassMeta<?> sType, 
+			BeanPropertyMeta bpm, String attrName, Resource parentResource) throws SerializeException {
+		ClassMeta<?> elementType = sType.getElementType();
+		for (Object e : c) {
+			Namespace ns = null;
+			if (bpm != null) {
+				ns = bpm.getExtendedMeta(RdfBeanPropertyMeta.class).getNamespace();
+				if (ns == null && useXmlNamespaces)
+					ns = bpm.getExtendedMeta(XmlBeanPropertyMeta.class).getNamespace();
+			}
+			if (ns == null)
+				ns = juneauBpNs;
+			else if (autoDetectNamespaces)
+				addModelPrefix(ns);
+			RDFNode n2 = serializeAnything(e, false, elementType, null, null, null);
+			Property p = model.createProperty(ns.getUri(), encodeElementName(attrName));
+			parentResource.addProperty(p, n2);
+		}
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/2a37f310/juneau-core-test/src/test/java/org/apache/juneau/ParserReaderTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/ParserReaderTest.java b/juneau-core-test/src/test/java/org/apache/juneau/ParserReaderTest.java
index 82be1ac..49a8918 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/ParserReaderTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/ParserReaderTest.java
@@ -30,25 +30,25 @@ public class ParserReaderTest {
 		String t = "01234567890123456789012345678901234567890123456789";
 
 		// Min buff size is 20.
-		ParserReader pr = new ParserReader(new StringReader(t));
+		ParserReader pr = createParserReader(t);
 		String r = read(pr);
 		assertEquals(t, r);
 		pr.close();
 
-		pr = new ParserReader(new StringReader(t));
+		pr = createParserReader(t);
 		pr.read();
 		pr.unread();
 		r = read(pr);
 		assertEquals(t, r);
 		pr.close();
 
-		pr = new ParserReader(new StringReader(t));
+		pr = createParserReader(t);
 		assertEquals('0', (char)pr.peek());
 		assertEquals('0', (char)pr.peek());
 		r = read(pr);
 		assertEquals(t, r);
 
-		pr = new ParserReader(new StringReader(t));
+		pr = createParserReader(t);
 		pr.read();
 		pr.unread();
 		try {
@@ -68,7 +68,7 @@ public class ParserReaderTest {
 		String r = null;
 
 		// Min buff size is 20.
-		ParserReader pr = new ParserReader(t);
+		ParserReader pr = createParserReader(t);
 		read(pr, 5);
 		pr.mark();
 		read(pr, 10);
@@ -78,7 +78,7 @@ public class ParserReaderTest {
 		assertEquals("56789c123456789d123456789e123456789f123456789g123456789h123456789i123456789j123456789", r);
 
 		// Force doubling of buffer size
-		pr = new ParserReader(t);
+		pr =createParserReader(t);
 		read(pr, 5);
 		pr.mark();
 		read(pr, 20);
@@ -96,7 +96,7 @@ public class ParserReaderTest {
 		String t = "a123456789b123456789c123456789d123456789e123456789f123456789g123456789h123456789i123456789j123456789";
 
 		// Min buff size is 20.
-		ParserReader pr = new ParserReader(t);
+		ParserReader pr = createParserReader(t);
 		assertEquals("a123456789", pr.read(10));
 		pr.mark();
 		assertEquals("b123456789c123456789", pr.read(20));
@@ -115,7 +115,7 @@ public class ParserReaderTest {
 		String t = "a123456789b123456789c123456789d123456789e123456789f123456789g123456789h123456789i123456789j123456789";
 
 		// Min buff size is 20.
-		ParserReader pr = new ParserReader(t);
+		ParserReader pr = createParserReader(t);
 		assertEquals("a123456789", pr.read(10));
 		pr.mark();
 		assertEquals("b123456789", pr.read(10));
@@ -124,7 +124,7 @@ public class ParserReaderTest {
 		assertEquals("b12345678xc123456789", pr.getMarked());
 		pr.close();
 
-		pr = new ParserReader(t);
+		pr = createParserReader(t);
 		assertEquals("a123456789", pr.read(10));
 		pr.mark();
 		assertEquals("b123456789", pr.read(10));
@@ -142,7 +142,7 @@ public class ParserReaderTest {
 		String t = "a123456789b123456789c123456789d123456789e123456789f123456789g123456789h123456789i123456789j123456789";
 
 		// Min buff size is 20.
-		ParserReader pr = new ParserReader(t);
+		ParserReader pr = createParserReader(t);
 		assertEquals("a123456789", pr.read(10));
 		pr.mark();
 		assertEquals("b123456789", pr.read(10));
@@ -151,7 +151,7 @@ public class ParserReaderTest {
 		assertEquals("b12345678c123456789", pr.getMarked());
 		pr.close();
 
-		pr = new ParserReader(t);
+		pr = createParserReader(t);
 		assertEquals("a123456789", pr.read(10));
 		pr.mark();
 		assertEquals("b123456789", pr.read(10));
@@ -179,4 +179,8 @@ public class ParserReaderTest {
 		}
 		return sb.toString();
 	}
+
+	private ParserReader createParserReader(Object in) throws Exception {
+		return new ParserReader(new ParserPipe(in, false, false, null, null));
+	}
 }