http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core/src/main/java/org/apache/juneau/jena/package.html ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/jena/package.html b/juneau-core/src/main/java/org/apache/juneau/jena/package.html deleted file mode 100644 index 6036583..0000000 --- a/juneau-core/src/main/java/org/apache/juneau/jena/package.html +++ /dev/null @@ -1,1445 +0,0 @@ -<!DOCTYPE HTML> -<!-- -/*************************************************************************************************************************** - * 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. - * - ***************************************************************************************************************************/ - --> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> - <style type="text/css"> - /* For viewing in Page Designer */ - @IMPORT url("../../../../../../javadoc.css"); - - /* For viewing in REST interface */ - @IMPORT url("../htdocs/javadoc.css"); - body { - margin: 20px; - } - </style> - <script> - /* Replace all @code and @link tags. */ - window.onload = function() { - document.body.innerHTML = document.body.innerHTML.replace(/\{\@code ([^\}]+)\}/g, '<code>$1</code>'); - document.body.innerHTML = document.body.innerHTML.replace(/\{\@link (([^\}]+)\.)?([^\.\}]+)\}/g, '<code>$3</code>'); - } - </script> -</head> -<body> -<p>Jena-based RDF serialization and parsing support</p> -<script> - function toggle(x) { - var div = x.nextSibling; - while (div != null && div.nodeType != 1) - div = div.nextSibling; - if (div != null) { - var d = div.style.display; - if (d == 'block' || d == '') { - div.style.display = 'none'; - x.className += " closed"; - } else { - div.style.display = 'block'; - x.className = x.className.replace(/(?:^|\s)closed(?!\S)/g , '' ); - } - } - } -</script> - -<a id='TOC'></a><h5 class='toc'>Table of Contents</h5> -<ol class='toc'> - <li><p><a class='doclink' href='#RdfOverview'>RDF support overview</a></p> - <ol> - <li><p><a class='doclink' href='#RdfOverviewExample'>Example</a></p> - </ol> - <li><p><a class='doclink' href='#RdfSerializer'>RdfSerializer class</a></p> - <ol> - <li><p><a class='doclink' href='#Namespaces'>Namespaces</a></p> - <li><p><a class='doclink' href='#UriProperties'>URI properties</a></p> - <li><p><a class='doclink' href='#BeanAnnotations'>@Bean and @BeanProperty annotations</a></p> - <li><p><a class='doclink' href='#Collections'>Collections</a></p> - <li><p><a class='doclink' href='#RootProperty'>Root property</a></p> - <li><p><a class='doclink' href='#TypedLiterals'>Typed literals</a></p> - <li><p><a class='doclink' href='#Recursion'>Non-tree models and recursion detection</a></p> - <li><p><a class='doclink' href='#SerializerConfigurableProperties'>Configurable properties</a></p> - <li><p><a class='doclink' href='#SerializerOtherNotes'>Other notes</a></p> - </ol> - <li><p><a class='doclink' href='#RdfParser'>RdfParser class</a></p> - <ol> - <li><p><a class='doclink' href='#GenericParsing'>Parsing into generic POJO models</a></p> - <li><p><a class='doclink' href='#ParserConfigurableProperties'>Configurable properties</a></p> - <li><p><a class='doclink' href='#ParserOtherNotes'>Other notes</a></p> - </ol> - <li><p><a class='doclink' href='#RestApiSupport'>REST API support</a></p> - <ol> - <li><p><a class='doclink' href='#RestServerSupport'>REST server support</a></p> - <ol> - <li><p><a class='doclink' href='#RestServletJenaDefault'>Using RestServletJenaDefault</a></p> - <li><p><a class='doclink' href='#RestServlet'>Using RestServlet with annotations</a></p> - <li><p><a class='doclink' href='#DefaultJenaProvider'>Using JAX-RS DefaultJenaProvider</a></p> - <li><p><a class='doclink' href='#BaseProvider'>Using JAX-RS BaseProvider with annotations</a></p> - </ol> - <li><p><a class='doclink' href='#RestClientSupport'>REST client support</a></p> - </ol> -</ol> - - -<!-- ======================================================================================================== --> -<a id="RdfOverview"></a> -<h2 class='topic' onclick='toggle(this)'>1 - RDF support overview</h2> -<div class='topic'> - <p> - Juneau supports serializing and parsing arbitrary POJOs to and from the following RDF formats: - </p> - <ul> - <li>RDF/XML - <li>Abbreviated RDF/XML - <li>N-Triple - <li>Turtle - <li>N3 - </ul> - <p> - Juneau can serialize and parse instances of any of the following POJO types: - </p> - <ul class='spaced-list'> - <li>Java primitive objects (e.g. <code>String</code>, <code>Integer</code>, <code>Boolean</code>, <code>Float</code>). - <li>Java collections framework objects (e.g. <code>HashSet</code>, <code>TreeMap</code>) containing anything on this list. - <li>Multi-dimensional arrays of any type on this list. - <li>Java Beans with properties of any type on this list. - <li>Classes with standard transformations to and from <code>Strings</code> (e.g. classes containing <code>toString()</code>, - <code>fromString()</code>, <code>valueOf()</code>, <code>constructor(String)</code>). - </ul> - <p> - In addition to the types shown above, Juneau includes the ability to define 'swaps' to transform non-standard object and - property types to serializable forms (e.g. to transform <code>Calendars</code> to and from <code>ISO8601</code> strings, - or <code>byte[]</code> arrays to and from base-64 encoded strings).<br> - These can be associated with serializers/parsers, or can be associated with classes or bean properties through type and method annotations. - </p> - <p> - Refer to <a href='../../../../overview-summary.html#Core.PojoCategories' class='doclink'>POJO Categories</a> for a complete definition of supported POJOs. - </p> - <h6 class='topic'>Prerequisites</h6> - <p> - Juneau uses the Jena library for these formats. <br> - The predefined serializers and parsers convert POJOs to and from RDF models and then uses Jena to convert them to and from the various RDF languages. - </p> - <p> - Jena libraries must be provided on the classpath separately if you plan on making use of the RDF support. - </p> - <p> - The minimum list of required jars are: - </p> - <ul> - <li><code>jena-core-2.7.1.jar</code> - <li><code>jena-iri-0.9.2.jar</code> - <li><code>log4j-1.2.16.jar</code> - <li><code>slf4j-api-1.6.4.jar</code> - <li><code>slf4j-log4j12-1.6.4.jar</code> - </ul> - - <!-- ======================================================================================================== --> - <a id="RdfOverviewExample"></a> - <h3 class='topic' onclick='toggle(this)'>1.1 - RDF support overview - example</h3> - <div class='topic'> - <p> - The example shown here is from the Address Book resource located in the <code>org.apache.juneau.sample.war</code> application. - </p> - <p> - The POJO model consists of a <code>List</code> of <code>Person</code> beans, with each <code>Person</code> containing - zero or more <code>Address</code> beans. - </p> - <p> - When you point a browser at <code>/sample/addressBook</code>, the POJO is rendered as HTML: - </p> - <img class='bordered' src="doc-files/Example_HTML.png"> - <p> - By appending <code>?Accept=<i>mediaType</i>&plainText=true</code> to the URL, you can view the data in the various RDF supported formats. - </p> - - <h6 class='figure'>RDF/XML</h6> - <img class='bordered' src="doc-files/Example_RDFXML.png"> - - <h6 class='figure'>Abbreviated RDF/XML</h6> - <img class='bordered' src="doc-files/Example_RDFXMLABBREV.png"> - - <h6 class='figure'>N-Triple</h6> - <img class='bordered' src="doc-files/Example_NTriple.png"> - - <h6 class='figure'>Turtle</h6> - <img class='bordered' src="doc-files/Example_Turtle.png"> - - <h6 class='figure'>N3</h6> - <img class='bordered' src="doc-files/Example_N3.png"> - </div> -</div> - -<!-- ======================================================================================================== --> -<a id="RdfSerializer"></a> -<h2 class='topic' onclick='toggle(this)'>2 - RdfSerializer class</h2> -<div class='topic'> - <p> - The {@link org.apache.juneau.jena.RdfSerializer} class is the top-level class for all Jena-based serializers.<br> - Language-specific serializers are defined as inner subclasses of the <code>RdfSerializer</code> class: - </p> - <ul> - <li>{@link org.apache.juneau.jena.RdfSerializer.Xml} - <li>{@link org.apache.juneau.jena.RdfSerializer.XmlAbbrev} - <li>{@link org.apache.juneau.jena.RdfSerializer.NTriple} - <li>{@link org.apache.juneau.jena.RdfSerializer.Turtle} - <li>{@link org.apache.juneau.jena.RdfSerializer.N3} - </ul> - <p> - Static reusable instances of serializers are also provided with default settings: - </p> - <ul> - <li>{@link org.apache.juneau.jena.RdfSerializer#DEFAULT_XML} - <li>{@link org.apache.juneau.jena.RdfSerializer#DEFAULT_XMLABBREV} - <li>{@link org.apache.juneau.jena.RdfSerializer#DEFAULT_TURTLE} - <li>{@link org.apache.juneau.jena.RdfSerializer#DEFAULT_NTRIPLE} - <li>{@link org.apache.juneau.jena.RdfSerializer#DEFAULT_N3} - </ul> - <p> - Abbreviated RDF/XML is currently the most widely accepted and readable RDF syntax, so the examples shown here will use that format. - </p> - <p> - For brevity, the examples will use public fields instead of getters/setters to reduce the size of the examples.<br> - In the real world, you'll typically want to use standard bean getters and setters. - </p> - <p> - To start off simple, we'll begin with the following simplified bean and build it up. - </p> - <p class='bcode'> - <jk>public class</jk> Person { - <jc>// Bean properties</jc> - <jk>public int</jk> <jf>id</jf>; - <jk>public</jk> String <jf>name</jf>; - - <jc>// Bean constructor (needed by parser)</jc> - <jk>public</jk> Person() {} - - <jc>// Normal constructor</jc> - <jk>public</jk> Person(<jk>int</jk> id, String name) { - <jk>this</jk>.<jf>id</jf> = id; - <jk>this</jk>.<jf>name</jf> = name; - } - } - </p> - <p> - The following code shows how to convert this to abbreviated RDF/XML: - </p> - <p class='bcode'> - <jc>// Create a new serializer with readable output.</jc> - RdfSerializer s = <jk>new</jk> RdfSerializer.XmlAbbrev().setProperty(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3); - - <jc>// Create our bean.</jc> - Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>); - - <jc>// Serialize the bean to RDF/XML.</jc> - String rdfXml = s.serialize(p); - </p> - <p> - It should be noted that serializers can also be created by cloning existing serializers: - </p> - <p class='bcode'> - <jc>// Create a new serializer with readable output by cloning an existing serializer.</jc> - RdfSerializer s = RdfSerializer.<jsf>DEFAULT_XMLABBREV</jsf>.clone().setProperty(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3); - </p> - <p> - This code produces the following output: - </p> - <p class='bcode'> - <xt><rdf:RDF</xt> - <xa>xmlns:rdf</xa>=<xs>"http://www.w3.org/1999/02/22-rdf-syntax-ns#"</xs> - <xa>xmlns:j</xa>=<xs>"http://www.apache.org/juneau/"</xs> - <xa>xmlns:jp</xa>=<xs>"http://www.apache.org/juneaubp/"</xs><xt>></xt> - <xt><rdf:Description></xt> - <xt><jp:id></xt>1<xt></jp:id></xt> - <xt><jp:name></xt>John Smith<xt></jp:name></xt> - <xt></rdf:Description></xt> - <xt></rdf:RDF></xt> - </p> - <p> - Notice that we've taken an arbitrary POJO and converted it to RDF.<br> - The Juneau serializers and parsers are designed to work with arbitrary POJOs without requiring - any annotations.<br> - That being said, several annotations are provided to customize how POJOs are handled to produce usable RDF. - </p> - - <!-- ======================================================================================================== --> - <a id="Namespaces"></a> - <h3 class='topic' onclick='toggle(this)'>2.1 - Namespaces</h3> - <div class='topic'> - <p> - You'll notice in the previous example that Juneau namespaces are used to represent bean property names.<br> - These are used by default when namespaces are not explicitly specified. - </p> - <p> - The <code>juneau</code> namespace is used for generic names for objects that don't have namespaces associated with them. - </p> - <p> - The <code>juneaubp</code> namespace is used on bean properties that don't have namespaces associated with them. - </p> - <p> - The easiest way to specify namespaces is through annotations.<br> - In this example, we're going to associate the prefix <code>'per'</code> to our bean class and all - properties of this class.<br> - We do this by adding the following annotation to our class: - </p> - <p class='bcode'> - <ja>@Rdf</ja>(prefix=<js>"per"</js>) - <jk>public class</jk> Person { - </p> - <p> - In general, the best approach is to define the namespace URIs at the package level using a <code>package-info.java</code> - class, like so: - </p> - <p class='bcode'> - <jc>// RDF namespaces used in this package</jc> - <ja>@RdfSchema</ja>( - prefix=<js>"ab"</js>, - rdfNs={ - <ja>@RdfNs</ja>(prefix=<js>"ab"</js>, namespaceURI=<js>"http://www.apache.org/addressBook/"</js>), - <ja>@RdfNs</ja>(prefix=<js>"per"</js>, namespaceURI=<js>"http://www.apache.org/person/"</js>), - <ja>@RdfNs</ja>(prefix=<js>"addr"</js>, namespaceURI=<js>"http://www.apache.org/address/"</js>), - <ja>@RdfNs</ja>(prefix=<js>"mail"</js>, namespaceURI=<js>"http://www.apache.org/mail/"</js>) - } - ) - <jk>package</jk> org.apache.juneau.sample.addressbook; - <jk>import</jk> org.apache.juneau.xml.annotation.*; - </p> - <p> - This assigns a default prefix of <js>"ab"</js> for all classes and properties within the project, - and specifies various other prefixes used within this project. - </p> - <p> - Now when we rerun the sample code, we'll get the following: - </p> - <p class='bcode'> - <xt><rdf:RDF</xt> - <xa>xmlns:rdf</xa>=<xs>"http://www.w3.org/1999/02/22-rdf-syntax-ns#"</xs> - <xa>xmlns:j</xa>=<xs>"http://www.apache.org/juneau/"</xs> - <xa>xmlns:jp</xa>=<xs>"http://www.apache.org/juneaubp/"</xs> - <xa>xmlns:per</xa>=<xs>"http://www.apache.org/person/"</xs><xt>></xt> - <xt><rdf:Description></xt> - <xt><per:id></xt>1<xt></per:id></xt> - <xt><per:name></xt>John Smith<xt></per:name></xt> - <xt></rdf:Description></xt> - <xt></rdf:RDF></xt> - </p> - <p> - Namespace auto-detection ({@link org.apache.juneau.xml.XmlSerializerContext#XML_autoDetectNamespaces}) is enabled - on serializers by default.<br> - This causes the serializer to make a first-pass over the data structure to look for namespaces.<br> - In high-performance environments, you may want to consider disabling auto-detection and providing an explicit list of namespaces to the serializer - to avoid this scanning step. - </p> - <p class='bcode'> - <jc>// Create a new serializer, but manually specify the namespaces.</jc> - RdfSerializer s = <jk>new</jk> RdfSerializer.XmlAbbrev() - .setProperty(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3) - .setProperty(XmlSerializerContext.<jsf>XML_autoDetectNamespaces</jsf>, <jk>false</jk>) - .setProperty(XmlSerializerContext.<jsf>XML_namespaces</jsf>, <js>"{per:'http://www.apache.org/person/'}"</js>); - </p> - <p> - This code change will produce the same output as before, but will perform slightly better since it doesn't have to crawl the POJO tree before serializing the result. - </p> - </div> - - <!-- ======================================================================================================== --> - <a id="UriProperties"></a> - <h3 class='topic' onclick='toggle(this)'>2.2 - URI properties</h3> - <div class='topic'> - <p> - Bean properties of type <code>java.net.URI</code> or <code>java.net.URL</code> have special meaning to the RDF serializer.<br> - They are interpreted as resource identifiers. - </p> - <p> - In the following code, we're adding 2 new properties.<br> - The first property is annotated with <ja>@BeanProperty</ja> to identify that this property is the - resource identifier for this bean.<br> - The second unannotated property is interpreted as a reference to another resource. - </p> - <p class='bcode'> - <jk>public class</jk> Person { - - <jc>// Bean properties</jc> - <ja>@Rdf</ja>(beanUri=<jk>true</jk>) - <jk>public</jk> URI <jf>uri</jf>; - - <jk>public</jk> URI <jf>addressBookUri</jf>; - - ... - - <jc>// Normal constructor</jc> - <jk>public</jk> Person(<jk>int</jk> id, String name, String uri, String addressBookUri) <jk>throws</jk> URISyntaxException { - <jk>this</jk>.<jf>id</jf> = id; - <jk>this</jk>.<jf>name</jf> = name; - <jk>this</jk>.<jf>uri</jf> = <jk>new</jk> URI(uri); - <jk>this</jk>.<jf>addressBookUri</jf> = <jk>new</jk> URI(addressBookUri); - } - } - </p> - <p> - We alter our code to pass in values for these new properties. - </p> - <p class='bcode'> - <jc>// Create our bean.</jc> - Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>, <js>"http://sample/addressBook/person/1"</js>, <js>"http://sample/addressBook"</js>); - </p> - <p> - Now when we run the sample code, we get the following: - </p> - <p class='bcode'> - <xt><rdf:RDF</xt> - <xa>xmlns:rdf</xa>=<xs>"http://www.w3.org/1999/02/22-rdf-syntax-ns#"</xs> - <xa>xmlns:j</xa>=<xs>"http://www.apache.org/juneau/"</xs> - <xa>xmlns:jp</xa>=<xs>"http://www.apache.org/juneaubp/"</xs> - <xa>xmlns:per</xa>=<xs>"http://www.apache.org/person/"</xs><xt>></xt> - <xt><rdf:Description <b><xa>rdf:about</xa>=<xs>"http://sample/addressBook/person/1"</xs></b>></xt> - <xt><per:addressBookUri</xt> <xa>rdf:resource</xa>=<xs>"http://sample/addressBook"</xs><xt>/></xt> - <xt><per:id></xt>1<xt></per:id></xt> - <xt><per:name></xt>John Smith<xt></per:name></xt> - <xt></rdf:Description></xt> - <xt></rdf:RDF></xt> - </p> - <p> - The {@link org.apache.juneau.annotation.URI} annotation can also be used on classes and properties - to identify them as URLs when they're not instances of <code>java.net.URI</code> or <code>java.net.URL</code> - (not needed if <code><ja>@Rdf</ja>(beanUri=<jk>true</jk>)</code> is already specified). - </p> - <p> - The following properties would have produced the same output as before. Note that the <ja>@URI</ja> annotation is only needed - on the second property. - </p> - <p class='bcode'> - <jk>public class</jk> Person { - - <jc>// Bean properties</jc> - <ja>@Rdf</ja>(beanUri=<jk>true</jk>) <jk>public</jk> String <jf>uri</jf>; - - <ja>@URI</ja> <jk>public</jk> String <jf>addressBookUri</jf>; - </p> - <p> - Also take note of the {@link org.apache.juneau.serializer.SerializerContext#SERIALIZER_relativeUriBase} and {@link org.apache.juneau.serializer.SerializerContext#SERIALIZER_absolutePathUriBase} - settings that can be specified on the serializer to resolve relative and context-root-relative URIs to fully-qualfied URIs. - </p> - <p> - This can be useful if you want to keep the URI authority and context root information out of the bean logic layer. - </p> - <p> - The following code produces the same output as before, but the URIs on the beans are relative. - </p> - <p class='bcode'> - <jc>// Create a new serializer with readable output.</jc> - RdfSerializer s = <jk>new</jk> RdfSerializer.XmlAbbrev() - .setProperty(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3); - .setProperty(SerializerContext.<jsf>SERIALIZER_relativeUriBase</jsf>, <js>"http://myhost/sample"</js>); - .setProperty(SerializerContext.<jsf>SERIALIZER_absolutePathUriBase</jsf>, <js>"http://myhost"</js>); - - <jc>// Create our bean.</jc> - Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>, <js>"person/1"</js>, <js>"/"</js>); - - <jc>// Serialize the bean to RDF/XML.</jc> - String rdfXml = s.serialize(p); - </p> - </div> - - <!-- ======================================================================================================== --> - <a id="BeanAnnotations"></a> - <h3 class='topic' onclick='toggle(this)'>2.3 - @Bean and @BeanProperty annotations</h3> - <div class='topic'> - <p> - The {@link org.apache.juneau.annotation.Bean} and {@link org.apache.juneau.annotation.BeanProperty} annotations - are used to customize the behavior of beans across the entire framework.<br> - In addition to using them to identify the resource URI for the bean shown above, they have various other uses: - </p> - <ul class='spaced-list'> - <li>Hiding bean properties. - <li>Specifying the ordering of bean properties. - <li>Overriding the names of bean properties. - <li>Associating transforms at both the class and property level (to convert non-serializable POJOs to serializable forms). - </ul> - <p> - For example, we now add a <code>birthDate</code> property, and associate a swap with it to transform - it to an ISO8601 date-time string in GMT time.<br> - By default, <code>Calendars</code> are treated as beans by the framework, which is usually not how you want them serialized.<br> - Using swaps, we can convert them to standardized string forms. - </p> - <p class='bcode'> - <jk>public class</jk> Person { - - <jc>// Bean properties</jc> - <ja>@BeanProperty</ja>(swap=CalendarSwap.ISO8601DTZ.<jk>class</jk>) <jk>public</jk> Calendar birthDate; - ... - - <jc>// Normal constructor</jc> - <jk>public</jk> Person(<jk>int</jk> id, String name, String uri, String addressBookUri, String birthDate) <jk>throws</jk> Exception { - ... - <jk>this</jk>.<jf>birthDate</jf> = <jk>new</jk> GregorianCalendar(); - <jk>this</jk>.<jf>birthDate</jf>.setTime(DateFormat.<jsm>getDateInstance</jsm>(DateFormat.<jsf>MEDIUM</jsf>).parse(birthDate)); - } - } - </p> - <p> - And we alter our code to pass in the birthdate. - </p> - <p class='bcode'> - <jc>// Create our bean.</jc> - Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>, <js>"http://sample/addressBook/person/1"</js>, <js>"http://sample/addressBook"</js>, <js>"Aug 12, 1946"</js>); - </p> - <p> - Now when we rerun the sample code, we'll get the following: - </p> - <p class='bcode'> - <xt><rdf:RDF</xt> - <xa>xmlns:rdf</xa>=<xs>"http://www.w3.org/1999/02/22-rdf-syntax-ns#"</xs> - <xa>xmlns:j</xa>=<xs>"http://www.apache.org/juneau/"</xs> - <xa>xmlns:jp</xa>=<xs>"http://www.apache.org/juneaubp/"</xs> - <xa>xmlns:per</xa>=<xs>"http://www.apache.org/person/"</xs><xt>></xt> - <xt><rdf:Description <xa>rdf:about</xa>=<xs>"http://sample/addressBook/person/1"</xs>></xt> - <xt><per:addressBookUri</xt> <xa>rdf:resource</xa>=<xs>"http://sample/addressBook"</xs><xt>/></xt> - <xt><per:id></xt>1<xt></per:id></xt> - <xt><per:name></xt>John Smith<xt></per:name></xt> - <xt><per:birthDate></xt>1946-08-12T00:00:00Z<xt></per:birthDate></xt> - <xt></rdf:Description></xt> - <xt></rdf:RDF></xt> - </p> - </div> - - - <!-- ======================================================================================================== --> - <a id="Collections"></a> - <h3 class='topic' onclick='toggle(this)'>2.4 - Collections</h3> - <div class='topic'> - <p> - Collections and arrays are converted to RDF sequences.<br> - In our example, let's add a list-of-beans property to our sample class: - </p> - <p class='bcode'> - <jk>public class</jk> Person { - - <jc>// Bean properties</jc> - <jk>public</jk> LinkedList<Address> <jf>addresses</jf> = <jk>new</jk> LinkedList<Address>(); - ... - } - </p> - <p> - The <code>Address</code> class has the following properties defined: - </p> - <p class='bcode'> - <ja>@Rdf</ja>(prefix=<js>"addr"</js>) - <jk>public class</jk> Address { - - <jc>// Bean properties</jc> - <ja>@Rdf</ja>(beanUri=<jk>true</jk>) <jk>public</jk> URI <jf>uri</jf>; - <jk>public</jk> URI <jf>personUri</jf>; - - <jk>public int</jk> <jf>id</jf>; - - <ja>@Rdf</ja>(prefix=<js>"mail"</js>) - <jk>public</jk> String <jf>street</jf>, <jf>city</jf>, <jf>state</jf>; - - <ja>@Rdf</ja>(prefix=<js>"mail"</js>) - <jk>public int</jk> <jf>zip</jf>; - - <jk>public boolean</jk> <jf>isCurrent</jf>; - } - </p> - <p> - Next, add some quick-and-dirty code to add an address to our person bean: - </p> - <p class='bcode'> - <jc>// Create a new serializer (revert back to namespace autodetection).</jc> - RdfSerializer s = <jk>new</jk> RdfSerializer.XmlAbbrev().setProperty(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3); - - <jc>// Create our bean.</jc> - Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>, <js>"http://sample/addressBook/person/1"</js>, <js>"http://sample/addressBook"</js>, <js>"Aug 12, 1946"</js>); - Address a = <jk>new</jk> Address(); - a.<jf>uri</jf> = <jk>new</jk> URI(<js>"http://sample/addressBook/address/1"</js>); - a.<jf>personUri</jf> = <jk>new</jk> URI(<js>"http://sample/addressBook/person/1"</js>); - a.<jf>id</jf> = 1; - a.<jf>street</jf> = <js>"100 Main Street"</js>; - a.<jf>city</jf> = <js>"Anywhereville"</js>; - a.<jf>state</jf> = <js>"NY"</js>; - a.<jf>zip</jf> = 12345; - a.<jf>isCurrent</jf> = <jk>true</jk>; - p.<jf>addresses</jf>.add(a); - </p> - <p> - Now when we run the sample code, we get the following: - </p> - <p class='bcode'> - <xt><rdf:RDF</xt> - <xa>xmlns:rdf</xa>=<xs>"http://www.w3.org/1999/02/22-rdf-syntax-ns#"</xs> - <xa>xmlns:j</xa>=<xs>"http://www.apache.org/juneau/"</xs> - <xa>xmlns:jp</xa>=<xs>"http://www.apache.org/juneaubp/"</xs> - <xa>xmlns:per</xa>=<xs>"http://www.apache.org/person/"</xs> - <b><xa>xmlns:mail</xa>=<xs>"http://www.apache.org/mail/"</xs></b> - <b><xa>xmlns:addr</xa>=<xs>"http://www.apache.org/address/"</xs></b><xt>></xt> - <xt><rdf:Description <xa>rdf:about</xa>=<xs>"http://sample/addressBook/person/1"</xs>></xt> - <xt><per:addressBookUri</xt> <xa>rdf:resource</xa>=<xs>"http://sample/addressBook"</xs><xt>/></xt> - <xt><per:id></xt>1<xt></per:id></xt> - <xt><per:name></xt>John Smith<xt></per:name></xt> - <b><xt><per:addresses></xt> - <xt><rdf:Seq></xt> - <xt><rdf:li></xt> - <xt><rdf:Description <xa>rdf:about</xa>=<xs>"http://sample/addressBook/address/1"</xs>></xt> - <xt><addr:personUri <xa>rdf:resource</xa>=<xs>"http://sample/addressBook/person/1"</xs>/></xt> - <xt><addr:id></xt>1<xt></addr:id></xt> - <xt><mail:street></xt>100 Main Street<xt></mail:street></xt> - <xt><mail:city></xt>Anywhereville<xt></mail:city></xt> - <xt><mail:state></xt>NY<xt></mail:state></xt> - <xt><mail:zip></xt>12345<xt></mail:zip></xt> - <xt><addr:isCurrent></xt>true<xt></addr:isCurrent></xt> - <xt></rdf:Description></xt> - <xt></rdf:li></xt> - <xt></rdf:Seq></xt> - <xt></per:addresses></xt></b> - <xt></rdf:Description></xt> - <xt></rdf:RDF></xt> - </p> - </div> - - - <!-- ======================================================================================================== --> - <a id="RootProperty"></a> - <h3 class='topic' onclick='toggle(this)'>2.5 - Root property</h3> - <div class='topic'> - <p> - For all RDF languages, the POJO objects get broken down into simple triplets.<br> - Unfortunately, for tree-structured data like the POJOs shown above, this causes the root node of the tree to become lost.<br> - There is no easy way to identify that <code>person/1</code> is the root node in our tree once in triplet form, and in - some cases it's impossible. - </p> - <p> - By default, the {@link org.apache.juneau.jena.RdfParser} class handles this by scanning - all the nodes and identifying the nodes without incoming references.<br> - However, this is inefficient, especially for large models.<br> - And in cases where the root node is referenced by another node in the model by URL, it's not possible to locate the root at all. - </p> - <p> - To resolve this issue, the property {@link org.apache.juneau.jena.RdfSerializerContext#RDF_addRootProperty} was introduced.<br> - When enabled, this adds a special <code>root</code> attribute to the root node to make it easy to locate by the parser. - </p> - <p> - To enable, set the <jsf>RDF_addRootProperty</jsf> property to <jk>true</jk> on the serializer: - </p> - <p class='bcode'> - <jc>// Create a new serializer.</jc> - RdfSerializer s = <jk>new</jk> RdfSerializer.XmlAbbrev() - .setProperty(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3), - .setProperty(RdfSerializerContext.<jsf>RDF_addRootProperty</jsf>, <jk>true</jk>); - </p> - <p> - Now when we rerun the sample code, we'll see the added <code>root</code> attribute on the root resource. - </p> - <p class='bcode'> - <xt><rdf:RDF</xt> - <xa>xmlns:rdf</xa>=<xs>"http://www.w3.org/1999/02/22-rdf-syntax-ns#"</xs> - <xa>xmlns:j</xa>=<xs>"http://www.apache.org/juneau/"</xs> - <xa>xmlns:jp</xa>=<xs>"http://www.apache.org/juneaubp/"</xs> - <xa>xmlns:per</xa>=<xs>"http://www.apache.org/person/"</xs> - <xa>xmlns:mail</xa>=<xs>"http://www.apache.org/mail/"</xs> - <xa>xmlns:addr</xa>=<xs>"http://www.apache.org/address/"</xs><xt>></xt> - <xt><rdf:Description <xa>rdf:about</xa>=<xs>"http://sample/addressBook/person/1"</xs>></xt> - <b><xt><j:root></xt>true<xt></j:root></xt></b> - <xt><per:addressBookUri</xt> <xa>rdf:resource</xa>=<xs>"http://sample/addressBook"</xs><xt>/></xt> - <xt><per:id></xt>1<xt></per:id></xt> - <xt><per:name></xt>John Smith<xt></per:name></xt> - <xt><per:addresses></xt> - <xt><rdf:Seq></xt> - <xt><rdf:li></xt> - <xt><rdf:Description <xa>rdf:about</xa>=<xs>"http://sample/addressBook/address/1"</xs>></xt> - <xt><addr:personUri <xa>rdf:resource</xa>=<xs>"http://sample/addressBook/person/1"</xs>/></xt> - <xt><addr:id></xt>1<xt></addr:id></xt> - <xt><mail:street></xt>100 Main Street<xt></mail:street></xt> - <xt><mail:city></xt>Anywhereville<xt></mail:city></xt> - <xt><mail:state></xt>NY<xt></mail:state></xt> - <xt><mail:zip></xt>12345<xt></mail:zip></xt> - <xt><addr:isCurrent></xt>true<xt></addr:isCurrent></xt> - <xt></rdf:Description></xt> - <xt></rdf:li></xt> - <xt></rdf:Seq></xt> - <xt></per:addresses></xt> - <xt></rdf:Description></xt> - <xt></rdf:RDF></xt> - </p> - </div> - - - <!-- ======================================================================================================== --> - <a id="TypedLiterals"></a> - <h3 class='topic' onclick='toggle(this)'>2.6 - Typed literals</h3> - <div class='topic'> - <p> - XML-Schema datatypes can be added to non-<code>String</code> literals through the {@link org.apache.juneau.jena.RdfSerializerContext#RDF_addLiteralTypes} - setting. - </p> - <p> - To enable, set the <jsf>RDF_addLiteralTypes</jsf> property to <jk>true</jk> on the serializer: - </p> - <p class='bcode'> - <jc>// Create a new serializer (revert back to namespace autodetection).</jc> - RdfSerializer s = <jk>new</jk> RdfSerializer.XmlAbbrev() - .setProperty(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3), - .setProperty(RdfSerializerContext.<jsf>RDF_addLiteralTypes</jsf>, <jk>true</jk>); - </p> - <p> - Now when we rerun the sample code, we'll see the added <code>root</code> attribute on the root resource. - </p> - <p class='bcode'> - <xt><rdf:RDF</xt> - <xa>xmlns:rdf</xa>=<xs>"http://www.w3.org/1999/02/22-rdf-syntax-ns#"</xs> - <xa>xmlns:j</xa>=<xs>"http://www.apache.org/juneau/"</xs> - <xa>xmlns:jp</xa>=<xs>"http://www.apache.org/juneaubp/"</xs> - <xa>xmlns:per</xa>=<xs>"http://www.apache.org/person/"</xs> - <xa>xmlns:mail</xa>=<xs>"http://www.apache.org/mail/"</xs> - <xa>xmlns:addr</xa>=<xs>"http://www.apache.org/address/"</xs><xt>></xt> - <xt><rdf:Description <xa>rdf:about</xa>=<xs>"http://sample/addressBook/person/1"</xs>></xt> - <xt><per:addressBookUri</xt> <xa>rdf:resource</xa>=<xs>"http://sample/addressBook"</xs><xt>/></xt> - <xt><per:id</xt> <b><xa>rdf:datatype</xa>=<xs>"http://www.w3.org/2001/XMLSchema#int"</xs></b><xt>></xt>1<xt></per:id></xt> - <xt><per:name></xt>John Smith<xt></per:name></xt> - <xt><per:addresses></xt> - <xt><rdf:Seq></xt> - <xt><rdf:li></xt> - <xt><rdf:Description <xa>rdf:about</xa>=<xs>"http://sample/addressBook/address/1"</xs>></xt> - <xt><addr:personUri <xa>rdf:resource</xa>=<xs>"http://sample/addressBook/person/1"</xs>/></xt> - <xt><addr:id</xt> <b><xa>rdf:datatype</xa>=<xs>"http://www.w3.org/2001/XMLSchema#int"</xs></b>></xt>1<xt></addr:id></xt> - <xt><mail:street></xt>100 Main Street<xt></mail:street></xt> - <xt><mail:city></xt>Anywhereville<xt></mail:city></xt> - <xt><mail:state></xt>NY<xt></mail:state></xt> - <xt><mail:zip</xt> <b><xa>rdf:datatype</xa>=<xs>"http://www.w3.org/2001/XMLSchema#int"</xs></b>></xt>12345<xt></mail:zip></xt> - <xt><addr:isCurrent</xt> <b><xa>rdf:datatype</xa>=<xs>"http://www.w3.org/2001/XMLSchema#boolean"</xs></b>></xt>true<xt></addr:isCurrent></xt> - <xt></rdf:Description></xt> - <xt></rdf:li></xt> - <xt></rdf:Seq></xt> - <xt></per:addresses></xt> - <xt></rdf:Description></xt> - <xt></rdf:RDF></xt> - </p> - </div> - - - <!-- ======================================================================================================== --> - <a id="Recursion"></a> - <h3 class='topic' onclick='toggle(this)'>2.7 - Non-tree models and recursion detection</h3> - <div class='topic'> - <p> - The RDF serializer is designed to be used against tree structures.<br> - It expects that there not be loops in the POJO model (e.g. children with references to parents, etc...).<br> - If you try to serialize models with loops, you will usually cause a <code>StackOverflowError</code> to - be thrown (if {@link org.apache.juneau.serializer.SerializerContext#SERIALIZER_maxDepth} is not reached first). - </p> - <p> - If you still want to use the XML serializer on such models, Juneau provides the - {@link org.apache.juneau.serializer.SerializerContext#SERIALIZER_detectRecursions} setting.<br> - It tells the serializer to look for instances of an object in the current branch of the tree and - skip serialization when a duplicate is encountered. - </p> - <p> - Recursion detection introduces a performance penalty of around 20%.<br> - For this reason the setting is disabled by default. - </p> - </div> - - - <!-- ======================================================================================================== --> - <a id="SerializerConfigurableProperties"></a> - <h3 class='topic' onclick='toggle(this)'>2.8 - Configurable properties</h3> - <div class='topic'> - <p> - See the following classes for all configurable properties that can be used on this serializer: - </p> - <ul class='spaced-list'> - <li>{@link org.apache.juneau.BeanContext} - Bean context properties. - <li>{@link org.apache.juneau.jena.RdfSerializerContext} - Serializer context properties. - </ul> - </div> - - - <!-- ======================================================================================================== --> - <a id="SerializerOtherNotes"></a> - <h3 class='topic' onclick='toggle(this)'>2.9 - Other notes</h3> - <div class='topic'> - <ul class='spaced-list'> - <li>Like all other Juneau serializers, the RDF serializer is thread safe and maintains an internal cache of bean classes encountered. - For performance reasons, it's recommended that serializers be reused whenever possible instead of always creating new instances. - </ul> - </div> -</div> - - -<!-- ======================================================================================================== --> -<a id="RdfParser"></a> -<h2 class='topic' onclick='toggle(this)'>3 - RdfParser class</h2> -<div class='topic'> - <p> - The {@link org.apache.juneau.jena.RdfParser} class is the top-level class for all Jena-based parsers.<br> - Language-specific parsers are defined as inner subclasses of the <code>RdfParser</code> class: - </p> - <ul> - <li>{@link org.apache.juneau.jena.RdfParser.Xml} - <li>{@link org.apache.juneau.jena.RdfParser.NTriple} - <li>{@link org.apache.juneau.jena.RdfParser.Turtle} - <li>{@link org.apache.juneau.jena.RdfParser.N3} - </ul> - <p> - The <code>RdfParser.Xml</code> parser handles both regular and abbreviated RDF/XML. - </p> - <p> - Static reusable instances of parsers are also provided with default settings: - </p> - <ul> - <li>{@link org.apache.juneau.jena.RdfParser#DEFAULT_XML} - <li>{@link org.apache.juneau.jena.RdfParser#DEFAULT_TURTLE} - <li>{@link org.apache.juneau.jena.RdfParser#DEFAULT_NTRIPLE} - <li>{@link org.apache.juneau.jena.RdfParser#DEFAULT_N3} - </ul> - <p> - For an example, we will build upon the previous example and parse the generated RDF/XML back into the original bean. - </p> - <p class='bcode'> - <jc>// Create a new serializer with readable output.</jc> - RdfSerializer s = <jk>new</jk> RdfSerializer.XmlAbbrev() - .setProperty(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3) - .setProperty(RdfSerializerContext.<jsf>RDF_addRootProperty</jsf>, <jk>true</jk>); - - <jc>// Create our bean.</jc> - Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>, <js>"http://sample/addressBook/person/1"</js>, <js>"http://sample/addressBook"</js>, <js>"Aug 12, 1946"</js>); - Address a = <jk>new</jk> Address(); - a.<jf>uri</jf> = <jk>new</jk> URI(<js>"http://sample/addressBook/address/1"</js>); - a.<jf>personUri</jf> = <jk>new</jk> URI(<js>"http://sample/addressBook/person/1"</js>); - a.<jf>id</jf> = 1; - a.<jf>street</jf> = <js>"100 Main Street"</js>; - a.<jf>city</jf> = <js>"Anywhereville"</js>; - a.<jf>state</jf> = <js>"NY"</js>; - a.<jf>zip</jf> = 12345; - a.<jf>isCurrent</jf> = <jk>true</jk>; - p.<jf>addresses</jf>.add(a); - - <jc>// Serialize the bean to RDF/XML.</jc> - String rdfXml = s.serialize(p); - - <jc>// Parse it back into a bean using the reusable XML parser.</jc> - p = RdfParser.<jsf>DEFAULT_XML</jsf>.parse(rdfXml, Person.<jk>class</jk>); - - <jc>// Render it as JSON.</jc> - String json = JsonSerializer.<jsf>DEFAULT_LAX_READABLE</jsf>.serialize(p); - System.<jsm>err</jsm>.println(json); - </p> - <p> - We print it out to JSON to show that all the data has been preserved: - </p> - <p class='bcode'> - { - uri: <js>'http://sample/addressBook/person/1'</js>, - addressBookUri: <js>'http://sample/addressBook'</js>, - id: 1, - name: <js>'John Smith'</js>, - birthDate: <js>'1946-08-12T00:00:00Z'</js>, - addresses: [ - { - uri: <js>'http://sample/addressBook/address/1'</js>, - personUri: <js>'http://sample/addressBook/person/1'</js>, - id: 1, - street: <js>'100 Main Street'</js>, - city: <js>'Anywhereville'</js>, - state: <js>'NY'</js>, - zip: 12345, - isCurrent: <jk>true</jk> - } - ] - } - </p> - - - <!-- ======================================================================================================== --> - <a id="GenericParsing"></a> - <h3 class='topic' onclick='toggle(this)'>3.1 - Parsing into generic POJO models</h3> - <div class='topic'> - <p> - The RDF parser is not limited to parsing back into the original bean classes.<br> - If the bean classes are not available on the parsing side, the parser can also be used to - parse into a generic model consisting of <code>Maps</code>, <code>Collections</code>, and primitive - objects. - </p> - <p> - You can parse into any <code>Map</code> type (e.g. <code>HashMap</code>, <code>TreeMap</code>), but - using {@link org.apache.juneau.ObjectMap} is recommended since it has many convenience methods - for converting values to various types. <br> - The same is true when parsing collections. You can use any Collection (e.g. <code>HashSet</code>, <code>LinkedList</code>) - or array (e.g. <code>Object[]</code>, <code>String[]</code>, <code>String[][]</code>), but using - {@link org.apache.juneau.ObjectList} is recommended. - </p> - <p> - When the map or list type is not specified, or is the abstract <code>Map</code>, <code>Collection</code>, or <code>List</code> types, - the parser will use <code>ObjectMap</code> and <code>ObjectList</code> by default. - </p> - <p> - In the following example, we parse into an <code>ObjectMap</code> and use the convenience methods for performing data conversion on values in the map. - </p> - <p class='bcode'> - <jc>// Parse RDF into a generic POJO model.</jc> - ObjectMap m = RdfParser.<jsf>DEFAULT_XML</jsf>.parse(rdfXml, ObjectMap.<jk>class</jk>); - - <jc>// Get some simple values.</jc> - String name = m.getString(<js>"name"</js>); - <jk>int</jk> id = m.getInt(<js>"id"</js>); - - <jc>// Get a value convertable from a String.</jc> - URI uri = m.get(URI.<jk>class</jk>, <js>"uri"</js>); - - <jc>// Get a value using a swap.</jc> - CalendarSwap swap = <jk>new</jk> CalendarSwap.ISO8601DTZ(); - Calendar birthDate = m.get(swap, <js>"birthDate"</js>); - - <jc>// Get the addresses.</jc> - ObjectList addresses = m.getObjectList(<js>"addresses"</js>); - - <jc>// Get the first address and convert it to a bean.</jc> - Address address = addresses.get(Address.<jk>class</jk>, 0); - </p> - - <p> - However, there are caveats when parsing into generic models due to the nature of RDF.<br> - Watch out for the following: - </p> - <ul class='spaced-list'> - <li>The ordering of entries are going to be inconsistent.<br><br> - <li>Bean URIs are always going to be denoted with the key <js>"uri"</js>.<br> - Therefore, you cannot have a bean with a URI property and a separate property named <js>"uri"</js>.<br> - The latter will overwrite the former.<br> - This isn't a problem when parsing into beans instead of generic POJO models. - <li>All values are strings.<br> - This normally isn't a problem when using <code>ObjectMap</code> and <code>ObjectList</code> since - various methods are provided for converting to the correct type anyway. - <li>The results may not be what is expected if there are lots of URL reference loops in the RDF model.<br> - As nodes are processed from the root node down through the child nodes, the parser keeps - track of previously processed parent URIs and handles them accordingly.<br> - If it finds that the URI has previously been processed, it handles it as a normal URI string and doesn't - process further.<br> - However, depending on how complex the reference loops are, the parsed data may end up having the - same data in it, but structured differently from the original POJO. - </ul> - <p> - We can see some of these when we render the <code>ObjectMap</code> back to JSON. - </p> - <p class='bcode'> - System.<jsm>err</jsm>.println(JsonSerializer.<jsf>DEFAULT_LAX_READABLE</jsf>.serialize(m)); - </p> - <p> - This is what's produced: - </p> - <p class='bcode'> - { - uri: <js>'http://sample/addressBook/person/1'</js>, - addresses: [ - { - uri: <js>'http://sample/addressBook/address/1'</js>, - isCurrent: <js>'true'</js>, - zip: <js>'12345'</js>, - state: <js>'NY'</js>, - city: <js>'Anywhereville'</js>, - street: <js>'100 Main Street'</js>, - id: <js>'1'</js>, - personUri: <js>'http://sample/addressBook/person/1'</js> - } - ], - birthDate: <js>'1946-08-12T00:00:00Z'</js>, - addressBookUri: <js>'http://sample/addressBook'</js>, - name: <js>'John Smith'</js>, - id: <js>'1'</js>, - root: <js>'true'</js> - } - </p> - <p> - As a general rule, parsing into beans is often more efficient than parsing into generic models.<br> - And working with beans is often less error prone than working with generic models. - </p> - </div> - - <!-- ======================================================================================================== --> - <a id="ParserConfigurableProperties"></a> - <h3 class='topic' onclick='toggle(this)'>3.2 - Configurable properties</h3> - <!-- TODO --> - <div class='topic'> - <p> - See the following classes for all configurable properties that can be used on this parser: - </p> - <ul class='spaced-list'> - <li>{@link org.apache.juneau.BeanContext} - Bean context properties. - <li>{@link org.apache.juneau.jena.RdfParserContext} - Parser context properties. - </ul> - </div> - - <!-- ======================================================================================================== --> - <a id="ParserOtherNotes"></a> - <h3 class='topic' onclick='toggle(this)'>3.3 - Other notes</h3> - <div class='topic'> - <ul class='spaced-list'> - <li>Like all other Juneau parsers, the RDF parser is thread safe and maintains an internal cache of bean classes encountered. - For performance reasons, it's recommended that parser be reused whenever possible instead of always creating new instances. - </ul> - </div> - -</div> - - -<!-- ======================================================================================================== --> -<a id="RestApiSupport"></a> -<h2 class='topic' onclick='toggle(this)'>4 - REST API support</h2> -<div class='topic'> - <p> - Juneau provides fully-integrated support for RDF serialization/parsing in the REST server and client APIs. - </p> - <p> - The next two sections describe these in detail. - </p> - - <!-- ======================================================================================================== --> - <a id="RestServerSupport"></a> - <h3 class='topic' onclick='toggle(this)'>4.1 - REST server support</h3> - <div class='topic'> - <p> - There are four general ways of defining REST interfaces with support for RDF media types.<br> - Two using the built-in Juneau Server API, and two using the JAX-RS integration component. - </p> - <ul class='spaced-list'> - <li>Create a servlet that subclasses from {@link org.apache.juneau.server.jena.RestServletJenaDefault}.<br> - This includes serialization and parsing for all Jena supported types, including all supported flavors of RDF. - <li>Create a servlet that subclasses from {@link org.apache.juneau.server.RestServlet} and specify the - RDF serializers and parsers using the {@link org.apache.juneau.server.annotation.RestResource#serializers()} and - {@link org.apache.juneau.server.annotation.RestResource#parsers()} on the entire servlet class, or - the {@link org.apache.juneau.server.annotation.RestMethod#serializers()} and {@link org.apache.juneau.server.annotation.RestMethod#parsers()} - annotations on individual methods within the class. - <li>Register {@link org.apache.juneau.server.jaxrs.rdf.DefaultJenaProvider} with JAX-RS to provide support RDF support for all JAX-RS resource.<br> - This includes serialization and parsing for all Juneau supported types (JSON, XML, HTML...), including all supported flavors of RDF. - <li>Create and register a subclass of {@link org.apache.juneau.server.jaxrs.BaseProvider} and specify the serializers and parsers to use on JAX-RS resources. - </ul> - <p> - In general, the Juneau REST server API is much more configurable and easier to use than JAX-RS, but beware that the author may be slightly biased in this statement. - </p> - - <!-- ======================================================================================================== --> - <a id="RestServletJenaDefault"></a> - <h4 class='topic' onclick='toggle(this)'>4.1.1 - Using RestServletJenaDefault</h4> - <div class='topic'> - <p> - The quickest way to implement a REST resource with RDF support is to create a subclass of {@link org.apache.juneau.server.jena.RestServletJenaDefault}.<br> - This class provides support for all the RDF flavors in addition to JSON, XML, HTML, and URL-Encoding. - </p> - <p> - The reason why RDF support was not added to {@link org.apache.juneau.server.RestServletDefault} directly was to keep the Jena prerequisites - out of the <code>org.apache.juneau.server</code> package. - </p> - <p> - The <code>AddressBookResource</code> example shown in the first chapter uses the <code>RestServletJenaDefault</code> class.<br> - The start of the class definition is shown below: - </p> - <p class='bcode'> - <jc>// Proof-of-concept resource that shows off the capabilities of working with POJO resources. - // Consists of an in-memory address book repository.</jc> - <ja>@RestResource</ja>( - messages=<js>"nls/AddressBookResource"</js>, - properties={ - <ja>@Property</ja>(name=RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, value=<js>"3"</js>), - <ja>@Property</ja>(name=RdfSerializerContext.<jsf>RDF_addRootProperty</jsf>, value=<js>"true"</js>), - <ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>), - <ja>@Property</ja>(name=HtmlSerializerContext.<jsf>HTML_uriAnchorText</jsf>, value=<jsf>TO_STRING</jsf>), - <ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, value=<js>"$L{title}"</js>), - <ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_description</jsf>, value=<js>"$L{description}"</js>), - <ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_links</jsf>, value=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js>) - }, - encoders=GzipEncoder.<jk>class</jk> - ) - <jk>public class</jk> AddressBookResource <jk>extends</jk> RestServletJenaDefault { - </p> - <p> - Notice how serializer and parser properties can be specified using the <code>@RestResource.properties()</code> annotation.<br> - The <jsf>RDF_rdfxml_tab</jsf> and <jsf>RDF_addRootProperty</jsf> are properties on the RDF serializers.<br> - The <jsf>SERIALIZER_quoteChar</jsf> property is common to all serializers.<br> - The remaining properties are specific to the HTML serializer. - </p> - <p> - The <code>$L{...}</code> variable represent localized strings pulled from the resource bundle identified by the <code>messages</code> annotation. - These variables are replaced at runtime based on the HTTP request locale. - Several built-in runtime variable types are defined, and the API can be extended to include user-defined variables. - See {@link org.apache.juneau.server.RestServlet#getVarResolver()} for more information. - </p> - <p> - This document won't go into all the details of the Juneau <code>RestServlet</code> class.<br> - Refer to the {@link org.apache.juneau.server} documentation for more information on the REST servlet class in general. - </p> - <p> - The rest of the code in the resource class consists of REST methods that simply accept and return POJOs.<br> - The framework takes care of all content negotiation, serialization/parsing, and error handling.<br> - Below are 3 of those methods to give you a general idea of the concept: - </p> - <p class='bcode'> - <jc>// GET person request handler</jc> - <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/people/{id}/*"</js>, rc={200,404}) - <jk>public</jk> Person getPerson(RestRequest req, <ja>@Path</ja> <jk>int</jk> id) throws Exception { - properties.put(HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, req.getPathInfo()); - <jk>return</jk> findPerson(id); - } - - <jc>// POST person handler</jc> - <ja>@RestMethod</ja>(name=<js>"POST"</js>, path=<js>"/people"</js>, guards=AdminGuard.<jk>class</jk>, rc={307,404}) - <jk>public void</jk> createPerson(RestResponse res, <ja>@Body</ja> CreatePerson cp) <jk>throws</jk> Exception { - Person p = addressBook.createPerson(cp); - res.sendRedirect(p.<jf>uri</jf>); - } - - <jc>// DELETE person handler</jc> - <ja>@RestMethod</ja>(name=<js>"DELETE"</js>, path=<js>"/people/{id}"</js>, guards=AdminGuard.<jk>class</jk>, rc={200,404}) - <jk>public</jk> String deletePerson(RestResponse res, <ja>@Path</ja> <jk>int</jk> id) <jk>throws</jk> Exception { - Person p = findPerson(id); - addressBook.remove(p); - <jk>return</jk> <js>"DELETE successful"</js>; - } - </p> - <p> - The resource class can be registered with the web application like any other servlet, or can be - defined as a child of another resource through the {@link org.apache.juneau.server.annotation.RestResource#children()} annotation. - </div> - - <!-- ======================================================================================================== --> - <a id="RestServlet"></a> - <h4 class='topic' onclick='toggle(this)'>4.1.2 - Using RestServlet with annotations</h4> - <div class='topic'> - <p> - For fine-tuned control of media types, the {@link org.apache.juneau.server.RestServlet} class - can be subclassed directly.<br> - The serializers/parsers can be specified through annotations at the class and/or method levels. - </p> - <p> - An equivalent <code>AddressBookResource</code> class could be defined to only support RDF/XML using - the following definition: - </p> - <p class='bcode'> - <ja>@RestResource</ja>( - serializers={RdfSerializer.XmlAbbrev.<jk>class</jk>}, - parsers={RdfParser.Xml.<jk>class</jk>}, - properties={ - <ja>@Property</ja>(name=RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, value=<js>"3"</js>), - <ja>@Property</ja>(name=RdfSerializerContext.<jsf>RDF_addRootProperty</jsf>, value=<js>"true"</js>), - <ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>) - } - ) - <jk>public class</jk> AddressBookResource <jk>extends</jk> RestServlet { - </p> - <p> - Likewise, serializers and parsers can be specified/augmented/overridden at the method level like so: - </p> - <p class='bcode'> - <jc>// GET person request handler</jc> - <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/people/{id}/*"</js>, rc={200,404}, - serializers={RdfSerializer.XmlAbbrev.<jk>class</jk>}, - parsers={RdfParser.Xml.<jk>class</jk>}, - properties={ - <ja>@Property</ja>(name=RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, value=<js>"3"</js>), - <ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>) - } - ) - <jk>public</jk> Person getPerson(RestRequest req, <ja>@Path</ja> <jk>int</jk> id) throws Exception { - properties.put(HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, req.getPathInfo()); - <jk>return</jk> findPerson(id); - } - </p> - <p> - The {@link org.apache.juneau.server.annotation.RestMethod#serializersInherit()} and - {@link org.apache.juneau.server.annotation.RestMethod#parsersInherit()} control how various artifacts - are inherited from the parent class.<br> - Refer to {@link org.apache.juneau.server} for additional information on using these annotations. - </p> - </div> - - <!-- ======================================================================================================== --> - <a id="DefaultJenaProvider"></a> - <h4 class='topic' onclick='toggle(this)'>4.1.3 - Using JAX-RS DefaultJenaProvider</h4> - <div class='topic'> - <p> - RDF media type support in JAX-RS can be achieved by using the {@link org.apache.juneau.server.jaxrs.rdf.DefaultJenaProvider} class.<br> - It implements the JAX-RS <code>MessageBodyReader</code> and <code>MessageBodyWriter</code> interfaces for all Juneau supported media types. - </p> - <p> - The <code>DefaultJenaProvider</code> class definition is shown below: - </p> - <p class='bcode'> - <ja>@Provider</ja> - <ja>@Produces</ja>( - <js>"application/json,text/json,"</js>+ <jc>// JsonSerializer</jc> - <js>"application/json+simple,text/json+simple,"</js>+ <jc>// JsonSerializer.Simple</jc> - <js>"application/json+schema,text/json+schema,"</js>+ <jc>// JsonSchemaSerializer</jc> - <js>"text/xml,"</js>+ <jc>// XmlDocSerializer</jc> - <js>"text/xml+simple,"</js>+ <jc>// XmlDocSerializer.Simple</jc> - <js>"text/xml+schema,"</js>+ <jc>// XmlSchemaDocSerializer</jc> - <js>"text/html,"</js>+ <jc>// HtmlDocSerializer</jc> - <js>"application/x-www-form-urlencoded,"</js>+ <jc>// UrlEncodingSerializer</jc> - <js>"text/xml+soap,"</js>+ <jc>// SoapXmlSerializer</jc> - <js>"text/xml+rdf,"</js>+ <jc>// RdfSerializer.Xml</jc> - <js>"text/xml+rdf+abbrev,"</js>+ <jc>// RdfSerializer.XmlAbbrev</jc> - <js>"text/n-triple,"</js>+ <jc>// RdfSerializer.NTriple</jc> - <js>"text/turtle,"</js>+ <jc>// RdfSerializer.Turtle</jc> - <js>"text/n3,"</js>+ <jc>// RdfSerializer.N3</jc> - <js>"application/x-java-serialized-object"</js> <jc>// JavaSerializedObjectSerializer</jc> - ) - <ja>@Consumes</ja>( - <js>"application/json,text/json,"</js>+ <jc>// JsonParser</jc> - <js>"text/xml,"</js>+ <jc>// XmlParser</jc> - <js>"text/html,"</js>+ <jc>// HtmlParser</jc> - <js>"application/x-www-form-urlencoded,"</js>+ <jc>// UrlEncodingParser</jc> - <js>"text/xml+rdf,"</js>+ <jc>// RdfParser.Xml</jc> - <js>"text/n-triple,"</js>+ <jc>// RdfParser.NTriple</jc> - <js>"text/turtle,"</js>+ <jc>// RdfParser.Turtle</jc> - <js>"text/n3,"</js>+ <jc>// RdfParser.N3</jc> - <js>"application/x-java-serialized-object"</js> <jc>// JavaSerializedObjectParser</jc> - ) - <ja>@JuneauProvider</ja>( - serializers={ - JsonSerializer.<jk>class</jk>, - JsonSerializer.Simple.<jk>class</jk>, - JsonSchemaSerializer.<jk>class</jk>, - XmlDocSerializer.<jk>class</jk>, - XmlDocSerializer.Simple.<jk>class</jk>, - XmlSchemaDocSerializer.<jk>class</jk>, - HtmlDocSerializer.<jk>class</jk>, - UrlEncodingSerializer.<jk>class</jk>, - SoapXmlSerializer.<jk>class</jk>, - RdfSerializer.Xml.<jk>class</jk>, - RdfSerializer.XmlAbbrev.<jk>class</jk>, - RdfSerializer.NTriple.<jk>class</jk>, - RdfSerializer.Turtle.<jk>class</jk>, - RdfSerializer.N3.<jk>class</jk>, - JavaSerializedObjectSerializer.<jk>class</jk> - }, - parsers={ - JsonParser.<jk>class</jk>, - XmlParser.<jk>class</jk>, - HtmlParser.<jk>class</jk>, - UrlEncodingParser.<jk>class</jk>, - RdfParser.Xml.<jk>class</jk>, - RdfParser.NTriple.<jk>class</jk>, - RdfParser.Turtle.<jk>class</jk>, - RdfParser.N3.<jk>class</jk>, - JavaSerializedObjectParser.<jk>class</jk>, - } - ) - <jk>public final class</jk> DefaultJenaProvider <jk>extends</jk> BaseProvider {} - </p> - <p> - That's the entire class. It consists of only annotations to hook up media types to Juneau serializers and parsers.<br> - The <ja>@Provider</ja>, <ja>@Produces</ja>, and <ja>@Consumes</ja> annotations are standard JAX-RS annotations, and the <ja>@JuneauProvider</ja> annotation is from Juneau. - </p> - <p> - To enable the provider, you need to make the JAX-RS environment aware of it.<br> - In Wink, this is accomplished by adding an entry to a config file. - </p> - <p class='bcode'> - <xt><web-app</xt> <xa>version</xa>=<xs>"2.3"</xs><xt>></xt> - <xt><servlet></xt> - <xt><servlet-name></xt>WinkService<xt></servlet-name></xt> - <xt><servlet-class></xt>org.apache.wink.server.internal.servlet.RestServlet<xt></servlet-class></xt> - <xt><init-param></xt> - <xt><param-name></xt>applicationConfigLocation<xt></param-name></xt> - <xt><param-value></xt>/WEB-INF/wink.cfg<xt></param-value></xt> - <xt></init-param></xt> - <xt></servlet></xt> - </p> - <p> - Simply include a reference to the provider in the configuration file. - <p class='bcode'> - org.apache.juneau.server.jaxrs.DefaultJenaProvider - </p> - <p> - Properties can be specified on providers through the {@link org.apache.juneau.server.jaxrs.JuneauProvider#properties()} annotation. - </p> - <p> - Properties can also be specified at the method level by using the {@link org.apache.juneau.server.annotation.RestMethod#properties} annotation, like so: - </p> - <p class='bcode'> - <ja>@GET</ja> - <ja>@Produces</ja>(<js>"*/*"</js>) - <ja>@RestMethod</ja>( <jc>/* Override some properties */</jc> - properties={ - <ja>@Property</ja>(name=RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, value=<js>"3"</js>), - <ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>) - } - ) - <jk>public</jk> Message getMessage() { - <jk>return</jk> message; - } - </p> - <h6 class='topic'>Limitations</h6> - <p> - In general, the Juneau REST API is considerably more flexible than the JAX-RS API, since you can specify and override - serializers, parsers, properties, transforms, converters, guards, etc... at both the class and method levels.<br> - Therefore, the JAX-RS API has the following limitations that the Juneau Server API does not: - </p> - <ul class='spaced-list'> - <li>The ability to specify different media type providers at the class and method levels.<br> - For example, you may want to use <code>RdfSerializer.Xml</code> with one set of properties on - one class, and another instance with different properties on another class.<br> - There is currently no way to define this at the class level.<br> - You can override properties at the method level, but this can be cumbersome since it would have to be - done for all methods in the resource. - <li>The Juneau Server API allows you to manipulate properties programatically through the {@link org.apache.juneau.server.RestResponse#setProperty(String,Object)} - method, and through the {@link org.apache.juneau.server.annotation.Properties} annotation.<br> - There is no equivalent in JAX-RS. - </ul> - </div> - - <!-- ======================================================================================================== --> - <a id="BaseProvider"></a> - <h4 class='topic' onclick='toggle(this)'>4.1.4 - Using JAX-RS BaseProvider with annotations</h4> - <div class='topic'> - <p> - To provide support for only RDF media types, you can define your own provider class, like so: - </p> - <p class='bcode'> - <ja>@Provider</ja> - <ja>@Produces</ja>( - <js>"text/xml+rdf,"</js>+ <jc>// RdfSerializer.Xml</jc> - <js>"text/xml+rdf+abbrev,"</js>+ <jc>// RdfSerializer.XmlAbbrev</jc> - <js>"text/n-triple,"</js>+ <jc>// RdfSerializer.NTriple</jc> - <js>"text/turtle,"</js>+ <jc>// RdfSerializer.Turtle</jc> - <js>"text/n3"</js>+ <jc>// RdfSerializer.N3</jc> - ) - <ja>@Consumes</ja>( - <js>"text/xml+rdf,"</js>+ <jc>// RdfParser.Xml</jc> - <js>"text/n-triple,"</js>+ <jc>// RdfParser.NTriple</jc> - <js>"text/turtle,"</js>+ <jc>// RdfParser.Turtle</jc> - <js>"text/n3"</js> <jc>// RdfParser.N3</jc> - ) - <ja>@JuneauProvider</ja>( - serializers={ - RdfSerializer.Xml.<jk>class</jk>, - RdfSerializer.XmlAbbrev.<jk>class</jk>, - RdfSerializer.NTriple.<jk>class</jk>, - RdfSerializer.Turtle.<jk>class</jk>, - RdfSerializer.N3.<jk>class</jk>, - }, - parsers={ - RdfParser.Xml.<jk>class</jk>, - RdfParser.NTriple.<jk>class</jk>, - RdfParser.Turtle.<jk>class</jk>, - RdfParser.N3.<jk>class</jk>, - }, - properties={ - <ja>@Property</ja>(name=RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, value=<js>"3"</js>), - <ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>) - } - ) - <jk>public final class</jk> MyRdfProvider <jk>extends</jk> BaseProvider {} - </p> - <p> - Then register it with Wink the same way as <code>DefaultJenaProvider</code>. - </p> - </div> - - </div> - - <!-- ======================================================================================================== --> - <a id="RestClientSupport"></a> - <h3 class='topic' onclick='toggle(this)'>4.2 - REST client support</h3> - <div class='topic'> - <p> - The {@link org.apache.juneau.client.RestClient} class provides an easy-to-use REST client interface with - pluggable media type handling using any of the Juneau serializers and parsers. - </p> - <p> - Defining a client to support RDF media types on HTTP requests and responses can be done in one line of code: - </p> - <p class='bcode'> - <jc>// Create a client to handle RDF/XML requests and responses.</jc> - RestClient client = <jk>new</jk> RestClient(RdfSerializer.XmlAbbrev.<jk>class</jk>, RdfParser.Xml.<jk>class</jk>); - </p> - <p> - The client handles all content negotiation based on the registered serializers and parsers. - </p> - <p> - The following code is pulled from the main method of the <code>ClientTest</code> class in the sample web application, and - is run against the <code>AddressBookResource</code> class running within the sample app. - It shows how the client can be used to interact with the REST API while completely hiding the negotiated content type and working with nothing more than beans. - </p> - <p class='bcode'> - String root = <js>"http://localhost:9080/sample/addressBook"</js>; - - <jc>// Get the current contents of the address book</jc> - AddressBook ab = client.doGet(root).getResponse(AddressBook.<jk>class</jk>); - System.<jsm>out</jsm>.println(<js>"Number of entries = "</js> + ab.size()); - - <jc>// Delete the existing entries</jc> - <jk>for</jk> (Person p : ab) { - String r = client.doDelete(p.<jf>uri</jf>).getResponse(String.<jk>class</jk>); - System.<jsm>out</jsm>.println(<js>"Deleted person "</js> + p.<jf>name</jf> + <js>", response = "</js> + r); - } - - <jc>// Make sure they're gone</jc> - ab = client.doGet(root).getResponse(AddressBook.<jk>class</jk>); - System.<jsm>out</jsm>.println(<js>"Number of entries = "</js> + ab.size()); - - <jc>// Add 1st person again</jc> - CreatePerson cp = <jk>new</jk> CreatePerson( - <js>"Barack Obama"</js>, - <jsm>toCalendar</jsm>(<js>"Aug 4, 1961"</js>), - <jk>new</jk> CreateAddress(<js>"1600 Pennsylvania Ave"</js>, <js>"Washington"</js>, <js>"DC"</js>, 20500, <jk>true</jk>), - <jk>new</jk> CreateAddress(<js>"5046 S Greenwood Ave"</js>, <js>"Chicago"</js>, <js>"IL"</js>, 60615, <jk>false</jk>) - ); - Person p = client.doPost(root + <js>"/people"</js>, cp).getResponse(Person.<jk>class</jk>); - System.<jsm>out</jsm>.println(<js>"Created person "</js> + p.<jf>name</jf> + <js>", uri = "</js> + p.<jf>uri</jf>); - - <jc>// Add 2nd person again, but add addresses separately</jc> - cp = <jk>new</jk> CreatePerson( - <js>"George Walker Bush"</js>, - toCalendar(<js>"Jul 6, 1946"</js>) - ); - p = client.doPost(root + <js>"/people"</js>, cp).getResponse(Person.<jk>class</jk>); - System.<jsm>out</jsm>.println(<js>"Created person "</js> + p.<jf>name</jf> + <js>", uri = "</js> + p.<jf>uri</jf>); - - <jc>// Add addresses to 2nd person</jc> - CreateAddress ca = <jk>new</jk> CreateAddress(<js>"43 Prairie Chapel Rd"</js>, <js>"Crawford"</js>, <js>"TX"</js>, 76638, <jk>true</jk>); - Address a = client.doPost(p.<jf>uri</jf> + <js>"/addresses"</js>, ca).getResponse(Address.<jk>class</jk>); - System.<jsm>out</jsm>.println(<js>"Created address "</js> + a.<jf>uri</jf>); - - ca = <jk>new</jk> CreateAddress(<js>"1600 Pennsylvania Ave"</js>, <js>"Washington"</js>, <js>"DC"</js>, 20500, <jk>false</jk>); - a = client.doPost(p.<jf>uri</jf> + "/addresses"</js>, ca).getResponse(Address.<jk>class</jk>); - System.<jsm>out</jsm>.println(<js>"Created address "</js> + a.<jf>uri</jf>); - - <jc>// Find 1st person, and change name</jc> - Person[] pp = client.doGet(root + <js>"?q={name:\"'Barack+Obama'\"}"</js>).getResponse(Person[].<jk>class</jk>); - String r = client.doPut(pp[0].<jf>uri</jf> + <js>"/name"</js>, <js>"Barack Hussein Obama"</js>).getResponse(String.<jk>class</jk>); - System.<jsm>out</jsm>.println(<js>"Changed name, response = "</js> + r); - p = client.doGet(pp[0].<jf>uri</jf>).getResponse(Person.<jk>class</jk>); - System.<jsm>out</jsm>.println(<js>"New name = "</js> + p.<jf>name</jf>); - </p> - <p> - The code above produces the following output. - </p> - <p class='bcode'> - Number of entries = 2 - Deleted person Barack Obama, response = DELETE successful - Deleted person George Walker Bush, response = DELETE successful - Number of entries = 0 - Created person Barack Obama, uri = http://localhost:9080/sample/addressBook/people/3 - Created person George Walker Bush, uri = http://localhost:9080/sample/addressBook/people/4 - Created address http://localhost:9080/sample/addressBook/addresses/7 - Created address http://localhost:9080/sample/addressBook/addresses/8 - Changed name, response = PUT successful - New name = Barack Hussein Obama - </p> - </div> -</div> -<p align="center"><i><b>*** fÃn ***</b></i></p> - -</body> -</html> \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core/src/test/java/org/apache/juneau/AnnotationsTest.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/test/java/org/apache/juneau/AnnotationsTest.java b/juneau-core/src/test/java/org/apache/juneau/AnnotationsTest.java deleted file mode 100755 index 378f088..0000000 --- a/juneau-core/src/test/java/org/apache/juneau/AnnotationsTest.java +++ /dev/null @@ -1,82 +0,0 @@ -// *************************************************************************************************************************** -// * 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; - -import static org.apache.juneau.TestUtils.*; -import static org.junit.Assert.*; - -import org.apache.juneau.annotation.*; -import org.junit.*; - - -@SuppressWarnings({"rawtypes","javadoc"}) -public class AnnotationsTest { - - //==================================================================================================== - // Bean with explicitly specified properties. - //==================================================================================================== - @Test - public void testBeanWithExplicitProperties() throws Exception { - BeanSession session = BeanContext.DEFAULT.createSession(); - BeanMap bm = null; - - // Basic test - bm = session.newBeanMap(Person1.class).load("{age:21,name:'foobar'}"); - assertNotNull(bm); - assertNotNull(bm.getBean()); - assertEquals(bm.get("age"), 21); - assertEquals(bm.get("name"), "foobar"); - - bm.put("age", 65); - bm.put("name", "futbol"); - assertEquals(bm.get("age"), 65); - assertEquals(bm.get("name"), "futbol"); - } - - /** Class with explicitly specified properties */ - @Bean(properties="age,name") - public static class Person1 { - public int age; - private String name; - public String getName() { - return name; - } - public void setName(String name) { - this.name = name; - } - } - - //==================================================================================================== - // Private/protected/default fields should be ignored. - //==================================================================================================== - @Test - public void testForOnlyPublicFields() throws Exception { - BeanSession session = BeanContext.DEFAULT.createSession(); - BeanMap bm = null; - - // Make sure only public fields are detected - bm = session.newBeanMap(A.class).load("{publicField:123}"); - assertNotNull("F1", bm); - assertNotNull("F2", bm.getBean()); - assertObjectEquals("{publicField:123}", bm.getBean()); - - } - - public static class A { - public int publicField; - protected int protectedField; - @SuppressWarnings("unused") - private int privateField; - int defaultField; - } -} \ No newline at end of file