6.4.0 (Oct 5, 2017)

The major change in this release is the project structure.

The library now consists of the following artifacts found in the Maven group `"org.apache.juneau"`:

Category | Maven Artifacts | Description | Prereqs
--- | --- | --- | ---
Juneau Core | juneau-marshall | Serializers and parsers for: JSON XML HTML UON URL-Encoding MessagePack SOAP/XML CSV BSON (coming soon) YAML (coming soon) Protobuf (coming soon) | Java 6
juneau-marshall-rdf | Serializers and parsers for: RDF/XML RDF/XML-Abbrev N-Triple Turtle N3 | Java 6 Apache Jena 2.7.1
juneau-dto | Data Transfer Objects for: HTML5 Atom Cognos JSON-Schema Swagger 2.0 | Java 6
juneau-svl | Simple Variable Language API | Java 6
juneau-config | Configuration file API | Java 6
Juneau REST | juneau-rest-server | REST Servlet API | Java 6 Servlet 3.1
juneau-rest-server-jaxrs | Optional JAX-RS support | Java 6 JAX-RS 2.0
juneau-rest-client | REST Client API | Java 6 Apache HttpClient 4.5
Juneau Microservice | juneau-microservice-server | REST Microservice Server API | Java 8 Eclipse Jetty 9.4.3
juneau-microservice-template | Developer template project | Java 8 Eclipse Jetty 9.4.3
Examples | `juneau-examples-core` | Core code examples |
`juneau-examples-rest` | REST code examples |
Juneau All | `juneau-all` | Combination of the following: juneau-marshall juneau-dto juneau-svl juneau-config juneau-rest-server juneau-rest-client | Java 6 Servlet 3.1 Apache HttpClient 4.5

##### juneau-marshall

- Improvements to swap support.
  - New {@link oaj.annotation.Swap @Swap} annotation.
    Replaces the `@Pojo` and `@BeanProperty(swap)` annotations.
  - Support for per-media-type swaps.
    Programmatic example:

    @Swap(MyJsonOnlySwap.class) public class MyPojo {} public class MyJsonOnlySwap extends PojoSwap<MyPojo,String> { public MediaType[] forMediaTypes() { return MediaType.forStrings("*/json"); } public String swap(BeanSession session, MyPojo o) throws Exception { return "It's JSON!"; }

    Annotated example:

    @Swap(impl=ToStringSwap.class, mediaTypes="*/json") public class MyBean { ... } public class ToStringSwap extends PojoSwap<Object,String> { public String swap(BeanSession session, Object o) throws Exception { return o.toString(); } }

  - Support for templated swaps which provide additional context information for a swap.
    The following is an example of a templated swap class used to serialize POJOs to HTML using FreeMarker:

    // Our abstracted templated swap class. public abstract class FreeMarkerSwap extends PojoSwap<Object,Reader> { public MediaType[] forMediaTypes() { return MediaType.forStrings("*/html"); } public Reader swap(BeanSession session, Object o, String template) throws Exception { return getFreeMarkerReader(template, o); // Some method that creates raw HTML. } }

    @Swap(impl=FreeMarkerSwap.class, template="MyPojo.div.ftl") public class MyPojo {}

  - New {@link oaj.annotation.Swaps @Swaps} annotation for defining multiple swaps against the same POJO when they're differentiated by media types:

    @Swaps( { @Swap(MyJsonSwap.class), @Swap(MyXmlSwap.class), @Swap(MyOtherSwap.class) } ) public class MyPojo {}

- New {@link oaj.transform.Surrogate} interface for identifying surrogate classes.
- Serializers can now serialize to {@link java.util.StringBuilder StringBuilders}.
- Serializers now serialize the contents of {@link java.io.Reader Readers} and {@link java.io.InputStream InputStreams} directly to the output stream or writer.
  When used with conjunction with `PojoSwaps`, this can be used to provide customized output for specific content types.

  @Pojo(swap=MyBeanSwap.class) public class MyBean {...} public class MyBeanSwap extends PojoSwap<MyBean,Object> { public Object swap(BeanSession session, MyPojo o) throws Exception { MediaType mt = session.getMediaType(); if (mt.hasSubType("json")) return new StringReader("{foo:'bar'}"); // Custom JSON output return o; // Otherwise treat as normal bean } } // Produces "{foo:'bar'}" String json = SimpleJsonSerializer.DEFAULT .toString(new MyBean());

  This feature helps with the implementation of language-agnostic template support such as for using FreeMaker to serialize POJOs to HTML.
- {@link oaj.serializer.SerializerSession} and {@link oaj.parser.ParserSession} objects are now reusable if used within the same thread.

  // Old way (still works) JsonSerializer.DEFAULT.serialize(writer1, pojo1); JsonSerializer.DEFAULT.serialize(writer2, pojo2); // Same, but using a session object SerializerSession session = JsonSerializer.DEFAULT.createSession(); try { session.serialize(writer1, pojo1); session.serialize(writer2, pojo2); } finally { session.close(); }

  This is mostly an internal change and doesn't affect the existing APIs.
- {@link oaj.transform.PojoSwap#swap(BeanSession,Object)} and {@link oaj.transform.PojoSwap#unswap(BeanSession,Object,ClassMeta)} can now throw arbitrary exceptions instead of having to wrap them in `SerializeException`/`ParseException`.
- New {@link oaj.utils.CalendarUtils} class that encapsulates serialization/parsing logic from {@link oaj.transforms.CalendarSwap} and {@link oaj.transforms.DateSwap}.
- New annotation {@link oaj.html.annotation.Html#anchorText}.
- New methods on {@link oaj.ObjectList}:
  - {@link oaj.ObjectList#get(int,Class) get(int,Class)}
  - {@link oaj.ObjectList#get(int,Type,Type...) get(int,Type,Type...)}
  - {@link oaj.ObjectList#getMap(int,Class,Class) getMap(int,Class,Class)}
  - {@link oaj.ObjectList#getList(int,Class) getList(int,Class)}
- New methods on {@link oaj.ObjectMap}:
  - {@link oaj.ObjectMap#get(String,Class) get(String,Class)}
  - {@link oaj.ObjectMap#get(String,Type,Type...) get(String,Type,Type...)}
  - {@link oaj.ObjectMap#getWithDefault(String,Object) getWithDefault(String,Object)}
  - {@link oaj.ObjectMap#getWithDefault(String,Object,Class) getWithDefault(String,Object,Class)}
  - {@link oaj.ObjectMap#getWithDefault(String,Object,Type,Type...) getWithDefault(String,Object,Type,Type...)}
  - {@link oaj.ObjectMap#getSwapped(String,PojoSwap) getSwapped(String,PojoSwap)}
  - {@link oaj.ObjectMap#getAt(String,Class) getAt(String,Class)}
  - {@link oaj.ObjectMap#getAt(String,Type,Type...) getAt(String,Type,Type...)}
  - {@link oaj.ObjectMap#getMap(String,Class,Class,Map) getMap(String,Class,Class,Map)}
  - {@link oaj.ObjectMap#getList(String,Class,List) getList(String,Class,List)}
- New methods on {@link oaj.utils.PojoRest}:
  - {@link oaj.utils.PojoRest#get(String,Class) get(String,Class)}
  - {@link oaj.utils.PojoRest#get(String,Type,Type...) get(String,Type,Type...)}
  - {@link oaj.utils.PojoRest#getWithDefault(String,Object) getWithDefault(String,Object)}
  - {@link oaj.utils.PojoRest#getWithDefault(String,Object,Class) getWithDefault(String,Object,Class)}
  - {@link oaj.utils.PojoRest#getWithDefault(String,Object,Type,Type...) getWithDefault(String,Object,Type,Type...)}
- Fixed bug where {@link oaj.BeanSession#getMediaType()} wasn't returning a value.
- Eliminated the @Consumes and @Produces annotations.
  The supported media types are now passed in through the constructors.
  This was changed to eliminate a performance issue where a field could not be set as final because the call to `getClass()` to retrieve the annotation value could not be called before calling the `super()` method.
- New class: {@link oaj.utils.PojoMerge}
- New doc: 2.6.2 - @Pojo annotation
- New doc: 2.6.5 - Serializing Readers and InputStreams

##### juneau-dto

- {@link oaj.dto.html5.HtmlElementMixed#children(Object...)} can now take in collections of objects.
- The DTO beans can now be serialized to strings of their typical language by calling the `toString()` method.
  For example, `Swagger.toString()` produces JSON and the HTML5 `Form.toString()` produces HTML.

##### juneau-rest-server

- Revamped and simplified servlet and REST-call lifecycle handling through new {@link oajr.annotation.RestHook @RestHook} annotation.
  - The {@link oajr.RestServlet#init(ServletConfig)} method is now final and can no longer be extended.
    Instead, use {@link oajr.annotation.HookEvent#INIT} or {@link oajr.annotation.HookEvent#POST_INIT} for initialization.
  - The following methods on {@link oajr.RestServlet} have been removed:
    - `init(RestConfig)` - Use {@link oajr.annotation.HookEvent#INIT} instead.
    - `onSuccess(RestRequest, RestResponse, long)` - Use {@link oajr.annotation.HookEvent#END_CALL} instead.
    - `onPreCall(RestRequest)` - Use {@link oajr.annotation.HookEvent#PRE_CALL} instead.
    - `onPostCall(RestRequest, RestResponse)` - Use {@link oajr.annotation.HookEvent#POST_CALL} instead.
- Simplified {@link oajr.widget.MenuItemWidget}.
  Exposes an abstract method {@link oajr.widget.MenuItemWidget#getContent(RestRequest)} that can return raw HTML via readers or char-sequences, or any other object (such as HTML5 beans) that will get converted to HTML using {@link oaj.html.HtmlSerializer#DEFAULT}.
- {@link oajr.RestResourceResolver} instances are now inherited from parent resources to child resources unless explicitly overridden at the child level.
  It's also been changed to an interface.
- New annotations on {@link oajr.annotation.RestResource @RestResource}:
  - {@link oajr.annotation.RestResource#resourceResolver() resourceResolver()}
    Allows you to specify a resource resolver on the servlet context to make it easier to work with dependency injection frameworks.
  - `RestResource.contextPath()` -
    Allows you to override the context path value inherited from the servlet container.
  - {@link oajr.annotation.RestResource#allowHeaderParams() allowHeaderParams()} -
    Replaces the `RestContext.REST_allowHeaderParams` setting.
  - `RestResource.allowMethodParam()` -
    Replaces the `RestContext.REST_allowMethodParam` setting.
  - {@link oajr.annotation.RestResource#allowBodyParam() allowBodyParam()} -
    Replaces the `RestContext.REST_allowBodyParam` setting.
  - {@link oajr.annotation.RestResource#renderResponseStackTraces() renderResponseStackTraces()} -
    Replaces the `RestContext.REST_xxx` setting.
  - {@link oajr.annotation.RestResource#useStackTraceHashes() useStackTraceHashes()} -
    Replaces the `RestContext.REST_useStackTraceHashes` setting.
  - {@link oajr.annotation.RestResource#defaultCharset() defaultCharset()} -
    Replaces the `RestContext.REST_defaultCharset` setting.
  - `RestResource.paramFormat()` -
    Replaces the `RestContext.REST_paramFormat` setting.
- New annotations on {@link oajr.annotation.RestMethod @RestMethod}:
  - {@link oajr.annotation.RestMethod#defaultCharset() defaultCharset()} -
    Replaces the `RestContext.REST_defaultCharset` setting.
  - `RestMethod.paramFormat()` -
    Replaces the `RestContext.REST_paramFormat` setting.
- The following implementation classes can now be defined as non-static inner classes of servlets/resources:
  - {@link oajr.widget.Widget}
  - {@link oajr.RestConverter}
  - {@link oajr.RestGuard}
  - {@link oajr.ResponseHandler}
  - {@link oajr.RestCallHandler}
  - {@link oajr.RestInfoProvider}
  - {@link oajr.RestResourceResolver}
  - {@link oajr.RestLogger}
  - {@link oaj.html.HtmlDocTemplate}
- New tooltip template: {@link oajr.widget.Tooltip}
- New dark theme:
- Stylesheet selection now stored in HTTP session when passed in via `?stylesheet` query parameter.
- New doc: Lifecycle Hooks
- Eliminated the `RestServletJenaDefault` class to remove the Jena dependency class on the `juneau-rest-server` artifact.
  It's simple enough to simply extend `BasicRestServlet` and add the RDF serializers and parsers.

##### juneau-microservice

- The microservice has been significantly modified to be configured via a `jetty.xml` file for maximum flexibility instead of the hodge-podge of support in the config file.
  Top-level servlets should now be defined in the provided `jetty.xml` file.
- New methods on {@link oaj.microservice.RestMicroservice}:
  - {@link oaj.microservice.RestMicroservice#addServlet(Servlet,String) addServlet(Servlet,String)}
  - {@link oaj.microservice.RestMicroservice#addServletAttribute(String,Object) addServletAttribute(String,Object)}
  - {@link oaj.microservice.RestMicroservice#getServer() getServer()}
  - {@link oaj.microservice.RestMicroservice#getInstance() getInstance()}
  - {@link oaj.microservice.RestMicroservice#getPort() getPort()}
  - {@link oaj.microservice.RestMicroservice#getContextPath() getContextPath()}
  - {@link oaj.microservice.RestMicroservice#getProtocol() getProtocol()}
  - {@link oaj.microservice.RestMicroservice#getHostName() getHostName()}
- New methods on {@link oaj.microservice.Microservice}:
  - {@link oaj.microservice.Microservice#getInstance() getInstance()}
- New class {@link oaj.microservice.JettyLogger} for directing Jetty logging to the java.util.logging framework.
- New class {@link oaj.microservice.resources.DebugResource} for viewing and generating Jetty thread dumps through REST calls.

##### org.apache.juneau.rest.examples

- New example of adding a menu-item widget to the Pet Store resource (including tooltips):