http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/5c4762ee/juneau-core/src/main/java/org/apache/juneau/urlencoding/package.html ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/package.html b/juneau-core/src/main/java/org/apache/juneau/urlencoding/package.html index 445bcc6..a2e8c15 100644 --- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/package.html +++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/package.html @@ -75,17 +75,6 @@ <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='#RestServletDefault'>Using RestServletDefault</a></p> - <li><p><a class='doclink' href='#RestServlet'>Using RestServlet with annotations</a></p> - <li><p><a class='doclink' href='#DefaultProvider'>Using JAX-RS DefaultProvider</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> <!-- ======================================================================================================== --> @@ -93,9 +82,14 @@ <h2 class='topic' onclick='toggle(this)'>1 - URL encoding support overview</h2> <div class='topic'> <p> - Juneau supports converting arbitrary POJOs to and from URL-encoded strings using ultra-efficient serializers and parsers.<br> - The serializer converts POJOs directly to URL-encoded strings without the need for intermediate DOM objects using a highly-efficient state machine.<br> - Likewise, the parser creates POJOs directly from URL-encoded strings without the need for intermediate DOM objects. + Juneau supports converting arbitrary POJOs to and from URL-encoded strings using ultra-efficient serializers + and parsers. + <br> + The serializer converts POJOs directly to URL-encoded strings without the need for intermediate DOM objects + using a highly-efficient state machine. + <br> + Likewise, the parser creates POJOs directly from URL-encoded strings without the need for intermediate DOM + objects. </p> <p> Juneau uses UON (URL-Encoded Object Notation) for representing POJOs. @@ -105,15 +99,20 @@ Juneau can serialize and parse instances of any of the following POJO types: </p> <ul class='spaced-list'> - <li>Java primitives and 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>Java primitives and 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>). - <li>Non-serializable classes and properties with associated <code>PojoSwaps</code> that convert them to serializable forms. + <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>). + <li>Non-serializable classes and properties with associated <code>PojoSwaps</code> that convert them to + serializable forms. </ul> <p> - Refer to <a href='../../../../overview-summary.html#Core.PojoCategories' class='doclink'>POJO Categories</a> for a complete definition of supported POJOs. + 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> @@ -126,16 +125,19 @@ <h3 class='topic' onclick='toggle(this)'>1.1 - URL-encoding 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.<br> - 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. + The example shown here is from the Address Book resource located in the + <code>org.apache.juneau.sample.war</code> application + <br> + 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/people/1</code>, the POJO is rendered as HTML: </p> <img class='bordered' src="doc-files/Example_HTML.png"> <p> - By appending <code>?Accept=application/x-www-form-urlencoded&plainText=true</code> to the URL, you can view the data as a URL-encoded string: + By appending <code>?Accept=application/x-www-form-urlencoded&plainText=true</code> to the URL, you can + view the data as a URL-encoded string: </p> <p class='bcode'> <un>0</un>=( @@ -204,8 +206,10 @@ Juneau supports two kinds of serialization: </p> <ul class='spaced-list'> - <li>Construction of full URL query parameter strings (e.g. <code>&key=value</code> pairs) from beans and maps. - <li>Construction of URL query parameter value strings (e.g. just the <code>value</code> portion of <code>&key=value</code> pairs) from any POJO. + <li>Construction of full URL query parameter strings (e.g. <code>&key=value</code> pairs) from beans + and maps. + <li>Construction of URL query parameter value strings (e.g. just the <code>value</code> portion of + <code>&key=value</code> pairs) from any POJO. </ul> <p> Top-level beans and maps can serialized as key/value pairs as shown below: @@ -215,8 +219,9 @@ http://localhost/sample?<ua>foo</ua>=<us>bar</us>&<ua>baz</ua>=<us>bing</us> </p> <p> - Lower-level beans and maps are also serialized as key/value pairs, but are surrounded with a <js>"(...)"</js> construct to denote an object mapping, - and uses a comma as the parameter delimiter instead of <js>"&"</js>.<br> + Lower-level beans and maps are also serialized as key/value pairs, but are surrounded with a + <js>"(...)"</js> construct to denote an object mapping, and uses a comma as the parameter delimiter + instead of <js>"&"</js>. </p> <h6 class='figure'>Example: A bean serialized as a query parameter value.</h6> <p class='bcode'> @@ -280,8 +285,10 @@ <p> Refer to the <a href='doc-files/rfc_uon.txt'>UON specification</a> for a complete set of syntax rules. <p> - <code>PojoSwaps</code> can be used to convert non-serializable POJOs into serializable forms, such as converting - <code>Calendar</code> object to ISO8601 strings, or <code><uk>byte</uk>[]</code> arrays to Base-64 encoded strings.<br> + <code>PojoSwaps</code> can be used to convert non-serializable POJOs into serializable forms, such as + converting <code>Calendar</code> object to ISO8601 strings, or <code><uk>byte</uk>[]</code> arrays to + Base-64 encoded strings. + <br> These transforms can be associated at various levels: </p> <ul class='spaced-list'> @@ -294,7 +301,8 @@ http://localhost/sample?<ua>a1=<us>'Sun,+03+Mar+1901+09:05:06+GMT'</us> </p> <p> - For more information about transforms, refer to <a class='doclink' href='../transform/package-summary.html#TOC'>org.apache.juneau.transform</a>. + For more information about transforms, refer to <a class='doclink' + href='../transform/package-summary.html#TOC'>org.apache.juneau.transform</a>. </p> </div> @@ -305,22 +313,31 @@ <h2 class='topic' onclick='toggle(this)'>2 - UrlEncodingSerializer and UonSerializer classes</h2> <div class='topic'> <p> - {@link org.apache.juneau.urlencoding.UrlEncodingSerializer} and {@link org.apache.juneau.uon.UonSerializer} classes are used to convert POJOs to URL-encoded strings.<br> + {@link org.apache.juneau.urlencoding.UrlEncodingSerializer} and {@link org.apache.juneau.uon.UonSerializer} + classes are used to convert POJOs to URL-encoded strings. + <br> The <code>UonSerializer</code> class converts parameter values to UON notation. - The <code>UrlEncodingSerializer</code> class converts a POJO to key/value URL-Encoded pairs using <code>UonSerializer</code> to serialize the values. + The <code>UrlEncodingSerializer</code> class converts a POJO to key/value URL-Encoded pairs using + <code>UonSerializer</code> to serialize the values. If you're trying to construct complete URL-Encoded entities, use <code>UrlEncodingSerializer</code>. If you're constructing your own key/value pairs, use <code>UonSerializer</code>. </p> <p> - The serializers include several configurable settings.<br> + The serializers include several configurable settings. + <br> Static reusable instances of serializers are provided with commonly-used settings: </p> <ul class='spaced-list'> - <li>{@link org.apache.juneau.urlencoding.UrlEncodingSerializer#DEFAULT} - All default settings, strict mode. - <li>{@link org.apache.juneau.urlencoding.UrlEncodingSerializer#DEFAULT_READABLE} - Use whitespace and indentation for readability. - <li>{@link org.apache.juneau.uon.UonSerializer#DEFAULT} - All default settings, strict mode. - <li>{@link org.apache.juneau.uon.UonSerializer#DEFAULT_READABLE} - Use whitespace and indentation for readability. - <li>{@link org.apache.juneau.uon.UonSerializer#DEFAULT_ENCODING} - Same as DEFAULT, but use URL-Encoding on special characters. + <li>{@link org.apache.juneau.urlencoding.UrlEncodingSerializer#DEFAULT} + - All default settings, strict mode. + <li>{@link org.apache.juneau.urlencoding.UrlEncodingSerializer#DEFAULT_READABLE} + - Use whitespace and indentation for readability. + <li>{@link org.apache.juneau.uon.UonSerializer#DEFAULT} + - All default settings, strict mode. + <li>{@link org.apache.juneau.uon.UonSerializer#DEFAULT_READABLE} + - Use whitespace and indentation for readability. + <li>{@link org.apache.juneau.uon.UonSerializer#DEFAULT_ENCODING} + - Same as DEFAULT, but use URL-Encoding on special characters. </ul> <p> The general guidelines on which serializer to use is: @@ -328,15 +345,17 @@ <ul class='spaced-list'> <li>Use encoding serializers when you're using the results to construct a URI yourself, and therefore need invalid URI characters to be encoded. - <li>Use unencoding serializers when you're creating parameter values and passing them off to some other + <li>Use un-encoding serializers when you're creating parameter values and passing them off to some other utility class that will itself encode invalid URI characters. <li>Use the readable serializer for debugging purposes. </ul> <h6 class='topic'>Notes about examples</h6> <p> - The examples shown in this document will use default strict settings.<br> - For brevity, the examples will use public fields instead of getters/setters to reduce the size of the examples.<br> + The examples shown in this document will use default strict settings. + <br> + 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> @@ -395,7 +414,8 @@ <ua>id</ua>=<un>1</un>&<ua>name</ua>=<us>'John+Smith'</us> </p> <p> - By default, the <code>UrlEncodingSerializer</code> class will URL-Encode special characters, and the <code>UonSerializer</code> will NOT URL-encode special characters. + By default, the <code>UrlEncodingSerializer</code> class will URL-Encode special characters, and the + <code>UonSerializer</code> will NOT URL-encode special characters. </p> @@ -404,21 +424,27 @@ <h3 class='topic' onclick='toggle(this)'>2.1 - @Bean and @BeanProperty annotations</h3> <div class='topic'> <p> - The {@link org.apache.juneau.annotation.Bean @Bean} and {@link org.apache.juneau.annotation.BeanProperty @BeanProperty} annotations - are used to customize the behavior of beans across the entire framework.<br> + The {@link org.apache.juneau.annotation.Bean @Bean} and {@link org.apache.juneau.annotation.BeanProperty @BeanProperty} + annotations are used to customize the behavior of beans across the entire framework. + <br> They have various 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). + <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 transform with it to transform - it to an ISO8601 date-time string in GMT time.<br> - We'll also add a couple of <code>URI</code> properties.<br> - By default, <code>Calendars</code> are treated as beans by the framework, which is usually not how you want them serialized.<br> + it to an ISO8601 date-time string in GMT time. + <br> + We'll also add a couple of <code>URI</code> properties. + <br> + By default, <code>Calendars</code> are treated as beans by the framework, which is usually not how you want + them serialized. + <br> Using transforms, we can convert them to standardized string forms. </p> <p class='bcode'> @@ -435,13 +461,16 @@ <jk>public</jk> Person() {} <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>public</jk> Person(<jk>int</jk> id, String name, String uri, String addressBookUri, String birthDate) + <jk>throws</jk> Exception { <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); <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)); + <jk>this</jk>.<jf>birthDate</jf> + .setTime(DateFormat.<jsm>getDateInstance</jsm>(DateFormat.<jsf>MEDIUM</jsf>) + .parse(birthDate)); } } </p> @@ -450,23 +479,27 @@ </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>); + 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'> - (<ua>id</ua>=<un>1</un>,<ua>name</ua>=<us>'John+Smith'</us>,<ua>uri</ua>=<us>http://sample/addressBook/person/1</us>,<ua>addressBookUri</ua>=<us>http://sample/addressBook</us>,<ua>birthDate</ua>=<us>1946-08-12T00:00:00Z</us>) + (<ua>id</ua>=<un>1</un>,<ua>name</ua>=<us>'John+Smith'</us>,<ua>uri</ua>=<us>http://sample/addressBook/person/1</us>, + <ua>addressBookUri</ua>=<us>http://sample/addressBook</us>,<ua>birthDate</ua>=<us>1946-08-12T00:00:00Z</us>) </p> <p> Using <code>UrlEncodingSerializer</code> instead would create the following: </p> <p class='bcode'> - <ua>id</ua>=<un>1</un>&<ua>name</ua>=<us>'John+Smith'</us>&<ua>uri</ua>=<us>http://sample/addressBook/person/1</us>&<ua>addressBookUri</ua>=<us>http://sample/addressBook</us>&<ua>birthDate</ua>=<us>1946-08-12T00:00:00Z</us> + <ua>id</ua>=<un>1</un>&<ua>name</ua>=<us>'John+Smith'</us>&<ua>uri</ua>=<us>http://sample/addressBook/person/1</us> + &<ua>addressBookUri</ua>=<us>http://sample/addressBook</us>&<ua>birthDate</ua>=<us>1946-08-12T00:00:00Z</us> </p> <p> - Another useful feature is the {@link org.apache.juneau.annotation.Bean#propertyNamer()} annotation that allows you to plug in your own - logic for determining bean property names.<br> + Another useful feature is the {@link org.apache.juneau.annotation.Bean#propertyNamer()} annotation that + allows you to plug in your own logic for determining bean property names. + <br> The {@link org.apache.juneau.PropertyNamerDLC} is an example of an alternate property namer. It converts bean property names to lowercase-dashed format. </p> @@ -478,7 +511,8 @@ </p> <h6 class='figure'>Results</h6> <p class='bcode'> - (<ua>id</ua>=<un>1</us>,<ua>name</ua>=<us>'John+Smith'</us>,<ua>uri</ua>=<us>http://sample/addressBook/person/1</us>,<ua>address-book-uri</ua>=<us>http://sample/addressBook</us>,<ua>birth-date</ua>=<us>1946-08-12T00:00:00Z</us>) + (<ua>id</ua>=<un>1</us>,<ua>name</ua>=<us>'John+Smith'</us>,<ua>uri</ua>=<us>http://sample/addressBook/person/1</us>, + <ua>address-book-uri</ua>=<us>http://sample/addressBook</us>,<ua>birth-date</ua>=<us>1946-08-12T00:00:00Z</us>) </p> </div> @@ -521,7 +555,8 @@ UonSerializer s = UonSerializer.<jsf>DEFAULT_READABLE</jsf>; <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>); + 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>); @@ -581,8 +616,9 @@ </p> </div> <p> - Note how the top level <code>Person</code> bean is serialized using the standard <js>'&'</js> delimiter, whereas the lower-level <code>Address</code> - bean is serialized using the <js>','</js> character to prevent the <code>addresses</code> field from being incompletely parsed. + Note how the top level <code>Person</code> bean is serialized using the standard <js>'&'</js> delimiter, + whereas the lower-level <code>Address</code> bean is serialized using the <js>','</js> character to prevent + the <code>addresses</code> field from being incompletely parsed. </p> @@ -592,15 +628,17 @@ <div class='topic'> <p> The URL-encoding serializer is designed to be used against POJO tree structures. <br> - It expects that there not be loops in the POJO model (e.g. children with references to parents, etc...).<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). + be thrown (if {@link org.apache.juneau.serializer.SerializerContext#SERIALIZER_maxDepth} is not reached first). </p> <p> If you still want to use the URL-encoding serializer on such models, Juneau provides the - {@link org.apache.juneau.serializer.SerializerContext#SERIALIZER_detectRecursions} setting.<br> + {@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. + skip serialization when a duplicate is encountered. </p> <p> For example, let's make a POJO model out of the following classes: @@ -623,7 +661,8 @@ </p> <p class='bcode'> <jc>// Clone an existing serializer and set property for detecting recursions.</jc> - UrlEncodingSerializer s = UrlEncodingSerializer.<jsf>DEFAULT_READABLE</jsf>.builder().detectRecursions(<jk>true</jk>).build(); + UrlEncodingSerializer s = UrlEncodingSerializer.<jsf>DEFAULT_READABLE</jsf>.builder() + .detectRecursions(<jk>true</jk>).build(); <jc>// Create a recursive loop.</jc> A a = <jk>new</jk> A(); @@ -648,7 +687,8 @@ Without recursion detection enabled, this would cause a stack-overflow error. </p> <p> - Recursion detection introduces a performance penalty of around 20%.<br> + Recursion detection introduces a performance penalty of around 20%. + <br> For this reason the setting is disabled by default. </p> </div> @@ -662,9 +702,12 @@ 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.uon.UonSerializerContext} - UON serializer context properties. - <li>{@link org.apache.juneau.urlencoding.UrlEncodingSerializerContext} - URL-Encoding serializer context properties. + <li>{@link org.apache.juneau.BeanContext} + - Bean context properties. + <li>{@link org.apache.juneau.uon.UonSerializerContext} + - UON serializer context properties. + <li>{@link org.apache.juneau.urlencoding.UrlEncodingSerializerContext} + - URL-Encoding serializer context properties. </ul> </div> @@ -674,8 +717,11 @@ <h3 class='topic' onclick='toggle(this)'>2.5 - Other notes</h3> <div class='topic'> <ul class='spaced-list'> - <li>Like all other Juneau serializers, the URL-encoding serializers are thread safe and maintain an internal cache of bean classes encountered.<br> - For performance reasons, it's recommended that serializers be reused whenever possible instead of always creating new instances. + <li>Like all other Juneau serializers, the URL-encoding serializers are thread safe and maintain an internal + cache of bean classes encountered. + <br> + For performance reasons, it's recommended that serializers be reused whenever possible instead of + always creating new instances. </ul> </div> </div> @@ -686,30 +732,39 @@ <h2 class='topic' onclick='toggle(this)'>3 - UrlEncodingParser and UonParser classes</h2> <div class='topic'> <p> - {@link org.apache.juneau.urlencoding.UrlEncodingParser} and {@link org.apache.juneau.uon.UonParser} classes are used to convert URL-encoded strings back into POJOs.<br> + {@link org.apache.juneau.urlencoding.UrlEncodingParser} and {@link org.apache.juneau.uon.UonParser} classes + are used to convert URL-encoded strings back into POJOs. + <br> The <code>UonParser</code> class converts UON-encoded parameter values to POJOs. - The <code>UrlEncodingParser</code> class converts entire URL-Encoded strings to POJOs using <code>UonSerializer</code> to serialize indivisual values. + The <code>UrlEncodingParser</code> class converts entire URL-Encoded strings to POJOs using + <code>UonSerializer</code> to serialize individual values. If you're trying to parse an entire URL-Encoded string, use <code>UrlEncodingParser</code>. - If you're trying to parse an individual value (such as that returned by <code>RestServlet.getQueryParameter(name)</code>), use <code>UonParser</code>. + If you're trying to parse an individual value (such as that returned by + <code>RestServlet.getQueryParameter(name)</code>), use <code>UonParser</code>. </p> <p> The following static reusable instances of <code>UrlEncodingParser</code> are provided for convenience: </p> <ul class='spaced-list'> - <li>{@link org.apache.juneau.urlencoding.UrlEncodingParser#DEFAULT} - Default parser for entire URL-encoded strings, decode <code>%xx</code> sequences. - <li>{@link org.apache.juneau.uon.UonParser#DEFAULT} - Default parser for URL-encoded parameter values, don't decode <code>%xx</code> sequences. - <li>{@link org.apache.juneau.uon.UonParser#DEFAULT_DECODING} - Default parser for URL-encoded parameter values, decode <code>%xx</code> sequences. + <li>{@link org.apache.juneau.urlencoding.UrlEncodingParser#DEFAULT} + - Default parser for entire URL-encoded strings, decode <code>%xx</code> sequences. + <li>{@link org.apache.juneau.uon.UonParser#DEFAULT} + - Default parser for URL-encoded parameter values, don't decode <code>%xx</code> sequences. + <li>{@link org.apache.juneau.uon.UonParser#DEFAULT_DECODING} + - Default parser for URL-encoded parameter values, decode <code>%xx</code> sequences. </ul> <p> - The general guildlines on which parser to use is: + The general guidelines on which parser to use is: </p> <ul class='spaced-list'> - <li>Use the <code>DEFAULT</code> parser for parameter values that have already had <code>%xx</code> sequences decoded, - such as when using <code>HttpServletRequest.getQueryParameter(name)</code>. - <li>Use the <code>DEFAULT_ENCODED</code> parser if the input has not already had <code>%xx</code> sequences decoded. + <li>Use the <code>DEFAULT</code> parser for parameter values that have already had <code>%xx</code> sequences + decoded, such as when using <code>HttpServletRequest.getQueryParameter(name)</code>. + <li>Use the <code>DEFAULT_ENCODED</code> parser if the input has not already had <code>%xx</code> sequences + decoded. </ul> <p> - Let's build upon the previous example and parse the generated URL-encoded string back into the original bean.<br> + Let's build upon the previous example and parse the generated URL-encoded string back into the original bean. + <br> We start with the URL-encoded string that was generated. </p> <p class='bcode'> @@ -717,7 +772,8 @@ UonSerializer s = UonSerializer.<jsf>DEFAULT_READABLE</jsf>; <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>); + 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>); @@ -797,22 +853,24 @@ <h3 class='topic' onclick='toggle(this)'>3.1 - Parsing into generic POJO models</h3> <div class='topic'> <p> - The URL-encoding 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. + The URL-encoding 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. + 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. + 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> Starting back with our original URL-encoded string: @@ -849,9 +907,10 @@ String json = JsonSerializer.<jsf>DEFAULT_LAX_READABLE</jsf>.serialize(m); </p> <p> - What we end up with is the exact same output.<br> - Even the numbers and booleans are preserved because they are parsed into <code>Number</code> and <code>Boolean</code> objects - when parsing into generic models. + What we end up with is the exact same output. + <br> + Even the numbers and booleans are preserved because they are parsed into <code>Number</code> and + <code>Boolean</code> objects when parsing into generic models. </p> <p class='bcode'> { @@ -901,7 +960,8 @@ </p> <p> - As a general rule, parsing into beans is often more efficient than parsing into generic models.<br> + 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> @@ -927,414 +987,16 @@ <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 URL-encoding parsers are thread safe and maintain an internal cache of bean classes encountered.<br> - For performance reasons, it's recommended that parser be reused whenever possible instead of always creating new instances. + <li>Like all other Juneau parsers, the URL-encoding parsers are thread safe and maintain an internal cache + of bean classes encountered. + <br> + 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 URL-encoding serialization/parsing in the REST server and client APIs.<br> - 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 JSON. - 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.rest.RestServletDefault}.<br> - This includes URL-encoding serialization/parsing support by default, in addition to several other media types. - <li>Create a servlet that subclasses from {@link org.apache.juneau.rest.RestServlet} and specify the - URL-encoding serializer and/or parser using the {@link org.apache.juneau.rest.annotation.RestResource#serializers()} and - {@link org.apache.juneau.rest.annotation.RestResource#parsers()} on the entire servlet class, or - the {@link org.apache.juneau.rest.annotation.RestMethod#serializers()} and {@link org.apache.juneau.rest.annotation.RestMethod#parsers()} - annotations on individual methods within the class. - <li>Register {@link org.apache.juneau.rest.jaxrs.DefaultProvider} with JAX-RS.<br> - This includes URL-encoding serialization/parsing support by default, in addition to several other media types. - <li>Create and register a subclass of {@link org.apache.juneau.rest.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="RestServletDefault"></a> - <h4 class='topic' onclick='toggle(this)'>4.1.1 - Using RestServletDefault</h4> - <div class='topic'> - <p> - The quickest way to implement a REST resource with URL-encoding support is to create a subclass of {@link org.apache.juneau.rest.RestServletDefault}.<br> - This class provides support for JSON, XML, HTML, URL-Encoding, and others. - </p> - <p> - The <code>AddressBookResource</code> example shown in the first chapter uses the <code>RestServletJenaDefault</code> class - which is a subclass of <code>RestServletDefault</code> with additional support for RDF languages.<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>, - title=<js>"$L{title}"</js>, - description=<js>"$L{description}"</js>, - htmldoc=<ja>@HtmlDoc</ja>( - links=<js>"{options:'?method=OPTIONS'}"</js> - ), - properties={ - <ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_useWhitespace</jsf>, value=<js>"true"</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> - In this case, we're overriding the <jsf>SERIALIZER_useWhitespace</jsf> property to add whitespace to the output. - 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.rest.RestContext#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 <a class='doclink' href='../rest/package-summary.html#TOC'>org.apache.juneau.rest</a> 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, RestResponse res, <ja>@Path</ja> <jk>int</jk> id) throws Exception { - res.setPageTitle(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.rest.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.rest.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 URL-encoding using - the following definition: - </p> - <p class='bcode'> - <ja>@RestResource</ja>( - serializers={UrlEncodingSerializer.<jk>class</jk>}, - parsers={UrlEncodingParser.<jk>class</jk>}, - properties={ - <ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_useWhitespace</jsf>, value=<js>"true"</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={UrlEncodingSerializer.<jk>class</jk>}, - parsers={UrlEncodingParser.<jk>class</jk>}, - properties={ - <ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_useWhitespace</jsf>, value=<js>"true"</js>) - } - ) - <jk>public</jk> Person getPerson(RestRequest req, RestResponse res, <ja>@Path</ja> <jk>int</jk> id) throws Exception { - res.setPageTitle(req.getPathInfo()); - <jk>return</jk> findPerson(id); - } - </p> - <p> - The {@link org.apache.juneau.rest.annotation.RestMethod#serializersInherit()} and - {@link org.apache.juneau.rest.annotation.RestMethod#parsersInherit()} control how various artifacts - are inherited from the parent class.<br> - Refer to <a class='doclink' href='../rest/package-summary.html#TOC'>org.apache.juneau.rest</a> for additional information on using these annotations. - </p> - </div> - - <!-- ======================================================================================================== --> - <a id="DefaultProvider"></a> - <h4 class='topic' onclick='toggle(this)'>4.1.3 - Using JAX-RS DefaultProvider</h4> - <div class='topic'> - <p> - URL-encoding media type support in JAX-RS can be achieved by using the {@link org.apache.juneau.rest.jaxrs.DefaultProvider} 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>DefaultProvider</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>"text/uon,"</js>+ <jc>// UonSerializer</jc> - <js>"application/x-www-form-urlencoded,"</js>+ <jc>// UrlEncodingSerializer</jc> - <js>"text/xml+soap,"</js>+ <jc>// SoapXmlSerializer</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>"text/uon,"</js>+ <jc>// UonParser</jc> - <js>"application/x-www-form-urlencoded,"</js>+ <jc>// UrlEncodingParser</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>, - UonSerializer.<jk>class</jk>, - UrlEncodingSerializer.<jk>class</jk>, - SoapXmlSerializer.<jk>class</jk>, - JavaSerializedObjectSerializer.<jk>class</jk> - }, - parsers={ - JsonParser.<jk>class</jk>, - XmlParser.<jk>class</jk>, - HtmlParser.<jk>class</jk>, - UonParser.<jk>class</jk>, - UrlEncodingParser.<jk>class</jk>, - JavaSerializedObjectParser.<jk>class</jk>, - } - ) - <jk>public final class</jk> DefaultProvider <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. - 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. - In Wink, this is accomplished by adding an entry to a config file. - </p> - <p class='bcode'> - <xt><web-app</xt> <ua>version</ua>=<us>"2.3"</us><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.rest.jaxrs.DefaultProvider - </p> - <p> - Properties can be specified on providers through the {@link org.apache.juneau.rest.jaxrs.JuneauProvider#properties()} annotation.<br> - Properties can also be specified at the method level by using the {@link org.apache.juneau.rest.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=SerializerContext.<jsf>SERIALIZER_useWhitespace</jsf>, value=<js>"true"</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>JsonSerializer</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.rest.RestResponse#setProperty(String,Object)} - method, and through the {@link org.apache.juneau.rest.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 JSON media types, you can define your own provider class, like so: - </p> - <p class='bcode'> - <ja>@Provider</ja> - <ja>@Produces</ja>( - <js>"application/x-www-form-urlencoded"</js> <jc>// UrlEncodingSerializer</jc> - ) - <ja>@Consumes</ja>( - <js>"application/x-www-form-urlencoded"</js> <jc>// UrlEncodingParser</jc> - ) - <ja>@JuneauProvider</ja>( - serializers={ - UrlEncodingSerializer.<jk>class</jk> - }, - parsers={ - UrlEncodingParser.<jk>class</jk>, - } - properties={ - <ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_useWhitespace</jsf>, value=<js>"true"</js>) - } - ) - <jk>public final class</jk> MyUrlEncodingProvider <jk>extends</jk> BaseProvider {} - </p> - <p> - Then register it with Wink the same way as <code>DefaultProvider</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.rest.client.RestClient} class provides an easy-to-use REST client interface with - pluggable media type handling using any of the Juneau serializers and parsers.<br> - Defining a client to support the URL-encoding media type on HTTP requests and responses can be done in one line of code: - </p> - <p class='bcode'> - <jc>// Create a client to handle URL-encoded requests and responses.</jc> - RestClient client = <uk>new</uk> RestClient(UrlEncodingSerializer.<uk>class</uk>, UrlEncodingParser.<uk>class</uk>); - </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.<br> - 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> - <h6 class='figure'>Example:</h6> - <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> - <h6 class='figure'>Results</h6> - <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>
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/5c4762ee/juneau-core/src/main/java/org/apache/juneau/utils/AMap.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/utils/AMap.java b/juneau-core/src/main/java/org/apache/juneau/utils/AMap.java index 69e5f8a..8fe5d92 100644 --- a/juneau-core/src/main/java/org/apache/juneau/utils/AMap.java +++ b/juneau-core/src/main/java/org/apache/juneau/utils/AMap.java @@ -20,7 +20,8 @@ import java.util.*; * Primarily used for testing purposes for quickly creating populated maps. * <p class='bcode'> * <jc>// Example:</jc> - * Map<String,Integer> m = <jk>new</jk> AMap<String,Integer>().append(<js>"foo"</js>,1).append(<js>"bar"</js>,2); + * Map<String,Integer> m = <jk>new</jk> AMap<String,Integer>() + * .append(<js>"foo"</js>,1).append(<js>"bar"</js>,2); * </p> * * @param <K> The key type. http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/5c4762ee/juneau-core/src/main/java/org/apache/juneau/utils/Args.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/utils/Args.java b/juneau-core/src/main/java/org/apache/juneau/utils/Args.java index 8768d25..72a1f0a 100644 --- a/juneau-core/src/main/java/org/apache/juneau/utils/Args.java +++ b/juneau-core/src/main/java/org/apache/juneau/utils/Args.java @@ -19,9 +19,11 @@ import java.util.*; import org.apache.juneau.*; /** - * Utility class to make it easier to work with command-line arguments pass in through a <code>main(String[] args)</code> method. + * Utility class to make it easier to work with command-line arguments pass in through a + * <code>main(String[] args)</code> method. * <p> - * Used to parse command-line arguments of the form <js>"[zero or more main arguments] [zero or more optional arguments]"</js>. + * Used to parse command-line arguments of the form + * <js>"[zero or more main arguments] [zero or more optional arguments]"</js>. * <p> * The format of a main argument is a token that does not start with <js>'-'</js>. * <p> @@ -135,7 +137,7 @@ public final class Args extends ObjectMap { /** * Returns main argument at the specified index, or <jk>null</jk> if the index is out of range. * <p> - * Can be used in conjuction with {@link #hasArg(int)} to check for existence of arg. + * Can be used in conjunction with {@link #hasArg(int)} to check for existence of arg. * <p class='bcode'> * <jc>// Check for no arguments</jc> * <jk>if</jk> (! args.hasArg(0)) http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/5c4762ee/juneau-core/src/main/java/org/apache/juneau/utils/IOPipe.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/utils/IOPipe.java b/juneau-core/src/main/java/org/apache/juneau/utils/IOPipe.java index 86a4d68..e4f94af 100644 --- a/juneau-core/src/main/java/org/apache/juneau/utils/IOPipe.java +++ b/juneau-core/src/main/java/org/apache/juneau/utils/IOPipe.java @@ -119,7 +119,7 @@ public class IOPipe { } /** - * Sames as calling {@link #byLines()} with <jk>true</jk>. + * Same as calling {@link #byLines()} with <jk>true</jk>. * * @return This object (for method chaining). */ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/5c4762ee/juneau-core/src/main/java/org/apache/juneau/utils/ManifestFile.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/utils/ManifestFile.java b/juneau-core/src/main/java/org/apache/juneau/utils/ManifestFile.java index dbca516..fb024ba 100644 --- a/juneau-core/src/main/java/org/apache/juneau/utils/ManifestFile.java +++ b/juneau-core/src/main/java/org/apache/juneau/utils/ManifestFile.java @@ -24,8 +24,8 @@ import org.apache.juneau.*; /** * Utility class for working with Jar manifest files. * <p> - * Copies the contents of a {@link Manifest} into an {@link ObjectMap} so that the various - * convenience methods on that class can be used to retrieve values. + * Copies the contents of a {@link Manifest} into an {@link ObjectMap} so that the various convenience methods on that + * class can be used to retrieve values. */ public class ManifestFile extends ObjectMap { http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/5c4762ee/juneau-core/src/main/java/org/apache/juneau/utils/MessageBundle.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/utils/MessageBundle.java b/juneau-core/src/main/java/org/apache/juneau/utils/MessageBundle.java index 5b22725..4812adb 100644 --- a/juneau-core/src/main/java/org/apache/juneau/utils/MessageBundle.java +++ b/juneau-core/src/main/java/org/apache/juneau/utils/MessageBundle.java @@ -28,10 +28,12 @@ import org.apache.juneau.annotation.*; * <li>Instead of throwing {@link MissingResourceException}, the {@link #getString(String)} method * will return <js>"{!!key}"</js> if the bundle was not found, and <js>"{!key}"</js> if bundle * was found but the key is not in the bundle. - * <li>A client locale can be set as a {@link ThreadLocal} object using the static {@link #setClientLocale(Locale)} so that client localized - * messages can be retrieved using the {@link #getClientString(String, Object...)} method on all instances of this class. + * <li>A client locale can be set as a {@link ThreadLocal} object using the static {@link #setClientLocale(Locale)} + * so that client localized messages can be retrieved using the {@link #getClientString(String, Object...)} + * method on all instances of this class. * <li>Resource bundles on parent classes can be added to the search path for this class by using the - * {@link #addSearchPath(Class, String)} method. This allows messages to be retrieved from the resource bundles of parent classes. + * {@link #addSearchPath(Class, String)} method. + * This allows messages to be retrieved from the resource bundles of parent classes. * <li>Locale-specific bundles can be retrieved by using the {@link #getBundle(Locale)} method. * <li>The {@link #getString(Locale, String, Object...)} method can be used to retrieve locale-specific messages. * <li>Messages in the resource bundle can optionally be prefixed with the simple class name. @@ -79,7 +81,8 @@ public class MessageBundle extends ResourceBundle { * @param forClass The class using this resource bundle. * @param bundlePath The path of the resource bundle to wrap. * This can be an absolute path (e.g. <js>"com.foo.MyMessages"</js>) or a path - * relative to the package of the <l>forClass</l> (e.g. <js>"MyMessages"</js> if <l>forClass</l> is <js>"com.foo.MyClass"</js>). + * relative to the package of the <l>forClass</l> (e.g. <js>"MyMessages"</js> if <l>forClass</l> is + * <js>"com.foo.MyClass"</js>). */ public MessageBundle(Class<?> forClass, String bundlePath) { this(forClass, bundlePath, Locale.getDefault()); @@ -157,7 +160,9 @@ public class MessageBundle extends ResourceBundle { * * @param key The resource bundle key. * @param args Optional {@link MessageFormat}-style arguments. - * @return The resolved value. Never <jk>null</jk>. <js>"{!!key}"</js> if the bundle is missing. <js>"{!key}"</js> if the key is missing. + * @return The resolved value. Never <jk>null</jk>. + * <js>"{!!key}"</js> if the bundle is missing. + * <js>"{!key}"</js> if the key is missing. */ public String getString(String key, Object...args) { String s = getString(key); @@ -172,7 +177,9 @@ public class MessageBundle extends ResourceBundle { * @param locale The locale of the resource bundle to retrieve message from. * @param key The resource bundle key. * @param args Optional {@link MessageFormat}-style arguments. - * @return The resolved value. Never <jk>null</jk>. <js>"{!!key}"</js> if the bundle is missing. <js>"{!key}"</js> if the key is missing. + * @return The resolved value. Never <jk>null</jk>. + * <js>"{!!key}"</js> if the bundle is missing. + * <js>"{!key}"</js> if the key is missing. */ public String getString(Locale locale, String key, Object...args) { if (locale == null) @@ -181,11 +188,14 @@ public class MessageBundle extends ResourceBundle { } /** - * Same as {@link #getString(String, Object...)} but uses the locale specified on the call to {@link #setClientLocale(Locale)}. + * Same as {@link #getString(String, Object...)} but uses the locale specified on the call to + * {@link #setClientLocale(Locale)}. * * @param key The resource bundle key. * @param args Optional {@link MessageFormat}-style arguments. - * @return The resolved value. Never <jk>null</jk>. <js>"{!!key}"</js> if the bundle is missing. <js>"{!key}"</js> if the key is missing. + * @return The resolved value. Never <jk>null</jk>. + * <js>"{!!key}"</js> if the bundle is missing. + * <js>"{!key}"</js> if the key is missing. */ public String getClientString(String key, Object...args) { return getString(clientLocale.get(), key, args); @@ -270,7 +280,7 @@ public class MessageBundle extends ResourceBundle { * <p> * Useful for debugging purposes. * Note that any class that implements a <code>toObjectMap()</code> method will automatically be serialized by - * calling this method and serializing the result. + * calling this method and serializing the result. * <p> * This method always constructs a new {@link ObjectMap} on each call. * http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/5c4762ee/juneau-core/src/main/java/org/apache/juneau/utils/MetadataMap.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/utils/MetadataMap.java b/juneau-core/src/main/java/org/apache/juneau/utils/MetadataMap.java index ab03730..127536b 100644 --- a/juneau-core/src/main/java/org/apache/juneau/utils/MetadataMap.java +++ b/juneau-core/src/main/java/org/apache/juneau/utils/MetadataMap.java @@ -71,7 +71,8 @@ public class MetadataMap { throw new RuntimeException(e); } if (o == null) - throw new BeanRuntimeException(c, "Could not find a constructor on class with a parameter to handle type {0}", constructorArg.getClass()); + throw new BeanRuntimeException(c, + "Could not find a constructor on class with a parameter to handle type {0}", constructorArg.getClass()); classes2[classes.length] = c; metadata2[classes.length] = o; classes = classes2; http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/5c4762ee/juneau-core/src/main/java/org/apache/juneau/utils/ObjectUtils.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/utils/ObjectUtils.java b/juneau-core/src/main/java/org/apache/juneau/utils/ObjectUtils.java index a48c3fc..912dc18 100644 --- a/juneau-core/src/main/java/org/apache/juneau/utils/ObjectUtils.java +++ b/juneau-core/src/main/java/org/apache/juneau/utils/ObjectUtils.java @@ -18,129 +18,137 @@ import org.apache.juneau.transform.*; /** * Utility class for efficiently converting objects between types. * <p> - * If the value isn't an instance of the specified type, then converts - * the value if possible.<br> + * If the value isn't an instance of the specified type, then converts the value if possible. * <p> * The following conversions are valid: - * <table class='styled'> - * <tr><th>Convert to type</th><th>Valid input value types</th><th>Notes</th></tr> - * <tr> - * <td> - * A class that is the normal type of a registered {@link PojoSwap}. - * </td> - * <td> - * A value whose class matches the transformed type of that registered {@link PojoSwap}. - * </td> - * <td> </td> - * </tr> - * <tr> - * <td> - * A class that is the transformed type of a registered {@link PojoSwap}. - * </td> - * <td> - * A value whose class matches the normal type of that registered {@link PojoSwap}. - * </td> - * <td> </td> - * </tr> - * <tr> - * <td> - * {@code Number} (e.g. {@code Integer}, {@code Short}, {@code Float},...)<br> - * <code>Number.<jsf>TYPE</jsf></code> (e.g. <code>Integer.<jsf>TYPE</jsf></code>, <code>Short.<jsf>TYPE</jsf></code>, <code>Float.<jsf>TYPE</jsf></code>,...) - * </td> - * <td> - * {@code Number}, {@code String}, <jk>null</jk> - * </td> - * <td> - * For primitive {@code TYPES}, <jk>null</jk> returns the JVM default value for that type. - * </td> - * </tr> - * <tr> - * <td> - * {@code Map} (e.g. {@code Map}, {@code HashMap}, {@code TreeMap}, {@code ObjectMap}) - * </td> - * <td> - * {@code Map} - * </td> - * <td> - * If {@code Map} is not constructible, a {@code ObjectMap} is created. - * </td> - * </tr> - * <tr> - * <td> - * {@code Collection} (e.g. {@code List}, {@code LinkedList}, {@code HashSet}, {@code ObjectList}) - * </td> - * <td> - * {@code Collection<Object>}<br> - * {@code Object[]} - * </td> - * <td> - * If {@code Collection} is not constructible, a {@code ObjectList} is created. - * </td> - * </tr> - * <tr> - * <td> - * {@code X[]} (array of any type X)<br> - * </td> - * <td> - * {@code List<X>}<br> - * </td> - * <td> </td> - * </tr> - * <tr> - * <td> - * {@code X[][]} (multi-dimensional arrays)<br> - * </td> - * <td> - * {@code List<List<X>>}<br> - * {@code List<X[]>}<br> - * {@code List[]<X>}<br> - * </td> - * <td> </td> - * </tr> - * <tr> - * <td> - * {@code Enum}<br> - * </td> - * <td> - * {@code String}<br> - * </td> - * <td> </td> - * </tr> - * <tr> - * <td> - * Bean<br> - * </td> - * <td> - * {@code Map}<br> - * </td> - * <td> </td> - * </tr> - * <tr> - * <td> - * {@code String}<br> - * </td> - * <td> - * Anything<br> - * </td> - * <td> - * Arrays are converted to JSON arrays<br> - * </td> - * </tr> - * <tr> - * <td> - * Anything with one of the following methods:<br> - * <code><jk>public static</jk> T fromString(String)</code><br> - * <code><jk>public static</jk> T valueOf(String)</code><br> - * <code><jk>public</jk> T(String)</code><br> - * </td> - * <td> - * <code>String</code><br> - * </td> - * <td> - * <br> - * </td> - * </tr> - * </table> + * <table class='styled'> + * <tr><th>Convert to type</th><th>Valid input value types</th><th>Notes</th></tr> + * <tr> + * <td> + * A class that is the normal type of a registered {@link PojoSwap}. + * </td> + * <td> + * A value whose class matches the transformed type of that registered {@link PojoSwap}. + * </td> + * <td> </td> + * </tr> + * <tr> + * <td> + * A class that is the transformed type of a registered {@link PojoSwap}. + * </td> + * <td> + * A value whose class matches the normal type of that registered {@link PojoSwap}. + * </td> + * <td> </td> + * </tr> + * <tr> + * <td> + * {@code Number} (e.g. {@code Integer}, {@code Short}, {@code Float},...) + * <br> + * <code>Number.<jsf>TYPE</jsf></code> (e.g. <code>Integer.<jsf>TYPE</jsf></code>, + * <code>Short.<jsf>TYPE</jsf></code>, <code>Float.<jsf>TYPE</jsf></code>,...) + * </td> + * <td> + * {@code Number}, {@code String}, <jk>null</jk> + * </td> + * <td> + * For primitive {@code TYPES}, <jk>null</jk> returns the JVM default value for that type. + * </td> + * </tr> + * <tr> + * <td> + * {@code Map} (e.g. {@code Map}, {@code HashMap}, {@code TreeMap}, {@code ObjectMap}) + * </td> + * <td> + * {@code Map} + * </td> + * <td> + * If {@code Map} is not constructible, a {@code ObjectMap} is created. + * </td> + * </tr> + * <tr> + * <td> + * {@code Collection} (e.g. {@code List}, {@code LinkedList}, {@code HashSet}, {@code ObjectList}) + * </td> + * <td> + * {@code Collection<Object>} + * <br> + * {@code Object[]} + * </td> + * <td> + * If {@code Collection} is not constructible, a {@code ObjectList} is created. + * </td> + * </tr> + * <tr> + * <td> + * {@code X[]} (array of any type X) + * <br> + * </td> + * <td> + * {@code List<X>} + * </td> + * <td> </td> + * </tr> + * <tr> + * <td> + * {@code X[][]} (multi-dimensional arrays) + * </td> + * <td> + * {@code List<List<X>>} + * <br> + * {@code List<X[]>} + * <br> + * {@code List[]<X>} + * </td> + * <td> </td> + * </tr> + * <tr> + * <td> + * {@code Enum} + * </td> + * <td> + * {@code String} + * </td> + * <td> </td> + * </tr> + * <tr> + * <td> + * Bean + * </td> + * <td> + * {@code Map} + * </td> + * <td> </td> + * </tr> + * <tr> + * <td> + * {@code String} + * </td> + * <td> + * Anything + * </td> + * <td> + * Arrays are converted to JSON arrays + * </td> + * </tr> + * <tr> + * <td> + * Anything with one of the following methods: + * <br> + * <code><jk>public static</jk> T fromString(String)</code> + * <br> + * <code><jk>public static</jk> T valueOf(String)</code> + * <br> + * <code><jk>public</jk> T(String)</code> + * </td> + * <td> + * <code>String</code> + * </td> + * <td> + * <br> + * </td> + * </tr> + * </table> */ public class ObjectUtils { http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/5c4762ee/juneau-core/src/main/java/org/apache/juneau/utils/PojoIntrospector.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/utils/PojoIntrospector.java b/juneau-core/src/main/java/org/apache/juneau/utils/PojoIntrospector.java index f7eb6d4..7eea934 100644 --- a/juneau-core/src/main/java/org/apache/juneau/utils/PojoIntrospector.java +++ b/juneau-core/src/main/java/org/apache/juneau/utils/PojoIntrospector.java @@ -25,7 +25,8 @@ import org.apache.juneau.parser.*; * <h5 class='section'>Example:</h5> * <p class='bcode'> * String s = <js>"foobar"</js>; - * String s2 = (String)<jk>new</jk> PojoIntrospector(s).invoke(<js>"substring(int,int)"</js>, <js>"[3,6]"</js>); <jc>// "bar"</jc> + * String s2 = (String)<jk>new</jk> PojoIntrospector(s) + * .invoke(<js>"substring(int,int)"</js>, <js>"[3,6]"</js>); <jc>// "bar"</jc> * </p> */ public final class PojoIntrospector { @@ -37,7 +38,8 @@ public final class PojoIntrospector { * Constructor. * * @param o The object on which Java methods will be invoked. - * @param p The parser to use to parse the method arguments. If <jk>null</jk>, {@link JsonParser#DEFAULT} is used. + * @param p The parser to use to parse the method arguments. + * If <jk>null</jk>, {@link JsonParser#DEFAULT} is used. */ public PojoIntrospector(Object o, ReaderParser p) { if (p == null) @@ -59,23 +61,26 @@ public final class PojoIntrospector { * Primary method. Invokes the specified method on this bean. * * @param method The method being invoked. - * @param args The arguments to pass as parameters to the method.<br> - * These will automatically be converted to the appropriate object type if possible.<br> + * @param args The arguments to pass as parameters to the method. + * These will automatically be converted to the appropriate object type if possible. * Can be <jk>null</jk> if method has no arguments. * @return The object returned by the call to the method, or <jk>null</jk> if target object is <jk>null</jk>. - * @throws IllegalAccessException If the <code>Constructor</code> object enforces Java language access control and the underlying constructor is inaccessible. + * @throws IllegalAccessException If the <code>Constructor</code> object enforces Java language access control and + * the underlying constructor is inaccessible. * @throws IllegalArgumentException If one of the following occurs: - * <ul class='spaced-list'> - * <li>The number of actual and formal parameters differ. - * <li>An unwrapping conversion for primitive arguments fails. - * <li>A parameter value cannot be converted to the corresponding formal parameter type by a method invocation conversion. - * <li>The constructor pertains to an enum type. - * </ul> + * <ul class='spaced-list'> + * <li>The number of actual and formal parameters differ. + * <li>An unwrapping conversion for primitive arguments fails. + * <li>A parameter value cannot be converted to the corresponding formal parameter type by a method invocation + * conversion. + * <li>The constructor pertains to an enum type. + * </ul> * @throws InvocationTargetException If the underlying constructor throws an exception. * @throws ParseException If the input contains a syntax error or is malformed. * @throws IOException */ - public Object invokeMethod(Method method, Reader args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException, ParseException, IOException { + public Object invokeMethod(Method method, Reader args) throws InvocationTargetException, IllegalArgumentException, + IllegalAccessException, ParseException, IOException { if (o == null) return null; Object[] params = args == null ? null : p.parseArgs(args, method.getGenericParameterTypes()); @@ -86,24 +91,26 @@ public final class PojoIntrospector { * Convenience method for invoking argument from method signature (@see {@link ClassUtils#getMethodSignature(Method)}. * * @param method The method being invoked. - * @param args The arguments to pass as parameters to the method.<br> - * These will automatically be converted to the appropriate object type if possible.<br> + * @param args The arguments to pass as parameters to the method. + * These will automatically be converted to the appropriate object type if possible. * Can be <jk>null</jk> if method has no arguments. * @return The object returned by the call to the method, or <jk>null</jk> if target object is <jk>null</jk>. * @throws NoSuchMethodException If method does not exist. - * @throws IllegalAccessException If the <code>Constructor</code> object enforces Java language access control and the underlying constructor is inaccessible. + * @throws IllegalAccessException If the <code>Constructor</code> object enforces Java language access control and + * the underlying constructor is inaccessible. * @throws IllegalArgumentException If one of the following occurs: - * <ul class='spaced-list'> - * <li>The number of actual and formal parameters differ. - * <li>An unwrapping conversion for primitive arguments fails. - * <li>A parameter value cannot be converted to the corresponding formal parameter type by a method invocation conversion. - * <li>The constructor pertains to an enum type. - * </ul> + * <ul class='spaced-list'> + * <li>The number of actual and formal parameters differ. + * <li>An unwrapping conversion for primitive arguments fails. + * <li>A parameter value cannot be converted to the corresponding formal parameter type by a method invocation conversion. + * <li>The constructor pertains to an enum type. + * </ul> * @throws InvocationTargetException If the underlying constructor throws an exception. * @throws ParseException If the input contains a syntax error or is malformed. * @throws IOException */ - public Object invokeMethod(String method, String args) throws NoSuchMethodException, IllegalArgumentException, InvocationTargetException, IllegalAccessException, ParseException, IOException { + public Object invokeMethod(String method, String args) throws NoSuchMethodException, IllegalArgumentException, + InvocationTargetException, IllegalAccessException, ParseException, IOException { if (o == null) return null; Method m = p.getBeanContext().createSession().getClassMeta(o.getClass()).getPublicMethods().get(method); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/5c4762ee/juneau-core/src/main/java/org/apache/juneau/utils/PojoQuery.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/utils/PojoQuery.java b/juneau-core/src/main/java/org/apache/juneau/utils/PojoQuery.java index 17292ef..aa51b3a 100644 --- a/juneau-core/src/main/java/org/apache/juneau/utils/PojoQuery.java +++ b/juneau-core/src/main/java/org/apache/juneau/utils/PojoQuery.java @@ -29,12 +29,12 @@ import org.apache.juneau.internal.*; * It can also perform just view filtering on beans/maps. * <p> * Examples of tabular POJO models: - * <ul> - * <li><tt>Collection{@code <Map>}</tt> - * <li><tt>Collection{@code <Bean>}</tt> - * <li><tt>Map[]</tt> - * <li><tt>Bean[]</tt> - * </ul> + * <ul> + * <li><tt>Collection{@code <Map>}</tt> + * <li><tt>Collection{@code <Bean>}</tt> + * <li><tt>Map[]</tt> + * <li><tt>Bean[]</tt> + * </ul> * <p> * Tabular POJO models can be thought of as tables of data. For example, a list of the following beans... * <p class='bcode'> @@ -53,18 +53,18 @@ import org.apache.juneau.internal.*; * </table> * <p> * From this table, you can perform the following functions: - * <ul class='spaced-list'> - * <li>Search - Return only rows where a search pattern matches. - * <li>View - Return only the specified subset of columns in the specified order. - * <li>Sort - Sort the table by one or more columns. - * <li>Position/limit - Only return a subset of rows. - * </ul> + * <ul class='spaced-list'> + * <li>Search - Return only rows where a search pattern matches. + * <li>View - Return only the specified subset of columns in the specified order. + * <li>Sort - Sort the table by one or more columns. + * <li>Position/limit - Only return a subset of rows. + * </ul> * * <h5 class='topic'>Search</h5> * <p> - * The search capabilities allow you to filter based on query patterns against - * strings, dates, and numbers. Queries take the form of a Map with column names - * as keys, and search patterns as values. <br> + * The search capabilities allow you to filter based on query patterns against strings, dates, and numbers. + * Queries take the form of a Map with column names as keys, and search patterns as values. + * <br> * Multiple search patterns are ANDed (i.e. all patterns must match for the row to be returned). * * <h5 class='section'>Example:</h5> @@ -76,9 +76,9 @@ import org.apache.juneau.internal.*; * * <h5 class='topic'>String Patterns</h5> * <p> - * Any objects can be queried against using string patterns. If the objects being - * searched are not strings, then the patterns are matched against whatever is - * return by the {@code Object#toString()} method. + * Any objects can be queried against using string patterns. + * If the objects being searched are not strings, then the patterns are matched against whatever is return by the + * {@code Object#toString()} method. * * <h6 class='topic'>Example string query patterns:</h6> * <ul> @@ -123,7 +123,8 @@ import org.apache.juneau.internal.*; * <p> * Any object of type {@link Date} or {@link Calendar} can be searched using date patterns. * <p> - * The default valid input timestamp formats (which can be overridden via the {@link #setValidTimestampFormats(String...)} method are... + * The default valid input timestamp formats (which can be overridden via the + * {@link #setValidTimestampFormats(String...)} method are... * * <ul> * <li><tt>yyyy.MM.dd.HH.mm.ss</tt> @@ -151,8 +152,8 @@ import org.apache.juneau.internal.*; * * <h5 class='topic'>View</h5> * <p> - * The view capability allows you to return only the specified subset of columns in the - * specified order.<br> + * The view capability allows you to return only the specified subset of columns in the specified order. + * <br> * The view parameter is a list of either <tt>Strings</tt> or <tt>Maps</tt>. * * <h6 class='topic'>Example view parameters:</h6> @@ -163,9 +164,10 @@ import org.apache.juneau.internal.*; * * <h5 class='topic'>Sort</h5> * <p> - * The sort capability allows you to sort values by the specified rows.<br> + * The sort capability allows you to sort values by the specified rows. + * <br> * The sort parameter is a list of strings with an optional <js>'+'</js> or <js>'-'</js> suffix representing - * ascending and descending order accordingly. + * ascending and descending order accordingly. * * <h6 class='topic'>Example sort parameters:</h6> * <ul> @@ -177,8 +179,7 @@ import org.apache.juneau.internal.*; * * <h5 class='topic'>Paging</h5> * <p> - * Use the <tt>position</tt> and <tt>limit</tt> parameters to specify a subset of rows to - * return. + * Use the <tt>position</tt> and <tt>limit</tt> parameters to specify a subset of rows to return. */ @SuppressWarnings({"unchecked","rawtypes"}) public final class PojoQuery { @@ -204,7 +205,7 @@ public final class PojoQuery { * * @param args The search arguments. * @return The filtered collection. - * <br>Returns the unaltered input if the input is not a collection or array of objects. + * Returns the unaltered input if the input is not a collection or array of objects. */ public List filter(SearchArgs args) { @@ -490,6 +491,7 @@ public final class PojoQuery { /** * Construct a number matcher for the given search pattern. + * * @param searchPattern A date search paattern. See class usage for a description. */ public NumberMatcher(String searchPattern) { @@ -634,8 +636,8 @@ public final class PojoQuery { } /** - * Use this method to override the allowed search patterns when used in locales where time formats are - * different. + * Use this method to override the allowed search patterns when used in locales where time formats are different. + * * @param s A comma-delimited list of valid time formats. */ public void setValidTimestampFormats(String...s) { @@ -650,6 +652,7 @@ public final class PojoQuery { /** * Construct a timestamp matcher for the given search pattern. + * * @param searchPattern The search pattern. */ DateMatcher(String searchPattern) { @@ -659,9 +662,10 @@ public final class PojoQuery { } /** - * Returns <jk>true</jk> if the specified date matches the pattern passed in through - * the contstructor.<br> - * The Object can be of type {@link Date} or {@link Calendar}.<br> + * Returns <jk>true</jk> if the specified date matches the pattern passed in through the constructor. + * <br> + * The Object can be of type {@link Date} or {@link Calendar}. + * <br> * Always returns <jk>false</jk> on <jk>null</jk> input. */ @Override /* IMatcher */ @@ -833,9 +837,10 @@ public final class PojoQuery { * Parses a timestamp string off the beginning of the string segment 'seg'. * Goes through each possible valid timestamp format until it finds a match. * The position where the parsing left off is stored in pp. + * * @param seg The string segment being parsed. * @param pp Where parsing last left off. - * @return An object represening a timestamp. + * @return An object representing a timestamp. */ private CalendarP parseDate(String seg, ParsePosition pp) { @@ -899,6 +904,7 @@ public final class PojoQuery { /** * Construct a string matcher for the given search pattern. + * * @param searchPattern The search pattern. See class usage for details. * @param ignoreCase If <jk>true</jk>, use case-insensitive matching. */
