001: /*
002: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.xml.internal.bind.v2.runtime;
027:
028: import java.io.IOException;
029: import java.lang.reflect.Array;
030: import java.util.ArrayList;
031: import java.util.Collection;
032: import java.util.Collections;
033: import java.util.List;
034:
035: import javax.xml.bind.ValidationEvent;
036: import javax.xml.bind.helpers.ValidationEventImpl;
037: import javax.xml.namespace.QName;
038: import javax.xml.stream.XMLStreamException;
039:
040: import com.sun.xml.internal.bind.v2.model.runtime.RuntimeArrayInfo;
041: import com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader;
042: import com.sun.xml.internal.bind.v2.runtime.unmarshaller.Receiver;
043: import com.sun.xml.internal.bind.v2.runtime.unmarshaller.TagName;
044: import com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext;
045:
046: import org.xml.sax.SAXException;
047:
048: /**
049: * {@link JaxBeanInfo} implementation that binds T[] to a complex type
050: * with an element for each item.
051: *
052: * @author Kohsuke Kawaguchi
053: */
054: final class ArrayBeanInfoImpl extends JaxBeanInfo {
055:
056: private final Class itemType;
057: private final JaxBeanInfo itemBeanInfo;
058: private final Loader loader;
059:
060: public ArrayBeanInfoImpl(JAXBContextImpl owner, RuntimeArrayInfo rai) {
061: super (owner, rai, rai.getType(), rai.getTypeName(), false,
062: true, false);
063: this .itemType = jaxbType.getComponentType();
064: this .itemBeanInfo = owner.getOrCreate(rai.getItemType());
065:
066: loader = new ArrayLoader(owner);
067: }
068:
069: private final class ArrayLoader extends Loader implements Receiver {
070: public ArrayLoader(JAXBContextImpl owner) {
071: super (false);
072: itemLoader = itemBeanInfo.getLoader(owner, true);
073: }
074:
075: private final Loader itemLoader;
076:
077: @Override
078: public void startElement(UnmarshallingContext.State state,
079: TagName ea) {
080: state.target = new ArrayList();
081: }
082:
083: @Override
084: public void leaveElement(UnmarshallingContext.State state,
085: TagName ea) {
086: state.target = toArray((List) state.target);
087: }
088:
089: @Override
090: public void childElement(UnmarshallingContext.State state,
091: TagName ea) throws SAXException {
092: if (ea.matches("", "item")) {
093: state.loader = itemLoader;
094: state.receiver = this ;
095: } else {
096: super .childElement(state, ea);
097: }
098: }
099:
100: @Override
101: public Collection<QName> getExpectedChildElements() {
102: return Collections.singleton(new QName("", "item"));
103: }
104:
105: public void receive(UnmarshallingContext.State state, Object o) {
106: ((List) state.target).add(o);
107: }
108: };
109:
110: protected Object toArray(List list) {
111: int len = list.size();
112: Object array = Array.newInstance(itemType, len);
113: for (int i = 0; i < len; i++)
114: Array.set(array, i, list.get(i));
115: return array;
116: }
117:
118: public void serializeBody(Object array, XMLSerializer target)
119: throws SAXException, IOException, XMLStreamException {
120: int len = Array.getLength(array);
121: for (int i = 0; i < len; i++) {
122: Object item = Array.get(array, i);
123: // TODO: check the namespace URI.
124: target.startElement("", "item", null, null);
125: if (item == null) {
126: target.writeXsiNilTrue();
127: } else {
128: target.childAsXsiType(item, "arrayItem", itemBeanInfo);
129: }
130: target.endElement();
131: }
132: }
133:
134: public final String getElementNamespaceURI(Object array) {
135: throw new UnsupportedOperationException();
136: }
137:
138: public final String getElementLocalName(Object array) {
139: throw new UnsupportedOperationException();
140: }
141:
142: public final Object createInstance(UnmarshallingContext context) {
143: // we first create a List and then later convert it to an array
144: return new ArrayList();
145: }
146:
147: public final boolean reset(Object array,
148: UnmarshallingContext context) {
149: return false;
150: }
151:
152: public final String getId(Object array, XMLSerializer target) {
153: return null;
154: }
155:
156: public final void serializeAttributes(Object array,
157: XMLSerializer target) {
158: // noop
159: }
160:
161: public final void serializeRoot(Object array, XMLSerializer target)
162: throws SAXException, IOException, XMLStreamException {
163: target.reportError(new ValidationEventImpl(
164: ValidationEvent.ERROR,
165: Messages.UNABLE_TO_MARSHAL_NON_ELEMENT.format(array
166: .getClass().getName()), null, null));
167: }
168:
169: public final void serializeURIs(Object array, XMLSerializer target) {
170: // noop
171: }
172:
173: public final Transducer getTransducer() {
174: return null;
175: }
176:
177: public final Loader getLoader(JAXBContextImpl context,
178: boolean typeSubstitutionCapable) {
179: // type substitution not possible
180: return loader;
181: }
182: }
|