Allow serializer and parser sessions to be reused. Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/2a37f310 Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/2a37f310 Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/2a37f310
Branch: refs/heads/master Commit: 2a37f31039f08cbdd1badcfe86e69461ac8b2299 Parents: 8879750c Author: JamesBognar <[email protected]> Authored: Fri Jul 28 14:22:08 2017 -0400 Committer: JamesBognar <[email protected]> Committed: Fri Jul 28 14:22:08 2017 -0400 ---------------------------------------------------------------------- .../java/org/apache/juneau/jena/RdfParser.java | 370 +-------- .../apache/juneau/jena/RdfParserSession.java | 480 ++++++++---- .../org/apache/juneau/jena/RdfSerializer.java | 314 +------- .../juneau/jena/RdfSerializerSession.java | 450 ++++++----- .../org/apache/juneau/ParserReaderTest.java | 26 +- .../org/apache/juneau/XmlValidatorParser.java | 30 +- .../apache/juneau/html/CommonParserTest.java | 2 +- .../apache/juneau/jena/CommonParserTest.java | 2 +- .../apache/juneau/json/CommonParserTest.java | 2 +- .../juneau/transforms/LocalizedDatesTest.java | 2 +- .../urlencoding/CommonParser_UonTest.java | 2 +- .../CommonParser_UrlEncodingTest.java | 2 +- .../juneau/urlencoding/UonParserReaderTest.java | 7 +- .../apache/juneau/utils/ParserReaderTest.java | 2 +- .../apache/juneau/utils/StringUtilsTest.java | 2 +- .../org/apache/juneau/xml/CommonParserTest.java | 2 +- .../org/apache/juneau/xml/XmlContentTest.java | 24 +- .../java/org/apache/juneau/BeanContext.java | 24 +- .../java/org/apache/juneau/BeanSession.java | 33 +- .../java/org/apache/juneau/BeanSessionArgs.java | 51 ++ .../main/java/org/apache/juneau/Context.java | 2 +- .../main/java/org/apache/juneau/CoreObject.java | 24 +- .../org/apache/juneau/CoreObjectBuilder.java | 2 +- .../java/org/apache/juneau/PropertyStore.java | 41 +- .../main/java/org/apache/juneau/Session.java | 37 +- .../java/org/apache/juneau/SessionArgs.java | 33 + .../java/org/apache/juneau/csv/CsvParser.java | 20 +- .../org/apache/juneau/csv/CsvParserSession.java | 98 +-- .../org/apache/juneau/csv/CsvSerializer.java | 63 +- .../apache/juneau/csv/CsvSerializerSession.java | 86 ++- .../apache/juneau/html/HtmlDocSerializer.java | 44 +- .../juneau/html/HtmlDocSerializerSession.java | 85 ++- .../org/apache/juneau/html/HtmlDocTemplate.java | 27 +- .../juneau/html/HtmlDocTemplateBasic.java | 35 +- .../java/org/apache/juneau/html/HtmlParser.java | 538 +------------ .../apache/juneau/html/HtmlParserSession.java | 562 +++++++++++++- .../juneau/html/HtmlSchemaDocSerializer.java | 108 +-- .../html/HtmlSchemaDocSerializerSession.java | 124 +++ .../org/apache/juneau/html/HtmlSerializer.java | 614 +-------------- .../juneau/html/HtmlSerializerSession.java | 633 ++++++++++++++- .../juneau/html/HtmlStrippedDocSerializer.java | 18 +- .../html/HtmlStrippedDocSerializerSession.java | 51 ++ .../java/org/apache/juneau/html/HtmlTag.java | 2 - .../org/apache/juneau/internal/IOUtils.java | 55 +- .../java/org/apache/juneau/jso/JsoParser.java | 13 +- .../org/apache/juneau/jso/JsoParserSession.java | 45 ++ .../org/apache/juneau/jso/JsoSerializer.java | 15 +- .../apache/juneau/jso/JsoSerializerSession.java | 52 ++ .../java/org/apache/juneau/json/JsonParser.java | 695 +---------------- .../apache/juneau/json/JsonParserSession.java | 730 ++++++++++++++++-- .../juneau/json/JsonSchemaSerializer.java | 126 +-- .../json/JsonSchemaSerializerSession.java | 129 ++++ .../org/apache/juneau/json/JsonSerializer.java | 241 +----- .../juneau/json/JsonSerializerSession.java | 229 +++++- .../juneau/msgpack/MsgPackInputStream.java | 20 +- .../apache/juneau/msgpack/MsgPackParser.java | 174 +---- .../juneau/msgpack/MsgPackParserSession.java | 204 ++++- .../juneau/msgpack/MsgPackSerializer.java | 170 +---- .../msgpack/MsgPackSerializerSession.java | 201 ++++- .../apache/juneau/parser/InputStreamParser.java | 2 +- .../juneau/parser/InputStreamParserSession.java | 50 ++ .../apache/juneau/parser/ParseException.java | 22 +- .../java/org/apache/juneau/parser/Parser.java | 269 +------ .../org/apache/juneau/parser/ParserContext.java | 6 + .../org/apache/juneau/parser/ParserGroup.java | 4 +- .../org/apache/juneau/parser/ParserInput.java | 230 ------ .../apache/juneau/parser/ParserListener.java | 19 +- .../org/apache/juneau/parser/ParserPipe.java | 278 +++++++ .../org/apache/juneau/parser/ParserReader.java | 65 +- .../org/apache/juneau/parser/ParserSession.java | 595 ++++++++++++--- .../apache/juneau/parser/ParserSessionArgs.java | 61 ++ .../org/apache/juneau/parser/ReaderParser.java | 2 +- .../juneau/parser/ReaderParserSession.java | 51 ++ .../juneau/plaintext/PlainTextParser.java | 11 +- .../plaintext/PlainTextParserSession.java | 43 ++ .../juneau/plaintext/PlainTextSerializer.java | 11 +- .../plaintext/PlainTextSerializerSession.java | 47 ++ .../serializer/OutputStreamSerializer.java | 36 +- .../OutputStreamSerializerSession.java | 75 ++ .../apache/juneau/serializer/Serializer.java | 211 ++--- .../juneau/serializer/SerializerContext.java | 6 + .../juneau/serializer/SerializerGroup.java | 4 +- .../juneau/serializer/SerializerOutput.java | 174 ----- .../juneau/serializer/SerializerPipe.java | 172 +++++ .../juneau/serializer/SerializerSession.java | 316 +++++--- .../serializer/SerializerSessionArgs.java | 65 ++ .../juneau/serializer/WriterSerializer.java | 44 +- .../serializer/WriterSerializerSession.java | 80 ++ .../apache/juneau/soap/SoapXmlSerializer.java | 34 +- .../juneau/soap/SoapXmlSerializerContext.java | 16 +- .../juneau/soap/SoapXmlSerializerSession.java | 75 ++ .../java/org/apache/juneau/uon/UonParser.java | 708 +---------------- .../org/apache/juneau/uon/UonParserSession.java | 760 +++++++++++++++++-- .../java/org/apache/juneau/uon/UonReader.java | 48 +- .../org/apache/juneau/uon/UonSerializer.java | 213 +----- .../apache/juneau/uon/UonSerializerSession.java | 250 ++++-- .../juneau/urlencoding/UrlEncodingParser.java | 300 +------- .../urlencoding/UrlEncodingParserSession.java | 310 +++++++- .../urlencoding/UrlEncodingSerializer.java | 222 +----- .../UrlEncodingSerializerSession.java | 226 +++++- .../org/apache/juneau/xml/XmlDocSerializer.java | 22 +- .../juneau/xml/XmlDocSerializerSession.java | 53 ++ .../java/org/apache/juneau/xml/XmlParser.java | 468 +----------- .../org/apache/juneau/xml/XmlParserSession.java | 645 ++++++++++++---- .../java/org/apache/juneau/xml/XmlReader.java | 301 ++++++++ .../juneau/xml/XmlSchemaDocSerializer.java | 13 +- .../xml/XmlSchemaDocSerializerSession.java | 53 ++ .../apache/juneau/xml/XmlSchemaSerializer.java | 546 +------------ .../juneau/xml/XmlSchemaSerializerSession.java | 551 ++++++++++++++ .../org/apache/juneau/xml/XmlSerializer.java | 630 +-------------- .../apache/juneau/xml/XmlSerializerSession.java | 693 ++++++++++++++--- juneau-core/src/main/javadoc/overview.html | 24 +- .../juneau/examples/rest/PhotosResource.java | 30 +- .../juneau/rest/client/RestCallLogger.java | 2 +- .../juneau/rest/client/RestRequestEntity.java | 21 +- .../apache/juneau/rest/jaxrs/BaseProvider.java | 37 +- .../juneau/rest/test/AcceptCharsetResource.java | 27 +- .../rest/test/CharsetEncodingsResource.java | 22 +- .../rest/test/DefaultContentTypesResource.java | 22 +- .../apache/juneau/rest/test/GroupsResource.java | 22 +- .../juneau/rest/test/InheritanceResource.java | 20 +- .../juneau/rest/test/NlsPropertyResource.java | 10 +- .../juneau/rest/test/OnPostCallResource.java | 28 +- .../juneau/rest/test/OnPreCallResource.java | 14 +- .../juneau/rest/test/ParsersResource.java | 48 +- .../juneau/rest/test/PropertiesResource.java | 24 +- .../juneau/rest/test/SerializersResource.java | 40 +- .../org/apache/juneau/rest/RequestBody.java | 11 +- .../java/org/apache/juneau/rest/RestConfig.java | 6 +- .../org/apache/juneau/rest/RestRequest.java | 3 + .../juneau/rest/RestResourceResolver.java | 44 -- .../juneau/rest/RestResourceResolverSimple.java | 59 ++ .../juneau/rest/annotation/RestResource.java | 2 +- .../juneau/rest/response/DefaultHandler.java | 35 +- .../org/apache/juneau/rest/vars/FileVar.java | 5 +- .../org/apache/juneau/rest/vars/RequestVar.java | 3 +- .../org/apache/juneau/rest/vars/UrlVar.java | 5 +- .../org/apache/juneau/rest/vars/WidgetVar.java | 2 +- .../juneau/rest/widget/MenuItemWidget.java | 17 +- 139 files changed, 9703 insertions(+), 9139 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/2a37f310/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java ---------------------------------------------------------------------- diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java index e2b58d5..d68c70a 100644 --- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java +++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java @@ -12,21 +12,12 @@ // *************************************************************************************************************************** package org.apache.juneau.jena; -import static org.apache.juneau.internal.StringUtils.*; import static org.apache.juneau.jena.Constants.*; import static org.apache.juneau.jena.RdfCommonContext.*; -import java.lang.reflect.*; -import java.util.*; - import org.apache.juneau.*; import org.apache.juneau.annotation.*; -import org.apache.juneau.http.*; import org.apache.juneau.parser.*; -import org.apache.juneau.transform.*; - -import com.hp.hpl.jena.rdf.model.*; -import com.hp.hpl.jena.util.iterator.*; /** * Parses RDF into POJOs. @@ -80,12 +71,7 @@ public class RdfParser extends ReaderParser { * @param propertyStore The property store containing all the settings for this object. */ public Xml(PropertyStore propertyStore) { - super(propertyStore); - } - - @Override - protected ObjectMap getOverrideProperties() { - return super.getOverrideProperties().append(RDF_language, LANG_RDF_XML); + super(propertyStore.copy().append(RDF_language, LANG_RDF_XML)); } } @@ -99,12 +85,7 @@ public class RdfParser extends ReaderParser { * @param propertyStore The property store containing all the settings for this object. */ public NTriple(PropertyStore propertyStore) { - super(propertyStore); - } - - @Override - protected ObjectMap getOverrideProperties() { - return super.getOverrideProperties().append(RDF_language, LANG_NTRIPLE); + super(propertyStore.copy().append(RDF_language, LANG_NTRIPLE)); } } @@ -118,12 +99,7 @@ public class RdfParser extends ReaderParser { * @param propertyStore The property store containing all the settings for this object. */ public Turtle(PropertyStore propertyStore) { - super(propertyStore); - } - - @Override - protected ObjectMap getOverrideProperties() { - return super.getOverrideProperties().append(RDF_language, LANG_TURTLE); + super(propertyStore.copy().append(RDF_language, LANG_TURTLE)); } } @@ -137,12 +113,7 @@ public class RdfParser extends ReaderParser { * @param propertyStore The property store containing all the settings for this object. */ public N3(PropertyStore propertyStore) { - super(propertyStore); - } - - @Override - protected ObjectMap getOverrideProperties() { - return super.getOverrideProperties().append(RDF_language, LANG_N3); + super(propertyStore.copy().append(RDF_language, LANG_N3)); } } @@ -164,337 +135,8 @@ public class RdfParser extends ReaderParser { return new RdfParserBuilder(propertyStore); } - @SuppressWarnings({"unchecked", "rawtypes"}) - @Override /* ReaderParser */ - protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception { - - RdfParserSession s = (RdfParserSession)session; - - Model model = s.getModel(); - RDFReader r = s.getRdfReader(); - r.read(model, session.getReader(), null); - - List<Resource> roots = getRoots(s, model); - - // Special case where we're parsing a loose collection of resources. - if (s.isLooseCollections() && type.isCollectionOrArray()) { - Collection c = null; - if (type.isArray() || type.isArgs()) - c = new ArrayList(); - else - c = ( - type.canCreateNewInstance(session.getOuter()) - ? (Collection<?>)type.newInstance(session.getOuter()) - : new ObjectList(session) - ); - - int argIndex = 0; - for (Resource resource : roots) - c.add(parseAnything(s, type.isArgs() ? type.getArg(argIndex++) : type.getElementType(), resource, - session.getOuter(), null)); - - if (type.isArray() || type.isArgs()) - return (T)session.toArray(type, c); - return (T)c; - } - - if (roots.isEmpty()) - return null; - if (roots.size() > 1) - throw new ParseException(session, "Too many root nodes found in model: {0}", roots.size()); - Resource resource = roots.get(0); - - return parseAnything(s, type, resource, session.getOuter(), null); - } - - /* - * Finds the roots in the model using either the "root" property to identify it, - * or by resorting to scanning the model for all nodes with no incoming predicates. - */ - private static List<Resource> getRoots(RdfParserSession session, Model m) { - List<Resource> l = new LinkedList<Resource>(); - - // First try to find the root using the "http://www.apache.org/juneau/root" property. - Property root = m.createProperty(session.getJuneauNsUri(), RDF_juneauNs_ROOT); - for (ResIterator i = m.listResourcesWithProperty(root); i.hasNext();) - l.add(i.next()); - - if (! l.isEmpty()) - return l; - - // Otherwise, we need to find all resources that aren't objects. - // We want to explicitly ignore statements where the subject - // and object are the same node. - Set<RDFNode> objects = new HashSet<RDFNode>(); - for (StmtIterator i = m.listStatements(); i.hasNext();) { - Statement st = i.next(); - RDFNode subject = st.getSubject(); - RDFNode object = st.getObject(); - if (object.isResource() && ! object.equals(subject)) - objects.add(object); - } - for (ResIterator i = m.listSubjects(); i.hasNext();) { - Resource r = i.next(); - if (! objects.contains(r)) - l.add(r); - } - return l; - } - - private <T> BeanMap<T> parseIntoBeanMap(RdfParserSession session, Resource r2, BeanMap<T> m) throws Exception { - BeanMeta<T> bm = m.getMeta(); - RdfBeanMeta rbm = bm.getExtendedMeta(RdfBeanMeta.class); - if (rbm.hasBeanUri() && r2.getURI() != null) - rbm.getBeanUriProperty().set(m, null, r2.getURI()); - for (StmtIterator i = r2.listProperties(); i.hasNext();) { - Statement st = i.next(); - Property p = st.getPredicate(); - String key = session.decodeString(p.getLocalName()); - BeanPropertyMeta pMeta = m.getPropertyMeta(key); - session.setCurrentProperty(pMeta); - if (pMeta != null) { - RDFNode o = st.getObject(); - ClassMeta<?> cm = pMeta.getClassMeta(); - if (cm.isCollectionOrArray() && isMultiValuedCollections(session, pMeta)) { - ClassMeta<?> et = cm.getElementType(); - Object value = parseAnything(session, et, o, m.getBean(false), pMeta); - setName(et, value, key); - pMeta.add(m, key, value); - } else { - Object value = parseAnything(session, cm, o, m.getBean(false), pMeta); - setName(cm, value, key); - pMeta.set(m, key, value); - } - } else if (! (p.equals(session.getRootProperty()) || p.equals(session.getTypeProperty()))) { - session.onUnknownProperty(key, m, -1, -1); - } - session.setCurrentProperty(null); - } - return m; - } - - private static boolean isMultiValuedCollections(RdfParserSession session, BeanPropertyMeta pMeta) { - if (pMeta != null && pMeta.getExtendedMeta(RdfBeanPropertyMeta.class).getCollectionFormat() != RdfCollectionFormat.DEFAULT) - return pMeta.getExtendedMeta(RdfBeanPropertyMeta.class).getCollectionFormat() == RdfCollectionFormat.MULTI_VALUED; - return session.getCollectionFormat() == RdfCollectionFormat.MULTI_VALUED; - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private <T> T parseAnything(RdfParserSession session, ClassMeta<T> eType, RDFNode n, Object outer, - BeanPropertyMeta pMeta) throws Exception { - - if (eType == null) - eType = (ClassMeta<T>)object(); - PojoSwap<T,Object> transform = (PojoSwap<T,Object>)eType.getPojoSwap(); - ClassMeta<?> sType = eType.getSerializedClassMeta(); - session.setCurrentClass(sType); - - if (! sType.canCreateNewInstance(outer)) { - if (n.isResource()) { - Statement st = n.asResource().getProperty(session.getTypeProperty()); - if (st != null) { - String c = st.getLiteral().getString(); - ClassMeta tcm = session.getClassMeta(c, pMeta, eType); - if (tcm != null) - sType = eType = tcm; - } - } - } - - Object o = null; - if (n.isResource() && n.asResource().getURI() != null && n.asResource().getURI().equals(RDF_NIL)) { - // Do nothing. Leave o == null. - } else if (sType.isObject()) { - if (n.isLiteral()) { - o = n.asLiteral().getValue(); - if (o instanceof String) { - o = session.decodeString(o); - } - } - else if (n.isResource()) { - Resource r = n.asResource(); - if (session.wasAlreadyProcessed(r)) - o = r.getURI(); - else if (r.getProperty(session.getValueProperty()) != null) { - o = parseAnything(session, object(), n.asResource().getProperty(session.getValueProperty()).getObject(), outer, null); - } else if (isSeq(session, r)) { - o = new ObjectList(session); - parseIntoCollection(session, r.as(Seq.class), (Collection)o, sType, pMeta); - } else if (isBag(session, r)) { - o = new ObjectList(session); - parseIntoCollection(session, r.as(Bag.class), (Collection)o, sType, pMeta); - } else if (r.canAs(RDFList.class)) { - o = new ObjectList(session); - parseIntoCollection(session, r.as(RDFList.class), (Collection)o, sType, pMeta); - } else { - // If it has a URI and no child properties, we interpret this as an - // external resource, and convert it to just a URL. - String uri = r.getURI(); - if (uri != null && ! r.listProperties().hasNext()) { - o = r.getURI(); - } else { - ObjectMap m2 = new ObjectMap(session); - parseIntoMap(session, r, m2, null, null, pMeta); - o = session.cast(m2, pMeta, eType); - } - } - } else { - throw new ParseException(session, "Unrecognized node type ''{0}'' for object", n); - } - } else if (sType.isBoolean()) { - o = session.convertToType(getValue(session, n, outer), boolean.class); - } else if (sType.isCharSequence()) { - o = session.decodeString(getValue(session, n, outer)); - } else if (sType.isChar()) { - o = session.decodeString(getValue(session, n, outer)).charAt(0); - } else if (sType.isNumber()) { - o = parseNumber(getValue(session, n, outer).toString(), (Class<? extends Number>)sType.getInnerClass()); - } else if (sType.isMap()) { - Resource r = n.asResource(); - if (session.wasAlreadyProcessed(r)) - return null; - Map m = (sType.canCreateNewInstance(outer) ? (Map)sType.newInstance(outer) : new ObjectMap(session)); - o = parseIntoMap(session, r, m, eType.getKeyType(), eType.getValueType(), pMeta); - } else if (sType.isCollectionOrArray() || sType.isArgs()) { - if (sType.isArray() || sType.isArgs()) - o = new ArrayList(); - else - o = (sType.canCreateNewInstance(outer) ? (Collection<?>)sType.newInstance(outer) : new ObjectList(session)); - Resource r = n.asResource(); - if (session.wasAlreadyProcessed(r)) - return null; - if (isSeq(session, r)) { - parseIntoCollection(session, r.as(Seq.class), (Collection)o, sType, pMeta); - } else if (isBag(session, r)) { - parseIntoCollection(session, r.as(Bag.class), (Collection)o, sType, pMeta); - } else if (r.canAs(RDFList.class)) { - parseIntoCollection(session, r.as(RDFList.class), (Collection)o, sType, pMeta); - } else { - throw new ParseException("Unrecognized node type ''{0}'' for collection", n); - } - if (sType.isArray() || sType.isArgs()) - o = session.toArray(sType, (Collection)o); - } else if (sType.canCreateNewBean(outer)) { - Resource r = n.asResource(); - if (session.wasAlreadyProcessed(r)) - return null; - BeanMap<?> bm = session.newBeanMap(outer, sType.getInnerClass()); - o = parseIntoBeanMap(session, r, bm).getBean(); - } else if (sType.isUri() && n.isResource()) { - o = sType.newInstanceFromString(outer, session.decodeString(n.asResource().getURI())); - } else if (sType.canCreateNewInstanceFromString(outer)) { - o = sType.newInstanceFromString(outer, session.decodeString(getValue(session, n, outer))); - } else if (sType.canCreateNewInstanceFromNumber(outer)) { - o = sType.newInstanceFromNumber(session, outer, parseNumber(getValue(session, n, outer).toString(), sType.getNewInstanceFromNumberClass())); - } else if (n.isResource()) { - Resource r = n.asResource(); - Map m = new ObjectMap(session); - parseIntoMap(session, r, m, sType.getKeyType(), sType.getValueType(), pMeta); - if (m.containsKey(session.getBeanTypePropertyName(eType))) - o = session.cast((ObjectMap)m, pMeta, eType); - else - throw new ParseException(session, "Class ''{0}'' could not be instantiated. Reason: ''{1}''", sType.getInnerClass().getName(), sType.getNotABeanReason()); - } else { - throw new ParseException("Class ''{0}'' could not be instantiated. Reason: ''{1}''", sType.getInnerClass().getName(), sType.getNotABeanReason()); - } - - if (transform != null && o != null) - o = transform.unswap(session, o, eType); - - if (outer != null) - setParent(eType, o, outer); - - return (T)o; - } - - private static boolean isSeq(RdfParserSession session, RDFNode n) { - if (n.isResource()) { - Statement st = n.asResource().getProperty(session.getRdfTypeProperty()); - if (st != null) - return RDF_SEQ.equals(st.getResource().getURI()); - } - return false; - } - - private static boolean isBag(RdfParserSession session, RDFNode n) { - if (n.isResource()) { - Statement st = n.asResource().getProperty(session.getRdfTypeProperty()); - if (st != null) - return RDF_BAG.equals(st.getResource().getURI()); - } - return false; - } - - private Object getValue(RdfParserSession session, RDFNode n, Object outer) throws Exception { - if (n.isLiteral()) - return n.asLiteral().getValue(); - if (n.isResource()) { - Statement st = n.asResource().getProperty(session.getValueProperty()); - if (st != null) { - n = st.getObject(); - if (n.isLiteral()) - return n.asLiteral().getValue(); - return parseAnything(session, object(), st.getObject(), outer, null); - } - } - throw new ParseException(session, "Unknown value type for node ''{0}''", n); - } - - private <K,V> Map<K,V> parseIntoMap(RdfParserSession session, Resource r, Map<K,V> m, ClassMeta<K> keyType, - ClassMeta<V> valueType, BeanPropertyMeta pMeta) throws Exception { - // Add URI as "uri" to generic maps. - if (r.getURI() != null) { - K uri = convertAttrToType(session, m, "uri", keyType); - V value = convertAttrToType(session, m, r.getURI(), valueType); - m.put(uri, value); - } - for (StmtIterator i = r.listProperties(); i.hasNext();) { - Statement st = i.next(); - Property p = st.getPredicate(); - String key = p.getLocalName(); - if (! (key.equals("root") && p.getURI().equals(session.getJuneauNsUri()))) { - key = session.decodeString(key); - RDFNode o = st.getObject(); - K key2 = convertAttrToType(session, m, key, keyType); - V value = parseAnything(session, valueType, o, m, pMeta); - setName(valueType, value, key); - m.put(key2, value); - } - - } - return m; - } - - @SuppressWarnings("unchecked") - private <E> Collection<E> parseIntoCollection(RdfParserSession session, Container c, Collection<E> l, - ClassMeta<?> type, BeanPropertyMeta pMeta) throws Exception { - int argIndex = 0; - for (NodeIterator ni = c.iterator(); ni.hasNext();) { - E e = (E)parseAnything(session, type.isArgs() ? type.getArg(argIndex++) : type.getElementType(), ni.next(), l, pMeta); - l.add(e); - } - return l; - } - - @SuppressWarnings("unchecked") - private <E> Collection<E> parseIntoCollection(RdfParserSession session, RDFList list, Collection<E> l, - ClassMeta<?> type, BeanPropertyMeta pMeta) throws Exception { - int argIndex = 0; - for (ExtendedIterator<RDFNode> ni = list.iterator(); ni.hasNext();) { - E e = (E)parseAnything(session, type.isArgs() ? type.getArg(argIndex++) : type.getElementType(), ni.next(), l, pMeta); - l.add(e); - } - return l; - } - - - //-------------------------------------------------------------------------------- - // Entry point methods - //-------------------------------------------------------------------------------- - @Override /* Parser */ - public RdfParserSession createSession(Object input, ObjectMap op, Method javaMethod, Object outer, Locale locale, - TimeZone timeZone, MediaType mediaType) { - return new RdfParserSession(ctx, op, input, javaMethod, outer, locale, timeZone, mediaType); + public ReaderParserSession createSession(ParserSessionArgs args) { + return new RdfParserSession(ctx, args); } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/2a37f310/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java ---------------------------------------------------------------------- diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java index 63a5eca..267d06f 100644 --- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java +++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java @@ -12,27 +12,29 @@ // *************************************************************************************************************************** package org.apache.juneau.jena; +import static org.apache.juneau.internal.StringUtils.*; import static org.apache.juneau.jena.Constants.*; import static org.apache.juneau.jena.RdfCommonContext.*; -import java.io.*; -import java.lang.reflect.*; import java.util.*; import org.apache.juneau.*; -import org.apache.juneau.http.*; import org.apache.juneau.parser.*; +import org.apache.juneau.transform.*; import org.apache.juneau.xml.*; import com.hp.hpl.jena.rdf.model.*; +import com.hp.hpl.jena.util.iterator.*; /** * Session object that lives for the duration of a single use of {@link RdfParser}. - * + * * <p> - * This class is NOT thread safe. It is meant to be discarded after one-time use. + * This class is NOT thread safe. + * It is typically discarded after one-time use although it can be reused against multiple inputs. */ -public class RdfParserSession extends ParserSession { +@SuppressWarnings({"unchecked", "rawtypes"}) +public class RdfParserSession extends ReaderParserSession { private final String rdfLanguage; private final Namespace juneauNs, juneauBpNs; @@ -46,38 +48,18 @@ public class RdfParserSession extends ParserSession { /** * Create a new session using properties specified in the context. * - * @param ctx + * @param ctx * The context creating this session object. * The context contains all the configuration settings for this object. - * @param input - * The input. - * Can be any of the following types: - * <ul> - * <li><jk>null</jk> - * <li>{@link Reader} - * <li>{@link CharSequence} - * <li>{@link InputStream} containing UTF-8 encoded text. - * <li>{@link File} containing system encoded text. - * </ul> - * @param op - * The override properties. - * These override any context properties defined in the context. - * @param javaMethod The java method that called this parser, usually the method in a REST servlet. - * @param outer The outer object for instantiating top-level non-static inner classes. - * @param locale - * The session locale. - * If <jk>null</jk>, then the locale defined on the context is used. - * @param timeZone - * The session timezone. - * If <jk>null</jk>, then the timezone defined on the context is used. - * @param mediaType The session media type (e.g. <js>"application/json"</js>). + * @param args + * Runtime session arguments. */ - protected RdfParserSession(RdfParserContext ctx, ObjectMap op, Object input, Method javaMethod, Object outer, - Locale locale, TimeZone timeZone, MediaType mediaType) { - super(ctx, op, input, javaMethod, outer, locale, timeZone, mediaType); + protected RdfParserSession(RdfParserContext ctx, ParserSessionArgs args) { + super(ctx, args); ObjectMap jenaSettings = new ObjectMap(); jenaSettings.putAll(ctx.jenaSettings); - if (op == null || op.isEmpty()) { + ObjectMap p = getProperties(); + if (p.isEmpty()) { this.rdfLanguage = ctx.rdfLanguage; this.juneauNs = ctx.juneauNs; this.juneauBpNs = ctx.juneauBpNs; @@ -85,12 +67,12 @@ public class RdfParserSession extends ParserSession { this.collectionFormat = ctx.collectionFormat; this.looseCollections = ctx.looseCollections; } else { - this.rdfLanguage = op.getString(RDF_language, ctx.rdfLanguage); - this.juneauNs = (op.containsKey(RDF_juneauNs) ? NamespaceFactory.parseNamespace(op.get(RDF_juneauNs)) : ctx.juneauNs); - this.juneauBpNs = (op.containsKey(RDF_juneauBpNs) ? NamespaceFactory.parseNamespace(op.get(RDF_juneauBpNs)) : ctx.juneauBpNs); - this.trimWhitespace = op.getBoolean(RdfParserContext.RDF_trimWhitespace, ctx.trimWhitespace); - this.collectionFormat = RdfCollectionFormat.valueOf(op.getString(RDF_collectionFormat, "DEFAULT")); - this.looseCollections = op.getBoolean(RDF_looseCollections, ctx.looseCollections); + this.rdfLanguage = p.getString(RDF_language, ctx.rdfLanguage); + this.juneauNs = (p.containsKey(RDF_juneauNs) ? NamespaceFactory.parseNamespace(p.get(RDF_juneauNs)) : ctx.juneauNs); + this.juneauBpNs = (p.containsKey(RDF_juneauBpNs) ? NamespaceFactory.parseNamespace(p.get(RDF_juneauBpNs)) : ctx.juneauBpNs); + this.trimWhitespace = p.getBoolean(RdfParserContext.RDF_trimWhitespace, ctx.trimWhitespace); + this.collectionFormat = RdfCollectionFormat.valueOf(p.getString(RDF_collectionFormat, "DEFAULT")); + this.looseCollections = p.getBoolean(RDF_looseCollections, ctx.looseCollections); } this.model = ModelFactory.createDefaultModel(); addModelPrefix(juneauNs); @@ -108,129 +90,55 @@ public class RdfParserSession extends ParserSession { } } - /** - * Returns <jk>true</jk> if this resource was already visited. - * - * @param r The resource to check. - * @return <jk>true</jk> if this resource was already visited. - */ - public final boolean wasAlreadyProcessed(Resource r) { - return ! urisVisited.add(r); - } + @Override /* ReaderParserSession */ + protected <T> T doParse(ParserPipe pipe, ClassMeta<T> type) throws Exception { - /** - * Returns the root property. - * - * @return The root property. - */ - public final Property getRootProperty() { - return pRoot; - } + RDFReader r = rdfReader; + r.read(model, pipe.getBufferedReader(), null); - /** - * Returns the RDF property identifier <js>"value"</js>. - * - * @return The RDF property identifier <js>"value"</js>. - */ - public final Property getValueProperty() { - return pValue; - } + List<Resource> roots = getRoots(model); - /** - * Returns the RDF property identifier <js>"_type"</js>. - * - * @return The RDF property identifier <js>"_type"</js>. - */ - public final Property getTypeProperty() { - return pType; - } - - /** - * Returns the RDF property identifier <js>"type"</js>. - * - * @return The RDF property identifier <js>"type"</js>. - */ - public final Property getRdfTypeProperty() { - return pRdfType; - } + // Special case where we're parsing a loose collection of resources. + if (looseCollections && type.isCollectionOrArray()) { + Collection c = null; + if (type.isArray() || type.isArgs()) + c = new ArrayList(); + else + c = ( + type.canCreateNewInstance(getOuter()) + ? (Collection<?>)type.newInstance(getOuter()) + : new ObjectList(this) + ); - /** - * Returns the RDF model being parsed into. - * - * @return The RDF model being parsed into. - */ - public final Model getModel() { - return model; - } + int argIndex = 0; + for (Resource resource : roots) + c.add(parseAnything(type.isArgs() ? type.getArg(argIndex++) : type.getElementType(), resource, + getOuter(), null)); - /** - * Returns the RDF reader that's reading the model. - * - * @return The RDF reader that's reading the model. - */ - public final RDFReader getRdfReader() { - return rdfReader; - } - - /** - * Returns the {@link RdfCommonContext#RDF_collectionFormat} setting value for this session. - * - * @return The {@link RdfCommonContext#RDF_collectionFormat} setting value for this session. - */ - public final RdfCollectionFormat getCollectionFormat() { - return collectionFormat; - } + if (type.isArray() || type.isArgs()) + return (T)toArray(type, c); + return (T)c; + } - /** - * Returns the {@link RdfCommonContext#RDF_looseCollections} setting value for this session. - * - * @return The {@link RdfCommonContext#RDF_looseCollections} setting value for this session. - */ - public final boolean isLooseCollections() { - return looseCollections; - } + if (roots.isEmpty()) + return null; + if (roots.size() > 1) + throw new ParseException(loc(), "Too many root nodes found in model: {0}", roots.size()); + Resource resource = roots.get(0); - /** - * Returns the Juneau namespace URI. - * - * @return The Juneau namespace URI. - */ - public final String getJuneauNsUri() { - return juneauNs.getUri(); + return parseAnything(type, resource, getOuter(), null); } - /** - * Adds the specified namespace as a model prefix. - * - * @param ns The XML namespace. - */ - public final void addModelPrefix(Namespace ns) { + private final void addModelPrefix(Namespace ns) { model.setNsPrefix(ns.getName(), ns.getUri()); } - /** - * Constructs a <code>Property</code> in the Juneau Bean namespace in this mode. - * - * @param name The property name. - * @return The new property object. - */ - public final Property getRdfProperty(String name) { - return model.createProperty(juneauBpNs.getUri(), name); - } - - /** + /* * Decodes the specified string. - * - * <p> * If {@link RdfParserContext#RDF_trimWhitespace} is <jk>true</jk>, the resulting string is trimmed before decoding. - * - * <p> * If {@link #isTrimStrings()} is <jk>true</jk>, the resulting string is trimmed after decoding. - * - * @param o The string to trim. - * @return The trimmed string, or <jk>null</jk> if the string was <jk>null</jk>. */ - public final String decodeString(Object o) { + private String decodeString(Object o) { if (o == null) return null; String s = o.toString(); @@ -243,4 +151,284 @@ public class RdfParserSession extends ParserSession { s = s.trim(); return s; } + + /* + * Finds the roots in the model using either the "root" property to identify it, + * or by resorting to scanning the model for all nodes with no incoming predicates. + */ + private List<Resource> getRoots(Model m) { + List<Resource> l = new LinkedList<Resource>(); + + // First try to find the root using the "http://www.apache.org/juneau/root" property. + Property root = m.createProperty(juneauNs.getUri(), RDF_juneauNs_ROOT); + for (ResIterator i = m.listResourcesWithProperty(root); i.hasNext();) + l.add(i.next()); + + if (! l.isEmpty()) + return l; + + // Otherwise, we need to find all resources that aren't objects. + // We want to explicitly ignore statements where the subject + // and object are the same node. + Set<RDFNode> objects = new HashSet<RDFNode>(); + for (StmtIterator i = m.listStatements(); i.hasNext();) { + Statement st = i.next(); + RDFNode subject = st.getSubject(); + RDFNode object = st.getObject(); + if (object.isResource() && ! object.equals(subject)) + objects.add(object); + } + for (ResIterator i = m.listSubjects(); i.hasNext();) { + Resource r = i.next(); + if (! objects.contains(r)) + l.add(r); + } + return l; + } + + private <T> BeanMap<T> parseIntoBeanMap(Resource r2, BeanMap<T> m) throws Exception { + BeanMeta<T> bm = m.getMeta(); + RdfBeanMeta rbm = bm.getExtendedMeta(RdfBeanMeta.class); + if (rbm.hasBeanUri() && r2.getURI() != null) + rbm.getBeanUriProperty().set(m, null, r2.getURI()); + for (StmtIterator i = r2.listProperties(); i.hasNext();) { + Statement st = i.next(); + Property p = st.getPredicate(); + String key = decodeString(p.getLocalName()); + BeanPropertyMeta pMeta = m.getPropertyMeta(key); + setCurrentProperty(pMeta); + if (pMeta != null) { + RDFNode o = st.getObject(); + ClassMeta<?> cm = pMeta.getClassMeta(); + if (cm.isCollectionOrArray() && isMultiValuedCollections(pMeta)) { + ClassMeta<?> et = cm.getElementType(); + Object value = parseAnything(et, o, m.getBean(false), pMeta); + setName(et, value, key); + pMeta.add(m, key, value); + } else { + Object value = parseAnything(cm, o, m.getBean(false), pMeta); + setName(cm, value, key); + pMeta.set(m, key, value); + } + } else if (! (p.equals(pRoot) || p.equals(pType))) { + onUnknownProperty(null, key, m, -1, -1); + } + setCurrentProperty(null); + } + return m; + } + + private boolean isMultiValuedCollections(BeanPropertyMeta pMeta) { + if (pMeta != null && pMeta.getExtendedMeta(RdfBeanPropertyMeta.class).getCollectionFormat() != RdfCollectionFormat.DEFAULT) + return pMeta.getExtendedMeta(RdfBeanPropertyMeta.class).getCollectionFormat() == RdfCollectionFormat.MULTI_VALUED; + return collectionFormat == RdfCollectionFormat.MULTI_VALUED; + } + + private <T> T parseAnything(ClassMeta<T> eType, RDFNode n, Object outer, BeanPropertyMeta pMeta) throws Exception { + + if (eType == null) + eType = (ClassMeta<T>)object(); + PojoSwap<T,Object> transform = (PojoSwap<T,Object>)eType.getPojoSwap(); + ClassMeta<?> sType = eType.getSerializedClassMeta(); + setCurrentClass(sType); + + if (! sType.canCreateNewInstance(outer)) { + if (n.isResource()) { + Statement st = n.asResource().getProperty(pType); + if (st != null) { + String c = st.getLiteral().getString(); + ClassMeta tcm = getClassMeta(c, pMeta, eType); + if (tcm != null) + sType = eType = tcm; + } + } + } + + Object o = null; + if (n.isResource() && n.asResource().getURI() != null && n.asResource().getURI().equals(RDF_NIL)) { + // Do nothing. Leave o == null. + } else if (sType.isObject()) { + if (n.isLiteral()) { + o = n.asLiteral().getValue(); + if (o instanceof String) { + o = decodeString(o); + } + } + else if (n.isResource()) { + Resource r = n.asResource(); + if (! urisVisited.add(r)) + o = r.getURI(); + else if (r.getProperty(pValue) != null) { + o = parseAnything(object(), n.asResource().getProperty(pValue).getObject(), outer, null); + } else if (isSeq(r)) { + o = new ObjectList(this); + parseIntoCollection(r.as(Seq.class), (Collection)o, sType, pMeta); + } else if (isBag(r)) { + o = new ObjectList(this); + parseIntoCollection(r.as(Bag.class), (Collection)o, sType, pMeta); + } else if (r.canAs(RDFList.class)) { + o = new ObjectList(this); + parseIntoCollection(r.as(RDFList.class), (Collection)o, sType, pMeta); + } else { + // If it has a URI and no child properties, we interpret this as an + // external resource, and convert it to just a URL. + String uri = r.getURI(); + if (uri != null && ! r.listProperties().hasNext()) { + o = r.getURI(); + } else { + ObjectMap m2 = new ObjectMap(this); + parseIntoMap(r, m2, null, null, pMeta); + o = cast(m2, pMeta, eType); + } + } + } else { + throw new ParseException(loc(), "Unrecognized node type ''{0}'' for object", n); + } + } else if (sType.isBoolean()) { + o = convertToType(getValue(n, outer), boolean.class); + } else if (sType.isCharSequence()) { + o = decodeString(getValue(n, outer)); + } else if (sType.isChar()) { + o = decodeString(getValue(n, outer)).charAt(0); + } else if (sType.isNumber()) { + o = parseNumber(getValue(n, outer).toString(), (Class<? extends Number>)sType.getInnerClass()); + } else if (sType.isMap()) { + Resource r = n.asResource(); + if (! urisVisited.add(r)) + return null; + Map m = (sType.canCreateNewInstance(outer) ? (Map)sType.newInstance(outer) : new ObjectMap(this)); + o = parseIntoMap(r, m, eType.getKeyType(), eType.getValueType(), pMeta); + } else if (sType.isCollectionOrArray() || sType.isArgs()) { + if (sType.isArray() || sType.isArgs()) + o = new ArrayList(); + else + o = (sType.canCreateNewInstance(outer) ? (Collection<?>)sType.newInstance(outer) : new ObjectList(this)); + Resource r = n.asResource(); + if (! urisVisited.add(r)) + return null; + if (isSeq(r)) { + parseIntoCollection(r.as(Seq.class), (Collection)o, sType, pMeta); + } else if (isBag(r)) { + parseIntoCollection(r.as(Bag.class), (Collection)o, sType, pMeta); + } else if (r.canAs(RDFList.class)) { + parseIntoCollection(r.as(RDFList.class), (Collection)o, sType, pMeta); + } else { + throw new ParseException("Unrecognized node type ''{0}'' for collection", n); + } + if (sType.isArray() || sType.isArgs()) + o = toArray(sType, (Collection)o); + } else if (sType.canCreateNewBean(outer)) { + Resource r = n.asResource(); + if (! urisVisited.add(r)) + return null; + BeanMap<?> bm = newBeanMap(outer, sType.getInnerClass()); + o = parseIntoBeanMap(r, bm).getBean(); + } else if (sType.isUri() && n.isResource()) { + o = sType.newInstanceFromString(outer, decodeString(n.asResource().getURI())); + } else if (sType.canCreateNewInstanceFromString(outer)) { + o = sType.newInstanceFromString(outer, decodeString(getValue(n, outer))); + } else if (sType.canCreateNewInstanceFromNumber(outer)) { + o = sType.newInstanceFromNumber(this, outer, parseNumber(getValue(n, outer).toString(), sType.getNewInstanceFromNumberClass())); + } else if (n.isResource()) { + Resource r = n.asResource(); + Map m = new ObjectMap(this); + parseIntoMap(r, m, sType.getKeyType(), sType.getValueType(), pMeta); + if (m.containsKey(getBeanTypePropertyName(eType))) + o = cast((ObjectMap)m, pMeta, eType); + else + throw new ParseException(loc(), "Class ''{0}'' could not be instantiated. Reason: ''{1}''", sType.getInnerClass().getName(), sType.getNotABeanReason()); + } else { + throw new ParseException("Class ''{0}'' could not be instantiated. Reason: ''{1}''", sType.getInnerClass().getName(), sType.getNotABeanReason()); + } + + if (transform != null && o != null) + o = transform.unswap(this, o, eType); + + if (outer != null) + setParent(eType, o, outer); + + return (T)o; + } + + private ObjectMap loc() { + return getLastLocation(); + } + + private boolean isSeq(RDFNode n) { + if (n.isResource()) { + Statement st = n.asResource().getProperty(pRdfType); + if (st != null) + return RDF_SEQ.equals(st.getResource().getURI()); + } + return false; + } + + private boolean isBag(RDFNode n) { + if (n.isResource()) { + Statement st = n.asResource().getProperty(pRdfType); + if (st != null) + return RDF_BAG.equals(st.getResource().getURI()); + } + return false; + } + + private Object getValue(RDFNode n, Object outer) throws Exception { + if (n.isLiteral()) + return n.asLiteral().getValue(); + if (n.isResource()) { + Statement st = n.asResource().getProperty(pValue); + if (st != null) { + n = st.getObject(); + if (n.isLiteral()) + return n.asLiteral().getValue(); + return parseAnything(object(), st.getObject(), outer, null); + } + } + throw new ParseException(loc(), "Unknown value type for node ''{0}''", n); + } + + private <K,V> Map<K,V> parseIntoMap(Resource r, Map<K,V> m, ClassMeta<K> keyType, + ClassMeta<V> valueType, BeanPropertyMeta pMeta) throws Exception { + // Add URI as "uri" to generic maps. + if (r.getURI() != null) { + K uri = convertAttrToType(m, "uri", keyType); + V value = convertAttrToType(m, r.getURI(), valueType); + m.put(uri, value); + } + for (StmtIterator i = r.listProperties(); i.hasNext();) { + Statement st = i.next(); + Property p = st.getPredicate(); + String key = p.getLocalName(); + if (! (key.equals("root") && p.getURI().equals(juneauNs.getUri()))) { + key = decodeString(key); + RDFNode o = st.getObject(); + K key2 = convertAttrToType(m, key, keyType); + V value = parseAnything(valueType, o, m, pMeta); + setName(valueType, value, key); + m.put(key2, value); + } + + } + return m; + } + + private <E> Collection<E> parseIntoCollection(Container c, Collection<E> l, + ClassMeta<?> type, BeanPropertyMeta pMeta) throws Exception { + int argIndex = 0; + for (NodeIterator ni = c.iterator(); ni.hasNext();) { + E e = (E)parseAnything(type.isArgs() ? type.getArg(argIndex++) : type.getElementType(), ni.next(), l, pMeta); + l.add(e); + } + return l; + } + + private <E> Collection<E> parseIntoCollection(RDFList list, Collection<E> l, + ClassMeta<?> type, BeanPropertyMeta pMeta) throws Exception { + int argIndex = 0; + for (ExtendedIterator<RDFNode> ni = list.iterator(); ni.hasNext();) { + E e = (E)parseAnything(type.isArgs() ? type.getArg(argIndex++) : type.getElementType(), ni.next(), l, pMeta); + l.add(e); + } + return l; + } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/2a37f310/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java ---------------------------------------------------------------------- diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java index 30c5163..e19d8b2 100644 --- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java +++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java @@ -15,18 +15,9 @@ package org.apache.juneau.jena; import static org.apache.juneau.jena.Constants.*; import static org.apache.juneau.jena.RdfCommonContext.*; -import java.lang.reflect.*; -import java.util.*; - import org.apache.juneau.*; import org.apache.juneau.annotation.*; -import org.apache.juneau.http.*; -import org.apache.juneau.internal.*; import org.apache.juneau.serializer.*; -import org.apache.juneau.transform.*; -import org.apache.juneau.xml.*; - -import com.hp.hpl.jena.rdf.model.*; /** * Serializes POJOs to RDF. @@ -51,7 +42,6 @@ import com.hp.hpl.jena.rdf.model.*; * * See <a class="doclink" href="package-summary.html#TOC">RDF Overview</a> for an overview of RDF support in Juneau. */ -@SuppressWarnings({ "rawtypes", "unchecked" }) @Produces(value="text/xml+rdf+abbrev", contentType="text/xml+rdf") public class RdfSerializer extends WriterSerializer { @@ -81,12 +71,7 @@ public class RdfSerializer extends WriterSerializer { * @param propertyStore The property store containing all the settings for this object. */ public Xml(PropertyStore propertyStore) { - super(propertyStore); - } - - @Override /* CoreObject */ - protected ObjectMap getOverrideProperties() { - return super.getOverrideProperties().append(RDF_language, LANG_RDF_XML); + super(propertyStore.copy().append(RDF_language, LANG_RDF_XML)); } } @@ -100,12 +85,7 @@ public class RdfSerializer extends WriterSerializer { * @param propertyStore The property store containing all the settings for this object. */ public XmlAbbrev(PropertyStore propertyStore) { - super(propertyStore); - } - - @Override /* CoreObject */ - protected ObjectMap getOverrideProperties() { - return super.getOverrideProperties().append(RDF_language, LANG_RDF_XML_ABBREV); + super(propertyStore.copy().append(RDF_language, LANG_RDF_XML_ABBREV)); } } @@ -119,12 +99,7 @@ public class RdfSerializer extends WriterSerializer { * @param propertyStore The property store containing all the settings for this object. */ public NTriple(PropertyStore propertyStore) { - super(propertyStore); - } - - @Override /* CoreObject */ - protected ObjectMap getOverrideProperties() { - return super.getOverrideProperties().append(RDF_language, LANG_NTRIPLE); + super(propertyStore.copy().append(RDF_language, LANG_NTRIPLE)); } } @@ -138,12 +113,7 @@ public class RdfSerializer extends WriterSerializer { * @param propertyStore The property store containing all the settings for this object. */ public Turtle(PropertyStore propertyStore) { - super(propertyStore); - } - - @Override /* CoreObject */ - protected ObjectMap getOverrideProperties() { - return super.getOverrideProperties().append(RDF_language, LANG_TURTLE); + super(propertyStore.copy().append(RDF_language, LANG_TURTLE)); } } @@ -157,12 +127,7 @@ public class RdfSerializer extends WriterSerializer { * @param propertyStore The property store containing all the settings for this object. */ public N3(PropertyStore propertyStore) { - super(propertyStore); - } - - @Override /* CoreObject */ - protected ObjectMap getOverrideProperties() { - return super.getOverrideProperties().append(RDF_language, LANG_N3); + super(propertyStore.copy().append(RDF_language, LANG_N3)); } } @@ -185,272 +150,7 @@ public class RdfSerializer extends WriterSerializer { } @Override /* Serializer */ - protected void doSerialize(SerializerSession session, SerializerOutput out, Object o) throws Exception { - - RdfSerializerSession s = (RdfSerializerSession)session; - - Model model = s.getModel(); - Resource r = null; - - ClassMeta<?> cm = session.getClassMetaForObject(o); - if (s.isLooseCollections() && cm != null && cm.isCollectionOrArray()) { - Collection c = s.sort(cm.isCollection() ? (Collection)o : toList(cm.getInnerClass(), o)); - for (Object o2 : c) - serializeAnything(s, o2, false, object(), "root", null, null); - } else { - RDFNode n = serializeAnything(s, o, false, s.getExpectedRootType(o), "root", null, null); - if (n.isLiteral()) { - r = model.createResource(); - r.addProperty(s.getValueProperty(), n); - } else { - r = n.asResource(); - } - - if (s.isAddRootProp()) - r.addProperty(s.getRootProp(), "true"); - } - - s.getRdfWriter().write(model, out.getWriter(), "http://unknown/"); - } - - private RDFNode serializeAnything(RdfSerializerSession session, Object o, boolean isURI, ClassMeta<?> eType, - String attrName, BeanPropertyMeta bpm, Resource parentResource) throws SerializeException { - Model m = session.getModel(); - - ClassMeta<?> aType = null; // The actual type - ClassMeta<?> wType = null; // The wrapped type - ClassMeta<?> sType = object(); // The serialized type - - aType = session.push(attrName, o, eType); - - if (eType == null) - eType = object(); - - // Handle recursion - if (aType == null) { - o = null; - aType = object(); - } - - if (o != null) { - - if (aType.isDelegate()) { - wType = aType; - aType = ((Delegate)o).getClassMeta(); - } - - sType = aType.getSerializedClassMeta(); - - // Swap if necessary - PojoSwap swap = aType.getPojoSwap(); - if (swap != null) { - o = swap.swap(session, o); - - // If the getSwapClass() method returns Object, we need to figure out - // the actual type now. - if (sType.isObject()) - sType = session.getClassMetaForObject(o); - } - } else { - sType = eType.getSerializedClassMeta(); - } - - String typeName = session.getBeanTypeName(eType, aType, bpm); - - RDFNode n = null; - - if (o == null || sType.isChar() && ((Character)o).charValue() == 0) { - if (bpm != null) { - if (! session.isTrimNulls()) { - n = m.createResource(RDF_NIL); - } - } else { - n = m.createResource(RDF_NIL); - } - - } else if (sType.isUri() || isURI) { - // Note that RDF URIs must be absolute to be valid! - String uri = getUri(session, o, null); - if (StringUtils.isAbsoluteUri(uri)) - n = m.createResource(uri); - else - n = m.createLiteral(session.encodeTextInvalidChars(uri)); - - } else if (sType.isCharSequence() || sType.isChar()) { - n = m.createLiteral(session.encodeTextInvalidChars(o)); - - } else if (sType.isNumber() || sType.isBoolean()) { - if (! session.isAddLiteralTypes()) - n = m.createLiteral(o.toString()); - else - n = m.createTypedLiteral(o); - - } else if (sType.isMap() || (wType != null && wType.isMap())) { - if (o instanceof BeanMap) { - BeanMap bm = (BeanMap)o; - Object uri = null; - RdfBeanMeta rbm = (RdfBeanMeta)bm.getMeta().getExtendedMeta(RdfBeanMeta.class); - if (rbm.hasBeanUri()) - uri = rbm.getBeanUriProperty().get(bm, null); - String uri2 = getUri(session, uri, null); - n = m.createResource(uri2); - serializeBeanMap(session, bm, (Resource)n, typeName); - } else { - Map m2 = (Map)o; - n = m.createResource(); - serializeMap(session, m2, (Resource)n, sType); - } - - } else if (sType.isBean()) { - BeanMap bm = session.toBeanMap(o); - Object uri = null; - RdfBeanMeta rbm = (RdfBeanMeta)bm.getMeta().getExtendedMeta(RdfBeanMeta.class); - if (rbm.hasBeanUri()) - uri = rbm.getBeanUriProperty().get(bm, null); - String uri2 = getUri(session, uri, null); - n = m.createResource(uri2); - serializeBeanMap(session, bm, (Resource)n, typeName); - - } else if (sType.isCollectionOrArray() || (wType != null && wType.isCollection())) { - Collection c = session.sort(sType.isCollection() ? (Collection)o : toList(sType.getInnerClass(), o)); - RdfCollectionFormat f = session.getCollectionFormat(); - RdfClassMeta rcm = sType.getExtendedMeta(RdfClassMeta.class); - if (rcm.getCollectionFormat() != RdfCollectionFormat.DEFAULT) - f = rcm.getCollectionFormat(); - if (bpm != null && bpm.getExtendedMeta(RdfBeanPropertyMeta.class).getCollectionFormat() != RdfCollectionFormat.DEFAULT) - f = bpm.getExtendedMeta(RdfBeanPropertyMeta.class).getCollectionFormat(); - switch (f) { - case BAG: n = serializeToContainer(session, c, eType, m.createBag()); break; - case LIST: n = serializeToList(session, c, eType); break; - case MULTI_VALUED: serializeToMultiProperties(session, c, eType, bpm, attrName, parentResource); break; - default: n = serializeToContainer(session, c, eType, m.createSeq()); - } - } else { - n = m.createLiteral(session.encodeTextInvalidChars(session.toString(o))); - } - - session.pop(); - - return n; - } - - private static String getUri(RdfSerializerSession session, Object uri, Object uri2) { - String s = null; - if (uri != null) - s = uri.toString(); - if ((s == null || s.isEmpty()) && uri2 != null) - s = uri2.toString(); - if (s == null) - return null; - return session.getUriResolver().resolve(s); - } - - private void serializeMap(RdfSerializerSession session, Map m, Resource r, ClassMeta<?> type) throws SerializeException { - - m = session.sort(m); - - ClassMeta<?> keyType = type.getKeyType(), valueType = type.getValueType(); - - ArrayList<Map.Entry<Object,Object>> l = new ArrayList<Map.Entry<Object,Object>>(m.entrySet()); - Collections.reverse(l); - for (Map.Entry<Object,Object> me : l) { - Object value = me.getValue(); - - Object key = session.generalize(me.getKey(), keyType); - - Namespace ns = session.getJuneauBpNs(); - Model model = session.getModel(); - Property p = model.createProperty(ns.getUri(), session.encodeElementName(session.toString(key))); - RDFNode n = serializeAnything(session, value, false, valueType, key == null ? null : session.toString(key), null, r); - if (n != null) - r.addProperty(p, n); - } - } - - private void serializeBeanMap(RdfSerializerSession session, BeanMap<?> m, Resource r, String typeName) throws SerializeException { - List<BeanPropertyValue> l = m.getValues(session.isTrimNulls(), typeName != null ? session.createBeanTypeNameProperty(m, typeName) : null); - Collections.reverse(l); - for (BeanPropertyValue bpv : l) { - BeanPropertyMeta pMeta = bpv.getMeta(); - ClassMeta<?> cMeta = pMeta.getClassMeta(); - - if (pMeta.getExtendedMeta(RdfBeanPropertyMeta.class).isBeanUri()) - continue; - - String key = bpv.getName(); - Object value = bpv.getValue(); - Throwable t = bpv.getThrown(); - if (t != null) - session.onBeanGetterException(pMeta, t); - - if (session.canIgnoreValue(cMeta, key, value)) - continue; - - BeanPropertyMeta bpm = bpv.getMeta(); - Namespace ns = bpm.getExtendedMeta(RdfBeanPropertyMeta.class).getNamespace(); - if (ns == null && session.isUseXmlNamespaces()) - ns = bpm.getExtendedMeta(XmlBeanPropertyMeta.class).getNamespace(); - if (ns == null) - ns = session.getJuneauBpNs(); - else if (session.isAutoDetectNamespaces()) - session.addModelPrefix(ns); - - Property p = session.getModel().createProperty(ns.getUri(), session.encodeElementName(key)); - RDFNode n = serializeAnything(session, value, pMeta.isUri(), cMeta, key, pMeta, r); - if (n != null) - r.addProperty(p, n); - } - } - - - private Container serializeToContainer(RdfSerializerSession session, Collection c, ClassMeta<?> type, Container list) throws SerializeException { - - ClassMeta<?> elementType = type.getElementType(); - for (Object e : c) { - RDFNode n = serializeAnything(session, e, false, elementType, null, null, null); - list = list.add(n); - } - return list; - } - - private RDFList serializeToList(RdfSerializerSession session, Collection c, ClassMeta<?> type) throws SerializeException { - ClassMeta<?> elementType = type.getElementType(); - List<RDFNode> l = new ArrayList<RDFNode>(c.size()); - for (Object e : c) { - l.add(serializeAnything(session, e, false, elementType, null, null, null)); - } - return session.getModel().createList(l.iterator()); - } - - private void serializeToMultiProperties(RdfSerializerSession session, Collection c, ClassMeta<?> sType, - BeanPropertyMeta bpm, String attrName, Resource parentResource) throws SerializeException { - ClassMeta<?> elementType = sType.getElementType(); - for (Object e : c) { - Namespace ns = null; - if (bpm != null) { - ns = bpm.getExtendedMeta(RdfBeanPropertyMeta.class).getNamespace(); - if (ns == null && session.isUseXmlNamespaces()) - ns = bpm.getExtendedMeta(XmlBeanPropertyMeta.class).getNamespace(); - } - if (ns == null) - ns = session.getJuneauBpNs(); - else if (session.isAutoDetectNamespaces()) - session.addModelPrefix(ns); - RDFNode n2 = serializeAnything(session, e, false, elementType, null, null, null); - Property p = session.getModel().createProperty(ns.getUri(), session.encodeElementName(attrName)); - parentResource.addProperty(p, n2); - } - - } - - - //-------------------------------------------------------------------------------- - // Entry point methods - //-------------------------------------------------------------------------------- - - @Override /* Serializer */ - public RdfSerializerSession createSession(ObjectMap op, Method javaMethod, Locale locale, - TimeZone timeZone, MediaType mediaType, UriContext uriContext) { - return new RdfSerializerSession(ctx, op, javaMethod, locale, timeZone, mediaType, uriContext); + public WriterSerializerSession createSession(SerializerSessionArgs args) { + return new RdfSerializerSession(ctx, args); } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/2a37f310/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java ---------------------------------------------------------------------- diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java index d7dabb8..3e8f1ba 100644 --- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java +++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java @@ -16,24 +16,26 @@ import static org.apache.juneau.jena.Constants.*; import static org.apache.juneau.jena.RdfCommonContext.*; import static org.apache.juneau.jena.RdfSerializerContext.*; -import java.lang.reflect.*; import java.util.*; import org.apache.juneau.*; -import org.apache.juneau.http.*; +import org.apache.juneau.internal.*; import org.apache.juneau.msgpack.*; import org.apache.juneau.serializer.*; +import org.apache.juneau.transform.*; import org.apache.juneau.xml.*; import com.hp.hpl.jena.rdf.model.*; /** * Session object that lives for the duration of a single use of {@link RdfSerializer}. - * + * * <p> - * This class is NOT thread safe. It is meant to be discarded after one-time use. + * This class is NOT thread safe. + * It is typically discarded after one-time use although it can be reused within the same thread. */ -public final class RdfSerializerSession extends SerializerSession { +@SuppressWarnings({ "rawtypes", "unchecked" }) +public final class RdfSerializerSession extends WriterSerializerSession { private final String rdfLanguage; private final Namespace juneauNs, juneauBpNs; @@ -44,7 +46,7 @@ public final class RdfSerializerSession extends SerializerSession { looseCollections, autoDetectNamespaces, addBeanTypeProperties; - private final Property pRoot, pValue, pType; + private final Property pRoot, pValue; private final Model model; private final RDFWriter writer; private final RdfCollectionFormat collectionFormat; @@ -53,32 +55,24 @@ public final class RdfSerializerSession extends SerializerSession { /** * Create a new session using properties specified in the context. * - * @param ctx + * @param ctx * The context creating this session object. * The context contains all the configuration settings for this object. - * @param op - * The override properties. - * These override any context properties defined in the context. - * @param javaMethod The java method that called this serializer, usually the method in a REST servlet. - * @param locale - * The session locale. - * If <jk>null</jk>, then the locale defined on the context is used. - * @param timeZone - * The session timezone. - * If <jk>null</jk>, then the timezone defined on the context is used. - * @param mediaType The session media type (e.g. <js>"application/json"</js>). - * @param uriContext - * The URI context. - * Identifies the current request URI used for resolution of URIs to absolute or root-relative form. + * @param args + * Runtime arguments. + * These specify session-level information such as locale and URI context. + * It also include session-level properties that override the properties defined on the bean and + * serializer contexts. + * <br>If <jk>null</jk>, defaults to {@link SerializerSessionArgs#DEFAULT}. */ - protected RdfSerializerSession(RdfSerializerContext ctx, ObjectMap op, Method javaMethod, - Locale locale, TimeZone timeZone, MediaType mediaType, UriContext uriContext) { - super(ctx, op, javaMethod, locale, timeZone, mediaType, uriContext); + protected RdfSerializerSession(RdfSerializerContext ctx, SerializerSessionArgs args) { + super(ctx, args); ObjectMap jenaSettings = new ObjectMap(); jenaSettings.put("rdfXml.tab", isUseWhitespace() ? 2 : 0); jenaSettings.put("rdfXml.attributeQuoteChar", Character.toString(getQuoteChar())); jenaSettings.putAll(ctx.jenaSettings); - if (op == null || op.isEmpty()) { + ObjectMap p = getProperties(); + if (p.isEmpty()) { this.rdfLanguage = ctx.rdfLanguage; this.juneauNs = ctx.juneauNs; this.juneauBpNs = ctx.juneauBpNs; @@ -91,22 +85,22 @@ public final class RdfSerializerSession extends SerializerSession { this.namespaces = ctx.namespaces; addBeanTypeProperties = ctx.addBeanTypeProperties; } else { - this.rdfLanguage = op.getString(RDF_language, ctx.rdfLanguage); - this.juneauNs = (op.containsKey(RDF_juneauNs) ? NamespaceFactory.parseNamespace(op.get(RDF_juneauNs)) : ctx.juneauNs); - this.juneauBpNs = (op.containsKey(RDF_juneauBpNs) ? NamespaceFactory.parseNamespace(op.get(RDF_juneauBpNs)) : ctx.juneauBpNs); - this.addLiteralTypes = op.getBoolean(RDF_addLiteralTypes, ctx.addLiteralTypes); - this.addRootProperty = op.getBoolean(RDF_addRootProperty, ctx.addRootProperty); - for (Map.Entry<String,Object> e : op.entrySet()) { + this.rdfLanguage = p.getString(RDF_language, ctx.rdfLanguage); + this.juneauNs = (p.containsKey(RDF_juneauNs) ? NamespaceFactory.parseNamespace(p.get(RDF_juneauNs)) : ctx.juneauNs); + this.juneauBpNs = (p.containsKey(RDF_juneauBpNs) ? NamespaceFactory.parseNamespace(p.get(RDF_juneauBpNs)) : ctx.juneauBpNs); + this.addLiteralTypes = p.getBoolean(RDF_addLiteralTypes, ctx.addLiteralTypes); + this.addRootProperty = p.getBoolean(RDF_addRootProperty, ctx.addRootProperty); + for (Map.Entry<String,Object> e : p.entrySet()) { String key = e.getKey(); if (key.startsWith("Rdf.jena.")) jenaSettings.put(key.substring(9), e.getValue()); } - this.collectionFormat = RdfCollectionFormat.valueOf(op.getString(RDF_collectionFormat, "DEFAULT")); - this.looseCollections = op.getBoolean(RDF_looseCollections, ctx.looseCollections); - this.useXmlNamespaces = op.getBoolean(RDF_useXmlNamespaces, ctx.useXmlNamespaces); - this.autoDetectNamespaces = op.getBoolean(RDF_autoDetectNamespaces, ctx.autoDetectNamespaces); - this.namespaces = op.get(Namespace[].class, RDF_namespaces, ctx.namespaces); - addBeanTypeProperties = op.getBoolean(RDF_addBeanTypeProperties, ctx.addBeanTypeProperties); + this.collectionFormat = RdfCollectionFormat.valueOf(p.getString(RDF_collectionFormat, "DEFAULT")); + this.looseCollections = p.getBoolean(RDF_looseCollections, ctx.looseCollections); + this.useXmlNamespaces = p.getBoolean(RDF_useXmlNamespaces, ctx.useXmlNamespaces); + this.autoDetectNamespaces = p.getBoolean(RDF_autoDetectNamespaces, ctx.autoDetectNamespaces); + this.namespaces = p.get(Namespace[].class, RDF_namespaces, ctx.namespaces); + addBeanTypeProperties = p.getBoolean(RDF_addBeanTypeProperties, ctx.addBeanTypeProperties); } this.model = ModelFactory.createDefaultModel(); addModelPrefix(juneauNs); @@ -115,7 +109,6 @@ public final class RdfSerializerSession extends SerializerSession { addModelPrefix(ns); this.pRoot = model.createProperty(juneauNs.getUri(), RDF_juneauNs_ROOT); this.pValue = model.createProperty(juneauNs.getUri(), RDF_juneauNs_VALUE); - this.pType = model.createProperty(juneauNs.getUri(), RDF_juneauNs_TYPE); writer = model.getWriter(rdfLanguage); // Only apply properties with this prefix! @@ -128,172 +121,291 @@ public final class RdfSerializerSession extends SerializerSession { writer.setProperty(e.getKey().substring(propPrefix.length()), e.getValue()); } - /** + /* * Adds the specified namespace as a model prefix. - * - * @param ns The XML namespace. */ - public void addModelPrefix(Namespace ns) { + private void addModelPrefix(Namespace ns) { model.setNsPrefix(ns.getName(), ns.getUri()); } /** - * Returns the {@link RdfCommonContext#RDF_collectionFormat} setting value for this session. + * Returns the {@link MsgPackSerializerContext#MSGPACK_addBeanTypeProperties} setting value for this session. * - * @return The {@link RdfCommonContext#RDF_collectionFormat} setting value for this session. + * @return The {@link MsgPackSerializerContext#MSGPACK_addBeanTypeProperties} setting value for this session. */ - public final RdfCollectionFormat getCollectionFormat() { - return collectionFormat; + @Override /* SerializerSession */ + public final boolean isAddBeanTypeProperties() { + return addBeanTypeProperties; } - /** - * Returns the {@link RdfCommonContext#RDF_useXmlNamespaces} setting value for this session. - * - * @return The {@link RdfCommonContext#RDF_useXmlNamespaces} setting value for this session. + /* + * XML-encodes the specified string using the {@link XmlUtils#escapeText(Object)} method. */ - public final boolean isUseXmlNamespaces() { - return useXmlNamespaces; + private String encodeTextInvalidChars(Object o) { + if (o == null) + return null; + String s = toString(o); + return XmlUtils.escapeText(s); } - /** - * Returns the {@link RdfCommonContext#RDF_looseCollections} setting value for this session. - * - * @return The {@link RdfCommonContext#RDF_looseCollections} setting value for this session. + /* + * XML-encoded the specified element name using the {@link XmlUtils#encodeElementName(Object)} method. */ - public final boolean isLooseCollections() { - return looseCollections; + private String encodeElementName(Object o) { + return XmlUtils.encodeElementName(toString(o)); } + + @Override /* Serializer */ + protected void doSerialize(SerializerPipe out, Object o) throws Exception { - /** - * Returns the {@link RdfCommonContext#RDF_language} setting value for this session. - * - * @return The {@link RdfCommonContext#RDF_language} setting value for this session. - */ - public final String getRdfLanguage() { - return rdfLanguage; - } + Resource r = null; - /** - * Returns the {@link RdfCommonContext#RDF_juneauNs} setting value for this session. - * - * @return The {@link RdfCommonContext#RDF_juneauNs} setting value for this session. - */ - public final Namespace getJuneauNs() { - return juneauNs; - } + ClassMeta<?> cm = getClassMetaForObject(o); + if (looseCollections && cm != null && cm.isCollectionOrArray()) { + Collection c = sort(cm.isCollection() ? (Collection)o : toList(cm.getInnerClass(), o)); + for (Object o2 : c) + serializeAnything(o2, false, object(), "root", null, null); + } else { + RDFNode n = serializeAnything(o, false, getExpectedRootType(o), "root", null, null); + if (n.isLiteral()) { + r = model.createResource(); + r.addProperty(pValue, n); + } else { + r = n.asResource(); + } - /** - * Returns the {@link RdfCommonContext#RDF_juneauBpNs} setting value for this session. - * - * @return The {@link RdfCommonContext#RDF_juneauBpNs} setting value for this session. - */ - public final Namespace getJuneauBpNs() { - return juneauBpNs; - } + if (addRootProperty) + r.addProperty(pRoot, "true"); + } - /** - * Returns the {@link RdfSerializerContext#RDF_addLiteralTypes} setting value for this session. - * - * @return The {@link RdfSerializerContext#RDF_addLiteralTypes} setting value for this session. - */ - public final boolean isAddLiteralTypes() { - return addLiteralTypes; + writer.write(model, out.getWriter(), "http://unknown/"); } - /** - * Returns the {@link RdfSerializerContext#RDF_addRootProperty} setting value for this session. - * - * @return The {@link RdfSerializerContext#RDF_addRootProperty} setting value for this session. - */ - public final boolean isAddRootProp() { - return addRootProperty; - } + private RDFNode serializeAnything(Object o, boolean isURI, ClassMeta<?> eType, + String attrName, BeanPropertyMeta bpm, Resource parentResource) throws SerializeException { + Model m = model; - /** - * Returns the {@link RdfSerializerContext#RDF_autoDetectNamespaces} setting value for this session. - * - * @return The {@link RdfSerializerContext#RDF_autoDetectNamespaces} setting value for this session. - */ - public final boolean isAutoDetectNamespaces() { - return autoDetectNamespaces; - } + ClassMeta<?> aType = null; // The actual type + ClassMeta<?> wType = null; // The wrapped type + ClassMeta<?> sType = object(); // The serialized type - /** - * Returns the {@link MsgPackSerializerContext#MSGPACK_addBeanTypeProperties} setting value for this session. - * - * @return The {@link MsgPackSerializerContext#MSGPACK_addBeanTypeProperties} setting value for this session. - */ - @Override /* SerializerSession */ - public final boolean isAddBeanTypeProperties() { - return addBeanTypeProperties; - } + aType = push(attrName, o, eType); - /** - * Returns the RDF property that identifies the root node in the RDF model. - * - * @return The RDF property that identifies the root node in the RDF model. - */ - public final Property getRootProp() { - return pRoot; + if (eType == null) + eType = object(); + + // Handle recursion + if (aType == null) { + o = null; + aType = object(); + } + + if (o != null) { + + if (aType.isDelegate()) { + wType = aType; + aType = ((Delegate)o).getClassMeta(); + } + + sType = aType.getSerializedClassMeta(); + + // Swap if necessary + PojoSwap swap = aType.getPojoSwap(); + if (swap != null) { + o = swap.swap(this, o); + + // If the getSwapClass() method returns Object, we need to figure out + // the actual type now. + if (sType.isObject()) + sType = getClassMetaForObject(o); + } + } else { + sType = eType.getSerializedClassMeta(); + } + + String typeName = getBeanTypeName(eType, aType, bpm); + + RDFNode n = null; + + if (o == null || sType.isChar() && ((Character)o).charValue() == 0) { + if (bpm != null) { + if (! isTrimNulls()) { + n = m.createResource(RDF_NIL); + } + } else { + n = m.createResource(RDF_NIL); + } + + } else if (sType.isUri() || isURI) { + // Note that RDF URIs must be absolute to be valid! + String uri = getUri(o, null); + if (StringUtils.isAbsoluteUri(uri)) + n = m.createResource(uri); + else + n = m.createLiteral(encodeTextInvalidChars(uri)); + + } else if (sType.isCharSequence() || sType.isChar()) { + n = m.createLiteral(encodeTextInvalidChars(o)); + + } else if (sType.isNumber() || sType.isBoolean()) { + if (! addLiteralTypes) + n = m.createLiteral(o.toString()); + else + n = m.createTypedLiteral(o); + + } else if (sType.isMap() || (wType != null && wType.isMap())) { + if (o instanceof BeanMap) { + BeanMap bm = (BeanMap)o; + Object uri = null; + RdfBeanMeta rbm = (RdfBeanMeta)bm.getMeta().getExtendedMeta(RdfBeanMeta.class); + if (rbm.hasBeanUri()) + uri = rbm.getBeanUriProperty().get(bm, null); + String uri2 = getUri(uri, null); + n = m.createResource(uri2); + serializeBeanMap(bm, (Resource)n, typeName); + } else { + Map m2 = (Map)o; + n = m.createResource(); + serializeMap(m2, (Resource)n, sType); + } + + } else if (sType.isBean()) { + BeanMap bm = toBeanMap(o); + Object uri = null; + RdfBeanMeta rbm = (RdfBeanMeta)bm.getMeta().getExtendedMeta(RdfBeanMeta.class); + if (rbm.hasBeanUri()) + uri = rbm.getBeanUriProperty().get(bm, null); + String uri2 = getUri(uri, null); + n = m.createResource(uri2); + serializeBeanMap(bm, (Resource)n, typeName); + + } else if (sType.isCollectionOrArray() || (wType != null && wType.isCollection())) { + Collection c = sort(sType.isCollection() ? (Collection)o : toList(sType.getInnerClass(), o)); + RdfCollectionFormat f = collectionFormat; + RdfClassMeta rcm = sType.getExtendedMeta(RdfClassMeta.class); + if (rcm.getCollectionFormat() != RdfCollectionFormat.DEFAULT) + f = rcm.getCollectionFormat(); + if (bpm != null && bpm.getExtendedMeta(RdfBeanPropertyMeta.class).getCollectionFormat() != RdfCollectionFormat.DEFAULT) + f = bpm.getExtendedMeta(RdfBeanPropertyMeta.class).getCollectionFormat(); + switch (f) { + case BAG: n = serializeToContainer(c, eType, m.createBag()); break; + case LIST: n = serializeToList(c, eType); break; + case MULTI_VALUED: serializeToMultiProperties(c, eType, bpm, attrName, parentResource); break; + default: n = serializeToContainer(c, eType, m.createSeq()); + } + } else { + n = m.createLiteral(encodeTextInvalidChars(toString(o))); + } + + pop(); + + return n; } - /** - * Returns the RDF property that represents a value in the RDF model. - * - * @return The RDF property that represents a value in the RDF model. - */ - public final Property getValueProperty() { - return pValue; + private String getUri(Object uri, Object uri2) { + String s = null; + if (uri != null) + s = uri.toString(); + if ((s == null || s.isEmpty()) && uri2 != null) + s = uri2.toString(); + if (s == null) + return null; + return getUriResolver().resolve(s); } - /** - * Returns the RDF property that represents a class in the RDF model. - * - * @return The RDF property that represents a class in the RDF model. - */ - public final Property getTypeProperty() { - return pType; + private void serializeMap(Map m, Resource r, ClassMeta<?> type) throws SerializeException { + + m = sort(m); + + ClassMeta<?> keyType = type.getKeyType(), valueType = type.getValueType(); + + ArrayList<Map.Entry<Object,Object>> l = new ArrayList<Map.Entry<Object,Object>>(m.entrySet()); + Collections.reverse(l); + for (Map.Entry<Object,Object> me : l) { + Object value = me.getValue(); + + Object key = generalize(me.getKey(), keyType); + + Namespace ns = juneauBpNs; + Property p = model.createProperty(ns.getUri(), encodeElementName(toString(key))); + RDFNode n = serializeAnything(value, false, valueType, key == null ? null : toString(key), null, r); + if (n != null) + r.addProperty(p, n); + } } - /** - * Returns the RDF model being serialized. - * - * @return The RDF model being serialized. - */ - public final Model getModel() { - return model; + private void serializeBeanMap(BeanMap<?> m, Resource r, String typeName) throws SerializeException { + List<BeanPropertyValue> l = m.getValues(isTrimNulls(), typeName != null ? createBeanTypeNameProperty(m, typeName) : null); + Collections.reverse(l); + for (BeanPropertyValue bpv : l) { + BeanPropertyMeta pMeta = bpv.getMeta(); + ClassMeta<?> cMeta = pMeta.getClassMeta(); + + if (pMeta.getExtendedMeta(RdfBeanPropertyMeta.class).isBeanUri()) + continue; + + String key = bpv.getName(); + Object value = bpv.getValue(); + Throwable t = bpv.getThrown(); + if (t != null) + onBeanGetterException(pMeta, t); + + if (canIgnoreValue(cMeta, key, value)) + continue; + + BeanPropertyMeta bpm = bpv.getMeta(); + Namespace ns = bpm.getExtendedMeta(RdfBeanPropertyMeta.class).getNamespace(); + if (ns == null && useXmlNamespaces) + ns = bpm.getExtendedMeta(XmlBeanPropertyMeta.class).getNamespace(); + if (ns == null) + ns = juneauBpNs; + else if (autoDetectNamespaces) + addModelPrefix(ns); + + Property p = model.createProperty(ns.getUri(), encodeElementName(key)); + RDFNode n = serializeAnything(value, pMeta.isUri(), cMeta, key, pMeta, r); + if (n != null) + r.addProperty(p, n); + } } - /** - * Returns the RDF writer that's being serialized to. - * - * @return The RDF writer that's being serialized to. - */ - public final RDFWriter getRdfWriter() { - return writer; + + private Container serializeToContainer(Collection c, ClassMeta<?> type, Container list) throws SerializeException { + + ClassMeta<?> elementType = type.getElementType(); + for (Object e : c) { + RDFNode n = serializeAnything(e, false, elementType, null, null, null); + list = list.add(n); + } + return list; } - /** - * XML-encodes the specified string using the {@link XmlUtils#escapeText(Object)} method. - * - * @param o The string being encoded. - * @return The encoded string, or <jk>null</jk> if the input was <jk>null</jk>. - */ - public final String encodeTextInvalidChars(Object o) { - if (o == null) - return null; - String s = toString(o); - return XmlUtils.escapeText(s); + private RDFList serializeToList(Collection c, ClassMeta<?> type) throws SerializeException { + ClassMeta<?> elementType = type.getElementType(); + List<RDFNode> l = new ArrayList<RDFNode>(c.size()); + for (Object e : c) { + l.add(serializeAnything(e, false, elementType, null, null, null)); + } + return model.createList(l.iterator()); } - /** - * XML-encoded the specified element name using the {@link XmlUtils#encodeElementName(Object)} method. - * - * @param o The string being encoded. - * @return The encoded string. - */ - public final String encodeElementName(Object o) { - String s = toString(o); - return XmlUtils.encodeElementName(s); + private void serializeToMultiProperties(Collection c, ClassMeta<?> sType, + BeanPropertyMeta bpm, String attrName, Resource parentResource) throws SerializeException { + ClassMeta<?> elementType = sType.getElementType(); + for (Object e : c) { + Namespace ns = null; + if (bpm != null) { + ns = bpm.getExtendedMeta(RdfBeanPropertyMeta.class).getNamespace(); + if (ns == null && useXmlNamespaces) + ns = bpm.getExtendedMeta(XmlBeanPropertyMeta.class).getNamespace(); + } + if (ns == null) + ns = juneauBpNs; + else if (autoDetectNamespaces) + addModelPrefix(ns); + RDFNode n2 = serializeAnything(e, false, elementType, null, null, null); + Property p = model.createProperty(ns.getUri(), encodeElementName(attrName)); + parentResource.addProperty(p, n2); + } } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/2a37f310/juneau-core-test/src/test/java/org/apache/juneau/ParserReaderTest.java ---------------------------------------------------------------------- diff --git a/juneau-core-test/src/test/java/org/apache/juneau/ParserReaderTest.java b/juneau-core-test/src/test/java/org/apache/juneau/ParserReaderTest.java index 82be1ac..49a8918 100755 --- a/juneau-core-test/src/test/java/org/apache/juneau/ParserReaderTest.java +++ b/juneau-core-test/src/test/java/org/apache/juneau/ParserReaderTest.java @@ -30,25 +30,25 @@ public class ParserReaderTest { String t = "01234567890123456789012345678901234567890123456789"; // Min buff size is 20. - ParserReader pr = new ParserReader(new StringReader(t)); + ParserReader pr = createParserReader(t); String r = read(pr); assertEquals(t, r); pr.close(); - pr = new ParserReader(new StringReader(t)); + pr = createParserReader(t); pr.read(); pr.unread(); r = read(pr); assertEquals(t, r); pr.close(); - pr = new ParserReader(new StringReader(t)); + pr = createParserReader(t); assertEquals('0', (char)pr.peek()); assertEquals('0', (char)pr.peek()); r = read(pr); assertEquals(t, r); - pr = new ParserReader(new StringReader(t)); + pr = createParserReader(t); pr.read(); pr.unread(); try { @@ -68,7 +68,7 @@ public class ParserReaderTest { String r = null; // Min buff size is 20. - ParserReader pr = new ParserReader(t); + ParserReader pr = createParserReader(t); read(pr, 5); pr.mark(); read(pr, 10); @@ -78,7 +78,7 @@ public class ParserReaderTest { assertEquals("56789c123456789d123456789e123456789f123456789g123456789h123456789i123456789j123456789", r); // Force doubling of buffer size - pr = new ParserReader(t); + pr =createParserReader(t); read(pr, 5); pr.mark(); read(pr, 20); @@ -96,7 +96,7 @@ public class ParserReaderTest { String t = "a123456789b123456789c123456789d123456789e123456789f123456789g123456789h123456789i123456789j123456789"; // Min buff size is 20. - ParserReader pr = new ParserReader(t); + ParserReader pr = createParserReader(t); assertEquals("a123456789", pr.read(10)); pr.mark(); assertEquals("b123456789c123456789", pr.read(20)); @@ -115,7 +115,7 @@ public class ParserReaderTest { String t = "a123456789b123456789c123456789d123456789e123456789f123456789g123456789h123456789i123456789j123456789"; // Min buff size is 20. - ParserReader pr = new ParserReader(t); + ParserReader pr = createParserReader(t); assertEquals("a123456789", pr.read(10)); pr.mark(); assertEquals("b123456789", pr.read(10)); @@ -124,7 +124,7 @@ public class ParserReaderTest { assertEquals("b12345678xc123456789", pr.getMarked()); pr.close(); - pr = new ParserReader(t); + pr = createParserReader(t); assertEquals("a123456789", pr.read(10)); pr.mark(); assertEquals("b123456789", pr.read(10)); @@ -142,7 +142,7 @@ public class ParserReaderTest { String t = "a123456789b123456789c123456789d123456789e123456789f123456789g123456789h123456789i123456789j123456789"; // Min buff size is 20. - ParserReader pr = new ParserReader(t); + ParserReader pr = createParserReader(t); assertEquals("a123456789", pr.read(10)); pr.mark(); assertEquals("b123456789", pr.read(10)); @@ -151,7 +151,7 @@ public class ParserReaderTest { assertEquals("b12345678c123456789", pr.getMarked()); pr.close(); - pr = new ParserReader(t); + pr = createParserReader(t); assertEquals("a123456789", pr.read(10)); pr.mark(); assertEquals("b123456789", pr.read(10)); @@ -179,4 +179,8 @@ public class ParserReaderTest { } return sb.toString(); } + + private ParserReader createParserReader(Object in) throws Exception { + return new ParserReader(new ParserPipe(in, false, false, null, null)); + } }
