[[jaxb]]
= JAXB View Models

:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR  CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
:page-partial:


The most powerful way to implement a view model (at the expense of some boilerplate) is to use JAXB view models.
These can serialize both properties (value types and references to entities) and collections (references to entities).

Here's a typical example of a JAXB view model, to allow (certain properties of) two ``Customer``s to be compared:

[source,java]
.CompareCustomers.java, using JAXB
----
@XmlRootElement(name = "compareCustomers")          // <.>
@XmlType(
        propOrder = {                               // <.>
            "customer1",
            "customer2"
        }
)
@XmlAccessorType(XmlAccessType.FIELD)               // <.>
public class CompareCustomers {

    @XmlElement(required = true)                    // <.>
    @Getter @Setter
    Customer customer1;

    @XmlElement(required = true)                    // <.>
    @Getter @Setter
    Customer customer2;

    @XmlTransient                                   // <.>
    public String getCustomer1Name() {
        return getCustomer1().getName();
    }

    @XmlTransient                                   // <.>
    public String getCustomer2Name() {
        return getCustomer2().getName();
    }

    ...
}
----

<.> The JAXB xref:refguide:applib-ant:XmlRootElement.adoc[@XmlRootElement] annotation indicates this is a view model to Apache Causeway, which then uses JAXB to serialize the state of the view model between interactions
<.> Optionally, the properties of the view model can be listed using the `XmlType#propOrder` attribute. +
This is an all-or-nothing affair: either all properties must be listed, or else the annotation omitted.
<.> Specifying field accessor type allows the Lombok `@Getter` and `@Setter` annotations to be used.
<.> The `@XmlElement` indicates the property is part of the view model's state.
For collections, the `@XmlElementWrapper` would also typically be used.
<.> The `@XmlTransient` indicates that the property is derived and should be ignored by JAXB. +
The derived properties could also have been implemented using xref:userguide:ROOT:mixins.adoc[mixins].



[#referencing-domain-entities]
== Referencing Domain Entities

It's quite common for view models to be "backed by" (be projections of) some underlying domain entity.
For example, the `CompareCustomers` view model described xref:userguide:ROOT:view-models.adoc#jaxb[above] actually references two underlying ``Customer`` entities.

It wouldn't make sense to serialize out the state of a persistent entity.
However, the identity of the underlying entity is well defined; Apache Causeway defines the xref:refguide:schema:common.adoc[common schema] which defines the `<oid-dto>` element (and corresponding `OidDto` class): the object's type and its identifier.
This is basically a formal XML equivalent to the `Bookmark` object obtained from the xref:refguide:applib:index/services/bookmark/BookmarkService.adoc[BookmarkService].

There is only one requirement to make this work: every referenced domain entity must be annotated with xref:refguide:applib-ant:XmlJavaTypeAdapter.adoc[@XmlJavaTypeAdapter], specifying the framework-provided `PersistentEntityAdapter`.
And this class is similar to the xref:refguide:applib:index/services/bookmark/BookmarkService.adoc[BookmarkService]: it knows how to create an `OidDto` from an object reference.

Thus, in our view model we can legitimately write:

[source,java]
----
public class CompareCustomers {

    @XmlElement(required = true)
    @Getter @Setter
    Customer customer1;
    ...
}
----

All we need to do is remember to add that `@XmlJavaTypeAdapter` annotation to the referenced entity:

[source,java]
----
@XmlJavaTypeAdapter(PersistentEntityAdapter.class)
public class Customer ...  {
    ...
}
----

It's also possible for a DTO view models to hold collections of objects.
These can be of any type, either simple properties, or references to other objects.
The only bit of boilerplate that is required is the `@XmlElementWrapper` annotation.
This instructs JAXB to create an XML element (based on the field name) to contain each of the elements.
(If this is omitted then the contents of the collection are at the same level as the properties; almost certainly not what is required).

For example, we could perhaps generalize the view model to hold a set of ``Customer``s to be compared:

[source,java]
----
public class CompareCustomers {
    ...
    @XmlElementWrapper
    @XmlElement(name = "customers")
    @Getter @Setter
    protected List<Customer> customersToCompare = Lists.newArrayList();
}
----


[[joda-datatypes]]
== JODA Time Datatypes

If your JAXB view model contains fields using the JODA datatypes (`LocalDate` and so on), then `@XmlJavaTypeAdapter` additional annotations in order to "teach" JAXB how to serialize out the state.

The Apache Causeway applib provides a number of adapters to use out-of-the-box.
For example:

[source,java]
----
@XmlRootElement(name = "categorizeIncomingInvoice")
@XmlType(
        propOrder = {
                ...
                "dateReceived",
                ...
        }
)
@XmlAccessorType(XmlAccessType.FIELD)
public class IncomingInvoiceViewModel extends IncomingOrderAndInvoiceViewModel {

    @XmlJavaTypeAdapter(JodaLocalDateStringAdapter.ForJaxb.class)
    private LocalDate dateReceived;

    ...
}
----

The full list of adapter classes are:

.JAXB adapters
[cols="1a,2a",options="header"]
|===

| JODA datatype
| Adapter

.2+| `org.joda.time.DateTime`
| `JodaDateTimeStringAdapter.ForJaxb`
| `JodaDateTimeXMLGregorianCalendarAdapter.ForJaxb`

.2+| `org.joda.time.LocalDate`
| `JodaLocalDateStringAdapter.ForJaxb`
| `JodaLocalDateXMLGregorianCalendarAdapter.ForJaxb`

.2+| `org.joda.time.LocalDateTime`
| `JodaLocalDateTimeStringAdapter.ForJaxb`
| `JodaLocalDateTimeXMLGregorianCalendarAdapter.ForJaxb`


.2+| `org.joda.time.LocalTime`
| `JodaLocalTimeStringAdapter.ForJaxb`
| `JodaLocalTimeXMLGregorianCalendarAdapter.ForJaxb`

| `java.sql.Timestamp`
| `JavaSqlTimestampXmlGregorianCalendarAdapter.ForJaxb`


|===

[TIP]
====
If you want use other Joda data types, check out link:http://blog.bdoughan.com/2011/05/jaxb-and-joda-time-dates-and-times.html[this blog post].
====



