<?xml version="1.0" encoding="UTF-8"?>
<!--

DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.

Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.

The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
and Distribution License("CDDL") (collectively, the "License").  You
may not use this file except in compliance with the License.  You can
obtain a copy of the License at
http://glassfish.java.net/public/CDDL+GPL_1_1.html
or packager/legal/LICENSE.txt.  See the License for the specific
language governing permissions and limitations under the License.

When distributing the software, include this License Header Notice in each
file and include the License file at packager/legal/LICENSE.txt.

GPL Classpath Exception:
Oracle designates this particular file as subject to the "Classpath"
exception as provided by Oracle in the GPL Version 2 section of the License
file that accompanied this code.

Modifications:
If applicable, add the following below the License Header, with the fields
enclosed by brackets [] replaced by your own identifying information:
"Portions Copyright [year] [name of copyright owner]"

Contributor(s):
If you wish your version of this file to be governed by only the CDDL or
only the GPL Version 2, indicate your decision by adding "[Contributor]
elects to include this software in this distribution under the [CDDL or GPL
Version 2] license."  If you don't indicate a single choice of license, a
recipient has the option to distribute your version of this file under
either the CDDL, the GPL Version 2 or to extend the choice of license to
its licensees as provided above.  However, if you add GPL Version 2 code
and therefore, elected the GPL Version 2 license, then the option applies
only if the new code is made subject to such option by the copyright
holder.

        -->
<!DOCTYPE book [
<!ENTITY % ents SYSTEM "docbook.ent">
%ents;
]>
<section version="5.0"
         xml:id="annotating-your-classes-mapping-cyclic-references-to-xml"
         xml:lang="en" xmlns="http://docbook.org/ns/docbook"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xmlns:ns5="http://www.w3.org/1999/xhtml"
         xmlns:ns3="http://www.w3.org/2000/svg"
         xmlns:ns="http://docbook.org/ns/docbook"
         xmlns:m="http://www.w3.org/1998/Math/MathML">
    <title>Mapping cyclic references to XML</title>

    <para>Object models designed in Java often have cycles, which prevent
    straight-forward conversion to XML by JAXB. In fact, when you try to
    marshal an object tree that contains a cycle, the JAXB marshaller reports
    an error, pointing out the objects that formed the cycle. This is because
    JAXB by itself cannot figure out how to cut cycles into a tree.</para>

    <para>Thus it is your responsibility to annotate classes and use other
    means to "tell" JAXB how to handle a cycle. This chapter talks about
    various techniques to do this.</para>

    <section xml:id="Parent_pointers">
        <title>Parent pointers</title>

        <para>One of the very common forms of cycle is a parent pointer. The
        following example illustrates a typical parent pointer, and how this
        can be turned into "natural" XML:</para>

        <example>
            <title>Classes with parent pointer</title>

            <programlisting language="java"><![CDATA[@XmlRootElement
class Department {
  @XmlAttribute
  String name;
  @XmlElement(name="employee")
  List<Employee> employees;
}

class Employee {
  @XmlTransient
  Department department;  // parent pointer
  @XmlAttribute
  String name;

  public void afterUnmarshal(Unmarshaller u, Object parent) {
    this.department = (Department)parent;
  }
}]]></programlisting>
        </example>

        <para>This will produce the following XML:</para>

        <example>
            <title>XML view of department</title>

            <programlisting language="xml"><![CDATA[<department name="accounting">
  <employee name="Joe Chin" />
  <employee name="Adam Smith" />
  ...
</department>]]></programlisting>
        </example>

        <para>And reading this document back into Java objects will produce
        the expected tree with all the proper parent pointers set up
        correctly.</para>

        <para>The first technique here is the use of <link
        xlink:href="https://jaxb.dev.java.net/nonav/jaxb20-fcs/docs/api/index.html?javax/xml/bind/annotation//3.5.1XmlTransient.html"><literal>XmlTransient</literal></link> on the parent pointer. This tells
        JAXB that you don't need this parent pointer to be represented
        explicitly in XML, because the fact that <literal>employee</literal> is
        always contained inside <literal>department</literal> implies the
        parent/child relationship. This causes the marshaller to produce the
        expected XML. However, when you unmarshal it, since this field is not
        bound, the <literal>Employee.department</literal> field will be left
        null.</para>

        <para>That's where the second technique comes in, which is the use of
        the <literal>afterUnmarshal</literal> callback. This method is invoked by
        the JAXB implementation on each instance when the unmarshalling of a
        <literal>Employee</literal> object completes. Furthermore, the second
        parameter to the method is the parent object, which in this case is a
        <literal>Department</literal> object. So in this example, this sets up the
        parent pointer correctly.</para>

        <para>This callback can be also used to perform other
        post-unmarshalling set up work.</para>
    </section>

    <section xml:id="Many_to_many_relationship">
        <title>Many-to-many relationship</title>

        <para>TBD</para>
    </section>

    <section xml:id="_XmlID_and__XmlIDREF">
        <title><literal>@XmlID</literal> and
        <literal>@XmlIDREF</literal></title>

        <para>When a reference to another object is annotated with <link
        xlink:href="https://jaxb.dev.java.net/nonav/jaxb20-fcs/docs/api/index.html?javax/xml/bind/annotation//3.5.3XmlIDREF.html"><literal>XmlIDREF</literal></link> , its corresponding XML it will be
        referenced by <literal>xs:IDREF</literal>, instead of containment. See below
        for an example:</para>

        <para>Example of <literal>@XmlID</literal> and
        <literal>@XmlIDREF</literal></para>

        <informalexample>
            <programlisting language="java"><![CDATA[@XmlRootElement
class Root {
  List<Foo> foos;
  List<Bar> bars;
}
class Foo {
  // you don't have to make it an attribute, but that's more common
  @XmlAttribute @XmlIDREF Bar bar;
}
class Bar {
  // you don't have to make it an attribute, but that's more common
  @XmlAttribute @XmlID String id;
}]]></programlisting>
        </informalexample>

        <example>
            <title>Schema for above</title>

            <programlisting language="xml"><![CDATA[<xs:complexType name="foo">
  <xs:sequence/>
  <xs:attribute name="bar" type="xs:IDREF"/>
  </xs:sequence>
</xs:complexType>
<xs:complexType name="bar">
  <xs:sequence/>
  <xs:attribute name="id" type="xs:ID"/>
</xs:complexType>]]></programlisting>
        </example>

        <example>
            <title>A sample instance</title>

            <programlisting language="xml"><![CDATA[<root>
  <foo bar="x"/>
  <foo bar="y"/>
  <bar id="x"/>
  <bar id="y"/>
</root>]]></programlisting>
        </example>

        <para>There are a few things to consider when you do this. First, the
        object to be referenced must have an ID that is unique within the
        whole document. You'd also need to ensure that the referenced objects
        are <emphasis>contained</emphasis> somewhere else (like in the
        <literal>Root</literal> class in this case), or else <literal>Bar</literal>
        objects will never be marshalled. This technique can be used to remove
        the cyclic references, but it's only possible when your object model
        has an easy cut point.</para>
    </section>

    <section xml:id="Use_the_CycleRecoverable_interface">
        <title>Use the CycleRecoverable interface</title>

        <para>Starting 2.1 EA2, the JAXB RI exposes <link
        xlink:href="http://fisheye5.cenqua.com/browse/jaxb2-sources/jaxb-ri/runtime/src/com/sun/xml/bind/CycleRecoverable.java?r=jaxb-2_1-branch"><literal>CycleRecoverable</literal></link> interface. Applications can
        choose to implement this interface in some of its objects. When a
        cyclic reference is detected during marshalling, and if the object
        that formed a cycle implements this interface, then the method on this
        interface is called to allow an application to nominate its
        replacement to be written to XML. In this way, the application can
        recover from a cycle gracefully.</para>

        <para>See <link
        xlink:href="http://forums.java.net/jive/thread.jspa?threadID=13670&amp;start=15#158545">a
        posting from <literal>gadams00</literal></link> for a complete illustration
        of this feature.</para>

        <para>This technique allows you to cope with a situation where you
        cannot easily determine upfront as to where a cycle might happen. On
        the other hand, this feature is a JAXB RI feature. Another downside of
        this is that unless you nominate your replacement carefully, you can
        make the marshalling output invalid with respect to the schema, and
        thus you might hit another problem when you try to read it back
        later.</para>
    </section>
</section>
