http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
new file mode 100644
index 0000000..267d06f
--- /dev/null
+++ 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
@@ -0,0 +1,434 @@
+// 
***************************************************************************************************************************
+// * 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.internal.StringUtils.*;
+import static org.apache.juneau.jena.Constants.*;
+import static org.apache.juneau.jena.RdfCommonContext.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+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 typically discarded after one-time use although it can be reused 
against multiple inputs.
+ */
+@SuppressWarnings({"unchecked", "rawtypes"})
+public class RdfParserSession extends ReaderParserSession {
+
+       private final String rdfLanguage;
+       private final Namespace juneauNs, juneauBpNs;
+       private final Property pRoot, pValue, pType, pRdfType;
+       private final Model model;
+       private final boolean trimWhitespace, looseCollections;
+       private final RDFReader rdfReader;
+       private final Set<Resource> urisVisited = new HashSet<Resource>();
+       private final RdfCollectionFormat collectionFormat;
+
+       /**
+        * Create a new session using properties specified in the context.
+        *
+        * @param ctx
+        *      The context creating this session object.
+        *      The context contains all the configuration settings for this 
object.
+        * @param args
+        *      Runtime session arguments.
+        */
+       protected RdfParserSession(RdfParserContext ctx, ParserSessionArgs 
args) {
+               super(ctx, args);
+               ObjectMap jenaSettings = new ObjectMap();
+               jenaSettings.putAll(ctx.jenaSettings);
+               ObjectMap p = getProperties();
+               if (p.isEmpty()) {
+                       this.rdfLanguage = ctx.rdfLanguage;
+                       this.juneauNs = ctx.juneauNs;
+                       this.juneauBpNs = ctx.juneauBpNs;
+                       this.trimWhitespace = ctx.trimWhitespace;
+                       this.collectionFormat = ctx.collectionFormat;
+                       this.looseCollections = ctx.looseCollections;
+               } else {
+                       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);
+               addModelPrefix(juneauBpNs);
+               this.pRoot = model.createProperty(juneauNs.getUri(), 
RDF_juneauNs_ROOT);
+               this.pValue = model.createProperty(juneauNs.getUri(), 
RDF_juneauNs_VALUE);
+               this.pType = model.createProperty(juneauBpNs.getUri(), 
RDF_juneauNs_TYPE);
+               this.pRdfType = 
model.createProperty("http://www.w3.org/1999/02/22-rdf-syntax-ns#type";);
+               rdfReader = model.getReader(rdfLanguage);
+
+               // Note: NTripleReader throws an exception if you try to set 
any properties on it.
+               if (! rdfLanguage.equals(LANG_NTRIPLE)) {
+                       for (Map.Entry<String,Object> e : 
jenaSettings.entrySet())
+                               rdfReader.setProperty(e.getKey(), e.getValue());
+               }
+       }
+
+       @Override /* ReaderParserSession */
+       protected <T> T doParse(ParserPipe pipe, ClassMeta<T> type) throws 
Exception {
+
+               RDFReader r = rdfReader;
+               r.read(model, pipe.getBufferedReader(), null);
+
+               List<Resource> roots = getRoots(model);
+
+               // 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)
+                               );
+
+                       int argIndex = 0;
+                       for (Resource resource : roots)
+                               c.add(parseAnything(type.isArgs() ? 
type.getArg(argIndex++) : type.getElementType(), resource, 
+                                       getOuter(), null));
+
+                       if (type.isArray() || type.isArgs())
+                               return (T)toArray(type, c);
+                       return (T)c;
+               }
+
+               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);
+
+               return parseAnything(type, resource, getOuter(), null);
+       }
+
+       private final void addModelPrefix(Namespace ns) {
+               model.setNsPrefix(ns.getName(), ns.getUri());
+       }
+
+       /*
+        * Decodes the specified string.
+        * If {@link RdfParserContext#RDF_trimWhitespace} is <jk>true</jk>, the 
resulting string is trimmed before decoding.
+        * If {@link #isTrimStrings()} is <jk>true</jk>, the resulting string 
is trimmed after decoding.
+        */
+       private String decodeString(Object o) {
+               if (o == null)
+                       return null;
+               String s = o.toString();
+               if (s.isEmpty())
+                       return s;
+               if (trimWhitespace)
+                       s = s.trim();
+               s = XmlUtils.decode(s, null);
+               if (isTrimStrings())
+                       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/75b0d8ee/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
new file mode 100644
index 0000000..b574186
--- /dev/null
+++ 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
@@ -0,0 +1,165 @@
+// 
***************************************************************************************************************************
+// * 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.jena.Constants.*;
+import static org.apache.juneau.jena.RdfCommonContext.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.serializer.*;
+
+/**
+ * Serializes POJOs to RDF.
+ *
+ * <h5 class='section'>Configurable properties:</h5>
+ * 
+ * Refer to <a class="doclink" 
href="package-summary.html#SerializerConfigurableProperties">Configurable 
Properties</a>
+ *     for the entire list of configurable properties.
+ *
+ * <h6 class='topic'>Behavior-specific subclasses</h6>
+ * 
+ * The following direct subclasses are provided for language-specific 
serializers:
+ * <ul>
+ *     <li>{@link RdfSerializer.Xml} - RDF/XML.
+ *     <li>{@link RdfSerializer.XmlAbbrev} - RDF/XML-ABBREV.
+ *     <li>{@link RdfSerializer.NTriple} - N-TRIPLE.
+ *     <li>{@link RdfSerializer.Turtle} - TURTLE.
+ *     <li>{@link RdfSerializer.N3} - N3.
+ * </ul>
+ *
+ * <h5 class='section'>Additional information:</h5>
+ * 
+ * See <a class="doclink" href="package-summary.html#TOC">RDF Overview</a> for 
an overview of RDF support in Juneau.
+ */
+public class RdfSerializer extends WriterSerializer {
+
+       /** Default RDF/XML serializer, all default settings.*/
+       public static final RdfSerializer DEFAULT_XML = new 
Xml(PropertyStore.create());
+
+       /** Default Abbreviated RDF/XML serializer, all default settings.*/
+       public static final RdfSerializer DEFAULT_XMLABBREV = new 
XmlAbbrev(PropertyStore.create());
+
+       /** Default Turtle serializer, all default settings.*/
+       public static final RdfSerializer DEFAULT_TURTLE = new 
Turtle(PropertyStore.create());
+
+       /** Default N-Triple serializer, all default settings.*/
+       public static final RdfSerializer DEFAULT_NTRIPLE = new 
NTriple(PropertyStore.create());
+
+       /** Default N3 serializer, all default settings.*/
+       public static final RdfSerializer DEFAULT_N3 = new 
N3(PropertyStore.create());
+
+
+       /** Produces RDF/XML output */
+       public static class Xml extends RdfSerializer {
+
+               /**
+                * Constructor.
+                * 
+                * @param propertyStore The property store containing all the 
settings for this object.
+                */
+               public Xml(PropertyStore propertyStore) {
+                       super(propertyStore.copy().append(RDF_language, 
LANG_RDF_XML), "text/xml+rdf");
+               }
+       }
+
+       /** Produces Abbreviated RDF/XML output */
+       public static class XmlAbbrev extends RdfSerializer {
+
+               /**
+                * Constructor.
+                * 
+                * @param propertyStore The property store containing all the 
settings for this object.
+                */
+               public XmlAbbrev(PropertyStore propertyStore) {
+                       super(propertyStore.copy().append(RDF_language, 
LANG_RDF_XML_ABBREV), "text/xml+rdf", "text/xml+rdf+abbrev");
+               }
+       }
+
+       /** Produces N-Triple output */
+       public static class NTriple extends RdfSerializer {
+
+               /**
+                * Constructor.
+                * 
+                * @param propertyStore The property store containing all the 
settings for this object.
+                */
+               public NTriple(PropertyStore propertyStore) {
+                       super(propertyStore.copy().append(RDF_language, 
LANG_NTRIPLE), "text/n-triple");
+               }
+       }
+
+       /** Produces Turtle output */
+       public static class Turtle extends RdfSerializer {
+
+               /**
+                * Constructor.
+                * 
+                * @param propertyStore The property store containing all the 
settings for this object.
+                */
+               public Turtle(PropertyStore propertyStore) {
+                       super(propertyStore.copy().append(RDF_language, 
LANG_TURTLE), "text/turtle");
+               }
+       }
+
+       /** Produces N3 output */
+       public static class N3 extends RdfSerializer {
+
+               /**
+                * Constructor.
+                * 
+                * @param propertyStore The property store containing all the 
settings for this object.
+                */
+               public N3(PropertyStore propertyStore) {
+                       super(propertyStore.copy().append(RDF_language, 
LANG_N3), "text/n3");
+               }
+       }
+
+
+       private final RdfSerializerContext ctx;
+
+       /**
+        * Constructor.
+        *
+        * @param propertyStore
+        *      The property store containing all the settings for this object.
+        * @param produces
+        *      The media type that this serializer produces.
+        * @param accept
+        *      The accept media types that the serializer can handle.
+        *      <p>
+        *      Can contain meta-characters per the <code>media-type</code> 
specification of
+        *      <a class="doclink" 
href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1";>RFC2616/14.1</a>
+        *      <p>
+        *      If empty, then assumes the only media type supported is 
<code>produces</code>.
+        *      <p>
+        *      For example, if this serializer produces 
<js>"application/json"</js> but should handle media types of
+        *      <js>"application/json"</js> and <js>"text/json"</js>, then the 
arguments should be:
+        *      <br><code><jk>super</jk>(propertyStore, 
<js>"application/json"</js>, <js>"application/json"</js>, 
<js>"text/json"</js>);</code>
+        *      <br>...or...
+        *      <br><code><jk>super</jk>(propertyStore, 
<js>"application/json"</js>, <js>"*&#8203;/json"</js>);</code>
+        */
+       public RdfSerializer(PropertyStore propertyStore, String produces, 
String...accept) {
+               super(propertyStore, produces, accept);
+               this.ctx = createContext(RdfSerializerContext.class);
+       }
+
+       @Override /* CoreObject */
+       public RdfSerializerBuilder builder() {
+               return new RdfSerializerBuilder(propertyStore);
+       }
+
+       @Override /* Serializer */
+       public WriterSerializerSession createSession(SerializerSessionArgs 
args) {
+               return new RdfSerializerSession(ctx, args);
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java
 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java
new file mode 100644
index 0000000..59b15c5
--- /dev/null
+++ 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java
@@ -0,0 +1,978 @@
+// 
***************************************************************************************************************************
+// * 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.jena.RdfCommonContext.*;
+import static org.apache.juneau.jena.RdfSerializerContext.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.http.*;
+import org.apache.juneau.jena.annotation.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.xml.*;
+import org.apache.juneau.xml.annotation.*;
+
+/**
+ * Builder class for building instances of RDF serializers.
+ */
+public class RdfSerializerBuilder extends SerializerBuilder {
+
+       /**
+        * Constructor, default settings.
+        */
+       public RdfSerializerBuilder() {
+               super();
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param propertyStore The initial configuration settings for this 
builder.
+        */
+       public RdfSerializerBuilder(PropertyStore propertyStore) {
+               super(propertyStore);
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializer build() {
+               return new RdfSerializer(propertyStore, "text/xml+rdf");
+       }
+
+
+       
//--------------------------------------------------------------------------------
+       // Properties
+       
//--------------------------------------------------------------------------------
+
+       /**
+        * <b>Configuration property:</b>  RDF language.
+        * 
+        * <ul>
+        *      <li><b>Name:</b> <js>"Rdf.language"</js>
+        *      <li><b>Data type:</b> <code>String</code>
+        *      <li><b>Default:</b> <js>"RDF/XML-ABBREV"</js>
+        * </ul>
+        * 
+        * <p>
+        * Can be any of the following:
+        * <ul class='spaced-list'>
+        *      <li>
+        *              <js>"RDF/XML"</js>
+        *      <li>
+        *              <js>"RDF/XML-ABBREV"</js>
+        *      <li>
+        *              <js>"N-TRIPLE"</js>
+        *      <li>
+        *              <js>"N3"</js> - General name for the N3 writer.
+        *              Will make a decision on exactly which writer to use 
(pretty writer, plain writer or simple writer) when 
+        *              created.
+        *              Default is the pretty writer but can be overridden with 
system property 
+        *              <code>com.hp.hpl.jena.n3.N3JenaWriter.writer</code>.
+        *      <li>
+        *              <js>"N3-PP"</js> - Name of the N3 pretty writer.
+        *              The pretty writer uses a frame-like layout, with 
prefixing, clustering like properties and embedding 
+        *              one-referenced bNodes.
+        *      <li>
+        *              <js>"N3-PLAIN"</js> - Name of the N3 plain writer.
+        *              The plain writer writes records by subject.
+        *      <li>
+        *              <js>"N3-TRIPLES"</js> - Name of the N3 triples writer.
+        *              This writer writes one line per statement, like 
N-Triples, but does N3-style prefixing.
+        *      <li>
+        *              <js>"TURTLE"</js> -  Turtle writer.
+        *              http://www.dajobe.org/2004/01/turtle/
+        * </ul>
+        * 
+        * <h5 class='section'>Notes:</h5>
+        * <ul>
+        *      <li>This is equivalent to calling 
<code>property(<jsf>RDF_language</jsf>, value)</code>.
+        *      <li>This introduces a slight performance penalty.
+        * </ul>
+        *
+        * @param value The new value for this property.
+        * @return This object (for method chaining).
+        * @see RdfCommonContext#RDF_language
+        */
+       public RdfSerializerBuilder language(String value) {
+               return property(RDF_language, value);
+       }
+
+       /**
+        * Shortcut for calling <code>language(<jsf>LANG_RDF_XML</jsf>)</code>
+        * 
+        * @return This object (for method chaining).
+        */
+       public RdfSerializerBuilder xml() {
+               return language(Constants.LANG_RDF_XML);
+       }
+
+       /**
+        * Shortcut for calling 
<code>language(<jsf>LANG_RDF_XML_ABBREV</jsf>)</code>
+        * 
+        * @return This object (for method chaining).
+        */
+       public RdfSerializerBuilder xmlabbrev() {
+               return language(Constants.LANG_RDF_XML_ABBREV);
+       }
+
+       /**
+        * Shortcut for calling <code>language(<jsf>LANG_NTRIPLE</jsf>)</code>
+        * 
+        * @return This object (for method chaining).
+        */
+       public RdfSerializerBuilder ntriple() {
+               return language(Constants.LANG_NTRIPLE);
+       }
+
+       /**
+        * Shortcut for calling <code>language(<jsf>LANG_N3</jsf>)</code>
+        * 
+        * @return This object (for method chaining).
+        */
+       public RdfSerializerBuilder n3() {
+               return language(Constants.LANG_N3);
+       }
+
+       /**
+        * Shortcut for calling <code>language(<jsf>LANG_TURTLE</jsf>)</code>
+        * 
+        * @return This object (for method chaining).
+        */
+       public RdfSerializerBuilder turtle() {
+               return language(Constants.LANG_TURTLE);
+       }
+
+       /**
+        * <b>Configuration property:</b>  XML namespace for Juneau properties.
+        * 
+        * <ul>
+        *      <li><b>Name:</b> <js>"Rdf.juneauNs"</js>
+        *      <li><b>Data type:</b> {@link Namespace}
+        *      <li><b>Default:</b> 
<code>{j:<js>'http://www.apache.org/juneau/'</js>}</code>
+        * </ul>
+        * 
+        * <h5 class='section'>Notes:</h5>
+        * <ul>
+        *      <li>This is equivalent to calling 
<code>property(<jsf>RDF_juneauNs</jsf>, value)</code>.
+        *      <li>This introduces a slight performance penalty.
+        * </ul>
+        *
+        * @param value The new value for this property.
+        * @return This object (for method chaining).
+        * @see RdfSerializerContext#RDF_juneauNs
+        */
+       public RdfSerializerBuilder juneauNs(Namespace value) {
+               return property(RDF_juneauNs, value);
+       }
+
+       /**
+        * <b>Configuration property:</b>  Default XML namespace for bean 
properties.
+        * 
+        * <ul>
+        *      <li><b>Name:</b> <js>"Rdf.juneauBpNs"</js>
+        *      <li><b>Data type:</b> {@link Namespace}
+        *      <li><b>Default:</b> 
<code>{j:<js>'http://www.apache.org/juneaubp/'</js>}</code>
+        * </ul>
+        * 
+        * <h5 class='section'>Notes:</h5>
+        * <ul>
+        *      <li>This is equivalent to calling 
<code>property(<jsf>RDF_juneauBpNs</jsf>, value)</code>.
+        *      <li>This introduces a slight performance penalty.
+        * </ul>
+        *
+        * @param value The new value for this property.
+        * @return This object (for method chaining).
+        * @see RdfSerializerContext#RDF_juneauBpNs
+        */
+       public RdfSerializerBuilder juneauBpNs(Namespace value) {
+               return property(RDF_juneauBpNs, value);
+       }
+
+       /**
+        * <b>Configuration property:</b>  Reuse XML namespaces when RDF 
namespaces not specified.
+        * 
+        * <ul>
+        *      <li><b>Name:</b> <js>"Rdf.useXmlNamespaces"</js>
+        *      <li><b>Data type:</b> <code>Boolean</code>
+        *      <li><b>Default:</b> <jk>true</jk>
+        * </ul>
+        * 
+        * <p>
+        * When specified, namespaces defined using {@link XmlNs} and {@link 
Xml} will be inherited by the RDF serializers.
+        * Otherwise, namespaces will be defined using {@link RdfNs} and {@link 
Rdf}.
+        * 
+        * <h5 class='section'>Notes:</h5>
+        * <ul>
+        *      <li>This is equivalent to calling 
<code>property(<jsf>RDF_useXmlNamespaces</jsf>, value)</code>.
+        *      <li>This introduces a slight performance penalty.
+        * </ul>
+        *
+        * @param value The new value for this property.
+        * @return This object (for method chaining).
+        * @see SerializerContext#SERIALIZER_sortMaps
+        */
+       public RdfSerializerBuilder useXmlNamespaces(boolean value) {
+               return property(RDF_useXmlNamespaces, value);
+       }
+
+       /**
+        * <b>Configuration property:</b>  Add XSI data types to 
non-<code>String</code> literals.
+        * 
+        * <ul>
+        *      <li><b>Name:</b> <js>"RdfSerializer.addLiteralTypes"</js>
+        *      <li><b>Data type:</b> <code>Boolean</code>
+        *      <li><b>Default:</b> <jk>false</jk>
+        *      <li><b>Session-overridable:</b> <jk>true</jk>
+        * </ul>
+        * 
+        * <h5 class='section'>Notes:</h5>
+        * <ul>
+        *      <li>This is equivalent to calling 
<code>property(<jsf>RDF_addLiteralTypes</jsf>, value)</code>.
+        *      <li>This introduces a slight performance penalty.
+        * </ul>
+        *
+        * @param value The new value for this property.
+        * @return This object (for method chaining).
+        * @see RdfSerializerContext#RDF_addLiteralTypes
+        */
+       public RdfSerializerBuilder addLiteralTypes(boolean value) {
+               return property(RDF_addLiteralTypes, value);
+       }
+
+       /**
+        * <b>Configuration property:</b>  Add RDF root identifier property to 
root node.
+        * 
+        * <ul>
+        *      <li><b>Name:</b> <js>"RdfSerializer.addRootProperty"</js>
+        *      <li><b>Data type:</b> <code>Boolean</code>
+        *      <li><b>Default:</b> <jk>false</jk>
+        *      <li><b>Session-overridable:</b> <jk>true</jk>
+        * </ul>
+        * 
+        * <p>
+        * When enabled an RDF property 
<code>http://www.apache.org/juneau/root</code> is added with a value of 
+        * <js>"true"</js> to identify the root node in the graph.
+        * This helps locate the root node during parsing.
+        * 
+        * <p>
+        * If disabled, the parser has to search through the model to find any 
resources without incoming predicates to 
+        * identify root notes, which can introduce a considerable performance 
degradation.
+        * 
+        * <h5 class='section'>Notes:</h5>
+        * <ul>
+        *      <li>This is equivalent to calling 
<code>property(<jsf>RDF_addRootProperty</jsf>, value)</code>.
+        *      <li>This introduces a slight performance penalty.
+        * </ul>
+        *
+        * @param value The new value for this property.
+        * @return This object (for method chaining).
+        * @see RdfSerializerContext#RDF_addRootProperty
+        */
+       public RdfSerializerBuilder addRootProperty(boolean value) {
+               return property(RDF_addRootProperty, value);
+       }
+
+       /**
+        * <b>Configuration property:</b>  Auto-detect namespace usage.
+        * 
+        * <ul>
+        *      <li><b>Name:</b> <js>"RdfSerializer.autoDetectNamespaces"</js>
+        *      <li><b>Data type:</b> <code>Boolean</code>
+        *      <li><b>Default:</b> <jk>true</jk>
+        *      <li><b>Session-overridable:</b> <jk>true</jk>
+        * </ul>
+        * 
+        * <p>
+        * Detect namespace usage before serialization.
+        * 
+        * <p>
+        * If enabled, then the data structure will first be crawled looking 
for namespaces that will be encountered before 
+        * the root element is serialized.
+        * 
+        * <h5 class='section'>Notes:</h5>
+        * <ul>
+        *      <li>This is equivalent to calling 
<code>property(<jsf>RDF_autoDetectNamespaces</jsf>, value)</code>.
+        *      <li>This introduces a slight performance penalty.
+        * </ul>
+        *
+        * @param value The new value for this property.
+        * @return This object (for method chaining).
+        * @see RdfSerializerContext#RDF_autoDetectNamespaces
+        */
+       public RdfSerializerBuilder autoDetectNamespaces(boolean value) {
+               return property(RDF_autoDetectNamespaces, value);
+       }
+
+       /**
+        * <b>Configuration property:</b>  Default namespaces.
+        * 
+        * <ul>
+        *      <li><b>Name:</b> <js>"RdfSerializer.namespaces.list"</js>
+        *      <li><b>Data type:</b> <code>List&lt;{@link Namespace}&gt;</code>
+        *      <li><b>Default:</b> empty list
+        *      <li><b>Session-overridable:</b> <jk>true</jk>
+        * </ul>
+        * 
+        * <p>
+        * The default list of namespaces associated with this serializer.
+        * 
+        * <h5 class='section'>Notes:</h5>
+        * <ul>
+        *      <li>This is equivalent to calling 
<code>property(<jsf>RDF_namespaces</jsf>, values)</code>.
+        *      <li>This introduces a slight performance penalty.
+        * </ul>
+        *
+        * @param values The new value for this property.
+        * @return This object (for method chaining).
+        * @see RdfSerializerContext#RDF_namespaces
+        */
+       public RdfSerializerBuilder namespaces(Namespace...values) {
+               return property(RDF_namespaces, values);
+       }
+
+       /**
+        * <b>Configuration property:</b>  RDF format for representing 
collections and arrays.
+        * 
+        * <ul>
+        *      <li><b>Name:</b> <js>"Rdf.collectionFormat"</js>
+        *      <li><b>Data type:</b> <code>RdfCollectionFormat</code>
+        *      <li><b>Default:</b> <js>"DEFAULT"</js>
+        * </ul>
+        * 
+        * <p>
+        * Possible values:
+        * <ul class='spaced-list'>
+        *      <li>
+        *              <js>"DEFAULT"</js> - Default format.  The default is an 
RDF Sequence container.
+        *      <li>
+        *              <js>"SEQ"</js> - RDF Sequence container.
+        *      <li>
+        *              <js>"BAG"</js> - RDF Bag container.
+        *      <li>
+        *              <js>"LIST"</js> - RDF List container.
+        *      <li>
+        *              <js>"MULTI_VALUED"</js> - Multi-valued properties.
+        * </ul>
+        * 
+        * <h5 class='section'>Notes:</h5>
+        * <ul>
+        *      <li>If you use <js>"BAG"</js> or <js>"MULTI_VALUED"</js>, the 
order of the elements in the collection will get 
+        *              lost.
+        * </ul>
+        * 
+        * <h5 class='section'>Notes:</h5>
+        * <ul>
+        *      <li>This is equivalent to calling 
<code>property(<jsf>RDF_collectionFormat</jsf>, value)</code>.
+        *      <li>This introduces a slight performance penalty.
+        * </ul>
+        *
+        * @param value The new value for this property.
+        * @return This object (for method chaining).
+        * @see RdfCommonContext#RDF_collectionFormat
+        */
+       public RdfSerializerBuilder collectionFormat(RdfCollectionFormat value) 
{
+               return property(RDF_collectionFormat, value);
+       }
+
+       /**
+        * <b>Configuration property:</b>  Collections should be serialized and 
parsed as loose collections.
+        * 
+        * <ul>
+        *      <li><b>Name:</b> <js>"Rdf.looseCollections"</js>
+        *      <li><b>Data type:</b> <code>Boolean</code>
+        *      <li><b>Default:</b> <jk>false</jk>
+        * </ul>
+        * 
+        * <p>
+        * When specified, collections of resources are handled as loose 
collections of resources in RDF instead of
+        * resources that are children of an RDF collection (e.g. Sequence, 
Bag).
+        * 
+        * <p>
+        * Note that this setting is specialized for RDF syntax, and is 
incompatible with the concept of
+        * losslessly representing POJO models, since the tree structure of 
these POJO models are lost
+        * when serialized as loose collections.
+        * 
+        * <p>
+        * This setting is typically only useful if the beans being parsed into 
do not have a bean property
+        * annotated with {@link Rdf#beanUri @Rdf(beanUri=true)}.
+        *
+        * <h5 class='section'>Example:</h5>
+        * <p class='bcode'>
+        *      WriterSerializer s = <jk>new</jk> 
RdfSerializerBuilder().xmlabbrev().looseCollections(<jk>true</jk>).build();
+        *      ReaderParser p = <jk>new</jk> 
RdfParserBuilder().xml().looseCollections(<jk>true</jk>).build();
+        *
+        *      List&lt;MyBean&gt; l = createListOfMyBeans();
+        *
+        *      <jc>// Serialize to RDF/XML as loose resources</jc>
+        *      String rdfXml = s.serialize(l);
+        *
+        *      <jc>// Parse back into a Java collection</jc>
+        *      l = p.parse(rdfXml, LinkedList.<jk>class</jk>, 
MyBean.<jk>class</jk>);
+        *
+        *      MyBean[] b = createArrayOfMyBeans();
+        *
+        *      <jc>// Serialize to RDF/XML as loose resources</jc>
+        *      String rdfXml = s.serialize(b);
+        *
+        *      <jc>// Parse back into a bean array</jc>
+        *      b = p.parse(rdfXml, MyBean[].<jk>class</jk>);
+        * </p>
+        * 
+        * <h5 class='section'>Notes:</h5>
+        * <ul>
+        *      <li>This is equivalent to calling 
<code>property(<jsf>RDF_looseCollections</jsf>, value)</code>.
+        * </ul>
+        *
+        * @param value The new value for this property.
+        * @return This object (for method chaining).
+        * @see RdfCommonContext#RDF_looseCollections
+        */
+       public RdfSerializerBuilder looseCollections(boolean value) {
+               return property(RDF_looseCollections, value);
+       }
+
+       @Override /* SerializerBuilder */
+       public RdfSerializerBuilder maxDepth(int value) {
+               super.maxDepth(value);
+               return this;
+       }
+
+       @Override /* SerializerBuilder */
+       public RdfSerializerBuilder initialDepth(int value) {
+               super.initialDepth(value);
+               return this;
+       }
+
+       @Override /* SerializerBuilder */
+       public RdfSerializerBuilder detectRecursions(boolean value) {
+               super.detectRecursions(value);
+               return this;
+       }
+
+       @Override /* SerializerBuilder */
+       public RdfSerializerBuilder ignoreRecursions(boolean value) {
+               super.ignoreRecursions(value);
+               return this;
+       }
+
+       @Override /* SerializerBuilder */
+       public RdfSerializerBuilder useWhitespace(boolean value) {
+               super.useWhitespace(value);
+               return this;
+       }
+
+       @Override /* SerializerBuilder */
+       public RdfSerializerBuilder ws() {
+               super.ws();
+               return this;
+       }
+
+       @Override /* SerializerBuilder */
+       public RdfSerializerBuilder addBeanTypeProperties(boolean value) {
+               super.addBeanTypeProperties(value);
+               return this;
+       }
+
+       @Override /* SerializerBuilder */
+       public RdfSerializerBuilder quoteChar(char value) {
+               super.quoteChar(value);
+               return this;
+       }
+
+       @Override /* SerializerBuilder */
+       public RdfSerializerBuilder sq() {
+               super.sq();
+               return this;
+       }
+
+       @Override /* SerializerBuilder */
+       public RdfSerializerBuilder trimNullProperties(boolean value) {
+               super.trimNullProperties(value);
+               return this;
+       }
+
+       @Override /* SerializerBuilder */
+       public RdfSerializerBuilder trimEmptyCollections(boolean value) {
+               super.trimEmptyCollections(value);
+               return this;
+       }
+
+       @Override /* SerializerBuilder */
+       public RdfSerializerBuilder trimEmptyMaps(boolean value) {
+               super.trimEmptyMaps(value);
+               return this;
+       }
+
+       @Override /* SerializerBuilder */
+       public RdfSerializerBuilder trimStrings(boolean value) {
+               super.trimStrings(value);
+               return this;
+       }
+
+       @Override /* SerializerBuilder */
+       public RdfSerializerBuilder uriContext(UriContext value) {
+               super.uriContext(value);
+               return this;
+       }
+
+       @Override /* SerializerBuilder */
+       public RdfSerializerBuilder uriResolution(UriResolution value) {
+               super.uriResolution(value);
+               return this;
+       }
+
+       @Override /* SerializerBuilder */
+       public RdfSerializerBuilder uriRelativity(UriRelativity value) {
+               super.uriRelativity(value);
+               return this;
+       }
+
+       @Override /* SerializerBuilder */
+       public RdfSerializerBuilder sortCollections(boolean value) {
+               super.sortCollections(value);
+               return this;
+       }
+
+       @Override /* SerializerBuilder */
+       public RdfSerializerBuilder sortMaps(boolean value) {
+               super.sortMaps(value);
+               return this;
+       }
+
+       @Override /* SerializerBuilder */
+       public RdfSerializerBuilder abridged(boolean value) {
+               super.abridged(value);
+               return this;
+       }
+
+       @Override /* SerializerBuilder */
+       public RdfSerializerBuilder listener(Class<? extends 
SerializerListener> value) {
+               super.listener(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder beansRequireDefaultConstructor(boolean 
value) {
+               super.beansRequireDefaultConstructor(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder beansRequireSerializable(boolean value) {
+               super.beansRequireSerializable(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder beansRequireSettersForGetters(boolean 
value) {
+               super.beansRequireSettersForGetters(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder beansRequireSomeProperties(boolean value) {
+               super.beansRequireSomeProperties(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder beanMapPutReturnsOldValue(boolean value) {
+               super.beanMapPutReturnsOldValue(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder beanConstructorVisibility(Visibility value) 
{
+               super.beanConstructorVisibility(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder beanClassVisibility(Visibility value) {
+               super.beanClassVisibility(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder beanFieldVisibility(Visibility value) {
+               super.beanFieldVisibility(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder methodVisibility(Visibility value) {
+               super.methodVisibility(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder useJavaBeanIntrospector(boolean value) {
+               super.useJavaBeanIntrospector(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder useInterfaceProxies(boolean value) {
+               super.useInterfaceProxies(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder ignoreUnknownBeanProperties(boolean value) {
+               super.ignoreUnknownBeanProperties(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder ignoreUnknownNullBeanProperties(boolean 
value) {
+               super.ignoreUnknownNullBeanProperties(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder ignorePropertiesWithoutSetters(boolean 
value) {
+               super.ignorePropertiesWithoutSetters(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder ignoreInvocationExceptionsOnGetters(boolean 
value) {
+               super.ignoreInvocationExceptionsOnGetters(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder ignoreInvocationExceptionsOnSetters(boolean 
value) {
+               super.ignoreInvocationExceptionsOnSetters(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder sortProperties(boolean value) {
+               super.sortProperties(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder notBeanPackages(String...values) {
+               super.notBeanPackages(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder notBeanPackages(Collection<String> values) {
+               super.notBeanPackages(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder setNotBeanPackages(String...values) {
+               super.setNotBeanPackages(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder setNotBeanPackages(Collection<String> 
values) {
+               super.setNotBeanPackages(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder removeNotBeanPackages(String...values) {
+               super.removeNotBeanPackages(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder removeNotBeanPackages(Collection<String> 
values) {
+               super.removeNotBeanPackages(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder notBeanClasses(Class<?>...values) {
+               super.notBeanClasses(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder notBeanClasses(Collection<Class<?>> values) 
{
+               super.notBeanClasses(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder setNotBeanClasses(Class<?>...values) {
+               super.setNotBeanClasses(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder setNotBeanClasses(Collection<Class<?>> 
values) {
+               super.setNotBeanClasses(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder removeNotBeanClasses(Class<?>...values) {
+               super.removeNotBeanClasses(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder removeNotBeanClasses(Collection<Class<?>> 
values) {
+               super.removeNotBeanClasses(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder beanFilters(Class<?>...values) {
+               super.beanFilters(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder beanFilters(Collection<Class<?>> values) {
+               super.beanFilters(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder setBeanFilters(Class<?>...values) {
+               super.setBeanFilters(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder setBeanFilters(Collection<Class<?>> values) 
{
+               super.setBeanFilters(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder removeBeanFilters(Class<?>...values) {
+               super.removeBeanFilters(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder removeBeanFilters(Collection<Class<?>> 
values) {
+               super.removeBeanFilters(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder pojoSwaps(Class<?>...values) {
+               super.pojoSwaps(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder pojoSwaps(Collection<Class<?>> values) {
+               super.pojoSwaps(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder setPojoSwaps(Class<?>...values) {
+               super.setPojoSwaps(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder setPojoSwaps(Collection<Class<?>> values) {
+               super.setPojoSwaps(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder removePojoSwaps(Class<?>...values) {
+               super.removePojoSwaps(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder removePojoSwaps(Collection<Class<?>> 
values) {
+               super.removePojoSwaps(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder implClasses(Map<Class<?>,Class<?>> values) {
+               super.implClasses(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public <T> RdfSerializerBuilder implClass(Class<T> interfaceClass, 
Class<? extends T> implClass) {
+               super.implClass(interfaceClass, implClass);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder includeProperties(Map<String,String> 
values) {
+               super.includeProperties(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder includeProperties(String beanClassName, 
String properties) {
+               super.includeProperties(beanClassName, properties);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder includeProperties(Class<?> beanClass, 
String properties) {
+               super.includeProperties(beanClass, properties);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder excludeProperties(Map<String,String> 
values) {
+               super.excludeProperties(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder excludeProperties(String beanClassName, 
String properties) {
+               super.excludeProperties(beanClassName, properties);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder excludeProperties(Class<?> beanClass, 
String properties) {
+               super.excludeProperties(beanClass, properties);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder beanDictionary(Class<?>...values) {
+               super.beanDictionary(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder beanDictionary(Collection<Class<?>> values) 
{
+               super.beanDictionary(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder setBeanDictionary(Class<?>...values) {
+               super.setBeanDictionary(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder setBeanDictionary(Collection<Class<?>> 
values) {
+               super.setBeanDictionary(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder removeFromBeanDictionary(Class<?>...values) 
{
+               super.removeFromBeanDictionary(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder 
removeFromBeanDictionary(Collection<Class<?>> values) {
+               super.removeFromBeanDictionary(values);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder beanTypePropertyName(String value) {
+               super.beanTypePropertyName(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder defaultParser(Class<?> value) {
+               super.defaultParser(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder locale(Locale value) {
+               super.locale(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder timeZone(TimeZone value) {
+               super.timeZone(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder mediaType(MediaType value) {
+               super.mediaType(value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder debug() {
+               super.debug();
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder property(String name, Object value) {
+               super.property(name, value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder properties(Map<String,Object> properties) {
+               super.properties(properties);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder addToProperty(String name, Object value) {
+               super.addToProperty(name, value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder putToProperty(String name, Object key, 
Object value) {
+               super.putToProperty(name, key, value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder putToProperty(String name, Object value) {
+               super.putToProperty(name, value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder removeFromProperty(String name, Object 
value) {
+               super.removeFromProperty(name, value);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder classLoader(ClassLoader classLoader) {
+               super.classLoader(classLoader);
+               return this;
+       }
+
+       @Override /* CoreObjectBuilder */
+       public RdfSerializerBuilder apply(PropertyStore copyFrom) {
+               super.apply(copyFrom);
+               return this;
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerContext.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerContext.java
 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerContext.java
new file mode 100644
index 0000000..2d5d6aa
--- /dev/null
+++ 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerContext.java
@@ -0,0 +1,197 @@
+// 
***************************************************************************************************************************
+// * 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 java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.xml.*;
+
+/**
+ * Configurable properties on the {@link RdfSerializer} class.
+ * 
+ * <p>
+ * Context properties are set by calling {@link 
PropertyStore#setProperty(String, Object)} on the property store
+ * passed into the constructor.
+ * 
+ * <p>
+ * See {@link PropertyStore} for more information about context properties.
+ *
+ * <h6 class='topic' id='ConfigProperties'>Configurable properties inherited 
by the RDF serializers</h6>
+ * <ul class='doctree'>
+ *     <li class='jc'>
+ *             <a class="doclink" 
href="../BeanContext.html#ConfigProperties">BeanContext</a> 
+ *             - Properties associated with handling beans on serializers and 
parsers.
+ *             <ul>
+ *                     <li class='jc'>
+ *                             <a class="doclink" 
href="../serializer/SerializerContext.html#ConfigProperties">SerializerContext</a>
 
+ *                             - Configurable properties common to all 
serializers.
+ *                             <ul>
+ *                                     <li class='jc'>
+ *                                             <a class="doclink" 
href="RdfCommonContext.html#ConfigProperties">RdfCommonContext</a> 
+ *                                             - Configurable properties 
common to the RDF serializers and parsers.
+ *                             </ul>
+ *                     </li>
+ *             </ul>
+ *     </li>
+ * </ul>
+ */
+public final class RdfSerializerContext extends SerializerContext implements 
RdfCommonContext {
+
+       /**
+        * <b>Configuration property:</b>  Add XSI data types to 
non-<code>String</code> literals.
+        * 
+        * <ul>
+        *      <li><b>Name:</b> <js>"RdfSerializer.addLiteralTypes"</js>
+        *      <li><b>Data type:</b> <code>Boolean</code>
+        *      <li><b>Default:</b> <jk>false</jk>
+        *      <li><b>Session-overridable:</b> <jk>true</jk>
+        * </ul>
+        */
+       public static final String RDF_addLiteralTypes = 
"RdfSerializer.addLiteralTypes";
+
+       /**
+        * <b>Configuration property:</b>  Add RDF root identifier property to 
root node.
+        * 
+        * <ul>
+        *      <li><b>Name:</b> <js>"RdfSerializer.addRootProperty"</js>
+        *      <li><b>Data type:</b> <code>Boolean</code>
+        *      <li><b>Default:</b> <jk>false</jk>
+        *      <li><b>Session-overridable:</b> <jk>true</jk>
+        * </ul>
+        * 
+        * <p>
+        * When enabled an RDF property 
<code>http://www.apache.org/juneau/root</code> is added with a value of 
<js>"true"</js>
+        * to identify the root node in the graph.
+        * This helps locate the root node during parsing.
+        * 
+        * <p>
+        * If disabled, the parser has to search through the model to find any 
resources without incoming predicates to 
+        * identify root notes, which can introduce a considerable performance 
degradation.
+        */
+       public static final String RDF_addRootProperty = 
"RdfSerializer.addRootProperty";
+
+       /**
+        * <b>Configuration property:</b>  Auto-detect namespace usage.
+        * 
+        * <ul>
+        *      <li><b>Name:</b> <js>"RdfSerializer.autoDetectNamespaces"</js>
+        *      <li><b>Data type:</b> <code>Boolean</code>
+        *      <li><b>Default:</b> <jk>true</jk>
+        *      <li><b>Session-overridable:</b> <jk>true</jk>
+        * </ul>
+        * 
+        * <p>
+        * Detect namespace usage before serialization.
+        * 
+        * <p>
+        * If enabled, then the data structure will first be crawled looking 
for namespaces that will be encountered before 
+        * the root element is serialized.
+        */
+       public static final String RDF_autoDetectNamespaces = 
"RdfSerializer.autoDetectNamespaces";
+
+       /**
+        * <b>Configuration property:</b>  Default namespaces.
+        * 
+        * <ul>
+        *      <li><b>Name:</b> <js>"RdfSerializer.namespaces.list"</js>
+        *      <li><b>Data type:</b> <code>List&lt;{@link Namespace}&gt;</code>
+        *      <li><b>Default:</b> empty list
+        *      <li><b>Session-overridable:</b> <jk>true</jk>
+        * </ul>
+        * 
+        * <p>
+        * The default list of namespaces associated with this serializer.
+        */
+       public static final String RDF_namespaces = 
"RdfSerializer.namespaces.list";
+
+       /**
+        * <b>Configuration property:</b>  Add <js>"_type"</js> properties when 
needed.
+        * 
+        * <ul>
+        *      <li><b>Name:</b> <js>"RdfSerializer.addBeanTypeProperties"</js>
+        *      <li><b>Data type:</b> <code>Boolean</code>
+        *      <li><b>Default:</b> <jk>false</jk>
+        *      <li><b>Session-overridable:</b> <jk>true</jk>
+        * </ul>
+        * 
+        * <p>
+        * If <jk>true</jk>, then <js>"_type"</js> properties will be added to 
beans if their type cannot be inferred 
+        * through reflection.
+        * This is used to recreate the correct objects during parsing if the 
object types cannot be inferred.
+        * For example, when serializing a {@code Map<String,Object>} field, 
where the bean class cannot be determined 
+        * from the value type.
+        * 
+        * <p>
+        * When present, this value overrides the {@link 
SerializerContext#SERIALIZER_addBeanTypeProperties} setting and is
+        * provided to customize the behavior of specific serializers in a 
{@link SerializerGroup}.
+        */
+       public static final String RDF_addBeanTypeProperties = 
"RdfSerializer.addBeanTypeProperties";
+
+
+       final boolean
+               addLiteralTypes,
+               addRootProperty,
+               useXmlNamespaces,
+               looseCollections,
+               autoDetectNamespaces,
+               addBeanTypeProperties;
+       final String rdfLanguage;
+       final Namespace juneauNs;
+       final Namespace juneauBpNs;
+       final RdfCollectionFormat collectionFormat;
+       final Map<String,Object> jenaSettings = new HashMap<String,Object>();
+       final Namespace[] namespaces;
+
+       /**
+        * Constructor.
+        * 
+        * <p>
+        * Typically only called from {@link PropertyStore#getContext(Class)}.
+        *
+        * @param ps The property store that created this context.
+        */
+       public RdfSerializerContext(PropertyStore ps) {
+               super(ps);
+               addLiteralTypes = ps.getProperty(RDF_addLiteralTypes, 
boolean.class, false);
+               addRootProperty = ps.getProperty(RDF_addRootProperty, 
boolean.class, false);
+               useXmlNamespaces = ps.getProperty(RDF_useXmlNamespaces, 
boolean.class, true);
+               looseCollections = ps.getProperty(RDF_looseCollections, 
boolean.class, false);
+               autoDetectNamespaces = ps.getProperty(RDF_autoDetectNamespaces, 
boolean.class, true);
+               rdfLanguage = ps.getProperty(RDF_language, String.class, 
"RDF/XML-ABBREV");
+               juneauNs = ps.getProperty(RDF_juneauNs, Namespace.class, new 
Namespace("j", "http://www.apache.org/juneau/";));
+               juneauBpNs = ps.getProperty(RDF_juneauBpNs, Namespace.class, 
new Namespace("jp", "http://www.apache.org/juneaubp/";));
+               collectionFormat = ps.getProperty(RDF_collectionFormat, 
RdfCollectionFormat.class, RdfCollectionFormat.DEFAULT);
+               namespaces = ps.getProperty(RDF_namespaces, Namespace[].class, 
new Namespace[0]);
+               addBeanTypeProperties = 
ps.getProperty(RDF_addBeanTypeProperties, boolean.class, 
ps.getProperty(SERIALIZER_addBeanTypeProperties, boolean.class, true));
+       }
+
+       @Override /* Context */
+       public ObjectMap asMap() {
+               return super.asMap()
+                       .append("RdfSerializerContext", new ObjectMap()
+                               .append("addLiteralTypes", addLiteralTypes)
+                               .append("addRootProperty", addRootProperty)
+                               .append("useXmlNamespaces", useXmlNamespaces)
+                               .append("looseCollections", looseCollections)
+                               .append("autoDetectNamespaces", 
autoDetectNamespaces)
+                               .append("rdfLanguage", rdfLanguage)
+                               .append("juneauNs", juneauNs)
+                               .append("juneauBpNs", juneauBpNs)
+                               .append("collectionFormat", collectionFormat)
+                               .append("namespaces", namespaces)
+                               .append("addBeanTypeProperties", 
addBeanTypeProperties)
+                       );
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
new file mode 100644
index 0000000..0f66237
--- /dev/null
+++ 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
@@ -0,0 +1,414 @@
+// 
***************************************************************************************************************************
+// * 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.jena.Constants.*;
+import static org.apache.juneau.jena.RdfCommonContext.*;
+import static org.apache.juneau.jena.RdfSerializerContext.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+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 typically discarded after one-time use although it can be reused 
within the same thread.
+ */
+@SuppressWarnings({ "rawtypes", "unchecked" })
+public final class RdfSerializerSession extends WriterSerializerSession {
+
+       private final String rdfLanguage;
+       private final Namespace juneauNs, juneauBpNs;
+       private final boolean
+               addLiteralTypes,
+               addRootProperty,
+               useXmlNamespaces,
+               looseCollections,
+               autoDetectNamespaces,
+               addBeanTypeProperties;
+       private final Property pRoot, pValue;
+       private final Model model;
+       private final RDFWriter writer;
+       private final RdfCollectionFormat collectionFormat;
+       private final Namespace[] namespaces;
+
+       /**
+        * Create a new session using properties specified in the context.
+        *
+        * @param ctx
+        *      The context creating this session object.
+        *      The context contains all the configuration settings for this 
object.
+        * @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.
+        */
+       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);
+               ObjectMap p = getProperties();
+               if (p.isEmpty()) {
+                       this.rdfLanguage = ctx.rdfLanguage;
+                       this.juneauNs = ctx.juneauNs;
+                       this.juneauBpNs = ctx.juneauBpNs;
+                       this.addLiteralTypes = ctx.addLiteralTypes;
+                       this.addRootProperty = ctx.addRootProperty;
+                       this.collectionFormat = ctx.collectionFormat;
+                       this.looseCollections = ctx.looseCollections;
+                       this.useXmlNamespaces = ctx.useXmlNamespaces;
+                       this.autoDetectNamespaces = ctx.autoDetectNamespaces;
+                       this.namespaces = ctx.namespaces;
+                       addBeanTypeProperties = ctx.addBeanTypeProperties;
+               } else {
+                       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(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.getWithDefault(RDF_namespaces, 
ctx.namespaces, Namespace[].class);
+                       addBeanTypeProperties = 
p.getBoolean(RDF_addBeanTypeProperties, ctx.addBeanTypeProperties);
+               }
+               this.model = ModelFactory.createDefaultModel();
+               addModelPrefix(juneauNs);
+               addModelPrefix(juneauBpNs);
+               for (Namespace ns : this.namespaces)
+                       addModelPrefix(ns);
+               this.pRoot = model.createProperty(juneauNs.getUri(), 
RDF_juneauNs_ROOT);
+               this.pValue = model.createProperty(juneauNs.getUri(), 
RDF_juneauNs_VALUE);
+               writer = model.getWriter(rdfLanguage);
+
+               // Only apply properties with this prefix!
+               String propPrefix = 
RdfCommonContext.LANG_PROP_MAP.get(rdfLanguage);
+               if (propPrefix == null)
+                       throw new FormattedRuntimeException("Unknown RDF 
language encountered: ''{0}''", rdfLanguage);
+
+               for (Map.Entry<String,Object> e : jenaSettings.entrySet())
+                       if (e.getKey().startsWith(propPrefix))
+                               
writer.setProperty(e.getKey().substring(propPrefix.length()), e.getValue());
+       }
+
+       /*
+        * Adds the specified namespace as a model prefix.
+        */
+       private void addModelPrefix(Namespace ns) {
+               model.setNsPrefix(ns.getName(), ns.getUri());
+       }
+
+       /**
+        * 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;
+       }
+
+       /*
+        * XML-encodes the specified string using the {@link 
XmlUtils#escapeText(Object)} method.
+        */
+       private String encodeTextInvalidChars(Object o) {
+               if (o == null)
+                       return null;
+               String s = toString(o);
+               return XmlUtils.escapeText(s);
+       }
+
+       /*
+        * XML-encoded the specified element name using the {@link 
XmlUtils#encodeElementName(Object)} method.
+        */
+       private String encodeElementName(Object o) {
+               return XmlUtils.encodeElementName(toString(o));
+       }
+       
+       @Override /* Serializer */
+       protected void doSerialize(SerializerPipe out, Object o) throws 
Exception {
+
+               Resource r = null;
+
+               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();
+                       }
+
+                       if (addRootProperty)
+                               r.addProperty(pRoot, "true");
+               }
+
+               writer.write(model, out.getWriter(), "http://unknown/";);
+       }
+
+       private RDFNode serializeAnything(Object o, boolean isURI, ClassMeta<?> 
eType, 
+                       String attrName, BeanPropertyMeta bpm, Resource 
parentResource) throws Exception {
+               Model m = model;
+
+               ClassMeta<?> aType = null;       // The actual type
+               ClassMeta<?> wType = null;       // The wrapped type
+               ClassMeta<?> sType = object();   // The serialized type
+
+               aType = 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(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 if (sType.isReader() || sType.isInputStream()) {
+                       n = 
m.createLiteral(encodeTextInvalidChars(IOUtils.read(o)));
+               
+               } else {
+                       n = 
m.createLiteral(encodeTextInvalidChars(toString(o)));
+               }
+
+               pop();
+
+               return n;
+       }
+
+       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);
+       }
+
+       private void serializeMap(Map m, Resource r, ClassMeta<?> type) throws 
Exception {
+
+               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);
+               }
+       }
+
+       private void serializeBeanMap(BeanMap<?> m, Resource r, String 
typeName) throws Exception {
+               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);
+               }
+       }
+
+
+       private Container serializeToContainer(Collection c, ClassMeta<?> type, 
Container list) throws Exception {
+
+               ClassMeta<?> elementType = type.getElementType();
+               for (Object e : c) {
+                       RDFNode n = serializeAnything(e, false, elementType, 
null, null, null);
+                       list = list.add(n);
+               }
+               return list;
+       }
+
+       private RDFList serializeToList(Collection c, ClassMeta<?> type) throws 
Exception {
+               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());
+       }
+
+       private void serializeToMultiProperties(Collection c, ClassMeta<?> 
sType, 
+                       BeanPropertyMeta bpm, String attrName, Resource 
parentResource) throws Exception {
+               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/75b0d8ee/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfUtils.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfUtils.java
 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfUtils.java
new file mode 100644
index 0000000..0432efb
--- /dev/null
+++ 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfUtils.java
@@ -0,0 +1,92 @@
+// 
***************************************************************************************************************************
+// * 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 java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.jena.annotation.*;
+import org.apache.juneau.xml.*;
+
+/**
+ * Utility classes.
+ */
+public class RdfUtils {
+
+       /**
+        * Find the namespace given a list of <ja>@Rdf</ja> and 
<ja>@RdfSchema</ja> annotations.
+        * 
+        * <p>
+        * The annotations should be a child-to-parent ordering of annotations 
found on a class or method.
+        *
+        * @param rdfs The <code>@Rdf</code> annotations to search.
+        * @param schemas The list of known RDF schemas.
+        * @return The resolved namespace, or <jk>null</jk> if the namespace 
could not be resolved.
+        */
+       public static Namespace findNamespace(List<Rdf> rdfs, List<RdfSchema> 
schemas) {
+
+               for (Rdf rdf : rdfs) {
+                       Namespace ns = findNamespace(rdf.prefix(), 
rdf.namespace(), rdfs, schemas);
+                       if (ns != null)
+                               return ns;
+               }
+
+               for (RdfSchema schema : schemas) {
+                       Namespace ns = findNamespace(schema.prefix(), 
schema.namespace(), null, schemas);
+                       if (ns != null)
+                               return ns;
+               }
+
+               return null;
+       }
+
+       private static Namespace findNamespace(String prefix, String ns, 
List<Rdf> rdfs, List<RdfSchema> schemas) {
+
+               // If both prefix and namespace specified, use that Namespace 
mapping.
+               if (! (prefix.isEmpty() || ns.isEmpty()))
+                       return NamespaceFactory.get(prefix, ns);
+
+               // If only prefix specified, need to search for namespaceURI.
+               if (! prefix.isEmpty()) {
+                       if (rdfs != null)
+                               for (Rdf rdf2 : rdfs)
+                                       if (rdf2.prefix().equals(prefix) && ! 
rdf2.namespace().isEmpty())
+                                               return 
NamespaceFactory.get(prefix, rdf2.namespace());
+                       for (RdfSchema schema : schemas) {
+                               if (schema.prefix().equals(prefix) && ! 
schema.namespace().isEmpty())
+                                       return NamespaceFactory.get(prefix, 
schema.namespace());
+                               for (RdfNs rdfNs : schema.rdfNs())
+                                       if (rdfNs.prefix().equals(prefix))
+                                               return 
NamespaceFactory.get(prefix, rdfNs.namespaceURI());
+                       }
+                       throw new BeanRuntimeException("Found @Rdf.prefix 
annotation with no matching URI.  prefix='"+prefix+"'");
+               }
+
+               // If only namespaceURI specified, need to search for prefix.
+               if (! ns.isEmpty()) {
+                       if (rdfs != null)
+                               for (Rdf rdf2 : rdfs)
+                                       if (rdf2.namespace().equals(ns) && ! 
rdf2.prefix().isEmpty())
+                                               return 
NamespaceFactory.get(rdf2.prefix(), ns);
+                       for (RdfSchema schema : schemas) {
+                               if (schema.namespace().equals(ns) && ! 
schema.prefix().isEmpty())
+                                       return 
NamespaceFactory.get(schema.prefix(), ns);
+                               for (RdfNs rdfNs : schema.rdfNs())
+                                       if (rdfNs.namespaceURI().equals(ns))
+                                               return 
NamespaceFactory.get(rdfNs.prefix(), ns);
+                       }
+               }
+
+               return null;
+       }
+}

Reply via email to