http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java 
b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
new file mode 100644
index 0000000..604d98a
--- /dev/null
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
@@ -0,0 +1,502 @@
+// 
***************************************************************************************************************************
+// * 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.lang.reflect.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.transform.*;
+
+import com.hp.hpl.jena.rdf.model.*;
+import com.hp.hpl.jena.util.iterator.*;
+
+/**
+ * Parses RDF into POJOs.
+ *
+ * <h6 class='topic'>Configurable properties</h6>
+ * <p>
+ *     Refer to <a class='doclink' 
href='package-summary.html#ParserConfigurableProperties'>Configurable 
Properties</a>
+ *             for the entire list of configurable properties.
+ *
+ * <h6 class='topic'>Behavior-specific subclasses</h6>
+ * <p>
+ *     The following direct subclasses are provided for language-specific 
parsers:
+ * <ul class='spaced-list'>
+ *     <li>{@link RdfParser.Xml} - RDF/XML and RDF/XML-ABBREV.
+ *     <li>{@link RdfParser.NTriple} - N-TRIPLE.
+ *     <li>{@link RdfParser.Turtle} - TURTLE.
+ *     <li>{@link RdfParser.N3} - N3.
+ * </ul>
+ *
+ * <h6 class='topic'>Additional Information</h6>
+ * <p>
+ *     See <a class='doclink' href='package-summary.html#TOC'>RDF Overview</a> 
for an overview of RDF support in Juneau.
+ */
+@Consumes(value="text/xml+rdf")
+public class RdfParser extends ReaderParser {
+
+       /** Default XML parser, all default settings.*/
+       public static final RdfParser DEFAULT_XML = new RdfParser.Xml().lock();
+
+       /** Default Turtle parser, all default settings.*/
+       public static final RdfParser DEFAULT_TURTLE = new 
RdfParser.Turtle().lock();
+
+       /** Default N-Triple parser, all default settings.*/
+       public static final RdfParser DEFAULT_NTRIPLE = new 
RdfParser.NTriple().lock();
+
+       /** Default N3 parser, all default settings.*/
+       public static final RdfParser DEFAULT_N3 = new RdfParser.N3().lock();
+
+
+       /** Consumes RDF/XML input */
+       @Consumes("text/xml+rdf")
+       public static class Xml extends RdfParser {
+               /** Constructor */
+               public Xml() {
+                       setProperty(RDF_language, LANG_RDF_XML);
+               }
+       }
+
+       /** Consumes N-Triple input */
+       @Consumes(value="text/n-triple")
+       public static class NTriple extends RdfParser {
+               /** Constructor */
+               public NTriple() {
+                       setProperty(RDF_language, LANG_NTRIPLE);
+               }
+       }
+
+       /** Consumes Turtle input */
+       @Consumes(value="text/turtle")
+       public static class Turtle extends RdfParser {
+               /** Constructor */
+               public Turtle() {
+                       setProperty(RDF_language, LANG_TURTLE);
+               }
+       }
+
+       /** Consumes N3 input */
+       @Consumes(value="text/n3")
+       public static class N3 extends RdfParser {
+               /** Constructor */
+               public N3() {
+                       setProperty(RDF_language, LANG_N3);
+               }
+       }
+
+
+       @SuppressWarnings({"unchecked", "rawtypes"})
+       @Override /* ReaderParser */
+       protected <T> T doParse(ParserSession session, ClassMeta<T> type) 
throws Exception {
+
+               RdfParserSession s = (RdfParserSession)session;
+
+               type = session.normalizeClassMeta(type);
+
+               Model model = s.getModel();
+               RDFReader r = s.getRdfReader();
+               r.read(model, session.getReader(), null);
+
+               List<Resource> roots = getRoots(s, model);
+
+               // Special case where we're parsing a loose collection of 
resources.
+               if (s.isLooseCollections() && type.isCollectionOrArray()) {
+                       Collection c = null;
+                       if (type.isArray())
+                               c = new ArrayList();
+                       else
+                               c = 
(type.canCreateNewInstance(session.getOuter()) ? 
(Collection<?>)type.newInstance(session.getOuter()) : new ObjectList(session));
+                       for (Resource resource : roots)
+                               c.add(parseAnything(s, type.getElementType(), 
resource, session.getOuter()));
+
+                       if (type.isArray())
+                               return (T)session.toArray(type, c);
+                       return (T)c;
+               }
+
+               if (roots.isEmpty())
+                       return null;
+               if (roots.size() > 1)
+                       throw new ParseException(session, "Too many root nodes 
found in model:  {0}", roots.size());
+               Resource resource = roots.get(0);
+
+               return parseAnything(s, type, resource, session.getOuter());
+       }
+
+       /*
+        * 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(RdfParserSession session, Model m) {
+               List<Resource> l = new LinkedList<Resource>();
+
+               // First try to find the root using the 
"http://www.apache.org/juneau/root"; property.
+               Property root = m.createProperty(session.getJuneauNsUri(), 
RDF_juneauNs_ROOT);
+               for (ResIterator i  = m.listResourcesWithProperty(root); 
i.hasNext();)
+                       l.add(i.next());
+
+               if (! l.isEmpty())
+                       return l;
+
+               // Otherwise, we need to find all resources that aren't objects.
+               // We want to explicitly ignore statements where the subject
+               // and object are the same node.
+               Set<RDFNode> objects = new HashSet<RDFNode>();
+               for (StmtIterator i = m.listStatements(); i.hasNext();) {
+                       Statement st = i.next();
+                       RDFNode subject = st.getSubject();
+                       RDFNode object = st.getObject();
+                       if (object.isResource() && ! object.equals(subject))
+                               objects.add(object);
+               }
+               for (ResIterator i = m.listSubjects(); i.hasNext();) {
+                       Resource r = i.next();
+                       if (! objects.contains(r))
+                               l.add(r);
+               }
+               return l;
+       }
+
+       private <T> BeanMap<T> parseIntoBeanMap(RdfParserSession session, 
Resource r2, BeanMap<T> m) throws Exception {
+               BeanMeta<T> bm = m.getMeta();
+               RdfBeanMeta rbm = bm.getExtendedMeta(RdfBeanMeta.class);
+               if (rbm.hasBeanUri() && r2.getURI() != null)
+                       rbm.getBeanUriProperty().set(m, r2.getURI());
+               Property subTypeIdProperty = null;
+               BeanPropertyMeta stp = bm.getSubTypeProperty();
+               if (stp != null) {
+                       subTypeIdProperty = session.getProperty(stp.getName());
+                       Statement st = r2.getProperty(subTypeIdProperty);
+                       if (st == null)
+                               throw new ParseException(session, "Could not 
find subtype ID property for bean of type ''{0}''", m.getClassMeta());
+                       String subTypeId = st.getLiteral().getString();
+                       stp.set(m, subTypeId);
+               }
+               for (StmtIterator i = r2.listProperties(); i.hasNext();) {
+                       Statement st = i.next();
+                       Property p = st.getPredicate();
+                       if (p.equals(subTypeIdProperty))
+                               continue;
+                       String key = session.decodeString(p.getLocalName());
+                       BeanPropertyMeta pMeta = m.getPropertyMeta(key);
+                       session.setCurrentProperty(pMeta);
+                       if (pMeta != null) {
+                               RDFNode o = st.getObject();
+                               ClassMeta<?> cm = pMeta.getClassMeta();
+                               if (cm.isCollectionOrArray() && 
isMultiValuedCollections(session, pMeta)) {
+                                       ClassMeta<?> et = cm.getElementType();
+                                       Object value = parseAnything(session, 
et, o, m.getBean(false));
+                                       setName(et, value, key);
+                                       pMeta.add(m, value);
+                               } else {
+                                       Object value = parseAnything(session, 
cm, o, m.getBean(false));
+                                       setName(cm, value, key);
+                                       pMeta.set(m, value);
+                               }
+                       } else if (! (p.equals(session.getRootProperty()) || 
p.equals(session.getClassProperty()) || p.equals(subTypeIdProperty))) {
+                               if (bm.isSubTyped()) {
+                                       RDFNode o = st.getObject();
+                                       Object value = parseAnything(session, 
object(), o, m.getBean(false));
+                                       m.put(key, value);
+                               } else {
+                                       onUnknownProperty(session, key, m, -1, 
-1);
+                               }
+                       }
+                       session.setCurrentProperty(null);
+               }
+               return m;
+       }
+
+       private boolean isMultiValuedCollections(RdfParserSession session, 
BeanPropertyMeta pMeta) {
+               if (pMeta != null && 
pMeta.getExtendedMeta(RdfBeanPropertyMeta.class).getCollectionFormat() != 
RdfCollectionFormat.DEFAULT)
+                       return 
pMeta.getExtendedMeta(RdfBeanPropertyMeta.class).getCollectionFormat() == 
RdfCollectionFormat.MULTI_VALUED;
+               return session.getCollectionFormat() == 
RdfCollectionFormat.MULTI_VALUED;
+       }
+
+       @SuppressWarnings({ "unchecked", "rawtypes" })
+       private <T> T parseAnything(RdfParserSession session, ClassMeta<T> 
eType, RDFNode n, Object outer) throws Exception {
+
+               if (eType == null)
+                       eType = (ClassMeta<T>)object();
+               PojoSwap<T,Object> transform = 
(PojoSwap<T,Object>)eType.getPojoSwap();
+               ClassMeta<?> sType = eType.getSerializedClassMeta();
+               session.setCurrentClass(sType);
+
+               if (! sType.canCreateNewInstance(outer)) {
+                       if (n.isResource()) {
+                               Statement st = 
n.asResource().getProperty(session.getClassProperty());
+                               if (st != null) {
+                                       String c = st.getLiteral().getString();
+                                       sType = eType = 
(ClassMeta<T>)session.getClassMetaFromString(c);
+                               }
+                       }
+               }
+
+               Object o = null;
+               if (n.isResource() && n.asResource().getURI() != null && 
n.asResource().getURI().equals(RDF_NIL)) {
+                       // Do nothing.  Leave o == null.
+               } else if (sType.isObject()) {
+                       if (n.isLiteral()) {
+                               o = n.asLiteral().getValue();
+                               if (o instanceof String) {
+                                       o = session.decodeString(o);
+                               }
+                       }
+                       else if (n.isResource()) {
+                               Resource r = n.asResource();
+                               if (session.wasAlreadyProcessed(r))
+                                       o = r.getURI();
+                               else if 
(r.getProperty(session.getValueProperty()) != null) {
+                                       o = parseAnything(session, object(), 
n.asResource().getProperty(session.getValueProperty()).getObject(), outer);
+                               } else if (isSeq(session, r)) {
+                                       o = new ObjectList(session);
+                                       parseIntoCollection(session, 
r.as(Seq.class), (Collection)o, sType.getElementType());
+                               } else if (isBag(session, r)) {
+                                       o = new ObjectList(session);
+                                       parseIntoCollection(session, 
r.as(Bag.class), (Collection)o, sType.getElementType());
+                               } else if (r.canAs(RDFList.class)) {
+                                       o = new ObjectList(session);
+                                       parseIntoCollection(session, 
r.as(RDFList.class), (Collection)o, sType.getElementType());
+                               } 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 {
+                                               o = new ObjectMap(session);
+                                               parseIntoMap(session, r, 
(Map)o, null, null);
+                                       }
+                               }
+                       } else {
+                               throw new ParseException(session, "Unrecognized 
node type ''{0}'' for object", n);
+                       }
+               } else if (sType.isBoolean()) {
+                       o = session.convertToType(getValue(session, n, outer), 
boolean.class);
+               } else if (sType.isCharSequence()) {
+                       o = session.decodeString(getValue(session, n, outer));
+               } else if (sType.isChar()) {
+                       o = session.decodeString(getValue(session, n, 
outer)).charAt(0);
+               } else if (sType.isNumber()) {
+                       o = parseNumber(getValue(session, n, outer).toString(), 
(Class<? extends Number>)sType.getInnerClass());
+               } else if (sType.isMap()) {
+                       Resource r = n.asResource();
+                       if (session.wasAlreadyProcessed(r))
+                               return null;
+                       Map m = (sType.canCreateNewInstance(outer) ? 
(Map)sType.newInstance(outer) : new ObjectMap(session));
+                       o = parseIntoMap(session, r, m, eType.getKeyType(), 
eType.getValueType());
+               } else if (sType.isCollectionOrArray()) {
+                       if (sType.isArray())
+                               o = new ArrayList();
+                       else
+                               o = (sType.canCreateNewInstance(outer) ? 
(Collection<?>)sType.newInstance(outer) : new ObjectList(session));
+                       Resource r = n.asResource();
+                       if (session.wasAlreadyProcessed(r))
+                               return null;
+                       if (isSeq(session, r)) {
+                               parseIntoCollection(session, r.as(Seq.class), 
(Collection)o, sType.getElementType());
+                       } else if (isBag(session, r)) {
+                               parseIntoCollection(session, r.as(Bag.class), 
(Collection)o, sType.getElementType());
+                       } else if (r.canAs(RDFList.class)) {
+                               parseIntoCollection(session, 
r.as(RDFList.class), (Collection)o, sType.getElementType());
+                       } else {
+                               throw new ParseException("Unrecognized node 
type ''{0}'' for collection", n);
+                       }
+                       if (sType.isArray())
+                               o = session.toArray(sType, (Collection)o);
+               } else if (sType.canCreateNewInstanceFromObjectMap(outer)) {
+                       Resource r = n.asResource();
+                       if (session.wasAlreadyProcessed(r))
+                               return null;
+                       Map m = new ObjectMap(session);
+                       parseIntoMap(session, r, m, eType.getKeyType(), 
eType.getValueType());
+                       o = sType.newInstanceFromObjectMap(outer, (ObjectMap)m);
+               } else if (sType.canCreateNewBean(outer)) {
+                       Resource r = n.asResource();
+                       if (session.wasAlreadyProcessed(r))
+                               return null;
+                       BeanMap<?> bm = session.newBeanMap(outer, 
sType.getInnerClass());
+                       o = parseIntoBeanMap(session, r, bm).getBean();
+               } else if (sType.isUri() && n.isResource()) {
+                       o = sType.newInstanceFromString(outer, 
session.decodeString(n.asResource().getURI()));
+               } else if (sType.canCreateNewInstanceFromString(outer)) {
+                       o = sType.newInstanceFromString(outer, 
session.decodeString(getValue(session, n, outer)));
+               } else if (sType.canCreateNewInstanceFromNumber(outer)) {
+                       o = sType.newInstanceFromNumber(session, outer, 
parseNumber(getValue(session, n, outer).toString(), 
sType.getNewInstanceFromNumberClass()));
+               } else {
+                       throw new ParseException("Class ''{0}'' could not be 
instantiated.  Reason: ''{1}''", sType.getInnerClass().getName(), 
sType.getNotABeanReason());
+               }
+
+               if (transform != null && o != null)
+                       o = transform.unswap(session, o, eType);
+
+               if (outer != null)
+                       setParent(eType, o, outer);
+
+               return (T)o;
+       }
+
+       private boolean isSeq(RdfParserSession session, RDFNode n) {
+               if (n.isResource()) {
+                       Statement st = 
n.asResource().getProperty(session.getTypeProperty());
+                       if (st != null)
+                               return 
RDF_SEQ.equals(st.getResource().getURI());
+               }
+               return false;
+       }
+
+       private boolean isBag(RdfParserSession session, RDFNode n) {
+               if (n.isResource()) {
+                       Statement st = 
n.asResource().getProperty(session.getTypeProperty());
+                       if (st != null)
+                               return 
RDF_BAG.equals(st.getResource().getURI());
+               }
+               return false;
+       }
+
+       private Object getValue(RdfParserSession session, RDFNode n, Object 
outer) throws Exception {
+               if (n.isLiteral())
+                       return n.asLiteral().getValue();
+               if (n.isResource()) {
+                       Statement st = 
n.asResource().getProperty(session.getValueProperty());
+                       if (st != null) {
+                               n = st.getObject();
+                               if (n.isLiteral())
+                                       return n.asLiteral().getValue();
+                               return parseAnything(session, object(), 
st.getObject(), outer);
+                       }
+               }
+               throw new ParseException(session, "Unknown value type for node 
''{0}''", n);
+       }
+
+       private <K,V> Map<K,V> parseIntoMap(RdfParserSession session, Resource 
r, Map<K,V> m, ClassMeta<K> keyType, ClassMeta<V> valueType) throws Exception {
+               // Add URI as "uri" to generic maps.
+               if (r.getURI() != null) {
+                       K uri = convertAttrToType(session, m, "uri", keyType);
+                       V value = convertAttrToType(session, m, r.getURI(), 
valueType);
+                       m.put(uri, value);
+               }
+               for (StmtIterator i = r.listProperties(); i.hasNext();) {
+                       Statement st = i.next();
+                       Property p = st.getPredicate();
+                       String key = p.getLocalName();
+                       if (! (key.equals("root") && 
p.getURI().equals(session.getJuneauNsUri()))) {
+                               key = session.decodeString(key);
+                               RDFNode o = st.getObject();
+                               K key2 = convertAttrToType(session, m, key, 
keyType);
+                               V value = parseAnything(session, valueType, o, 
m);
+                               setName(valueType, value, key);
+                               m.put(key2, value);
+                       }
+
+               }
+               // TODO Auto-generated method stub
+               return m;
+       }
+
+       private <E> Collection<E> parseIntoCollection(RdfParserSession session, 
Container c, Collection<E> l, ClassMeta<E> et) throws Exception {
+               for (NodeIterator ni = c.iterator(); ni.hasNext();) {
+                       E e = parseAnything(session, et, ni.next(), l);
+                       l.add(e);
+               }
+               return l;
+       }
+
+       private <E> Collection<E> parseIntoCollection(RdfParserSession session, 
RDFList list, Collection<E> l, ClassMeta<E> et) throws Exception {
+               for (ExtendedIterator<RDFNode> ni = list.iterator(); 
ni.hasNext();) {
+                       E e = parseAnything(session, et, ni.next(), l);
+                       l.add(e);
+               }
+               return l;
+       }
+
+       
//--------------------------------------------------------------------------------
+       // Overridden methods
+       
//--------------------------------------------------------------------------------
+
+       @Override /* Parser */
+       public RdfParserSession createSession(Object input, ObjectMap op, 
Method javaMethod, Object outer, Locale locale, TimeZone timeZone) {
+               return new RdfParserSession(getContext(RdfParserContext.class), 
op, input, javaMethod, outer, locale, timeZone);
+       }
+
+       @Override /* CoreApi */
+       public RdfParser setProperty(String property, Object value) throws 
LockedException {
+               super.setProperty(property, value);
+               return this;
+       }
+
+       @Override /* CoreApi */
+       public RdfParser setProperties(ObjectMap properties) throws 
LockedException {
+               super.setProperties(properties);
+               return this;
+       }
+
+       @Override /* CoreApi */
+       public RdfParser addNotBeanClasses(Class<?>...classes) throws 
LockedException {
+               super.addNotBeanClasses(classes);
+               return this;
+       }
+
+       @Override /* CoreApi */
+       public RdfParser addBeanFilters(Class<?>...classes) throws 
LockedException {
+               super.addBeanFilters(classes);
+               return this;
+       }
+
+       @Override /* CoreApi */
+       public RdfParser addPojoSwaps(Class<?>...classes) throws 
LockedException {
+               super.addPojoSwaps(classes);
+               return this;
+       }
+
+       @Override /* CoreApi */
+       public RdfParser addToDictionary(Class<?>...classes) throws 
LockedException {
+               super.addToDictionary(classes);
+               return this;
+       }
+
+       @Override /* CoreApi */
+       public <T> RdfParser addImplClass(Class<T> interfaceClass, Class<? 
extends T> implClass) throws LockedException {
+               super.addImplClass(interfaceClass, implClass);
+               return this;
+       }
+
+       @Override /* CoreApi */
+       public RdfParser setClassLoader(ClassLoader classLoader) throws 
LockedException {
+               super.setClassLoader(classLoader);
+               return this;
+       }
+
+       @Override /* Lockable */
+       public RdfParser lock() {
+               super.lock();
+               return this;
+       }
+
+       @Override /* Lockable */
+       public RdfParser clone() {
+               try {
+                       RdfParser c = (RdfParser)super.clone();
+                       return c;
+               } catch (CloneNotSupportedException e) {
+                       throw new RuntimeException(e); // Shouldn't happen
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserContext.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserContext.java 
b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserContext.java
new file mode 100644
index 0000000..eb0c1f9
--- /dev/null
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserContext.java
@@ -0,0 +1,115 @@
+// 
***************************************************************************************************************************
+// * 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.parser.*;
+import org.apache.juneau.xml.*;
+
+/**
+ * Configurable properties on the {@link RdfParser} class.
+ * <p>
+ * Context properties are set by calling {@link 
ContextFactory#setProperty(String, Object)} on the context factory
+ * returned {@link CoreApi#getContextFactory()}.
+ * <p>
+ * The following convenience methods are also provided for setting context 
properties:
+ * <ul>
+ *     <li>{@link RdfParser#setProperty(String,Object)}
+ *     <li>{@link RdfParser#setProperties(ObjectMap)}
+ *     <li>{@link RdfParser#addNotBeanClasses(Class[])}
+ *     <li>{@link RdfParser#addBeanFilters(Class[])}
+ *     <li>{@link RdfParser#addPojoSwaps(Class[])}
+ *     <li>{@link RdfParser#addToDictionary(Class[])}
+ *     <li>{@link RdfParser#addImplClass(Class,Class)}
+ * </ul>
+ * <p>
+ * See {@link ContextFactory} for more information about context properties.
+ *
+ * <h6 class='topic' id='ConfigProperties'>Configurable properties on the RDF 
parsers</h6>
+ * <table class='styled' style='border-collapse: collapse;'>
+ *     <tr><th>Setting name</th><th>Description</th><th>Data 
type</th><th>Default value</th><th>Session overridable</th></tr>
+ *     <tr>
+ *             <td>{@link #RDF_trimWhitespace}</td>
+ *             <td>Trim whitespace from text elements.</td>
+ *             <td><code>Boolean</code></td>
+ *             <td><jk>false</jk></td>
+ *             <td><jk>true</jk></td>
+ *     </tr>
+ * </table>
+ *
+ * <h6 class='topic' id='ConfigProperties'>Configurable properties inherited 
by the RDF parsers</h6>
+ * <ul class='javahierarchy'>
+ *     <li class='c'><a class='doclink' 
href='../BeanContext.html#ConfigProperties'>BeanContext</a> - Properties 
associated with handling beans on serializers and parsers.
+ *     <ul>
+ *             <li class='c'><a class='doclink' 
href='../parser/ParserContext.html#ConfigProperties'>ParserContext</a> - 
Configurable properties common to all parsers.
+ *             <ul>
+ *                     <li class='i'><a class='doclink' 
href='RdfCommonContext.html#ConfigProperties'>RdfCommonContext</a> - 
Configurable properties common to the RDF serializers and parsers.
+ *             </ul>
+ *     </ul>
+ * </ul>
+ */
+public final class RdfParserContext extends ParserContext implements 
RdfCommonContext {
+
+       /**
+        * <b>Configuration property:</b>  Trim whitespace from text elements.
+        * <p>
+        * <ul>
+        *      <li><b>Name:</b> <js>"RdfParser.trimWhitespace"</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>, whitespace in text elements will be automatically 
trimmed.
+        */
+       public static final String RDF_trimWhitespace = 
"RdfParser.trimWhitespace";
+
+       final boolean trimWhitespace, looseCollections;
+       final String rdfLanguage;
+       final Namespace juneauNs, juneauBpNs;
+       final RdfCollectionFormat collectionFormat;
+       final Map<String,Object> jenaSettings = new HashMap<String,Object>();
+
+       /**
+        * Constructor.
+        * <p>
+        * Typically only called from {@link ContextFactory#getContext(Class)}.
+        *
+        * @param cf The factory that created this context.
+        */
+       public RdfParserContext(ContextFactory cf) {
+               super(cf);
+               trimWhitespace = cf.getProperty(RDF_trimWhitespace, 
boolean.class, false);
+               looseCollections = cf.getProperty(RDF_looseCollections, 
boolean.class, false);
+               rdfLanguage = cf.getProperty(RDF_language, String.class, 
"RDF/XML-ABBREV");
+               juneauNs = cf.getProperty(RDF_juneauNs, Namespace.class, new 
Namespace("j", "http://www.apache.org/juneau/";));
+               juneauBpNs = cf.getProperty(RDF_juneauBpNs, Namespace.class, 
new Namespace("j", "http://www.apache.org/juneaubp/";));
+               collectionFormat = cf.getProperty(RDF_collectionFormat, 
RdfCollectionFormat.class, RdfCollectionFormat.DEFAULT);
+       }
+
+       @Override /* Context */
+       public ObjectMap asMap() {
+               return super.asMap()
+                       .append("RdfParserContext", new ObjectMap()
+                               .append("trimWhitespace", trimWhitespace)
+                               .append("looseCollections", looseCollections)
+                               .append("rdfLanguage", rdfLanguage)
+                               .append("juneauNs", juneauNs)
+                               .append("juneauBpNs", juneauBpNs)
+                               .append("collectionFormat", collectionFormat)
+                       );
+       }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java 
b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
new file mode 100644
index 0000000..2c73a00
--- /dev/null
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
@@ -0,0 +1,234 @@
+// 
***************************************************************************************************************************
+// * 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 java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+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 
RdfParser}.
+ * <p>
+ * This class is NOT thread safe.  It is meant to be discarded after one-time 
use.
+ */
+public class RdfParserSession extends ParserSession {
+
+       private final String rdfLanguage;
+       private final Namespace juneauNs, juneauBpNs;
+       private final Property pRoot, pValue, pClass, pType;
+       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 input The input.  Can be any of the following types:
+        *      <ul>
+        *              <li><jk>null</jk>
+        *              <li>{@link Reader}
+        *              <li>{@link CharSequence}
+        *              <li>{@link InputStream} containing UTF-8 encoded text.
+        *              <li>{@link File} containing system encoded text.
+        *      </ul>
+        * @param op The override properties.
+        *      These override any context properties defined in the context.
+        * @param javaMethod The java method that called this parser, usually 
the method in a REST servlet.
+        * @param outer The outer object for instantiating top-level non-static 
inner classes.
+        * @param locale The session locale.
+        *      If <jk>null</jk>, then the locale defined on the context is 
used.
+        * @param timeZone The session timezone.
+        *      If <jk>null</jk>, then the timezone defined on the context is 
used.
+        */
+       protected RdfParserSession(RdfParserContext ctx, ObjectMap op, Object 
input, Method javaMethod, Object outer, Locale locale, TimeZone timeZone) {
+               super(ctx, op, input, javaMethod, outer, locale, timeZone);
+               ObjectMap jenaSettings = new ObjectMap();
+               jenaSettings.putAll(ctx.jenaSettings);
+               if (op == null || op.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 = op.getString(RDF_language, 
ctx.rdfLanguage);
+                       this.juneauNs = (op.containsKey(RDF_juneauNs) ? 
NamespaceFactory.parseNamespace(op.get(RDF_juneauNs)) : ctx.juneauNs);
+                       this.juneauBpNs = (op.containsKey(RDF_juneauBpNs) ? 
NamespaceFactory.parseNamespace(op.get(RDF_juneauBpNs)) : ctx.juneauBpNs);
+                       this.trimWhitespace = 
op.getBoolean(RdfParserContext.RDF_trimWhitespace, ctx.trimWhitespace);
+                       this.collectionFormat = 
RdfCollectionFormat.valueOf(op.getString(RDF_collectionFormat, "DEFAULT"));
+                       this.looseCollections = 
op.getBoolean(RDF_looseCollections, ctx.looseCollections);
+               }
+               this.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.pClass = model.createProperty(juneauNs.getUri(), 
RDF_juneauNs_CLASS);
+               this.pType = 
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());
+               }
+       }
+
+       /**
+        * Returns <jk>true</jk> if this resource was already visited.
+        *
+        * @param r The resource to check.
+        * @return <jk>true</jk> if this resource was already visited.
+        */
+       public final boolean wasAlreadyProcessed(Resource r) {
+               return ! urisVisited.add(r);
+       }
+
+       /**
+        * Returns the root property.
+        *
+        * @return The root property.
+        */
+       public final Property getRootProperty() {
+               return pRoot;
+       }
+
+       /**
+        * Returns the RDF property identifier <js>"value"</js>.
+        *
+        * @return The RDF property identifier <js>"value"</js>.
+        */
+       public final Property getValueProperty() {
+               return pValue;
+       }
+
+       /**
+        * Returns the RDF property identifier <js>"class"</js>.
+        *
+        * @return The RDF property identifier <js>"class"</js>.
+        */
+       public final Property getClassProperty() {
+               return pClass;
+       }
+
+       /**
+        * Returns the RDF property identifier <js>"type"</js>.
+        *
+        * @return The RDF property identifier <js>"type"</js>.
+        */
+       public final Property getTypeProperty() {
+               return pType;
+       }
+
+       /**
+        * Returns the RDF model being parsed into.
+        *
+        * @return The RDF model being parsed into.
+        */
+       public final Model getModel() {
+               return model;
+       }
+
+       /**
+        * Returns the RDF reader that's reading the model.
+        *
+        * @return The RDF reader that's reading the model.
+        */
+       public final RDFReader getRdfReader() {
+               return rdfReader;
+       }
+
+       /**
+        * Returns the {@link RdfCommonContext#RDF_collectionFormat} setting 
value for this session.
+        *
+        * @return The {@link RdfCommonContext#RDF_collectionFormat} setting 
value for this session.
+        */
+       public final RdfCollectionFormat getCollectionFormat() {
+               return collectionFormat;
+       }
+
+       /**
+        * Returns the {@link RdfCommonContext#RDF_looseCollections} setting 
value for this session.
+        *
+        * @return The {@link RdfCommonContext#RDF_looseCollections} setting 
value for this session.
+        */
+       public final boolean isLooseCollections() {
+               return looseCollections;
+       }
+
+       /**
+        * Returns the Juneau namespace URI.
+        *
+        * @return The Juneau namespace URI.
+        */
+       public final String getJuneauNsUri() {
+               return juneauNs.getUri();
+       }
+
+       /**
+        * Adds the specified namespace as a model prefix.
+        *
+        * @param ns The XML namespace.
+        */
+       public final void addModelPrefix(Namespace ns) {
+               model.setNsPrefix(ns.getName(), ns.getUri());
+       }
+
+       /**
+        * Constructs a <code>Property</code> in the Juneau Bean namespace in 
this mode.
+        *
+        * @param name The property name.
+        * @return The new property object.
+        */
+       public final Property getProperty(String name) {
+               return model.createProperty(juneauBpNs.getUri(), name);
+       }
+
+       /**
+        * Decodes the specified string.
+        * <p>
+        * If {@link RdfParserContext#RDF_trimWhitespace} is <jk>true</jk>, the 
resulting string is trimmed before decoding.
+        * <p>
+        * If {@link #isTrimStrings()} is <jk>true</jk>, the resulting string 
is trimmed after decoding.
+        *
+        * @param o The string to trim.
+        * @return The trimmed string, or <jk>null</jk> if the string was 
<jk>null</jk>.
+        */
+       public final String decodeString(Object o) {
+               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;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java 
b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
new file mode 100644
index 0000000..0728b39
--- /dev/null
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
@@ -0,0 +1,466 @@
+// 
***************************************************************************************************************************
+// * 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 java.lang.reflect.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.transform.*;
+import org.apache.juneau.xml.*;
+
+import com.hp.hpl.jena.rdf.model.*;
+
+/**
+ * Serializes POJOs to RDF.
+ *
+ * <h6 class='topic'>Configurable properties</h6>
+ * <p>
+ *     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>
+ * <p>
+ *     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>
+ *
+ * <h6 class='topic'>Additional Information</h6>
+ * <p>
+ *     See <a class='doclink' href='package-summary.html#TOC'>RDF Overview</a> 
for an overview of RDF support in Juneau.
+ */
+@SuppressWarnings({ "rawtypes", "unchecked" })
+@Produces(value="text/xml+rdf+abbrev", contentType="text/xml+rdf")
+public class RdfSerializer extends WriterSerializer {
+
+       /** Default RDF/XML serializer, all default settings.*/
+       public static final RdfSerializer DEFAULT_XML = new 
RdfSerializer.Xml().lock();
+
+       /** Default Abbreviated RDF/XML serializer, all default settings.*/
+       public static final RdfSerializer DEFAULT_XMLABBREV = new 
RdfSerializer.XmlAbbrev().lock();
+
+       /** Default Turtle serializer, all default settings.*/
+       public static final RdfSerializer DEFAULT_TURTLE = new 
RdfSerializer.Turtle().lock();
+
+       /** Default N-Triple serializer, all default settings.*/
+       public static final RdfSerializer DEFAULT_NTRIPLE = new 
RdfSerializer.NTriple().lock();
+
+       /** Default N3 serializer, all default settings.*/
+       public static final RdfSerializer DEFAULT_N3 = new 
RdfSerializer.N3().lock();
+
+
+       /** Produces RDF/XML output */
+       @Produces("text/xml+rdf")
+       public static class Xml extends RdfSerializer {
+               /** Constructor */
+               public Xml() {
+                       setProperty(RDF_language, LANG_RDF_XML);
+               }
+       }
+
+       /** Produces Abbreviated RDF/XML output */
+       @Produces(value="text/xml+rdf+abbrev", contentType="text/xml+rdf")
+       public static class XmlAbbrev extends RdfSerializer {
+               /** Constructor */
+               public XmlAbbrev() {
+                       setProperty(RDF_language, LANG_RDF_XML_ABBREV);
+               }
+       }
+
+       /** Produces N-Triple output */
+       @Produces("text/n-triple")
+       public static class NTriple extends RdfSerializer {
+               /** Constructor */
+               public NTriple() {
+                       setProperty(RDF_language, LANG_NTRIPLE);
+               }
+       }
+
+       /** Produces Turtle output */
+       @Produces("text/turtle")
+       public static class Turtle extends RdfSerializer {
+               /** Constructor */
+               public Turtle() {
+                       setProperty(RDF_language, LANG_TURTLE);
+               }
+       }
+
+       /** Produces N3 output */
+       @Produces("text/n3")
+       public static class N3 extends RdfSerializer {
+               /** Constructor */
+               public N3() {
+                       setProperty(RDF_language, LANG_N3);
+               }
+       }
+
+
+       @Override /* Serializer */
+       protected void doSerialize(SerializerSession session, Object o) throws 
Exception {
+
+               RdfSerializerSession s = (RdfSerializerSession)session;
+
+               Model model = s.getModel();
+               Resource r = null;
+
+               ClassMeta<?> cm = session.getClassMetaForObject(o);
+               if (s.isLooseCollections() && cm != null && 
cm.isCollectionOrArray()) {
+                       Collection c = s.sort(cm.isCollection() ? (Collection)o 
: toList(cm.getInnerClass(), o));
+                       for (Object o2 : c)
+                               serializeAnything(s, o2, false, object(), 
"root", null, null);
+               } else {
+                       RDFNode n = serializeAnything(s, o, false, object(), 
"root", null, null);
+                       if (n.isLiteral()) {
+                               r = model.createResource();
+                               r.addProperty(s.getValueProperty(), n);
+                       } else {
+                               r = n.asResource();
+                       }
+
+                       if (s.isAddRootProp())
+                               r.addProperty(s.getRootProp(), "true");
+               }
+
+               s.getRdfWriter().write(model, session.getWriter(), 
"http://unknown/";);
+       }
+
+       private RDFNode serializeAnything(RdfSerializerSession session, Object 
o, boolean isURI, ClassMeta<?> eType, String attrName, BeanPropertyMeta bpm, 
Resource parentResource) throws SerializeException {
+               Model m = session.getModel();
+
+               ClassMeta<?> aType = null;       // The actual type
+               ClassMeta<?> wType = null;       // The wrapped type
+               ClassMeta<?> sType = object();   // The serialized type
+
+               aType = session.push(attrName, o, eType);
+
+               if (eType == null)
+                       eType = object();
+
+               // Handle recursion
+               if (aType == null) {
+                       o = null;
+                       aType = object();
+               }
+
+               if (o != null) {
+
+                       if (aType.isDelegate()) {
+                               wType = aType;
+                               aType = ((Delegate)o).getClassMeta();
+                       }
+
+                       sType = aType.getSerializedClassMeta();
+
+                       // Swap if necessary
+                       PojoSwap swap = aType.getPojoSwap();
+                       if (swap != null) {
+                               o = swap.swap(session, o);
+
+                               // If the getSwapClass() method returns Object, 
we need to figure out
+                               // the actual type now.
+                               if (sType.isObject())
+                                       sType = 
session.getClassMetaForObject(o);
+                       }
+               } else {
+                       sType = eType.getSerializedClassMeta();
+               }
+
+               RDFNode n = null;
+
+               if (o == null || sType.isChar() && ((Character)o).charValue() 
== 0) {
+                       if (bpm != null) {
+                               if (! session.isTrimNulls()) {
+                                       n = m.createResource(RDF_NIL);
+                               }
+                       } else {
+                               n = m.createResource(RDF_NIL);
+                       }
+
+               } else if (sType.isUri() || isURI) {
+                       n = m.createResource(getUri(session, o, null));
+
+               } else if (sType.isCharSequence() || sType.isChar()) {
+                       n = m.createLiteral(session.encodeTextInvalidChars(o));
+
+               } else if (sType.isNumber() || sType.isBoolean()) {
+                       if (! session.isAddLiteralTypes())
+                               n = m.createLiteral(o.toString());
+                       else
+                               n = m.createTypedLiteral(o);
+
+               } else if (sType.isMap() || (wType != null && wType.isMap())) {
+                       if (o instanceof BeanMap) {
+                               BeanMap bm = (BeanMap)o;
+                               Object uri = null;
+                               RdfBeanMeta rbm = 
(RdfBeanMeta)bm.getMeta().getExtendedMeta(RdfBeanMeta.class);
+                               if (rbm.hasBeanUri())
+                                       uri = rbm.getBeanUriProperty().get(bm);
+                               String uri2 = getUri(session, uri, null);
+                               n = m.createResource(uri2);
+                               serializeBeanMap(session, bm, (Resource)n);
+                       } else {
+                               Map m2 = (Map)o;
+                               n = m.createResource();
+                               serializeMap(session, m2, (Resource)n, sType);
+                       }
+
+               } else if (sType.hasToObjectMapMethod()) {
+                       Map m2 = sType.toObjectMap(o);
+                       n = m.createResource();
+                       serializeMap(session, m2, (Resource)n, sType);
+
+               } else if (sType.isBean()) {
+                       BeanMap bm = session.toBeanMap(o);
+                       Object uri = null;
+                       RdfBeanMeta rbm = 
(RdfBeanMeta)bm.getMeta().getExtendedMeta(RdfBeanMeta.class);
+                       if (rbm.hasBeanUri())
+                               uri = rbm.getBeanUriProperty().get(bm);
+                       String uri2 = getUri(session, uri, null);
+                       n = m.createResource(uri2);
+                       serializeBeanMap(session, bm, (Resource)n);
+
+               } else if (sType.isCollectionOrArray() || (wType != null && 
wType.isCollection())) {
+                       Collection c = session.sort(sType.isCollection() ? 
(Collection)o : toList(sType.getInnerClass(), o));
+                       RdfCollectionFormat f = session.getCollectionFormat();
+                       RdfClassMeta rcm = 
sType.getExtendedMeta(RdfClassMeta.class);
+                       if (rcm.getCollectionFormat() != 
RdfCollectionFormat.DEFAULT)
+                               f = rcm.getCollectionFormat();
+                       if (bpm != null && 
bpm.getExtendedMeta(RdfBeanPropertyMeta.class).getCollectionFormat() != 
RdfCollectionFormat.DEFAULT)
+                               f = 
bpm.getExtendedMeta(RdfBeanPropertyMeta.class).getCollectionFormat();
+                       switch (f) {
+                               case BAG: n = serializeToContainer(session, c, 
sType, m.createBag()); break;
+                               case LIST: n = serializeToList(session, c, 
sType); break;
+                               case MULTI_VALUED: 
serializeToMultiProperties(session, c, sType, bpm, attrName, parentResource); 
break;
+                               default: n = serializeToContainer(session, c, 
sType, m.createSeq());
+                       }
+               } else {
+                       n = 
m.createLiteral(session.encodeTextInvalidChars(session.toString(o)));
+               }
+
+               if (session.isAddBeanTypeProperties() && n != null && 
n.isResource()) {
+                       if (o != null && ! eType.equals(aType))
+                               
n.asResource().addProperty(session.getClassProperty(), aType.toString());
+                       else if (o == null)
+                               
n.asResource().addProperty(session.getClassProperty(), eType.toString());
+               }
+
+               session.pop();
+
+               return n;
+       }
+
+       private String getUri(RdfSerializerSession session, Object uri, Object 
uri2) {
+               String s = null;
+               if (uri != null)
+                       s = uri.toString();
+               if ((s == null || s.isEmpty()) && uri2 != null)
+                       s = uri2.toString();
+               if (s == null)
+                       return null;
+               if (s.indexOf("://") == -1) {
+                       String aUri = session.getAbsolutePathUriBase();
+                       String rUri = session.getRelativeUriBase();
+                       if (StringUtils.startsWith(s, '/')) {
+                               if (aUri != null)
+                                       return aUri + s;
+                       } else {
+                               if (rUri != null) {
+                                       if (rUri.equals("/"))
+                                               return '/' + s;
+                                       return rUri + '/' + s;
+                               }
+                       }
+               }
+               return s;
+       }
+
+       private void serializeMap(RdfSerializerSession session, Map m, Resource 
r, ClassMeta<?> type) throws SerializeException {
+
+               m = session.sort(m);
+
+               ClassMeta<?> keyType = type.getKeyType(), valueType = 
type.getValueType();
+
+               ArrayList<Map.Entry<Object,Object>> l = new 
ArrayList<Map.Entry<Object,Object>>(m.entrySet());
+               Collections.reverse(l);
+               for (Map.Entry<Object,Object> me : l) {
+                       Object value = me.getValue();
+
+                       Object key = session.generalize(me.getKey(), keyType);
+
+                       Namespace ns = session.getJuneauBpNs();
+                       Model model = session.getModel();
+                       Property p = model.createProperty(ns.getUri(), 
session.encodeElementName(session.toString(key)));
+                       RDFNode n = serializeAnything(session, value, false, 
valueType, key == null ? null : session.toString(key), null, r);
+                       if (n != null)
+                               r.addProperty(p, n);
+               }
+       }
+
+       private void serializeBeanMap(RdfSerializerSession session, BeanMap<?> 
m, Resource r) throws SerializeException {
+               List<BeanPropertyValue> l = m.getValues(session.isTrimNulls());
+               Collections.reverse(l);
+               for (BeanPropertyValue bpv : l) {
+                       BeanPropertyMeta pMeta = bpv.getMeta();
+                       ClassMeta<?> cMeta = pMeta.getClassMeta();
+
+                       if 
(pMeta.getExtendedMeta(RdfBeanPropertyMeta.class).isBeanUri())
+                               continue;
+
+                       String key = bpv.getName();
+                       Object value = bpv.getValue();
+                       Throwable t = bpv.getThrown();
+                       if (t != null)
+                               session.addBeanGetterWarning(pMeta, t);
+
+                       if (session.canIgnoreValue(cMeta, key, value))
+                               continue;
+
+                       BeanPropertyMeta bpm = bpv.getMeta();
+                       Namespace ns = 
bpm.getExtendedMeta(RdfBeanPropertyMeta.class).getNamespace();
+                       if (ns == null && session.isUseXmlNamespaces())
+                               ns = 
bpm.getExtendedMeta(XmlBeanPropertyMeta.class).getNamespace();
+                       if (ns == null)
+                               ns = session.getJuneauBpNs();
+                       else if (session.isAutoDetectNamespaces())
+                               session.addModelPrefix(ns);
+
+                       Property p = 
session.getModel().createProperty(ns.getUri(), session.encodeElementName(key));
+                       RDFNode n = serializeAnything(session, value, 
pMeta.isUri(), cMeta, key, pMeta, r);
+                       if (n != null)
+                               r.addProperty(p, n);
+               }
+       }
+
+
+       private Container serializeToContainer(RdfSerializerSession session, 
Collection c, ClassMeta<?> type, Container list) throws SerializeException {
+
+               ClassMeta<?> elementType = type.getElementType();
+               for (Object e : c) {
+                       RDFNode n = serializeAnything(session, e, false, 
elementType, null, null, null);
+                       list = list.add(n);
+               }
+               return list;
+       }
+
+       private RDFList serializeToList(RdfSerializerSession session, 
Collection c, ClassMeta<?> type) throws SerializeException {
+               ClassMeta<?> elementType = type.getElementType();
+               List<RDFNode> l = new ArrayList<RDFNode>(c.size());
+               for (Object e : c) {
+                       l.add(serializeAnything(session, e, false, elementType, 
null, null, null));
+               }
+               return session.getModel().createList(l.iterator());
+       }
+
+       private void serializeToMultiProperties(RdfSerializerSession session, 
Collection c, ClassMeta<?> sType, BeanPropertyMeta bpm, String attrName, 
Resource parentResource) throws SerializeException {
+               ClassMeta<?> elementType = sType.getElementType();
+               for (Object e : c) {
+                       Namespace ns = null;
+                       if (bpm != null) {
+                               ns = 
bpm.getExtendedMeta(RdfBeanPropertyMeta.class).getNamespace();
+                               if (ns == null && session.isUseXmlNamespaces())
+                                       ns = 
bpm.getExtendedMeta(XmlBeanPropertyMeta.class).getNamespace();
+                       }
+                       if (ns == null)
+                               ns = session.getJuneauBpNs();
+                       else if (session.isAutoDetectNamespaces())
+                               session.addModelPrefix(ns);
+                       RDFNode n2 = serializeAnything(session, e, false, 
elementType, null, null, null);
+                       Property p = 
session.getModel().createProperty(ns.getUri(), 
session.encodeElementName(attrName));
+                       parentResource.addProperty(p, n2);
+               }
+
+       }
+
+       
//--------------------------------------------------------------------------------
+       // Overridden methods
+       
//--------------------------------------------------------------------------------
+
+       @Override /* Serializer */
+       public RdfSerializerSession createSession(Object output, ObjectMap op, 
Method javaMethod, Locale locale, TimeZone timeZone) {
+               return new 
RdfSerializerSession(getContext(RdfSerializerContext.class), op, output, 
javaMethod, locale, timeZone);
+       }
+
+       @Override /* CoreApi */
+       public RdfSerializer setProperty(String property, Object value) throws 
LockedException {
+               super.setProperty(property, value);
+               return this;
+       }
+
+       @Override /* CoreApi */
+       public RdfSerializer setProperties(ObjectMap properties) throws 
LockedException {
+               super.setProperties(properties);
+               return this;
+       }
+
+       @Override /* CoreApi */
+       public RdfSerializer addNotBeanClasses(Class<?>...classes) throws 
LockedException {
+               super.addNotBeanClasses(classes);
+               return this;
+       }
+
+       @Override /* CoreApi */
+       public RdfSerializer addBeanFilters(Class<?>...classes) throws 
LockedException {
+               super.addBeanFilters(classes);
+               return this;
+       }
+
+       @Override /* CoreApi */
+       public RdfSerializer addPojoSwaps(Class<?>...classes) throws 
LockedException {
+               super.addPojoSwaps(classes);
+               return this;
+       }
+
+       @Override /* CoreApi */
+       public RdfSerializer addToDictionary(Class<?>...classes) throws 
LockedException {
+               super.addToDictionary(classes);
+               return this;
+       }
+
+       @Override /* CoreApi */
+       public <T> RdfSerializer addImplClass(Class<T> interfaceClass, Class<? 
extends T> implClass) throws LockedException {
+               super.addImplClass(interfaceClass, implClass);
+               return this;
+       }
+
+       @Override /* CoreApi */
+       public RdfSerializer setClassLoader(ClassLoader classLoader) throws 
LockedException {
+               super.setClassLoader(classLoader);
+               return this;
+       }
+
+       @Override /* Lockable */
+       public RdfSerializer lock() {
+               super.lock();
+               return this;
+       }
+
+       @Override /* Lockable */
+       public RdfSerializer clone() {
+               try {
+                       return (RdfSerializer)super.clone();
+               } catch (CloneNotSupportedException e) {
+                       throw new RuntimeException(e); // Shouldn't happen
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerContext.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerContext.java
 
b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerContext.java
new file mode 100644
index 0000000..fec2789
--- /dev/null
+++ 
b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerContext.java
@@ -0,0 +1,196 @@
+// 
***************************************************************************************************************************
+// * 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 
ContextFactory#setProperty(String, Object)} on the context factory
+ * returned {@link CoreApi#getContextFactory()}.
+ * <p>
+ * The following convenience methods are also provided for setting context 
properties:
+ * <ul>
+ *     <li>{@link RdfSerializer#setProperty(String,Object)}
+ *     <li>{@link RdfSerializer#setProperties(ObjectMap)}
+ *     <li>{@link RdfSerializer#addNotBeanClasses(Class[])}
+ *     <li>{@link RdfSerializer#addBeanFilters(Class[])}
+ *     <li>{@link RdfSerializer#addPojoSwaps(Class[])}
+ *     <li>{@link RdfSerializer#addToDictionary(Class[])}
+ *     <li>{@link RdfSerializer#addImplClass(Class,Class)}
+ * </ul>
+ * <p>
+ * See {@link ContextFactory} for more information about context properties.
+ *
+ * <h6 class='topic' id='ConfigProperties'>Configurable properties on the RDF 
serializers</h6>
+ * <table class='styled' style='border-collapse: collapse;'>
+ *     <tr><th>Setting name</th><th>Description</th><th>Data 
type</th><th>Default value</th><th>Session overridable</th></tr>
+ *     <tr>
+ *             <td>{@link #RDF_addLiteralTypes}</td>
+ *             <td>Add XSI data types to non-<code>String</code> literals.</td>
+ *             <td><code>Boolean</code></td>
+ *             <td><jk>false</jk></td>
+ *             <td><jk>true</jk></td>
+ *     </tr>
+ *     <tr>
+ *             <td>{@link #RDF_addRootProperty}</td>
+ *             <td>Add RDF root identifier property to root node.</td>
+ *             <td><code>Boolean</code></td>
+ *             <td><jk>false</jk></td>
+ *             <td><jk>true</jk></td>
+ *     </tr>
+ *     <tr>
+ *             <td>{@link #RDF_autoDetectNamespaces}</td>
+ *             <td>Auto-detect namespace usage.</td>
+ *             <td><code>Boolean</code></td>
+ *             <td><jk>true</jk></td>
+ *             <td><jk>true</jk></td>
+ *     </tr>
+ *     <tr>
+ *             <td>{@link #RDF_namespaces}</td>
+ *             <td>Default namespaces.</td>
+ *             <td><code>List&lt;{@link Namespace}&gt;</code></td>
+ *             <td>empty list</td>
+ *             <td><jk>true</jk></td>
+ *     </tr>
+ * </table>
+ *
+ * <h6 class='topic' id='ConfigProperties'>Configurable properties inherited 
by the RDF serializers</h6>
+ * <ul class='javahierarchy'>
+ *     <li class='c'><a class='doclink' 
href='../BeanContext.html#ConfigProperties'>BeanContext</a> - Properties 
associated with handling beans on serializers and parsers.
+ *     <ul>
+ *             <li class='c'><a class='doclink' 
href='../serializer/SerializerContext.html#ConfigProperties'>SerializerContext</a>
 - Configurable properties common to all serializers.
+ *             <ul>
+ *                     <li class='c'><a class='doclink' 
href='RdfCommonContext.html#ConfigProperties'>RdfCommonContext</a> - 
Configurable properties common to the RDF serializers and parsers.
+ *             </ul>
+ *     </ul>
+ * </ul>
+ */
+public final class RdfSerializerContext extends SerializerContext implements 
RdfCommonContext {
+
+       /**
+        * <b>Configuration property:</b>  Add XSI data types to 
non-<code>String</code> literals.
+        * <p>
+        * <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.
+        * <p>
+        * <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.
+        * <p>
+        * <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.
+        * <p>
+        * <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";
+
+
+       final boolean addLiteralTypes, addRootProperty, useXmlNamespaces, 
looseCollections, autoDetectNamespaces;
+       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 ContextFactory#getContext(Class)}.
+        *
+        * @param cf The factory that created this context.
+        */
+       public RdfSerializerContext(ContextFactory cf) {
+               super(cf);
+               addLiteralTypes = cf.getProperty(RDF_addLiteralTypes, 
boolean.class, false);
+               addRootProperty = cf.getProperty(RDF_addRootProperty, 
boolean.class, false);
+               useXmlNamespaces = cf.getProperty(RDF_useXmlNamespaces, 
boolean.class, true);
+               looseCollections = cf.getProperty(RDF_looseCollections, 
boolean.class, false);
+               autoDetectNamespaces = cf.getProperty(RDF_autoDetectNamespaces, 
boolean.class, true);
+               rdfLanguage = cf.getProperty(RDF_language, String.class, 
"RDF/XML-ABBREV");
+               juneauNs = cf.getProperty(RDF_juneauNs, Namespace.class, new 
Namespace("j", "http://www.apache.org/juneau/";));
+               juneauBpNs = cf.getProperty(RDF_juneauBpNs, Namespace.class, 
new Namespace("jp", "http://www.apache.org/juneaubp/";));
+               collectionFormat = cf.getProperty(RDF_collectionFormat, 
RdfCollectionFormat.class, RdfCollectionFormat.DEFAULT);
+               namespaces = cf.getProperty(RDF_namespaces, Namespace[].class, 
new Namespace[0]);
+       }
+
+       @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)
+                       );
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
 
b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
new file mode 100644
index 0000000..d30f934
--- /dev/null
+++ 
b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
@@ -0,0 +1,271 @@
+// 
***************************************************************************************************************************
+// * 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.lang.reflect.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.xml.*;
+
+import com.hp.hpl.jena.rdf.model.*;
+
+/**
+ * Session object that lives for the duration of a single use of {@link 
RdfSerializer}.
+ * <p>
+ * This class is NOT thread safe.  It is meant to be discarded after one-time 
use.
+ */
+public final class RdfSerializerSession extends SerializerSession {
+
+       private final String rdfLanguage;
+       private final Namespace juneauNs, juneauBpNs;
+       private final boolean addLiteralTypes, addRootProperty, 
useXmlNamespaces, looseCollections, autoDetectNamespaces;
+       private final Property pRoot, pValue, pClass;
+       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 output The output object.  See {@link 
JsonSerializerSession#getWriter()} for valid class types.
+        * @param op The override properties.
+        *      These override any context properties defined in the context.
+        * @param javaMethod The java method that called this parser, usually 
the method in a REST servlet.
+        * @param locale The session locale.
+        *      If <jk>null</jk>, then the locale defined on the context is 
used.
+        * @param timeZone The session timezone.
+        *      If <jk>null</jk>, then the timezone defined on the context is 
used.
+        */
+       protected RdfSerializerSession(RdfSerializerContext ctx, ObjectMap op, 
Object output, Method javaMethod, Locale locale, TimeZone timeZone) {
+               super(ctx, op, output, javaMethod, locale, timeZone);
+               ObjectMap jenaSettings = new ObjectMap();
+               jenaSettings.put("rdfXml.tab", isUseIndentation() ? 2 : 0);
+               jenaSettings.put("rdfXml.attributeQuoteChar", 
Character.toString(getQuoteChar()));
+               jenaSettings.putAll(ctx.jenaSettings);
+               if (op == null || op.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;
+               } else {
+                       this.rdfLanguage = op.getString(RDF_language, 
ctx.rdfLanguage);
+                       this.juneauNs = (op.containsKey(RDF_juneauNs) ? 
NamespaceFactory.parseNamespace(op.get(RDF_juneauNs)) : ctx.juneauNs);
+                       this.juneauBpNs = (op.containsKey(RDF_juneauBpNs) ? 
NamespaceFactory.parseNamespace(op.get(RDF_juneauBpNs)) : ctx.juneauBpNs);
+                       this.addLiteralTypes = 
op.getBoolean(RDF_addLiteralTypes, ctx.addLiteralTypes);
+                       this.addRootProperty = 
op.getBoolean(RDF_addRootProperty, ctx.addRootProperty);
+                       for (Map.Entry<String,Object> e : op.entrySet()) {
+                               String key = e.getKey();
+                               if (key.startsWith("Rdf.jena."))
+                                       jenaSettings.put(key.substring(9), 
e.getValue());
+                       }
+                       this.collectionFormat = 
RdfCollectionFormat.valueOf(op.getString(RDF_collectionFormat, "DEFAULT"));
+                       this.looseCollections = 
op.getBoolean(RDF_looseCollections, ctx.looseCollections);
+                       this.useXmlNamespaces = 
op.getBoolean(RDF_useXmlNamespaces, ctx.useXmlNamespaces);
+                       this.autoDetectNamespaces = 
op.getBoolean(RDF_autoDetectNamespaces, ctx.autoDetectNamespaces);
+                       this.namespaces = op.get(Namespace[].class, 
RDF_namespaces, ctx.namespaces);
+               }
+               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);
+               this.pClass = model.createProperty(juneauNs.getUri(), 
RDF_juneauNs_CLASS);
+               writer = model.getWriter(rdfLanguage);
+
+               // Only apply properties with this prefix!
+               String propPrefix = 
RdfCommonContext.LANG_PROP_MAP.get(rdfLanguage);
+               if (propPrefix == null)
+                       throw new RuntimeException("Unknown RDF language 
encountered: '"+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.
+        *
+        * @param ns The XML namespace.
+        */
+       public void addModelPrefix(Namespace ns) {
+               model.setNsPrefix(ns.getName(), ns.getUri());
+       }
+
+       /**
+        * Returns the {@link RdfCommonContext#RDF_collectionFormat} setting 
value for this session.
+        *
+        * @return The {@link RdfCommonContext#RDF_collectionFormat} setting 
value for this session.
+        */
+       public final RdfCollectionFormat getCollectionFormat() {
+               return collectionFormat;
+       }
+
+       /**
+        * Returns the {@link RdfCommonContext#RDF_useXmlNamespaces} setting 
value for this session.
+        *
+        * @return The {@link RdfCommonContext#RDF_useXmlNamespaces} setting 
value for this session.
+        */
+       public final boolean isUseXmlNamespaces() {
+               return useXmlNamespaces;
+       }
+
+       /**
+        * Returns the {@link RdfCommonContext#RDF_looseCollections} setting 
value for this session.
+        *
+        * @return The {@link RdfCommonContext#RDF_looseCollections} setting 
value for this session.
+        */
+       public final boolean isLooseCollections() {
+               return looseCollections;
+       }
+
+       /**
+        * Returns the {@link RdfCommonContext#RDF_language} setting value for 
this session.
+        *
+        * @return The {@link RdfCommonContext#RDF_language} setting value for 
this session.
+        */
+       public final String getRdfLanguage() {
+               return rdfLanguage;
+       }
+
+       /**
+        * Returns the {@link RdfCommonContext#RDF_juneauNs} setting value for 
this session.
+        *
+        * @return The {@link RdfCommonContext#RDF_juneauNs} setting value for 
this session.
+        */
+       public final Namespace getJuneauNs() {
+               return juneauNs;
+       }
+
+       /**
+        * Returns the {@link RdfCommonContext#RDF_juneauBpNs} setting value 
for this session.
+        *
+        * @return The {@link RdfCommonContext#RDF_juneauBpNs} setting value 
for this session.
+        */
+       public final Namespace getJuneauBpNs() {
+               return juneauBpNs;
+       }
+
+       /**
+        * Returns the {@link RdfSerializerContext#RDF_addLiteralTypes} setting 
value for this session.
+        *
+        * @return The {@link RdfSerializerContext#RDF_addLiteralTypes} setting 
value for this session.
+        */
+       public final boolean isAddLiteralTypes() {
+               return addLiteralTypes;
+       }
+
+       /**
+        * Returns the {@link RdfSerializerContext#RDF_addRootProperty} setting 
value for this session.
+        *
+        * @return The {@link RdfSerializerContext#RDF_addRootProperty} setting 
value for this session.
+        */
+       public final boolean isAddRootProp() {
+               return addRootProperty;
+       }
+
+       /**
+        * Returns the {@link RdfSerializerContext#RDF_autoDetectNamespaces} 
setting value for this session.
+        *
+        * @return The {@link RdfSerializerContext#RDF_autoDetectNamespaces} 
setting value for this session.
+        */
+       public final boolean isAutoDetectNamespaces() {
+               return autoDetectNamespaces;
+       }
+
+       /**
+        * Returns the RDF property that identifies the root node in the RDF 
model.
+        *
+        * @return The RDF property that identifies the root node in the RDF 
model.
+        */
+       public final Property getRootProp() {
+               return pRoot;
+       }
+
+       /**
+        * Returns the RDF property that represents a value in the RDF model.
+        *
+        * @return The RDF property that represents a value in the RDF model.
+        */
+       public final Property getValueProperty() {
+               return pValue;
+       }
+
+       /**
+        * Returns the RDF property that represents a class in the RDF model.
+        *
+        * @return The RDF property that represents a class in the RDF model.
+        */
+       public final Property getClassProperty() {
+               return pClass;
+       }
+
+       /**
+        * Returns the RDF model being serialized.
+        *
+        * @return The RDF model being serialized.
+        */
+       public final Model getModel() {
+               return model;
+       }
+
+       /**
+        * Returns the RDF writer that's being serialized to.
+        *
+        * @return The RDF writer that's being serialized to.
+        */
+       public final RDFWriter getRdfWriter() {
+               return writer;
+       }
+
+       /**
+        * XML-encodes the specified string using the {@link 
XmlUtils#encodeTextInvalidChars(Object)} method.
+        *
+        * @param o The string being encoded.
+        * @return The encoded string, or <jk>null</jk> if the input was 
<jk>null</jk>.
+        */
+       public final String encodeTextInvalidChars(Object o) {
+               if (o == null)
+                       return null;
+               String s = toString(o);
+               return XmlUtils.encodeTextInvalidChars(s);
+       }
+
+       /**
+        * XML-encoded the specified element name using the {@link 
XmlUtils#encodeElementName(Object)} method.
+        *
+        * @param o The string being encoded.
+        * @return The encoded string.
+        */
+       public final String encodeElementName(Object o) {
+               String s = toString(o);
+               return XmlUtils.encodeElementName(s);
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfUtils.java
----------------------------------------------------------------------
diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfUtils.java 
b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfUtils.java
new file mode 100644
index 0000000..4377e2e
--- /dev/null
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfUtils.java
@@ -0,0 +1,91 @@
+// 
***************************************************************************************************************************
+// * 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.
+        * 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;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-rdf/src/main/java/org/apache/juneau/jena/annotation/Rdf.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/annotation/Rdf.java 
b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/annotation/Rdf.java
new file mode 100644
index 0000000..275514b
--- /dev/null
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/annotation/Rdf.java
@@ -0,0 +1,71 @@
+// 
***************************************************************************************************************************
+// * 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.annotation;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+import java.lang.annotation.*;
+
+import org.apache.juneau.jena.*;
+
+/**
+ * Annotation for specifying options for RDF serializers.
+ * <p>
+ *     Can be applied to Java packages, types, fields, and methods.
+ * <p>
+ *     Can be used for the following:
+ * <ul class='spaced-list'>
+ *     <li>Override the default behavior of how collections and arrays are 
serialized.
+ * </ul>
+ */
+@Documented
+@Target({PACKAGE,TYPE,FIELD,METHOD})
+@Retention(RUNTIME)
+@Inherited
+public @interface Rdf {
+
+       /**
+        * Sets the XML prefix of this property or class.
+        * <p>
+        *      Must either be matched to a {@link #namespace()} annotation on 
the same object, parent object, or a {@link RdfNs} with the same name
+        *      through the {@link RdfSchema#rdfNs()} annotation on the package.
+        * </p>
+        */
+       String prefix() default "";
+
+       /**
+        * Sets the namespace URI of this property or class.
+        * <p>
+        *      Must be matched with a {@link #prefix()} annotation on this 
object, a parent object, or a {@link RdfNs} with the same name
+        *      through the {@link RdfSchema#rdfNs()} annotation on the package.
+        */
+       String namespace() default "";
+
+       /**
+        * The format for how collections (e.g. lists and arrays) are 
serialized in RDF.
+        * @see RdfCollectionFormat
+        */
+       RdfCollectionFormat collectionFormat() default 
RdfCollectionFormat.DEFAULT;
+
+       /**
+        * Marks a bean property as a resource URI identifier for the bean.
+        * <p>
+        * Has the following effects on the following serializers:
+        * <ul class='spaced-list'>
+        *      <li>{@link RdfSerializer} - Will be rendered as the value of 
the <js>"rdf:about"</js> attribute
+        *              for the bean.
+        * </ul>
+        */
+       boolean beanUri() default false;
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-rdf/src/main/java/org/apache/juneau/jena/annotation/RdfNs.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/annotation/RdfNs.java 
b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/annotation/RdfNs.java
new file mode 100644
index 0000000..0bf66cf
--- /dev/null
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/annotation/RdfNs.java
@@ -0,0 +1,39 @@
+// 
***************************************************************************************************************************
+// * 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.annotation;
+
+import static java.lang.annotation.RetentionPolicy.*;
+
+import java.lang.annotation.*;
+
+/**
+ * Namespace name/URL mapping pair.
+ * <p>
+ *     Used to identify a namespace/URI pair on a {@link RdfSchema#rdfNs()} 
annotation.
+ */
+@Documented
+@Target({})
+@Retention(RUNTIME)
+@Inherited
+public @interface RdfNs {
+
+       /**
+        * RDF namespace prefix.
+        */
+       String prefix();
+
+       /**
+        * RDF namespace URL.
+        */
+       String namespaceURI();
+}

Reply via email to