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.List;
031:
032: import javax.xml.bind.JAXBException;
033: import javax.xml.bind.ValidationEvent;
034: import javax.xml.bind.helpers.ValidationEventImpl;
035: import javax.xml.stream.XMLStreamException;
036:
037: import com.sun.istack.internal.FinalArrayList;
038: import com.sun.xml.internal.bind.WhiteSpaceProcessor;
039: import com.sun.xml.internal.bind.api.AccessorException;
040: import com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader;
041: import com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext;
042:
043: import org.xml.sax.SAXException;
044:
045: /**
046: * {@link JaxBeanInfo} implementation that binds T[] to a list of simple types.
047: *
048: * @author Kohsuke Kawaguchi
049: */
050: final class ValueListBeanInfoImpl extends JaxBeanInfo {
051:
052: private final Class itemType;
053: private final Transducer xducer; // for items
054:
055: public ValueListBeanInfoImpl(JAXBContextImpl owner, Class arrayType)
056: throws JAXBException {
057: super (owner, null, arrayType, false, true, false);
058: this .itemType = jaxbType.getComponentType();
059: this .xducer = owner.getBeanInfo(arrayType.getComponentType(),
060: true).getTransducer();
061: assert xducer != null;
062: }
063:
064: private final Loader loader = new Loader(true) {
065: @Override
066: public void text(UnmarshallingContext.State state,
067: CharSequence text) throws SAXException {
068: List<Object> r = new FinalArrayList<Object>();
069:
070: int idx = 0;
071: int len = text.length();
072:
073: while (true) {
074: int p = idx;
075: while (p < len
076: && !WhiteSpaceProcessor.isWhiteSpace(text
077: .charAt(p)))
078: p++;
079:
080: CharSequence token = text.subSequence(idx, p);
081: if (!token.equals(""))
082: try {
083: r.add(xducer.parse(token));
084: } catch (AccessorException e) {
085: handleGenericException(e, true);
086: continue; // move on to next
087: }
088:
089: if (p == len)
090: break; // done
091:
092: while (p < len
093: && WhiteSpaceProcessor.isWhiteSpace(text
094: .charAt(p)))
095: p++;
096: if (p == len)
097: break; // done
098:
099: idx = p;
100: }
101:
102: state.target = toArray(r);
103: }
104: };
105:
106: private Object toArray(List list) {
107: int len = list.size();
108: Object array = Array.newInstance(itemType, len);
109: for (int i = 0; i < len; i++)
110: Array.set(array, i, list.get(i));
111: return array;
112: }
113:
114: public void serializeBody(Object array, XMLSerializer target)
115: throws SAXException, IOException, XMLStreamException {
116: int len = Array.getLength(array);
117: for (int i = 0; i < len; i++) {
118: Object item = Array.get(array, i);
119: try {
120: xducer.writeText(target, item, "arrayItem");
121: } catch (AccessorException e) {
122: target.reportError("arrayItem", e);
123: }
124: }
125: }
126:
127: public final void serializeURIs(Object array, XMLSerializer target)
128: throws SAXException {
129: if (xducer.useNamespace()) {
130: int len = Array.getLength(array);
131: for (int i = 0; i < len; i++) {
132: Object item = Array.get(array, i);
133: try {
134: xducer.declareNamespace(item, target);
135: } catch (AccessorException e) {
136: target.reportError("arrayItem", e);
137: }
138: }
139: }
140: }
141:
142: public final String getElementNamespaceURI(Object array) {
143: throw new UnsupportedOperationException();
144: }
145:
146: public final String getElementLocalName(Object array) {
147: throw new UnsupportedOperationException();
148: }
149:
150: public final Object createInstance(UnmarshallingContext context) {
151: throw new UnsupportedOperationException();
152: }
153:
154: public final boolean reset(Object array,
155: UnmarshallingContext context) {
156: return false;
157: }
158:
159: public final String getId(Object array, XMLSerializer target) {
160: return null;
161: }
162:
163: public final void serializeAttributes(Object array,
164: XMLSerializer target) {
165: // noop
166: }
167:
168: public final void serializeRoot(Object array, XMLSerializer target)
169: throws SAXException {
170: target.reportError(new ValidationEventImpl(
171: ValidationEvent.ERROR,
172: Messages.UNABLE_TO_MARSHAL_NON_ELEMENT.format(array
173: .getClass().getName()), null, null));
174: }
175:
176: public final Transducer getTransducer() {
177: return null;
178: }
179:
180: public final Loader getLoader(JAXBContextImpl context,
181: boolean typeSubstitutionCapable) {
182: // type substitution impossible
183: return loader;
184: }
185: }
|