http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/1409d75e/juneau-core/juneau-marshall/src/main/javadoc/overview.html ---------------------------------------------------------------------- diff --git a/juneau-core/juneau-marshall/src/main/javadoc/overview.html b/juneau-core/juneau-marshall/src/main/javadoc/overview.html deleted file mode 100644 index 7f6a0f7..0000000 --- a/juneau-core/juneau-marshall/src/main/javadoc/overview.html +++ /dev/null @@ -1,11469 +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 file system and page designer */ - @IMPORT url("../../../../juneau-core/java/src/main/javadoc/javadoc.css"); - @IMPORT url("../../../../juneau-core/java/src/main/javadoc/resources/juneau-doc.css"); - @IMPORT url("../../../../juneau-core/java/src/main/javadoc/resources/juneau-code.css"); - - body { - margin: 20px; - } - .spaced-list li { padding:5px; } - .footer .spaced-list ul { margin:0 } - </style> - <script type="text/javascript"> - /* 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>Apache Juneau Overview</p> -<script type="text/javascript"> - 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> -<ul class='spaced-list'> - <li> - A toolkit for marshalling POJOs to a wide variety of content types using a common framework. - <li> - A REST server API for creating self-documenting REST interfaces using POJOs. - <li> - A REST client API for interacting with REST interfaces using POJOs. - <li> - A remote proxy API built on top of REST. - <li> - A sophisticated INI config file API. - <li> - A REST microservice API that combines all the features above for creating lightweight stand-alone REST - interfaces that start up in milliseconds. -</ul> - -<a id='TOC'></a><h5 class='toc'>Table of Contents</h5> -<ol class='toc'> - <li><p><a class='doclink' href='#Intro'>Juneau - What is it?</a></p> - <li><p><a class='doclink' href='#Core'>Juneau Core (org.apache.juneau)</a></p> - <ol> - <li><p><a class='doclink' href='#Core.Serializers'>Serializers</a></p> - <li><p><a class='doclink' href='#Core.Parsers'>Parsers</a></p> - <li><p><a class='doclink' href='#Core.SerializerAndParserGroups'>SerializerGroups and ParserGroups</a></p> - <li><p><a class='doclink' href='#Core.ObjectMap'>ObjectMap and ObjectList</a></p> - <li><p><a class='doclink' href='#Core.ConfigurableProperties'>Configurable Properties</a></p> - <li><p><a class='doclink' href='#Core.Transforms'>Transforms</a></p> - <ol> - <li><p><a class='doclink' href='#Core.PojoSwaps'>PojoSwaps</a></p> - <li><p><a class='doclink' href='#Core.SwapAnnotation'>@Swap annotation</a></p> - <li><p><a class='doclink' href='#Core.SwapMethods'>Swap methods</a></p> - <li><p><a class='doclink' href='#Core.BeanFilters'>BeanFilters and @Bean annotations</a></p> - <li><p><a class='doclink' href='#Core.SerializingReadersAndInputStreams'>Serializing Readers and InputStreams</a></p> - </ol> - <li><p><a class='doclink' href='#Core.BeanDictionaries'>Bean Name and Dictionaries</a></p> - <ol> - <li><p><a class='doclink' href='#Core.BeanSubTypes'>Bean Subtypes</a></p> - </ol> - <li><p><a class='doclink' href='#Core.VirtualBeans'>Virtual Beans</a></p> - <li><p><a class='doclink' href='#Core.PojoCategories'>POJO Categories</a></p> - <li><p><a class='doclink' href='#Core.SimpleVarLanguage'>Simple Variable Language</a></p> - <li><p><a class='doclink' href='#Core.ConfigFile'>Configuration Files</a></p> - <li><p><a class='doclink' href='#Core.SupportedLanguages'>Supported Languages</a></p> - <li><p><a class='doclink' href='#Core.JacksonComparison'>Comparison with Jackson</a></p> - </ol> - <li><p><a class='doclink' href='#DTOs'>Juneau Data Transfer Objects (org.apache.juneau.dto)</a></p> - <ol> - <li><p><a class='doclink' href='#DTOs.HTML5'>HTML5</a></p> - <li><p><a class='doclink' href='#DTOs.Atom'>Atom</a></p> - <li><p><a class='doclink' href='#DTOs.Swagger'>Swagger</a></p> - <li><p><a class='doclink' href='#DTOs.JsonSchema'>JSON-Schema</a></p> - </ol> - <li><p><a class='doclink' href='#Server'>Juneau Server (org.apache.juneau.rest)</a></p> - <li><p><a class='doclink' href='#Client'>Juneau Client (org.apache.juneau.rest.client)</a></p> - <li><p><a class='doclink' href='#Remoteable'>Remoteable services (org.apache.juneau.rest.remoteable)</a></p> - <ol> - <li><p><a class='doclink' href='#Remoteable.3rdParty'>Interface proxies against 3rd-party REST interfaces</a></p> - </ol> - <li><p><a class='doclink' href='#Microservices'>Juneau Microservices (org.apache.juneau.microservice)</a></p> - <li><p><a class='doclink' href='#Samples'>Samples</a></p> - <ol> - <li><p><a class='doclink' href='#Samples.Installing'>Installing in Eclipse</a></p> - <li><p><a class='doclink' href='#Samples.Running'>Running in Eclipse</a></p> - <li><p><a class='doclink' href='#Samples.Building'>Building and Running from Command-Line</a></p> - <li><p><a class='doclink' href='#Samples.RestResource'>MANIFEST.MF</a></p> - <li><p><a class='doclink' href='#Samples.RootResources'>RootResources</a></p> - <li><p><a class='doclink' href='#Samples.HelloWorldResource'>HelloWorldResource</a></p> - <li><p><a class='doclink' href='#Samples.MethodExampleResource'>MethodExampleResource</a></p> - <li><p><a class='doclink' href='#Samples.UrlEncodedFormResource'>UrlEncodedFormResource</a></p> - <li><p><a class='doclink' href='#Samples.RequestEchoResource'>RequestEchoResource</a></p> - <li><p><a class='doclink' href='#Samples.AddressBookResource'>AddressBookResource</a></p> - <ol> - <li><p><a class='doclink' href='#Samples.AddressBookResource.Classes'>Classes</a></p> - <li><p><a class='doclink' href='#Samples.AddressBookResource.Demo'>Demo</a></p> - <li><p><a class='doclink' href='#Samples.AddressBookResource.Traversable'>Traversable</a></p> - <li><p><a class='doclink' href='#Samples.AddressBookResource.Queryable'>Queryable</a></p> - <li><p><a class='doclink' href='#Samples.AddressBookResource.Introspectable'>Introspectable</a></p> - <li><p><a class='doclink' href='#Samples.AddressBookResource.RestClient'>ClientTest</a></p> - <li><p><a class='doclink' href='#Samples.AddressBookResource.Browser'>Browser Tips</a></p> - </ol> - <li><p><a class='doclink' href='#Samples.SampleRemoteableServlet'>SampleRemoteableServlet</a></p> - <li><p><a class='doclink' href='#Samples.TempDirResource'>TempDirResource</a></p> - <li><p><a class='doclink' href='#Samples.AtomFeedResource'>AtomFeedResource</a></p> - <li><p><a class='doclink' href='#Samples.DockerRegistryResource'>DockerRegistryResource</a></p> - <li><p><a class='doclink' href='#Samples.TumblrParserResource'>TumblrParserResource</a></p> - <li><p><a class='doclink' href='#Samples.PhotosResource'>PhotosResource</a></p> - <li><p><a class='doclink' href='#Samples.JsonSchemaResource'>JsonSchemaResource</a></p> - <li><p><a class='doclink' href='#Samples.SqlQueryResource'>SqlQueryResource</a></p> - <li><p><a class='doclink' href='#Samples.ConfigResource'>ConfigResource</a></p> - <li><p><a class='doclink' href='#Samples.LogsResource'>LogsResource</a></p> - </ol> - <li><p><a class='doclink' href='#BestPractices'>Best Practices</a></p> - <li><p><a class='doclink' href='#ImportantLinks'>Important Documentation Links</a></p> - <li><p><a class='doclink' href='#ReleaseNotes'>Release Notes</a></p> -</ol> - -<!-- ======================================================================================================== --> -<a id="Intro"></a> -<h2 class='topic' onclick='toggle(this)'>1 - Juneau - What is it?</h2> -<div class='topic'> - <p> - Juneau started off as a popular internal IBM toolkit called Juno. - Originally used for serializing POJOs to and from JSON, it later expanded in scope to include a variety of - content types, and then later REST servlet, client, and microservice APIs. - It's use grew to more than 50 projects and was one of the most popular community source projects within IBM. - </p> - <p> - In 2016, the code was donated to the Apache Foundation under the project <l>Apache Juneau</l>. - </p> - - <h5 class='toc'>Features</h5> - <ol class='toc'> - <li> - <p>Extensive and extensible support for a large variety of POJOs, including structured data (beans) and - unstructured data (<code>Maps</code> and <code>Collections</code>).</p> - <li> - <p>Serialization support:</p> - <ul> - <li>JSON (including variants) - <li>XML - <li>HTML - <li>URL-Encoding - <li>UON (URL-Encoded Object Notation) - <li>MessagePack - <li>RDF/XML - <li>RDF/XML-Abbrev - <li>N-Triple - <li>Turtle - <li>N3 - <li>SOAP/XML - </ul> - <li> - <p>Parsing support:</p> - <ul> - <li>JSON (including lax syntax, comments, concatenated strings) - <li>XML - <li>HTML - <li>URL-Encoding - <li>UON (URL-Encoded Object Notation) - <li>MessagePack - <li>RDF/XML - <li>RDF/XML-Abbrev - <li>N-Triple - <li>Turtle - <li>N3 - </ul> - <li> - <p>Data Transfer Objects:</p> - <ul> - <li>HTML5 - <li>ATOM - <li>Swagger - <li>Cognos - <li>JSON-Schema - </ul> - <p>DTOs can be used with any serializers and parsers (e.g. ATOM as JSON). - <li> - <p>Serialization of POJO meta-models (e.g. the POJO class structure itself) to:</p> - <ul> - <li>JSON-Schema - <li>XML-Schema - <li>HTML-Schema - </ul> - <li> - <p> - Serializers/parsers require only Java 6+. - (RDF support requires Jena 2.7.1+) - </p> - <li> - <p> - REST APIs require only Java 6+ and JEE 1.3+. - (JAX/RS integration component requires JAX/RS provider) - </p> - </ol> - - <h5 class='topic'>Components</h5> - <p> - Juneau ships as a single Java library called <l>juneau.jar</l>. - </p> - <p> - Juneau requires Java 6+. The majority of the code has no other dependencies except for the following packages: - </p> - <ul class='doctree'> - <li class='jp'> - <a class='doclink' href='org/apache/juneau/jena/package-summary.html#TOC'>org.apache.juneau.jena</a> - - RDF support. Requires Apache Jena 2.7.1+. - <li class='jp'> - <a class='doclink' href='org/apache/juneau/rest/package-summary.html#TOC'>org.apache.juneau.rest</a> - - REST servlet support. Requires JEE 1.3+. - <li class='jp'> - <a class='doclink' href='org/apache/juneau/rest/client/package-summary.html#TOC'>org.apache.juneau.rest.client</a> - - REST client support. Requires Apache HttpClient 4.5+. - </ul> - <p> - OSGi bundles are also provided that break down Juneau into the following components: - </p> - <ul class='spaced-list'> - <li> - <l>org.apache.juneau.core.jar</l> - Serializers, parsers, INI file support. - <li> - <l>org.apache.juneau.rest.jar</l> - REST servlet support. - <li> - <l>org.apache.juneau.rest.client.jar</l> - REST client support. - <li> - <l>org.apache.juneau.microservice.jar</l> - Microservice support. - </ul> - <p> - The following zip files are also provided: - </p> - <ul class='spaced-list'> - <li> - <l>microservice-project.zip</l> - Contains a template Eclipse project for quickly creating REST resources - as executable jars. - <li> - <l>microservice-samples-project.zip</l> - Contains sample code demonstrating various aspects of Juneau. - <br>These are discussed in detail in the <a class='doclink' href="#Samples">Samples</a> section. - </ul> - - <ul class='doctree'> - <li class='info'> - Many of the examples below use beans with public field properties instead of standard getters/setters. - This is to simplify the examples. - </ul> -</div> - -<!-- ======================================================================================================== --> -<a id="Core"></a> -<h2 class='topic' onclick='toggle(this)'>2 - Juneau Core (org.apache.juneau)</h2> -<div class='topic'> - <p> - The core packages of Juneau contains serializers and parsers for converting POJOs to and from a wide variety of - content types. - It uses a common API for defining serializers and parsers. - </p> - <p> - One of the goals of Juneau was to make serialization as simple as possible. - In a single line of code, you should be able to serialize and parse most POJOs. - Despite this simplicity, Juneau provides lots of extensibility and configuration properties for tailoring how - POJOs are serialized and parsed. - </p> - - <!-- ======================================================================================================== --> - <a id="Core.Serializers"></a> - <h3 class='topic' onclick='toggle(this)'>2.1 - Serializers</h3> - <div class='topic'> - <p> - The built-in serializers in Juneau are fast, efficient, and highly configurable. - They work by serializing POJOs directly to streams instead of using intermediate Document Object Model - objects. - </p> - <p> - In most cases, you can serialize objects in one line of code by using one of the default serializers: - </p> - <p class='bcode'> - <jc>// A simple bean</jc> - <jk>public class</jk> Person { - <jk>public</jk> String <jf>name</jf> = <js>"John Smith"</js>; - <jk>public int</jk> <jf>age</jf> = 21; - } - - <jc>// Serialize to JSON, XML, or HTML</jc> - Person p = <jk>new</jk> Person(); - - <jc>// Produces: - // "{name:'John Smith',age:21}"</jc> - String json = JsonSerializer.<jsf>DEFAULT</jsf>.serialize(p); - - <jc>// Produces: - // <object> - // <name>John Smith</name> - // <age>21</age> - // </object></jc> - String xml = XmlSerializer.<jsf>DEFAULT</jsf>.serialize(p); - - <jc>// Produces: - // <table> - // <tr><th>key</th><th>value</th></tr> - // <tr><td>name</td><td>John Smith</td></tr> - // <tr><td>age</td><td>21</td></tr> - // </table></jc> - String html = HtmlSerializer.<jsf>DEFAULT</jsf>.serialize(p); - - <jc>// Produces: - // "(name='John Smith',age=21)"</jc> - String uon = UonSerializer.<jsf>DEFAULT</jsf>.serialize(p); - - <jc>// Produces: - // "name='John+Smith'&age=21"</jc> - String urlencoding = UrlEncodingSerializer.<jsf>DEFAULT</jsf>.serialize(p); - - <jc>// Produces: - // 82 A4 6E 61 6D 65 AA 4A 6F 68 6E 20 53 6D 69 74 68 A3 61 67 65 15 </jc> - <jk>byte</jk>[] b = MsgPackSerializer.<jsf>DEFAULT</jsf>.serialize(p); - </p> - - <p> - In addition to the default serializers, customized serializers can be created using various built-in options: - </p> - - <p class='bcode'> - <jc>// Use one of the default serializers to serialize a POJO</jc> - String json = JsonSerializer.<jsf>DEFAULT</jsf>.serialize(someObject); - - <jc>// Create a custom serializer for lax syntax using single quote characters</jc> - JsonSerializer serializer = <jk>new</jk> JsonSerializerBuilder().simple().sq().build(); - - <jc>// Clone an existing serializer and modify it to use single-quotes</jc> - JsonSerializer serializer = JsonSerializer.<jsf>DEFAULT</jsf>.builder().sq().build(); - - <jc>// Serialize a POJO to JSON</jc> - String json = serializer.serialize(someObject); - </p> - <p> - Default serialization support is provided for Java primitives, <code>Maps</code>, <code>Collections</code>, - beans, and arrays. - <br>Extensible support for other data types such as <code>Calendars</code>, <code>Dates</code>, - <code>Iterators</code> is available through the use of POJO swaps (described later). - </p> - - <h6 class='topic'>Additional Information</h6> - <ul class='doctree'> - <li class='jp'> - <a class='doclink' href='org/apache/juneau/serializer/package-summary.html#TOC'>org.apache.juneau.serializer</a> - - Serializer API Javadoc - </ul> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.Parsers"></a> - <h3 class='topic' onclick='toggle(this)'>2.2 - Parsers</h3> - <div class='topic'> - <p> - Parsers work by parsing input directly into POJOs instead of having to create intermediate Document Object - Models. - This allows them to parse input with minimal object creation. - </p> - <p> - Like the serializers, you can often parse objects in one line of code by using one of the default parsers: - </p> - <p class='bcode'> - <jc>// Use one of the predefined parsers.</jc> - Parser parser = JsonParser.<jsf>DEFAULT</jsf>; - - <jc>// Parse a JSON object as a bean.</jc> - String json = <js>"{name:'John Smith',age:21}"</js>; - Person p = parser.parse(json, Person.<jk>class</jk>); - - <jc>// Or parse it into a generic Map.</jc> - Map m1 = parser.parse(json, Map.<jk>class</jk>); - - <jc>// Parse a JSON string.</jc> - json = <js>"'foobar'"</js>; - String s2 = parser.parse(json, String.<jk>class</jk>); - - <jc>// Parse a JSON number as a Long or Float.</jc> - json = <js>"123"</js>; - Long l3 = parser.parse(json, Long.<jk>class</jk>); - Float f3 = parser.parse(json, Float.<jk>class</jk>); - - <jc>// Parse a JSON object as a HashMap<String,Person>.</jc> - json = <js>"{a:{name:'John Smith',age:21},b:{name:'Joe Smith',age:42}}"</js>; - Map<String,Person> m4 = parser.parse(json, HashMap.<jk>class</jk>, String.<jk>class</jk>, Person.<jk>class</jk>) - - <jc>// Parse a JSON object as a HashMap<String,LinkedList<Person>>.</jc> - json = <js>"{a:[{name:'John Smith',age:21},{name:'Joe Smith',age:42}]}"</js>; - Map<String,List<Person>> m5 = parser.parse(json, HashMap.<jk>class</jk>, String.<jk>class</jk>, - LinkedList.<jk>class</jk>, Person.<jk>class</jk>) - - <jc>// Parse a JSON array of integers as a Collection of Integers or int[] array.</jc> - json = <js>"[1,2,3]"</js>; - List<Integer> l6 = parser.parse(json, LinkedList.<jk>class</jk>, Integer.<jk>class</jk>); - <jk>int</jk>[] i7 = parser.parse(json, <jk>int</jk>[].<jk>class</jk>); - </p> - <p> - The parsers can also be used to populating existing bean and collection objects: - </p> - <p class='bcode'> - <jc>// Use one of the predefined parsers.</jc> - Parser parser = JsonParser.<jsf>DEFAULT</jsf>; - - <jc>// Populate the properties on an existing bean from a JSON object.</jc> - String json = <js>"{name:'John Smith',age:21}"</js>; - Person p = <jk>new</jk> Person(); - parser.parseIntoBean(json, p); - - <jc>// Populate an existing list from a JSON array of numbers.</jc> - json = <js>"[1,2,3]"</js>; - List<Integer> l2 = <jk>new</jk> LinkedList<Integer>(); - parser.parseIntoCollection(json, l2, Integer.<jk>class</jk>); - - <jc>// Populate an existing map from a JSON object containing beans.</jc> - json = <js>"{a:{name:'John Smith',age:21},b:{name:'Joe Smith',age:42}}"</js>; - Map<String,Person> m3 = <jk>new</jk> TreeMap<String,Person>(); - parser.parseIntoMap(json, m3, String.<jk>class</jk>, Person.<jk>class</jk>); - </p> - <ul class='doctree'> - <li class='info'> - In the example above, we're parsing "lax" JSON (single quotes, unquoted attributes). - The JSON parser can handle any valid JSON syntax (such as quoted or unquoted attributes, single or double - quotes). - <br>It can also handle JSON fragments and embedded Javascript comments. - Many of the JSON examples provided will use lax syntax which is easier to read since we don't have to deal - with escapes. - </ul> - - <h6 class='topic'>Additional Information</h6> - <ul class='doctree'> - <li class='jp'> - <a class='doclink' href='org/apache/juneau/parser/package-summary.html#TOC'>org.apache.juneau.parser</a> - - Parser API Javadoc - </ul> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.SerializerAndParserGroups"></a> - <h3 class='topic' onclick='toggle(this)'>2.3 - SerializerGroups and ParserGroups</h3> - <div class='topic'> - <p> - Above the serializers and parsers are the {@link org.apache.juneau.serializer.SerializerGroup} and - {@link org.apache.juneau.parser.ParserGroup} classes. - These classes allow serializers and parsers to be retrieved by W3C-compliant HTTP <code>Accept</code> - and <code>Content-Type</code> values... - </p> - <p class='bcode'> - <jc>// Construct a new serializer group with configuration parameters that get applied to all serializers.</jc> - SerializerGroup sg = <jk>new</jk> SerializerGroupBuilder() - .append(JsonSerializer.<jk>class</jk>, UrlEncodingSerializer.<jk>class</jk>); - .ws <jc>// or .useWhitespace(true)</jc> - .pojoSwaps(CalendarSwap.ISO8601DT.<jk>class</jk>) - .build(); - - <jc>// Find the appropriate serializer by Accept type and serialize our POJO to the specified writer.</jc> - sg.getSerializer(<js>"text/invalid, text/json;q=0.8, text/*;q:0.6, *\/*;q=0.0"</js>) - .serialize(myPersonObject, myWriter); - - <jc>// Construct a new parser group with configuration parameters that get applied to all parsers.</jc> - ParserGroup pg = <jk>new</jk> ParserGroupBuilder() - .append(JsonSerializer.<jk>class</jk>, UrlEncodingSerializer.<jk>class</jk>); - .pojoSwaps(CalendarSwap.ISO8601DT.<jk>class</jk>) - .build(); - - Person p = pg.getParser(<js>"text/json"</js>).parse(myReader, Person.<jk>class</jk>); - </p> - <p> - The REST servlet API builds upon the <code>SerializerGroup</code> and <code>ParserGroup</code> classes - to provide annotated REST servlets that automatically negotiate the HTTP media types and allow the developer - to work with requests and responses as POJOs. - </p> - - <h6 class='topic'>Additional Information</h6> - <ul class='doctree'> - <li class='jc'> - {@link org.apache.juneau.serializer.SerializerGroup} - <li class='jc'> - {@link org.apache.juneau.parser.ParserGroup} - </ul> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.ObjectMap"></a> - <h3 class='topic' onclick='toggle(this)'>2.4 - ObjectMap and ObjectList</h3> - <div class='topic'> - <p> - The {@link org.apache.juneau.ObjectMap} and {@link org.apache.juneau.ObjectList} classes are generic Java - representations of JSON objects and arrays. - These classes can be used to create "unstructured" models for serialization (as opposed to "structured" - models consisting of beans). - If you want to quickly generate JSON/XML/HTML from generic maps/collections, or parse JSON/XML/HTML into - generic maps/collections, these classes work well. - </p> - <p> - These classes extend directly from the following JCF classes: - </p> - <ul class='doctree'> - <li class='jc'> - {@link java.util.LinkedHashMap java.util.LinkedHashMap} - <ul> - <li class='jc'> - {@link org.apache.juneau.ObjectMap org.apache.juneau.ObjectMap} - </ul> - </li> - <li class='jc'> - {@link java.util.LinkedList java.util.LinkedList} - <ul> - <li class='jc'> - {@link org.apache.juneau.ObjectMap org.apache.juneau.ObjectList} - </ul> - </li> - </ul> - <p> - The <l>ObjectMap</l> and <l>ObjectList</l> classes are very similar to the <l>JSONObject</l> and - <l>JSONArray</l> classes found in other libraries. - However, the names were chosen because the concepts of <l>Maps</l> and <l>Lists</l> are already familiar to - Java programmers, and these classes can be used with any of the serializers or parsers. - </p> - <p> - These object can be serialized in one of two ways: - </p> - <ol class='spaced-list'> - <li> - Using the provided {@link org.apache.juneau.ObjectMap#serializeTo(java.io.Writer)} or - {@link org.apache.juneau.ObjectList#serializeTo(java.io.Writer)} methods. - <li> - Passing them to one of the {@link org.apache.juneau.serializer.Serializer} serialize methods. - <li> - Simply calling the {@link org.apache.juneau.ObjectMap#toString()} or {@link org.apache.juneau.ObjectList#toString()} - methods which will serialize it as Simplified JSON. - </ol> - <p> - Any valid JSON can be parsed into an unstructured model consisting of generic - {@link org.apache.juneau.ObjectMap} and {@link org.apache.juneau.ObjectList} objects. - <br> - (In theory, any valid XML can also be parsed into an unstructured model, although this has not been - officially 'tested') - </p> - <p class='bcode'> - <jc>// Parse an arbitrary JSON document into an unstructered data model - // consisting of ObjectMaps, ObjectLists, and java primitive objects.</jc> - Parser parser = JsonParser.<jsf>DEFAULT</jsf>; - String json = <js>"{a:{name:'John Smith',age:21},b:{name:'Joe Smith',age:42}}"</js>; - ObjectMap m = parser.parse(json, ObjectMap.<jk>class</jk>); - - <jc>// Use ObjectMap API to extract data from the unstructured model.</jc> - <jk>int</jk> johnSmithAge = m.getObjectMap(<js>"a"</js>).getInt(<js>"age"</js>); - - <jc>// Convert it back into JSON.</jc> - json = JsonSerializer.<jsf>DEFAULT</jsf>.serialize(m); - - <jc>// Or convert it to XML.</jc> - String xml = XmlSerializer.<jsf>DEFAULT</jsf>.serialize(m); - - <jc>// Or just use toString().</jc> - json = m.toString(); - </p> - <ul class='doctree'> - <li class='info'> - As a general rule, if you do not specify a target type during parsing, or if the target type cannot be - determined through reflection, the parsers automatically generate <l>ObjectMaps</l> and <l>ObjectLists</l>. - </ul> - - <h6 class='topic'>Additional Information</h6> - <ul class='doctree'> - <li class='jc'> - {@link org.apache.juneau.ObjectMap} - <li class='jc'> - {@link org.apache.juneau.ObjectList} - </ul> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.ConfigurableProperties"></a> - <h3 class='topic' onclick='toggle(this)'>2.5 - Configurable Properties</h3> - <div class='topic'> - <p> - Serializers and parsers have a wide variety of configurable properties. - <br>For example, the following code shows how to configure a JSON serializer: - </p> - <p class='bcode'> - JsonSerializer s = <jk>new</jk> JsonSerializerBuilder().simple().ws().sq().build(); - </p> - <p> - However, each of the serializers and parsers already contain reusable instances with common configurations. - <br>For example, JSON has the following predefined reusable serializers and parsers: - </p> - <ul class='doctree'> - <li class='jc'> - {@link org.apache.juneau.json.JsonSerializer} - <ul> - <li class='jf'> - {@link org.apache.juneau.json.JsonSerializer#DEFAULT DEFAULT} - <li class='jf'> - {@link org.apache.juneau.json.JsonSerializer#DEFAULT_LAX DEFAULT_LAX} - <li class='jf'> - {@link org.apache.juneau.json.JsonSerializer#DEFAULT_READABLE DEFAULT_READABLE} - <li class='jf'> - {@link org.apache.juneau.json.JsonSerializer#DEFAULT_LAX_READABLE DEFAULT_LAX_READABLE} - </ul> - </li> - <li class='jc'> - {@link org.apache.juneau.json.JsonParser} - <ul> - <li class='jf'> - {@link org.apache.juneau.json.JsonParser#DEFAULT DEFAULT} - <li class='jf'> - {@link org.apache.juneau.json.JsonParser#DEFAULT_STRICT DEFAULT_STRICT} - </ul> - </li> - </ul> - <p> - These can be used directly, as follows: - </p> - <p class='bcode'> - <jc>// Serialize a POJO to LAX JSON.</jc> - String json = JsonSerializer.<jsf>DEFAULT_LAX</jsf>.serialize(myPojo); - </p> - <p> - Serializers and parsers can be locked to prevent further modification to the properties. - They can also be cloned to copy the configuration of other serializers and parsers. - </p> - <p class='bcode'> - <jc>// Clone and customize an existing serializer.</jc> - JsonSerializer s = JsonSerializer.<jsf>DEFAULT_LAX</jsf> - .builder() - .quoteChar(<js>'"'</js>) - .build(); - - <jc>// Lock it so that the configuration cannot be changed.</jc> - s.lock(); - </p> - - <h6 class='topic'>Additional Information</h6> - <p> - The following is a list of all configurable properties across all serializers and parsers. - </p> - <ul class='doctree'> - <li class='jc'> - <a class='doclink' href='org/apache/juneau/BeanContext.html#ConfigProperties'>BeanContext</a> - - Properties associated with handling beans on serializers and parsers. - <ul> - <li class='jc'> - <a class='doclink' href='org/apache/juneau/serializer/SerializerContext.html#ConfigProperties'>SerializerContext</a> - - Configurable properties common to all serializers. - <ul> - <li class='jc'> - <a class='doclink' href='org/apache/juneau/html/HtmlSerializerContext.html#ConfigProperties'>HtmlSerializerContext</a> - - Configurable properties on the HTML serializer. - <ul> - <li class='jc'> - <a class='doclink' href='org/apache/juneau/html/HtmlDocSerializerContext.html#ConfigProperties'>HtmlDocSerializerContext</a> - - Configurable properties on the HTML document serializer. - </ul> - </li> - <li class='jic'> - <a class='doclink' href='org/apache/juneau/jena/RdfCommonContext.html#ConfigProperties'>RdfCommonContext</a> - - Configurable properties common to the RDF serializers and parsers. - <ul> - <li class='jc'> - <a class='doclink' href='org/apache/juneau/jena/RdfSerializerContext.html#ConfigProperties'>RdfSerializerContext</a> - - Configurable properties on the RDF serializers. - </ul> - </li> - <li class='jc'> - <a class='doclink' href='org/apache/juneau/json/JsonSerializerContext.html#ConfigProperties'>JsonSerializerContext</a> - - Configurable properties on the JSON serializer. - <li class='jc'> - <a class='doclink' href='org/apache/juneau/msgpack/MsgPackSerializerContext.html#ConfigProperties'>MsgPackSerializerContext</a> - - Configurable properties on the MessagePack serializer. - <li class='jc'> - <a class='doclink' href='org/apache/juneau/soap/SoapXmlSerializerContext.html#ConfigProperties'>SoapXmlSerializerContext</a> - - Configurable properties on the SOAP/XML serializer. - <li class='jc'> - <a class='doclink' href='org/apache/juneau/urlencoding/UonSerializerContext.html#ConfigProperties'>UonSerializerContext</a> - - Configurable properties on the URL-Encoding and UON serializers. - <li class='jc'> - <a class='doclink' href='org/apache/juneau/xml/XmlSerializerContext.html#ConfigProperties'>XmlSerializerContext</a> - - Configurable properties on the XML serializer. - </ul> - </li> - <li class='jc'> - <a class='doclink' href='org/apache/juneau/parser/ParserContext.html#ConfigProperties'>ParserContext</a> - - Configurable properties common to all parsers. - <ul> - <li class='jc'> - <a class='doclink' href='org/apache/juneau/html/HtmlParserContext.html#ConfigProperties'>HtmlParserContext</a> - - Configurable properties on the HTML parser. - <li class='jic'> - <a class='doclink' href='org/apache/juneau/jena/RdfCommonContext.html#ConfigProperties'>RdfCommonContext</a> - - Configurable properties common to the RDF serializers and parsers. - <ul> - <li class='jc'><a class='doclink' href='org/apache/juneau/jena/RdfParserContext.html#ConfigProperties'>RdfParserContext</a> - - Configurable properties on the RDF parsers. - </ul> - </li> - <li class='jc'> - <a class='doclink' href='org/apache/juneau/json/JsonParserContext.html#ConfigProperties'>JsonParserContext</a> - - Configurable properties on the JSON parser. - <li class='jc'> - <a class='doclink' href='org/apache/juneau/msgpack/MsgPackParserContext.html#ConfigProperties'>MsgPackParserContext</a> - - Configurable properties on the MessagePack parser. - <li class='jc'> - <a class='doclink' href='org/apache/juneau/urlencoding/UonParserContext.html#ConfigProperties'>UonParserContext</a> - - Configurable properties on the URL-Encoding and UON parsers. - <li class='jc'> - <a class='doclink' href='org/apache/juneau/xml/XmlParserContext.html#ConfigProperties'>XmlParserContext</a> - - Configurable properties on the XML parser. - </ul> - </li> - </ul> - </li> - <li class='jc'> - <a class='doclink' href='org/apache/juneau/server/RestContext.html#ConfigProperties'>RestContext</a> - - Configurable properties on the REST servlet. - </li> - </ul> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.Transforms"></a> - <h3 class='topic' onclick='toggle(this)'>2.6 - Transforms</h3> - <div class='topic'> - <p> - By default, the Juneau framework can serialize and parse a wide variety of POJOs out-of-the-box. - However, two special classes are provided tailor how certain Java objects are handled by the framework. - These classes are: - </p> - <ul class='doctree'> - <li class='jc'> - {@link org.apache.juneau.transform.PojoSwap} - - Tailor how specific non-bean classes are handled by the framework. - <li class='jc'> - {@link org.apache.juneau.transform.BeanFilter} - - Tailor how specific bean classes are handled by the framework. - </ul> - <p> - Annotations are also provided that allow you to use transformations directly on class definitions: - </p> - <ul class='doctree'> - <li class='ja'> - {@link org.apache.juneau.annotation.Swap @Swap} - - Used to tailor how non-bean POJOs get interpreted by the framework. - <li class='ja'> - {@link org.apache.juneau.annotation.Bean @Bean} - - Used to tailor how beans get interpreted by the framework. - <li class='ja'> - {@link org.apache.juneau.annotation.BeanConstructor @BeanConstructor} - - Maps constructor arguments to property names on beans with read-only properties. - <li class='ja'> - {@link org.apache.juneau.annotation.BeanIgnore @BeanIgnore} - - Ignore classes, fields, and methods from being interpreted as bean or bean components. - <li class='ja'> - {@link org.apache.juneau.annotation.BeanProperty @BeanProperty} - - Used to tailor how bean properties get interpreted by the framework. - <li class='ja'> - {@link org.apache.juneau.annotation.NameProperty @NameProperty} - - Identifies a setter as a method for setting the name of a POJO as it's known by its parent object. - <li class='ja'> - {@link org.apache.juneau.annotation.ParentProperty @ParentProperty} - - Identifies a setter as a method for adding a parent reference to a child object. - <li class='ja'> - {@link org.apache.juneau.annotation.URI @URI} - - Used to identify a class or bean property as a URI. - </ul> - - <!-- ======================================================================================================== --> - <a id="Core.PojoSwaps"></a> - <h4 class='topic' onclick='toggle(this)'>2.6.1 - PojoSwaps</h4> - <div class='topic'> - <p> - {@link org.apache.juneau.transform.PojoSwap PojoSwaps} are a critical component of Juneau. - They allow the serializers and parsers to handle Java objects that wouldn't normally be serializable. - </p> - <p> - Swaps are very easy to understand. - Simply put, they can be thought of as 'object swappers' that swap in serializable objects for - non-serializable ones during serialization, and vis-versa during parsing. - </p> - <p> - Some examples of non-serializable POJOs are <code>File</code>, <code>Reader</code>, - <code>Iterable</code>, etc... - These are classes that aren't beans and cannot be represented as simple maps, collections, or primitives. - </p> - <p> - In the following example, we introduce a <code>PojoSwap</code> that will swap in ISO8601 strings for - <code>Date</code> objects: - </p> - <p class='bcode'> - <jc>// Sample swap for converting Dates to ISO8601 strings.</jc> - <jk>public class</jk> MyDateSwap <jk>extends</jk> PojoSwap<Date,String> { - - <jc>// ISO8601 formatter.</jc> - <jk>private</jk> DateFormat <jf>format</jf> = <jk>new</jk> SimpleDateFormat(<js>"yyyy-MM-dd'T'HH:mm:ssZ"</js>); - - <jd>/** Converts a Date object to an ISO8601 string. */</jd> - <ja>@Override</ja> - <jk>public</jk> String swap(BeanSession session, Date o) { - <jk>return</jk> <jf>format</jf>.format(o); - } - - <jd>/** Converts an ISO8601 string to a Date object. */</jd> - <ja>@Override</ja> - <jk>public</jk> Date unswap(BeanSession session, String o, ClassMeta hint) <jk>throws</jk> ParseException { - <jk>try</jk> { - <jk>return</jk> <jf>format</jf>.parse(o); - } <jk>catch</jk> (java.text.ParseException e) { - <jk>throw new</jk> ParseException(e); - } - } - } - </p> - <p> - The swap can then be associated with serializers and parsers like so: - </p> - <p class='bcode'> - <jc>// Sample bean with a Date field.</jc> - <jk>public class</jk> MyBean { - <jk>public</jk> Date <jf>date</jf> = <jk>new</jk> Date(112, 2, 3, 4, 5, 6); - } - - <jc>// Create a new JSON serializer, associate our date swap with it, and serialize a sample bean.</jc> - Serializer serializer = <jk>new</jk> JsonSerializerBuilder().pojoSwaps(MyDateSwap.<jk>class</jk>).build(); - String json = serializer.serialize(<jk>new</jk> MyBean()); <jc>// == "{date:'2012-03-03T04:05:06-0500'}"</jc> - - <jc>// Create a JSON parser, associate our date swap with it, and reconstruct our bean (including the date).</jc> - ReaderParser parser = <jk>new</jk> JsonParserBuilder().pojoSwaps(MyDateSwap.<jk>class</jk>).build(); - MyBean bean = parser.parse(json, MyBean.<jk>class</jk>); - <jk>int</jk> day = bean.<jf>date</jf>.getDay(); <jc>// == 3</jc> - </p> - <p> - Several <code>PojoSwaps</code> are already provided for common Java objects: - </p> - <ul class='doctree'> - <li class='jp'> - <a class='doclink' href='org/apache/juneau/transforms/package-summary.html#TOC'>org.apache.juneau.transforms</a> - <ul> - <li class='jc'> - {@link org.apache.juneau.transforms.ByteArrayBase64Swap} - <li class='jac'> - {@link org.apache.juneau.transforms.CalendarSwap} - <li class='jac'> - {@link org.apache.juneau.transforms.DateSwap} - <li class='jc'> - {@link org.apache.juneau.transforms.EnumerationSwap} - <li class='jc'> - {@link org.apache.juneau.transforms.IteratorSwap} - <li class='jc'> - {@link org.apache.juneau.transforms.ReaderSwap} - <li class='jc'> - {@link org.apache.juneau.transforms.XMLGregorianCalendarSwap} - </ul> - </li> - </ul> - <p> - In particular, the {@link org.apache.juneau.transforms.CalendarSwap} and - {@link org.apache.juneau.transforms.DateSwap} transforms provide a large number of customized swaps to - ISO, RFC, or localized strings. - </p> - <ul class='doctree'> - <li class='info'> - The 'swapped' class type must be a serializable type. - <br>See the definition for Category 4 objects in <a class='doclink' - href='#Core.PojoCategories'>POJO Categories</a>. - </ul> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.SwapAnnotation"></a> - <h4 class='topic' onclick='toggle(this)'>2.6.2 - @Swap annotation</h4> - <div class='topic'> - <p> - {@link org.apache.juneau.annotation.Swap @Swap} can be used to associate a swap class using an - annotation. - This is often cleaner than using the builder <code>pojoSwaps()</code> method since you can keep - your swap class near your POJO class. - </p> - <p class='bcode'> - <ja>@Swap</ja>(MyPojoSwap.<jk>class</jk>) - <jk>public class</jk> MyPojo { - ... - } - - <jc>// Sample swap for converting MyPojo classes to a simple string.</jc> - <jk>public class</jk> MyPojoSwap <jk>extends</jk> PojoSwap<MyPojo,String> { - - <ja>@Override</ja> - <jk>public</jk> String swap(BeanSession session, MyPojo o) { - <jk>return</jk> o.toSomeSerializableForm(); - } - } - </p> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.SwapMethods"></a> - <h4 class='topic' onclick='toggle(this)'>2.6.3 - Swap methods</h4> - <div class='topic'> - <p> - Various methods can be defined on a class directly to affect how it gets serialized. - This can often be simpler than using <code>PojoSwaps</code>. - </p> - <p> - Objects serialized as <code>Strings</code> can be parsed back into their original objects by - implementing one of the following methods on the class: - </p> - <ul class='spaced-list'> - <li> - <code><jk>public static</jk> T fromString(String)</code> method. - <br>Any of the following method names also work: - <ul> - <li><code>valueOf(String)</code> - <li><code>parse(String)</code> - <li><code>parseString(String)</code> - <li><code>forName(String)</code> - <li><code>forString(String)</code> - </ul> - <li> - <code><jk>public</jk> T(String)</code> constructor. - </ul> - <p> - Note that these methods cover conversion from several built-in Java types, meaning the parsers can - automatically construct these objects from strings: - </p> - <ul> - <li><code>fromString(String)</code> - {@link java.util.UUID} - <li><code>valueOf(String)</code> - {@link java.lang.Boolean}, {@link java.lang.Byte}, - {@link java.lang.Double}, {@link java.lang.Float}, - {@link java.lang.Integer}, {@link java.lang.Long}, {@link java.lang.Short}, {@link java.sql.Date}, - {@link java.sql.Time}, {@link java.sql.Timestamp} - <li><code>parse(String)</code> - {@link java.text.DateFormat}, {@link java.text.MessageFormat}, - {@link java.text.NumberFormat}, {@link java.util.Date}, {@link java.util.logging.Level} - <li><code>parseString(String)</code> - {@link javax.xml.bind.DatatypeConverter} - <li><code>forName(String)</code> - {@link java.lang.Class} - </ul> - <p> - If you want to force a bean-like class to be serialized as a string, you can use the - {@link org.apache.juneau.annotation.BeanIgnore @BeanIgnore} annotation on the class to force it to be - serialized to a string using the <code>toString()</code> method. - </p> - <p> - Serializing to other intermediate objects can be accomplished by defining a swap method directly on the - class: - </p> - <ul> - <li><code><jk>public</jk> X swap(BeanSession)</code> method, where <code>X</code> is any serializable - object. - </ul> - <p> - The <code>BeanSession</code> parameter allows you access to various information about the current - serialization session. - For example, you could provide customized results based on the media type being produced - ({@link org.apache.juneau.BeanSession#getMediaType()}). - </p> - <p> - The following example shows how an HTML5 form template object can be created that gets serialized as a - populated HTML5 {@link org.apache.juneau.dto.html5.Form} bean. - </p> - <p class='bcode'> - <jk>import static</jk> org.apache.juneau.dto.html5.HtmlBuilder.*; - - <jd>/** - * A simple HTML form template whose serialized form is an HTML5 Form object. - */</jd> - <jk>public class</jk> FormTemplate { - - <jk>private</jk> String <jf>action</jf>; - <jk>private int</jk> <jf>value1</jf>; - <jk>private boolean</jk> <jf>value2</jf>; - - <jc>// Some constructor that initializes our fields. </jc> - <jk>public</jk> FormTemplate(String action, <jk>int</jk> value1, <jk>boolean</jk> value2) { - <jk>this</jk>.<jf>action</jf> = action; - <jk>this</jk>.<jf>value1</jf> = value1; - <jk>this</jk>.<jf>value2</jf> = value2; - } - - <jc>// Special swap method that converts this template to a serializable bean</jc> - <jk>public</jk> Form swap(BeanSession session) { - <jk>return</jk> <jsm>form</jsm>(<jf>action</jf>, - <jsm>input</jsm>(<js>"text"</js>).name(<js>"v1"</js>).value(<jf>value1</jf>), - <jsm>input</jsm>(<js>"text"</js>).name(<js>"v2"</js>).value(<jf>value2</jf>) - ); - } - } - </p> - <p> - Swapped objects can be converted back into their original form by the parsers by specifying one of the - following methods: - </p> - <ul> - <li><code><jk>public static</jk> T unswap(BeanSession, X)</code> method where <code>X</code> is the - swap class type. - <li><code><jk>public</jk> T(X)</code> constructor where <code>X</code> is the swap class type. - </ul> - <p> - The following shows how our form template class can be modified to allow the parsers to reconstruct our - original object: - </p> - <p class='bcode'> - <jk>import static</jk> org.apache.juneau.dto.html5.HtmlBuilder.*; - - <jd>/** - * A simple HTML form template whose serialized form is an HTML5 Form object. - * This time with parsing support. - */</jd> - <ja>@Bean</ja>(beanDictionary=HtmlBeanDictionary.<jk>class</jk>) - <jk>public class</jk> FormTemplate { - - <jk>private</jk> String <jf>action</jf>; - <jk>private int</jk> <jf>value1</jf>; - <jk>private boolean</jk> <jf>value2</jf>; - - <jc>// Our 'unswap' constructor</jc> - <jk>public</jk> FormTemplate(Form f) { - <jk>this</jk>.<jf>action</jf> = f.getAttr(<js>"action"</js>); - <jk>this</jk>.<jf>value1</jf> = f.getChild(Input.<jk>class</jk>, 0) - .getAttr(<jk>int</jk>.<jk>class</jk>, <js>"value"</js>); - <jk>this</jk>.<jf>value2</jf> = f.getChild(Input.<jk>class</jk>, 1) - .getAttr(<jk>boolean</jk>.<jk>class</jk>, <js>"value"</js>); - } - - <jk>public</jk> FormTemplate(String action, <jk>int</jk> value1, <jk>boolean</jk> value2) { - <jk>this</jk>.<jf>action</jf> = action; - <jk>this</jk>.<jf>value1</jf> = value1; - <jk>this</jk>.<jf>value2</jf> = value2; - } - - <jk>public</jk> Form swap(BeanSession session) { - <jk>return</jk> <jsm>form</jsm>(<jf>action</jf>, - <jsm>input</jsm>(<js>"text"</js>).name(<js>"v1"</js>).value(<jf>value1</jf>), - <jsm>input</jsm>(<js>"text"</js>).name(<js>"v2"</js>).value(<jf>value2</jf>) - ); - } - } - </div> - - <!-- ======================================================================================================== --> - <a id="Core.BeanFilters"></a> - <h4 class='topic' onclick='toggle(this)'>2.6.4 - BeanFilters and @Bean annotations</h4> - <div class='topic'> - <p> - {@link org.apache.juneau.transform.BeanFilter BeanFilters} are used to control aspects of how beans are - handled during serialization and parsing. - They allow you to control various aspects of beans, such as... - </p> - <ul> - <li>Which properties to include or exclude. - <li>Property order. - <li>Property naming conventions. - <li>Overriding reading and writing of properties. - </ul> - <p> - In practice, however, it's simpler to use the {@link org.apache.juneau.annotation.Bean @Bean} and - {@link org.apache.juneau.annotation.BeanProperty @BeanProperty} annotations on your bean classes. - The annotations are functionally equivalent to the bean filter class. - </p> - <p class='bcode'> - <jc>// Address class with only street/city/state properties (in that order).</jc> - <jc>// All other properties are ignored.</jc> - <ja>@Bean</ja>(properties=<js>"street,city,state"</js>) - <jk>public class</jk> Address { - ... - </p> - <p> - Bean filters are defined through {@link org.apache.juneau.transform.BeanFilterBuilder BeanFilterBuilders}. - The programmatic equivalent to the the annotation above would be: - </p> - <p class='bcode'> - <jk>public class</jk> MyAddressBeanFilter <jk>extends</jk> BeanFilterBuilder { - - <jc>// Must provide a no-arg constructor!</jc> - <jk>public</jk> MyAddressBeanFilter() { - <jk>super</jk>(Address.<jk>class</jk>); <jc>// The bean class that this filter applies to.</jc> - setIncludeProperties(<js>"street,city,state"</js>); <jc>// The properties we want exposed.</jc> - } - } - </p> - <p> - Bean filters are added to serializers and parsers using the <code>*BeanFilters(Class...)</code> methods. - For example: - </p> - <p class='bcode'> - <jc>// Create a new JSON serializer and associate a bean filter with it.</jc> - Serializer serializer = <jk>new</jk> JsonSerializerBuilder().beanFilters(MyAddressBeanFilter.<jk>class</jk>).build(); - </p> - <p> - Note that if you use the annotation, you do NOT need to set anything on the serializers/parsers. - The annotations will be detected and bean filters will automatically be created for them. - </p> - <p> - The <code>addBeanFilter(Class...)</code> method also allows you to pass in interfaces. - Any class that's not a subclass of {@link org.apache.juneau.transform.BeanFilterBuilder} get interpreted - as bean interface classes. - These cause bean implementations of those interfaces to only expose the properties defined on the - interface. - </p> - <p class='bcode'> - <jc>// An interface with the 3 properties we want serialized.</jc> - <jk>public interface</jk> AddressInterface { - <jk>public</jk> String getStreet(); - <jk>public</jk> String getCity(); - <jk>public</jk> String getState(); - } - - <jc>// Our bean implementation.</jc> - <jk>public class</jk> Address <jk>implements</jk> AddressInterface { - ... - } - - <jc>// Create a new JSON serializer that only exposes street,city,state on Address bean.</jc> - Serializer serializer = <jk>new</jk> JsonSerializerBuilder().beanFilters(AddressInterface.<jk>class</jk>).build(); - </p> - - <h6 class='topic'>Additional Information</h6> - <ul class='doctree'> - <li class='jp'> - <a class='doclink' href='org/apache/juneau/transform/package-summary.html#TOC'>org.apache.juneau.transform</a> - </ul> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.SerializingReadersAndInputStreams"></a> - <h4 class='topic' onclick='toggle(this)'>2.6.5 - Serializing Readers and InputStreams</h4> - <div class='topic'> - <p> - Juneau serializers treat instances of Readers and InputStreams special by simply serializing their - contents directly to the output stream or writer. - This allows you to embed fully customized serializer output. - </p> - <p class='bcode'> - <jk>public class</jk> MyBean { - <jk>public</jk> Reader f1 = <jk>new</jk> StringReader(<js>"{'foo':'bar'}"</js>); - } - - <jc>// Produces "{f1:{'foo':'bar'}}"</jc> - String json = JsonSerializer.<jsf>DEFAULT_LAX</jsf>.toString(<jk>new</jk> MyBean()); - </p> - <p> - Note that if you're serializing Readers and InputStreams, it's up to you to make sure you're producing - valid output (in this case JSON). - </p> - <p> - A more typical scenario where this is useful is by using swaps to convert POJOs to Readers whose - contents are determined via the {@link org.apache.juneau.BeanSession#getMediaType()} method. - <br>In the following example, we're customizing the JSON output for a particular bean type, but leaving - all other renditions as-is: - </p> - <p class='bcode'> - <ja>@Swap</ja>(MyBeanSwap.<jk>class</jk>) - <jk>public class</jk> MyBean {...} - - <jk>public class</jk> MyBeanSwap <jk>extends</jk> PojoSwap<MyBean,Object> { - <jk>public</jk> Object swap(BeanSession session, MyPojo o) <jk>throws</jk> Exception { - MediaType mt = session.getMediaType(); - <jk>if</jk> (mt.hasSubType(<js>"json"</js>)) - <jk>return new</jk> StringReader(<js>"{myPojo:'foobar'}"</js>); <jc>// Custom JSON output</jc> - <jk>return</jk> o; <jc>// Otherwise serialize it as a normal bean</jc> - } - } - </p> - <ul class='doctree'> - <li class='info'> - Due to the nature of the RDF serializers, Readers and InputStreams are serialized as literals, - not as RDF text. - This is due to the fact that the RDF serializers use a DOM for serialization, so we don't have - access to the underlying stream. - </ul> - </div> - - </div> - - <!-- ======================================================================================================== --> - <a id="Core.BeanDictionaries"></a> - <h3 class='topic' onclick='toggle(this)'>2.7 - Bean Names and Dictionaries</h3> - <div class='topic'> - <p> - While parsing into beans, Juneau attempts to determine the class types of bean properties through - reflection on the bean property getter or setter. - Often this is insufficient if the property type is an interface or abstract class that cannot be - instantiated. - This is where bean names and dictionaries come into play. - </p> - <p> - Bean names and dictionary are used for identifying class types when they cannot be inferred through - reflection. - </p> - <p> - Bean classes are given names through the {@link org.apache.juneau.annotation.Bean#typeName() @Bean.typeName()} - annotation. - These names are then added to the serialized output as virtual <js>"_type"</js> properties (or element - names in XML). - </p> - <p> - On the parsing side, these type names are resolved to classes through the use of bean dictionaries. - </p> - <p> - For example, if a bean property is of type <code>Object</code>, then the serializer will add - <js>"_type"</js> attributes so that the class can be determined during parsing. - </p> - <p class='bcode'> - <ja>@Bean</ja>(typeName=<js>"foo"</js>) - <jk>public class</jk> Foo { - <jc>// A bean property where the object types cannot be inferred since it's an Object[].</jc> - <ja>@BeanProperty</ja>(typeDictionary={Bar.<jk>class</jk>,Baz.<jk>class</jk>}) - <jk>public</jk> Object[] x = <jk>new</jk> Object[]{<jk>new</jk> Bar(), <jk>new</jk> Baz()}; - } - - <ja>@Bean</ja>(typeName=<js>"bar"</js>) - <jk>public class</jk> Bar {} - - <ja>@Bean</ja>(typeName=<js>"baz"</js>) - <jk>public class</jk> Baz {} - </p> - <p> - When serialized as JSON, <js>"_type"</js> attributes would be added when needed to infer the type during - parsing: - </p> - <p class='bcode'> - { - x: [ - {_type:<js>'bar'</js>}, - {_type:<js>'baz'</js>} - ] - } - </p> - <p> - Type names can be represented slightly differently in different languages. - For example, the dictionary name is used as element names when serialized to XML. - This allows the <code>typeName</code> annotation to be used as a shortcut for defining element names for - beans. - </p> - <p> - When serialized as XML, the bean is rendered as: - </p> - <p class='bcode'> - <xt><foo></xt> - <xt><x></xt> - <xt><bar/></xt> - <xt><baz/></xt> - <xt></x></xt> - <xt></foo></xt> - </p> - <p> - Bean dictionaries are defined at two levels: - </p> - <ul> - <li>On individual bean properties through the - {@link org.apache.juneau.annotation.BeanProperty#beanDictionary() @BeanProperty.beanDictionary()} - annotation. - <li>Globally for a parser using the {@link org.apache.juneau.parser.ParserBuilder#beanDictionary(Class...)} - method. - </ul> - <ul class='doctree'> - <li class='info'> - Type names do not need to be universally unique. - However, they must be unique within a dictionary. - <li class='info'> - The following reserved words cannot be used as type names: - <code>object, array, number, boolean, null</code>. - <li class='info'> - Serialized type names are DISABLED by default. - They must be enabled on the serializer using the - {@link org.apache.juneau.serializer.SerializerContext#SERIALIZER_addBeanTypeProperties} - configuration property. - <li class='info'> - The <js>"_type"</js> property name can be overridden using the - {@link org.apache.juneau.BeanContext#BEAN_beanTypePropertyName} configuration property. - </ul> - - <!-- ======================================================================================================== --> - <a id="Core.BeanSubTypes"></a> - <h4 class='topic' onclick='toggle(this)'>2.7.1 - Bean Subtypes</h4> - <div class='topic'> - <p> - In addition to the bean type name support described above, simplified support is provided - for bean subtypes. - </p> - <p> - Bean subtypes are similar in concept to bean type names, except for the following differences: - </p> - <ul> - <li>You specify the list of possible subclasses through an annotation on a parent bean class. - <li>You do not need to register the subtype classes on the bean dictionary of the parser. - </ul> - <p> - In the following example, the abstract class has two subclasses: - </p> - <p class='bcode'> - <jc>// Abstract superclass</jc> - <ja>@Bean</ja>( - beanDictionary={A1.<jk>class</jk>, A2.<jk>class</jk>} - ) - <jk>public abstract class</jk> A { - <jk>public</jk> String <jf>f0</jf> = <js>"f0"</js>; - } - - <jc>// Subclass 1</jc> - <ja>@Bean</ja>(typeName=<js>"A1"</js>) - <jk>public class</jk> A1 <jk>extends</jk> A { - <jk>public</jk> String <jf>f1</jf>; - } - - <jc>// Subclass 2</jc> - <ja>@Bean</ja>(typeName=<js>"A2"</js>) - <jk>public class</jk> A2 <jk>extends</jk> A { - <jk>public</jk> String <jf>f2</jf>; - } - </p> - <p> - When serialized, the subtype is serialized as a virtual <js>"_type"</js> property: - </p> - <p class='bcode'> - JsonSerializer s = JsonSerializer.<jsf>DEFAULT_LAX</jsf>; - A1 a1 = <jk>new</jk> A1(); - a1.<jf>f1</jf> = <js>"f1"</js>; - String r = s.serialize(a1); - <jsm>assertEquals</jsm>(<js>"{_type:'A1',f1:'f1',f0:'f0'}"</js>, r); - </p> - <p> - The following shows what happens when parsing back into the original object. - </p> - <p class='bcode'> - JsonParser p = JsonParser.<jsf>DEFAULT</jsf>; - A a = p.parse(r, A.<jk>class</jk>); - <jsm>assertTrue</jsm>(a <jk>instanceof</jk> A1); - </p> - </div> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.VirtualBeans"></a> - <h3 class='topic' onclick='toggle(this)'>2.8 - Virtual Beans</h3> - <div class='topic'> - <p> - The {@link org.apache.juneau.BeanContext#BEAN_useInterfaceProxies} setting (enabled by default) allows - the Juneau parsers to parse content into virtual beans (bean interfaces without implementation classes). - </p> - <p> - For example, the following code creates an instance of the specified unimplemented interface: - </p> - <p class='bcode'> - <jc>// Our unimplemented interface</jc> - <jk>public interface</jk> Address { - - String getStreet(); - <jk>void</jk> setStreet(String x); - - String getCity(); - <jk>void</jk> setCity(String x); - - StateEnum getState(); - <jk>void</jk> setState(StateEnum x); - - <jk>int</jk> getZip(); - <jk>void</jk> setZip(<jk>int</jk> zip); - } - - <jc>// Our code</jc> - Address address = JsonParser.<jsf>DEFAULT</jsf>.parse( - <js>"{street:'123 Main St', city:'Anywhere', state:'PR', zip:12345}"</js>, - Address.<jk>class</jk> - ); - - <jk>int</jk> zip = address.getZip(); - address.setState(StateEnum.<jsf>NY</jsf>); - </p> - <p> - Getter and setter values can be any parsable values, even other virtual beans. - </p> - <p> - Under-the-covers, a virtual bean is simply a proxy interface on top of an existing <code>BeanMap</code> - instance. From a programmatic point-of-view, they're indistinguishable from real beans, and can be - manipulated and serialized like any other bean. - </p> - <p> - Virtual beans can also be created programmatically using the <code>BeanContext</code> class: - </p> - <p class='bcode'> - Address address = BeanContext.<jsf>DEFAULT</jsf>.createSession().newBean(Address.<jk>class</jk>); - </p> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.PojoCategories"></a> - <h3 class='topic' onclick='toggle(this)'>2.9 - POJO Categories</h3> - <div class='topic'> - <p> - The following chart shows POJOs categorized into groups and whether they can be serialized or parsed: - </p> - <table class='styled' style='border-collapse: collapse;'> - <tr><th>Group</th><th>Description</th><th>Examples</th><th>Can<br>serialize?</th><th>Can<br>parse?</th></tr> - <tr class='dark bb' style='background-color:lightyellow;'> - <td style='text-align:center'>1</td> - <td><b>Java primitive objects</b></td> - <td> - <ul class='normal'> - <li>{@code String} - <li>{@code Integer} - <li>{@code Float} - <li>{@code Boolean} - </ul> - </td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - </tr> - <tr class='dark bb' style='background-color:lightyellow'> - <td style='text-align:center'>2</td> - <td><b>Java Collections Framework objects and Java arrays</b></td> - <td> </td> - <td> </td> - <td> </td> - </tr> - <tr class='light bb'> - <td style='text-align:center'>2a</td> - <td> - <b>With standard keys/values</b> - <br>Map keys are group [1, 4a, 6a] objects. - <br>Map, Collection, and array values are group [1, 2, 3ac, 4a, 6a] objects. - </td> - <td> - <ul class='normal'> - <li><code>HashSet<String,Integer></code> - <li><code>TreeMap<Integer,Bean></code> - <li><code>List<<jk>int</jk>[][]></code> - <li><code>Bean[]</code> - </ul> - </td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - </tr> - <tr class='light bb'> - <td style='text-align:center'>2b</td> - <td> - <b>With non-standard keys/values</b> - <br>Map keys are group [2, 3, 4b, 5, 6b, 7] objects. - <br>Map, Collection, and array values are group [3b, 4b, 5, 6b, 7] objects. - </td> - <td> - <ul class='normal'> - <li><code>HashSet<Bean,Integer></code> - <li><code>TreeMap<Integer,Reader></code> - </ul> - </td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - <td style='background-color:salmon;text-align:center'><b>no</b></td> - </tr> - <tr class='dark bb' style='background-color:lightyellow'> - <td style='text-align:center'>3</td> - <td><b>Java Beans</b></td> - <td> </td> - <td> </td> - <td> </td> - </tr> - <tr class='light bb'> - <td style='text-align:center'>3a</td> - <td> - <b>With standard properties</b> - <br>These are beans that have no-arg constructors and one or more properties defined by public getter - and setter methods or public fields. - <br>Property values are group [1, 2, 3ac, 4a, 6a] objects. - </td> - <td> </td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - </tr> - <tr class='light bb'> - <td style='text-align:center'>3b</td> - <td> - <b>With non-standard properties or not true beans</b> - <br>These include true beans that have no-arg constructors and one or more properties defined by getter - and setter methods or properties, but property types include group [3b, 4b, 5, 6b, 7] objects. - <br>This also includes classes that look like beans but aren't true beans. - For example, classes that have getters but not setters, or classes without no-arg constructors. - </td> - <td> </td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - <td style='background-color:salmon;text-align:center'><b>no</b></td> - </tr> - <tr class='light bb'> - <td style='text-align:center'>3c</td> - <td> - <b>Virtual beans</b> - <br>These are unimplemented bean interfaces with properties of type [1, 2, 3ac, 4a, 6a] objects. - <br>Parsers will automatically create interface proxies on top of BeanMap instances. - </td> - <td> </td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - </tr> - <tr class='dark bb' style='background-color:lightyellow'> - <td style='text-align:center'>4</td> - <td> - <b>Swapped objects</b> - <br>These are objects that are not directly serializable, but have - {@link org.apache.juneau.transform.PojoSwap PojoSwaps} associated with them. - The purpose of a POJO swap is to convert an object to another object that is easier to serialize - and parse. - For example, the {@link org.apache.juneau.transforms.DateSwap.ISO8601DT} class can be used to - serialize {@link java.util.Date} objects to ISO8601 strings, and parse them back into - {@link java.util.Date} objects. - </td> - <td> </td> - <td> </td> - <td> </td> - </tr> - <tr class='light bb'> - <td style='text-align:center'>4a</td> - <td> - <b>2-way swapped to group [1, 2a, 3ac] objects</b> - <br>For example, a swap that converts a {@code Date} to a {@code String}. - </td> - <td> - <ul class='normal'> - <li><code>java.util.Date</code> - <li><code>java.util.GregorianCalendar</code> - </ul> - </td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - </tr> - <tr class='light bb'> - <td style='text-align:center'>4b</td> - <td> - <b>1-way swapped to group [1, 2, 3] objects</b> - <br>For example, a swap that converts an {@code Iterator} to a {@code List}. - This would be one way, since you cannot reconstruct an {@code Iterator}. - </td> - <td> - <ul class='normal'> - <li><code>java.util.Iterator</code> - </ul> - </td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - <td style='background-color:salmon;text-align:center'><b>no</b></td> - </tr> - <tr class='dark bb' style='background-color:lightyellow'> - <td style='text-align:center'>5</td> - <td> - <b>Readers and InputStreams</b> - <br>Contents are serialized directly to the output stream or writer. - </td> - <td> - <ul class='normal'> - <li>{@code FileInputStream} - <li>{@code StringReader} - </ul> - </td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - <td style='background-color:salmon;text-align:center'><b>no</b></td> - </tr> - - <tr class='dark bb' style='background-color:lightyellow'> - <td style='text-align:center'>6</td> - <td> - <b>Non-serializable objects with standard methods for converting to a serializable form</b><br> - </td> - <td> </td> - <td> </td> - <td> </td> - </tr> - <tr class='light bb' style='background-color:lightyellow'> - <td style='text-align:center'>6a</td> - <td> - Classes with a method that converts it to a serializable form: - <ul> - <li><code><jk>public</jk> X swap(BeanSession);</code> where <code>X</code> is in groups - [1, 2a, 3ac]. - <li><code><jk>public</jk> String toString();</code> where the string is any meaningful data. - </ul> - And a method that converts it back into the original object: - <ul> - <li><code><jk>public static</jk> T fromString(String);</code> - <li><code><jk>public static</jk> T valueOf(String);</code> - <li><code><jk>public static</jk> T parse(String);</code> - <li><code><jk>public static</jk> T parseString(String);</code> - <li><code><jk>public static</jk> T forName(String);</code> - <li><code><jk>public static</jk> T forString(String);</code> - <li><code><jk>public</jk> T(X);</code> where <code>X</code> is in groups [1, 2a, 3ac]. - <li><code><jk>public static</jk> T unswap(BeanSession,X);</code> where <code>X</code> is in - groups [1, 2a, 3ac]. - </ul> - </td> - <td> - <ul class='normal'> - <li><code>java.lang.Class</code> - <li><code>java.sql.Time</code> - <li><code>java.sql.Timestamp</code> - <li><code>java.text.MessageFormat</code> - <li><code>java.text.NumberFormat</code> - <li><code>java.util.Date</code> - <li><code>java.util.UUID</code> - <li><code>java.util.logging.Level</code> - <li><code>javax.xml.bind.DatatypeConverter</code> - </ul> - </td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - </tr> - <tr class='light bb' style='background-color:lightyellow'> - <td style='text-align:center'>6b</td> - <td> - Classes that only have a method to convert to a serializable form: - <ul> - <li><code><jk>public</jk> X swap(BeanSession);</code> where <code>X</code> is in groups - [1, 2, 3]. - <li><code><jk>public</jk> String toString();</code> where the string is any meaningful data. - </ul> - </td> - <td> </td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - <td style='background-color:salmon;text-align:center'><b>no</b></td> - </tr> - <tr class='dark' style='background-color:lightyellow'> - <td style='text-align:center'>7</td> - <td> - <b>All other objects</b> - <br>Anything that doesn't fall into one of the groups above are simply converted to {@code Strings} - using the {@code toString()} method. - </td> - <td> </td> - <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> - <td style='background-color:salmon;text-align:center'><b>no</b></td> - </tr> - </table> - <ul class='doctree'> - <li class='info'> - Serializers are designed to work on tree-shaped POJO models. - These are models where there are no referential loops (e.g. leaves with references to nodes, or nodes - in one branch referencing nodes in another branch). - There is a serializer setting {@code detectRecursions} to look for and handle these kinds of loops - (by setting these references to <jk>null</jk>), but it is not enabled by default since it introduces - a moderate performance penalty. - </ul> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.SVL"></a> - <h4 class='topic' onclick='toggle(this)'>2.10 - Simple Variable Language</h4> - <div class='topic'> - <p> - The <a class='doclink' href='org/apache/juneau/svl/package-summary.html#TOC'>org.apache.juneau.svl</a> - package defines an API for a language called "Simple Variable Language". - In a nutshell, Simple Variable Language (or SVL) is text that contains variables of the form - <js>"$varName{varKey}"</js>. - </p> - <p> - Variables can be recursively nested within the varKey (e.g. <js>"$FOO{$BAR{xxx},$BAZ{xxx}}"</js>). - Variables can also return values that themselves contain more variables. - </p> - <p class='bcode'> - <jc>// Use the default variable resolver to resolve a string that contains $S (system property) variables</jc> - String myProperty = VarResolver.<jsf>DEFAULT</jsf>.resolve(<js>"The Java home directory is $S{java.home}"</js>); - </p> - <p> - The following shows how variables can be arbitrarily nested... - </p> - <p class='bcode'> - <jc>// Look up a property in the following order: - // 1) MYPROPERTY environment variable. - // 2) 'my.property' system property if environment variable not found. - // 3) 'not found' string if system property not found.</jc> - String myproperty = VarResolver.<jsf>DEFAULT</jsf>.resolve(<js>"$E{MYPROPERTY,$S{my.property,not found}}"</js>); - </p> - <p> - SVL is a large topic on it's own. - It is used extensively in the ConfigFile, REST and Microservice APIs. - </p> - - <h6 class='topic'>Additional Information</h6> - <ul class='doctree'> - <li class='jp'> - <a class='doclink' href='org/apache/juneau/svl/package-summary.html#TOC'>org.apache.juneau.svl</a> - - Simple Variable Language Javadocs. - </ul> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.ConfigFile"></a> - <h3 class='topic' onclick='toggle(this)'>2.11 - Configuration Files</h3> - <div class='topic'> - <p> - The <a class='doclink' - href='org/apache/juneau/ini/package-summary.html#TOC'>org.apache.juneau.ini</a> package contains a powerful - API for creating and using INI-style config files. - </p> - <p> - An example of an INI file: - </p> - <p class='bcode'> - <cc># Default section</cc> - <ck>key1</ck> = <cv>1</cv> - <ck>key2</ck> = <cv>true</cv> - <ck>key3</ck> = <cv>[1,2,3]</cv> - <ck>key4</ck> = <cv>http://foo</cv> - - <cc># Section 1</cc> - <cs>[Section1]</cs> - <ck>key1</ck> = <cv>2</cv> - <ck>key2</ck> = <cv>false</cv> - <ck>key3</ck> = <cv>[4,5,6]</cv> - <ck>key4</ck> = <cv>http://bar</cv> - </p> - <p> - This class can be used to easily access contents of the file: - </p> - <p class='bcode'> - <jk>int</jk> key1; - <jk>boolean</jk> key2; - <jk>int</jk>[] key3; - URL key4; - - <jc>// Load our config file</jc> - ConfigFile f = <jk>new</jk> ConfigFileBuilder().build(<js>"MyConfig.cfg"</js>); - - <jc>// Read values from default section</jc> - key1 = f.getInt(<js>"key1"</js>); - key2 = f.getBoolean(<js>"key2"</js>); - key3 = f.getObject(<jk>int</jk>[].<jk>class</jk>, <js>"key3"</js>); - key4 = f.getObject(URL.<jk>class</jk>, <js>"key4"</js>); - - <jc>// Read values from section #1</jc> - key1 = f.getInt(<js>"Section1/key1"</js>); - key2 = f.getBoolean(<js>"Section1/key2"</js>); - key3 = f.getObject(<jk>int</jk>[].<jk>class</jk>, <js>"Section1/key3"</js>); - key4 = f.getObject(URL.<jk>class</jk>, <js>"Section1/key4"</js>); - </p> - <p> - The interface also allows a config file to be easily constructed programmatically: - </p> - <p class='bcode'> - <jc>// Construct the sample INI file programmatically</jc> - ConfigFile cf = <jk>new</jk> ConfigFileBuilder().build(<js>"MyConfig.cfg"</js>) - .addLines(<jk>null</jk>, - <js>"# Default section"</js>, - <js>"key1 = 1"</js>, - <js>"key2 = true"</js>, - <js>"key3 = [1,2,3]"</js>, - <js>"key4 = http://foo"</js>, - <js>""</js>) - .addHeaderComments(<js>"Section1"</js>, - <js>"# Section 1"</js>) - .addLines(<js>"Section1"</js>, - <js>"key1 = 2"</js>, - <js>"key2 = false"</js>, - <js>"key3 = [4,5,6]"</js>, - <js>"key4 = http://bar"</js>) - .save(); - </p> - <p> - The following is equivalent, except that it uses {@link org.apache.juneau.ini.ConfigFile#put(String, Object)} - to set values: - </p> - <p class='bcode'> - <jc>// Construct the sample INI file programmatically</jc> - ConfigFile cf = <jk>new</jk> ConfigFileBuilder().build(<js>"MyConfig.cfg"</js>) - .addLines(<jk>null</jk>, - <js>"# Default section"</js>) - .addHeaderComments(<js>"section1"</js>, - <js>"# Section 1"</js>); - cf.put(<js>"key1"</js>, 1); - cf.put(<js>"key2"</js>, <jk>true</jk>); - cf.put(<js>"key3"</js>, <jk>new int</jk>[]{1,2,3}); - cf.put(<js>"key4"</js>, <jk>new</jk> URL(<js>"http://foo"</js>)); - cf.put(<js>"Section1/key1"</js>, 2); - cf.put(<js>"Section1/key2"</js>, <jk>false</jk>); - cf.put(<js>"Section1/key3"</js>, <jk>new int</jk>[]{4,5,6}); - cf.put(<js>"Section1/key4"</js>, <jk>new</jk> URL(<js>"http://bar"</js>)); - cf.save(); - </p> - <p> - Values are LAX JSON (i.e. unquoted attributes, single quotes) except for top-level strings which are left - unquoted. - Any parsable object types are supported as values (e.g. arrays, collections, beans, swappable objects, - enums, etc...). - </p> - <p> - The config file looks deceptively simple, the config file API is a very powerful feature with many - capabilities, including: - </p> - <ul class='spaced-list'> - <li> - The ability to use variables to reference environment variables, system properties, other config file - entries, and a host of other types. - <li> - APIs for updating, modifying, and saving configuration files without losing comments or formatting. - <li> - Extensive listener APIs. - </ul> - - <h6 class='topic'>Example:</h6> - <p class='bcode'> - <cc>#--------------------------</cc> - <cc># My section</cc> - <cc>#--------------------------</cc> - <cs>[MySection]</cs> - - <cc># An integer</cc> - <ck>anInt</ck> = <cv>1</cv> - - <cc># A boolean</cc> - <ck>aBoolean</ck> = <cv>true</cv> - - <cc># An int array</cc> - <ck>anIntArray</ck> = <cv>[1,2,3]</cv> - - <cc># A POJO that can be converted from a String</cc> - <ck>aURL</ck> = <cv>http://foo </cv> - - <cc># A POJO that can be converted from JSON</cc> - <ck>aBean</ck> = <cv>{foo:'bar',baz:123}</cv> - - <cc># A system property</cc> - <ck>locale</ck> = <cv>$S{java.locale, en_US}</cv> - - <cc># An environment variable</cc> - <ck>path</ck> = <cv>$E{PATH, unknown}</cv> - - <cc># A manifest file entry</cc> - <ck>mainClass</ck> = <cv>$MF{Main-Class}</cv> - - <cc># Another value in this config file</cc> - <ck>sameAsAnInt</ck> = <cv>$C{MySection/anInt}</cv> - - <cc># A command-line argument in the form "myarg=foo"</cc> - <ck>myArg</ck> = <cv>$ARG{myarg}</cv> - - <cc># The first command-line argument</cc> - <ck>firstArg</ck> = <cv>$ARG{0}</cv> - - <cc># Look for system property, or env var if that doesn't exist, or command-line arg if that doesn't exist.</cc> - <ck>nested</ck> = <cv>$S{mySystemProperty,$E{MY_ENV_VAR,$ARG{0}}}</cv> - - <cc># A POJO with embedded variables</cc> - <ck>aBean2</ck> = <cv>{foo:'$ARG{0}',baz:$C{MySection/anInt}}</cv> - - </p> - <p class='bcode'> - <jc>// Java code for accessing config entries above.</jc> - ConfigFile cf = Microservice.<jsm>getConfig</jsm>(); - - <jk>int</jk> anInt = cf.getInt(<js>"MySection/anInt"</js>); - <jk>boolean</jk> aBoolean = cf.getBoolean(<js>"MySection/aBoolean"</js>); - <jk>int</jk>[] anIntArray = cf.getObject(<jk>int</jk>[].<jk>class</jk>, <js>"MySection/anIntArray"</js>); - URL aURL = cf.getObject(URL.<jk>class</jk>, <js>"MySection/aURL"</js>); - MyBean aBean = cf.getObject(MyBean.<jk>class</jk>, <js>"MySection/aBean"</js>); - Locale locale = cf.getObject(Locale.<jk>class</jk>, <js>"MySection/locale"</js>); - String path = cf.getString(<js>"MySection/path"</js>); - String mainClass = cf.getString(<js>"MySection/mainClass"</js>); - <jk>int</jk> sameAsAnInt = cf.getInt(<js>"MySection/sameAsAnInt"</js>); - String myArg = cf.getString(<js>"MySection/myArg"</js>); - String firstArg = cf.getString(<js>"MySection/firstArg"</js>); - </p> - <p> - Config files can also be used to directly populate beans using the - {@link org.apache.juneau.ini.ConfigFile#getSectionAsBean(String,Class,boolean)}: - </p> - <p class='bcode'> - <jc>// Example config file</jc> - <cs>[MyAddress]</cs> - <ck>name</ck> = <cv>John Smith</cv> - <ck>street</ck> = <cv>123 Main Street</cv> - <ck>city</ck> = <cv>Anywhere</cv> - <ck>state</ck> = <cv>NY</cv> - <ck>zip</ck> = <cv>12345</cv> - - <jc>// Example bean</jc> - <jk>public class</jk> Address { - public String name, street, city; - public StateEnum state; - public int zip; - } - - <jc>// Example usage</jc> - ConfigFile cf = <jk>new</jk> ConfigFileBuilder().build(<js>"MyConfig.cfg"</js>); - Address myAddress = cf.getSectionAsBean(<js>"MySection"</js>, Address.<jk>class</jk>); - </p> - <p> - Config file sections can also be accessed via interface proxies using - {@link org.apache.juneau.ini.ConfigFile#getSectionAsInterface(String,Class)}: - </p> - <p class='bcode'> - <jc>// Example config file</jc> - <cs>[MySection]</cs> - <ck>string</ck> = <cv>foo</cv> - <ck>int</ck> = <cv>123</cv> - <ck>enum</ck> = <cv>ONE</cv> - <ck>bean</ck> = <cv>{foo:'bar',baz:123}</cv> - <ck>int3dArray</ck> = <cv>[[[123,null],null],null]</cv> - <ck>bean1d3dListMap</ck> = <cv>{key:[[[[{foo:'bar',baz:123}]]]]}</cv> - - <jc>// Example interface</jc> - <jk>public interface</jk> MyConfigInterface { - - String getString(); - <jk>void</jk> setString(String x); - - <jk>int</jk> getInt(); - <jk>void</jk> setInt(<jk>int</jk> x); - - MyEnum getEnum(); - <jk>void</jk> setEnum(MyEnum x); - - MyBean getBean(); - <jk>void</jk> setBean(MyBean x); - - <jk>int</jk>[][][] getInt3dArray(); - <jk>void</jk> setInt3dArray(<jk>int</jk>[][][] x); - - Map<String,List<MyBean[][][]>> getBean1d3dListMap(); - <jk>void</jk> setBean1d3dListMap(Map<String,List<MyBean[][][]>> x); - } - - <jc>// Example usage</jc> - ConfigFile cf = <jk>new</jk> ConfigFileBuilder().build(<js>"MyConfig.cfg"</js>); - MyConfigInterface ci = cf.getSectionAsInterface(<js>"MySection"</js>, MyConfigInterface.<jk>class</jk>); - <jk>int</jk> myInt = ci.getInt(); - ci.setBean(<jk>new</jk> MyBean()); - cf.save(); - </p> - - <h6 class='topic'>Additional Information</h6> - <ul class='doctree'> - <li class='jp'> - <a class='doclink' href='org/apache/juneau/ini/package-summary.html#TOC'>org.apache.juneau.ini</a> - - Config API Javadocs. - </ul> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.SupportedLanguages"></a> - <h3 class='topic' onclick='toggle(this)'>2.12 - Supported Languages</h3> - <div class='topic'> - <p> - Extensive javadocs exist for individual language support. - Refer to these docs for language-specific information. - </p> - - <h6 class='topic'>Additional Information</h6> - <ul class='doctree'> - <li class='jp'> - <a class='doclink' href='org/apache/juneau/html/package-summary.html#TOC'>org.apache.juneau.html</a> - - HTML support. - <li class='jp'> - <a class='doclink' href='org/apache/juneau/jena/package-summary.html#TOC'>org.apache.juneau.jena</a> - - RDF support. - <li class='jp'> - <a class='doclink' href='org/apache/juneau/jso/package-summary.html#TOC'>org.apache.juneau.jso</a> - - Java Serialized Object support. - <li class='jp'> - <a class='doclink' href='org/apache/juneau/json/package-summary.html#TOC'>org.apache.juneau.json</a> - - JSON support. - <li class='jp'> - <a class='doclink' href='org/apache/juneau/msgpack/package-summary.html#TOC'>org.apache.juneau.msgpack</a> - - MessagePack support. - <li class='jp'> - <a class='doclink' href='org/apache/juneau/plaintext/package-summary.html#TOC'>org.apache.juneau.plaintext</a> - - Plain-text support. - <li class='jp'> - <a class='doclink' href='org/apache/juneau/soap/package-summary.html#TOC'>org.apache.juneau.soap</a> - - SOAP support. - <li class='jp'> - <a class='doclink' href='org/apache/juneau/urlencoding/package-summary.html#TOC'>org.apache.juneau.urlencoding</a> - - URL-Encoding and UON support. - <li class='jp'> - <a class='doclink' href='org/apache/juneau/xml/package-summary.html#TOC'>org.apache.juneau.xml</a> - - XML support. - <li class='jp'> - <a class='doclink' href='org/apache/juneau/dto/atom/package-summary.html#TOC'>org.apache.juneau.dto.atom</a> - - ATOM support. - <li class='jp'> - <a class='doclink' href='org/apache/juneau/dto/cognos/package-summary.html#TOC'>org.apache.juneau.dto.cognos</a> - - Cognos support. - </ul> - </div> - - <!-- ======================================================================================================== --> - <a id="Core.JacksonComparison"></a> - <h3 class='topic' onclick='toggle(this)'>2.13 - Comparison with Jackson</h3> - <div class='topic'> - <p> - Juneau was developed independently from Jackson, but shares many of the same features and capabilities. - Whereas Jackson was created to work primarily with JSON, Juneau was created to work for multiple languages. - Therefore, the terminology and annotations in Juneau are similar, but language-agnostic. - </p> - <p> - The following charts describe equivalent features between the two libraries: - </p> - - <h6 class='topic'>Annotations</h6> - <table class='styled'> - <tr><th>Jackson</th><th>Juneau</th></tr> - <tr> - <td> - <ja>@JsonGetter</ja> - <br><ja>@JsonSetter</ja> - </td> - <td> - {@link org.apache.juneau.annotation.BeanProperty @BeanProperty} - </td> - </tr> - <tr> - <td> - <ja>@JsonAnyGetter</ja> - <br><ja>@JsonAnySetter</ja> - </td> - <td> - {@link org.apache.juneau.annotation.BeanProperty#name() @BeanProperty(name="*")} - </td> - </tr> - <tr> - <td> - <ja>@JsonIgnore</ja> - <br><ja>@JsonIgnoreType</ja> - </td> - <td> - {@link org.apache.juneau.annotation.BeanIgnore @BeanIgnore} - </td> - </tr> - <tr> - <td><code><ja>@JsonIgnoreProperties</ja>({...})</code></td> - <td> - {@link org.apache.juneau.annotation.Bean#excludeProperties @Bean(excludeProperties="...")} - </td> - </tr> - <tr> - <td><code><ja>@JsonAutoDetect</ja>(fieldVisibility=...)</code></td> - <td> - No equivalent annotation, but can be controlled via: - <br>{@link org.apache.juneau.BeanContext#BEAN_beanFieldVisibility} - <br>{@link org.apache.juneau.BeanContext#BEAN_methodVisibility} - <br>Future annotation support planned. - </td> - </tr> - <tr> - <td> - <ja>@JsonCreator</ja> - <br><ja>@JsonProperty</ja> - </td> - <td> - {@link org.apache.juneau.annotation.BeanConstructor @BeanConstructor} - </td> - </tr> - <tr> - <td><ja>@JacksonInject</ja></td> - <td> - No equivalent. - <br>Future support planned. - </td> - - </tr> - <tr> - <td> - <ja>@JsonSerialize</ja> - <br><ja>@JsonDeserialize</ja> - </td> - <td> - Juneau uses swaps to convert non-serializable object to serializable forms: - <br>{@link org.apache.juneau.annotation.Swap @Swap} - </td> - </tr> - <tr> - <td><ja>@JsonInclude</ja></td> - <td> - No equivalent annotation, but can be controlled via various settings: - <br>{@link org.apache.juneau.BeanContext} - <br>{@link org.apache.juneau.serializer.SerializerContext} - <br>Future annotation support planned. - </td> - </tr> - <tr> - <td><ja>@JsonPropertyOrder</ja></td> - <td> - {@link org.apache.juneau.annotation.Bean#properties @Bean(properties="...")} - <br>{@link org.apache.juneau.annotation.Bean#sort @Bean(sort=x)} - </td> - </tr> - <tr> - <td> - <ja>@JsonValue</ja> - <br><ja>@JsonRawValue</ja> - </td> - <td> - No equivalents. - <br>Future support unlikely since these are JSON-centric. - </td> - </tr> - </table> - </div> -</div> - -<!-- ======================================================================================================== --> -<a id="DTOs"></a> -<h2 class='topic' onclick='toggle(this)'>3 - Juneau Data Transfer Objects (org.apache.juneau.dto)</h2> -<div class='topic'> - <p> - The Juneau Core library contains several predefined POJOs for generating commonly-used document types. - This section describes support for these POJOs. - </p> - - <!-- ======================================================================================================== --> - <a id="DTOs.HTML5"></a> - <h3 class='topic' onclick='toggle(this)'>3.1 - HTML5</h3> - <div class='topic'> - <
<TRUNCATED>