001: /*
002: * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
003: * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
004: */
005:
006: package javax.xml.bind;
007:
008: import javax.xml.namespace.QName;
009: import java.io.Serializable;
010:
011: /**
012: * <p>JAXB representation of an Xml Element.</p>
013: *
014: * <p>This class represents information about an Xml Element from both the element
015: * declaration within a schema and the element instance value within an xml document
016: * with the following properties
017: * <ul>
018: * <li>element's xml tag <b><tt>name</tt></b></li>
019: * <li><b><tt>value</tt></b> represents the element instance's atttribute(s) and content model</li>
020: * <li>element declaration's <b><tt>declaredType</tt></b> (<tt>xs:element @type</tt> attribute)</li>
021: * <li><b><tt>scope</tt></b> of element declaration</li>
022: * <li>boolean <b><tt>nil</tt></b> property. (element instance's <tt><b>xsi:nil</b></tt> attribute)</li>
023: * </ul>
024: *
025: * <p>The <tt>declaredType</tt> and <tt>scope</tt> property are the
026: * JAXB class binding for the xml type definition.
027: * </p>
028: *
029: * <p><b><tt>Scope</tt></b> is either {@link GlobalScope} or the Java class representing the
030: * complex type definition containing the schema element declaration.
031: * </p>
032: *
033: * <p>There is a property constraint that if <b><tt>value</tt></b> is <tt>null</tt>,
034: * then <tt>nil</tt> must be <tt>true</tt>. The converse is not true to enable
035: * representing a nil element with attribute(s). If <tt>nil</tt> is true, it is possible
036: * that <tt>value</tt> is non-null so it can hold the value of the attributes
037: * associated with a nil element.
038: * </p>
039: *
040: * @author Kohsuke Kawaguchi, Joe Fialli
041: * @since JAXB 2.0
042: */
043:
044: public class JAXBElement<T> implements Serializable {
045:
046: /** xml element tag name */
047: final protected QName name;
048:
049: /** Java datatype binding for xml element declaration's type. */
050: final protected Class<T> declaredType;
051:
052: /** Scope of xml element declaration representing this xml element instance.
053: * Can be one of the following values:
054: * - {@link GlobalScope} for global xml element declaration.
055: * - local element declaration has a scope set to the Java class
056: * representation of complex type defintion containing
057: * xml element declaration.
058: */
059: final protected Class scope;
060:
061: /** xml element value.
062: Represents content model and attributes of an xml element instance. */
063: protected T value;
064:
065: /** true iff the xml element instance has xsi:nil="true". */
066: protected boolean nil = false;
067:
068: /**
069: * Designates global scope for an xml element.
070: */
071: public static final class GlobalScope {
072: }
073:
074: /**
075: * <p>Construct an xml element instance.</p>
076: *
077: * @param name Java binding of xml element tag name
078: * @param declaredType Java binding of xml element declaration's type
079: * @param scope
080: * Java binding of scope of xml element declaration.
081: * Passing null is the same as passing <tt>GlobalScope.class</tt>
082: * @param value
083: * Java instance representing xml element's value.
084: * @see #getScope()
085: * @see #isTypeSubstituted()
086: */
087: public JAXBElement(QName name, Class<T> declaredType, Class scope,
088: T value) {
089: if (declaredType == null || name == null)
090: throw new IllegalArgumentException();
091: this .declaredType = declaredType;
092: if (scope == null)
093: scope = GlobalScope.class;
094: this .scope = scope;
095: this .name = name;
096: setValue(value);
097: }
098:
099: /**
100: * Construct an xml element instance.
101: *
102: * This is just a convenience method for <tt>new JAXBElement(name,declaredType,GlobalScope.class,value)</tt>
103: */
104: public JAXBElement(QName name, Class<T> declaredType, T value) {
105: this (name, declaredType, GlobalScope.class, value);
106: }
107:
108: /**
109: * Returns the Java binding of the xml element declaration's type attribute.
110: */
111: public Class<T> getDeclaredType() {
112: return declaredType;
113: }
114:
115: /**
116: * Returns the xml element tag name.
117: */
118: public QName getName() {
119: return name;
120: }
121:
122: /**
123: * <p>Set the content model and attributes of this xml element.</p>
124: *
125: * <p>When this property is set to <tt>null</tt>, <tt>isNil()</tt> must by <tt>true</tt>.
126: * Details of constraint are described at {@link #isNil()}.</pp>
127: *
128: * @see #isTypeSubstituted()
129: */
130: public void setValue(T t) {
131: this .value = t;
132: }
133:
134: /**
135: * <p>Return the content model and attribute values for this element.</p>
136: *
137: * <p>See {@link #isNil()} for a description of a property constraint when
138: * this value is <tt>null</tt></p>
139: */
140: public T getValue() {
141: return value;
142: }
143:
144: /**
145: * Returns scope of xml element declaration.
146: *
147: * @see #isGlobalScope()
148: * @return <tt>GlobalScope.class</tt> if this element is of global scope.
149: */
150: public Class getScope() {
151: return scope;
152: }
153:
154: /**
155: * <p>Returns <tt>true</tt> iff this element instance content model
156: * is nil.</p>
157: *
158: * <p>This property always returns <tt>true</tt> when {@link #getValue()} is null.
159: * Note that the converse is not true, when this property is <tt>true</tt>,
160: * {@link #getValue()} can contain a non-null value for attribute(s). It is
161: * valid for a nil xml element to have attribute(s).</p>
162: */
163: public boolean isNil() {
164: return (value == null) || nil;
165: }
166:
167: /**
168: * <p>Set whether this element has nil content.</p>
169: *
170: * @see #isNil()
171: */
172: public void setNil(boolean value) {
173: this .nil = value;
174: }
175:
176: /* Convenience methods
177: * (Not necessary but they do unambiguously conceptualize
178: * the rationale behind this class' fields.)
179: */
180:
181: /**
182: * Returns true iff this xml element declaration is global.
183: */
184: public boolean isGlobalScope() {
185: return this .scope == GlobalScope.class;
186: }
187:
188: /**
189: * Returns true iff this xml element instance's value has a different
190: * type than xml element declaration's declared type.
191: */
192: public boolean isTypeSubstituted() {
193: if (value == null)
194: return false;
195: return value.getClass() != declaredType;
196: }
197:
198: private static final long serialVersionUID = 1L;
199: }
|