View Javadoc
1   /*
2    * Redistribution and use of this software and associated documentation ("Software"), with or
3    * without modification, are permitted provided that the following conditions are met:
4    *
5    * 1. Redistributions of source code must retain copyright statements and notices. Redistributions
6    * must also contain a copy of this document.
7    *
8    * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
9    * conditions and the following disclaimer in the documentation and/or other materials provided with
10   * the distribution.
11   *
12   * 3. The name "Exolab" must not be used to endorse or promote products derived from this Software
13   * without prior written permission of Intalio, Inc. For written permission, please contact
14   * info@exolab.org.
15   *
16   * 4. Products derived from this Software may not be called "Exolab" nor may "Exolab" appear in
17   * their names without prior written permission of Intalio, Inc. Exolab is a registered trademark of
18   * Intalio, Inc.
19   *
20   * 5. Due credit should be given to the Exolab Project (http://www.exolab.org/).
21   *
22   * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR
23   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
24   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTALIO, INC. OR ITS
25   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
29   * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30   *
31   * Copyright 2002 (C) Intalio, Inc. All Rights Reserved.
32   *
33   * $Id$
34   */
35  package org.exolab.castor.xml.handlers;
36  
37  import org.exolab.castor.mapping.FieldHandler;
38  import org.exolab.castor.mapping.ValidityException;
39  import org.exolab.castor.xml.util.ContainerElement;
40  
41  /**
42   * The FieldHandler for ContainerElement.
43   *
44   * @author <a href="kvisco@intalio.com">Keith Visco</a>
45   * @version $Revision$ $Date: 2006-04-25 15:08:23 -0600 (Tue, 25 Apr 2006) $
46   * @see FieldDescriptor org.exolab.castor.mapping.FieldDescriptor
47   * @see FieldHandler org.exolab.castor.mapping.FieldHandler
48   */
49  public final class ContainerFieldHandler implements FieldHandler {
50  
51    /** Automatically choose the mode to use. */
52    public static final int MODE_AUTO = 0;
53    /** When the field is not a ContainerElement, this mode is used. */
54    public static final int MODE_PARENT_LINK = 1;
55    /** The mode for a ContainerElement. getValue and setValue operate on the parent. */
56    public static final int MODE_CHILD_LINK = 2;
57  
58    /** The actual FieldHandler to delegate to. */
59    private final FieldHandler _handler;
60    /** Mode to use for this ContainerFieldHandler. */
61    private final int _mode = MODE_AUTO;
62  
63    /**
64     * Creates a new ContainerFieldHandler with the given FieldHandler.
65     * 
66     * @param handler The field handler to delegate to.
67     */
68    public ContainerFieldHandler(final FieldHandler handler) {
69      super();
70      _handler = handler;
71    } // -- ContainerFieldHandler
72  
73    // -----------------------------/
74    // - Methods from FieldHandler -/
75    // -----------------------------/
76  
77    /**
78     * Returns the value of the field from the object. If mode is MODE_CHILD_LINK or mode is MODE_AUTO
79     * and the object is a ContainerElement, then the value of the parent is returned. Otherwise, a
80     * new ContainerElement is returned. The value of this new ContainerElement is the value of the
81     * provided object and the parent of the new ContainerElement is the provided object.
82     *
83     * @param object The object to get the value of
84     * @return The value of the field
85     * @throws IllegalStateException The Java object has changed and is no longer supported by this
86     *         handler, or the handler is not compatible with the Java object
87     */
88    public Object getValue(final Object object) throws IllegalStateException {
89      int mode = _mode;
90      if (mode == MODE_AUTO) {
91        if (object instanceof ContainerElement) {
92          mode = MODE_CHILD_LINK;
93        } else {
94          mode = MODE_PARENT_LINK;
95        }
96      }
97  
98      if (mode == MODE_CHILD_LINK) {
99        return _handler.getValue(((ContainerElement) object).getParent());
100     }
101 
102     // MODE_PARENT_LINK
103     ContainerElement container = new ContainerElement(_handler.getValue(object));
104     container.setParent(object);
105     return container;
106   } // -- getValue
107 
108   /**
109    * Creates a new instance of the object described by this field. Of the object provided is a
110    * ContainerElement, then a new isntance of the parent object is returned. Otherwise a new
111    * ContainerElement is created and returned, with the parent set to the provided object.
112    *
113    * @param parent The object for which the field is created
114    * @return A new instance of the field's value
115    * @throws IllegalStateException This field is a simple type and cannot be instantiated
116    */
117   public Object newInstance(final Object parent) throws IllegalStateException {
118     // -- MODE_CHILD_LINK and MODE_AUTO
119     if (parent instanceof ContainerElement) {
120       return _handler.newInstance(((ContainerElement) parent).getParent());
121     }
122 
123     // MODE_PARENT_LINK
124     ContainerElement container = new ContainerElement();
125     container.setParent(parent);
126     return container;
127   } // -- newInstance
128 
129   /**
130    * Sets the value of the field to a default value.
131    * <p>
132    * Reference fields are set to null, primitive fields are set to their default value, collection
133    * fields are emptied of all elements.
134    *
135    * @param object The object
136    * @throws IllegalStateException The Java object has changed and is no longer supported by this
137    *         handler, or the handler is not compatiable with the Java object
138    */
139   public void resetValue(final Object object) throws IllegalStateException {
140     _handler.resetValue(object);
141   }
142 
143   /**
144    * Sets the value of the field on the object. That is, sets the value of the container parent to
145    * the provided value.
146    *
147    * @param object The object whose value to set.
148    * @param value The new value
149    * @throws IllegalStateException The Java object has changed and is no longer supported by this
150    *         handler, or the handler is not compatiable with the Java object
151    * @throws IllegalArgumentException The value passed is not of a supported type
152    */
153   public void setValue(final Object object, final Object value)
154       throws IllegalStateException, IllegalArgumentException {
155     if (_mode == MODE_PARENT_LINK) {
156       // Do nothing for MODE_PARENT_LINK; the container is not part of the object model
157       return;
158     }
159 
160     // For MODE_AUTO and MODE_CHILD_LINK:
161     if (object instanceof ContainerElement) {
162       _handler.setValue(((ContainerElement) object).getParent(), value);
163     }
164   } // -- setValue
165 
166   /**
167    * Checks the field validity. Returns successfully if the field can be stored, is valid, etc,
168    * throws an exception otherwise.
169    *
170    * @param object The object
171    * @throws ValidityException The field is invalid, is required and null, or any other validity
172    *         violation
173    * @throws IllegalStateException The Java object has changed and is no longer supported by this
174    *         handler, or the handler is not compatiable with the Java object
175    */
176   public void checkValidity(final Object object) throws ValidityException, IllegalStateException {
177     // -- deprecated...do nothing
178   } // -- checkValidity
179 
180 } // -- ContainerFieldHandler