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.reflect;
027:
028: import javax.xml.bind.JAXBException;
029:
030: import com.sun.xml.internal.bind.WhiteSpaceProcessor;
031: import com.sun.xml.internal.bind.api.AccessorException;
032: import com.sun.xml.internal.bind.v2.runtime.Transducer;
033: import com.sun.xml.internal.bind.v2.runtime.XMLSerializer;
034:
035: import org.xml.sax.SAXException;
036:
037: /**
038: * {@link TransducedAccessor} for a list simple type.
039: *
040: * @author Kohsuke Kawaguchi
041: */
042: public final class ListTransducedAccessorImpl<BeanT, ListT, ItemT, PackT>
043: extends DefaultTransducedAccessor<BeanT> {
044: /**
045: * {@link Transducer} for each item type.
046: */
047: private final Transducer<ItemT> xducer;
048: /**
049: * {@link Lister} for handling list of tokens.
050: */
051: private final Lister<BeanT, ListT, ItemT, PackT> lister;
052: /**
053: * {@link Accessor} to get/set the list.
054: */
055: private final Accessor<BeanT, ListT> acc;
056:
057: public ListTransducedAccessorImpl(Transducer<ItemT> xducer,
058: Accessor<BeanT, ListT> acc,
059: Lister<BeanT, ListT, ItemT, PackT> lister) {
060: this .xducer = xducer;
061: this .lister = lister;
062: this .acc = acc;
063: }
064:
065: public boolean useNamespace() {
066: return xducer.useNamespace();
067: }
068:
069: public void declareNamespace(BeanT bean, XMLSerializer w)
070: throws AccessorException, SAXException {
071: ListT list = acc.get(bean);
072:
073: if (list != null) {
074: ListIterator<ItemT> itr = lister.iterator(list, w);
075:
076: while (itr.hasNext()) {
077: try {
078: ItemT item = itr.next();
079: if (item != null) {
080: xducer.declareNamespace(item, w);
081: }
082: } catch (JAXBException e) {
083: w.reportError(null, e);
084: }
085: }
086: }
087: }
088:
089: // TODO: this is inefficient, consider a redesign
090: // perhaps we should directly write to XMLSerializer,
091: // or maybe add more methods like writeLeafElement.
092: public String print(BeanT o) throws AccessorException, SAXException {
093: ListT list = acc.get(o);
094:
095: if (list == null)
096: return null;
097:
098: StringBuilder buf = new StringBuilder();
099: XMLSerializer w = XMLSerializer.getInstance();
100: ListIterator<ItemT> itr = lister.iterator(list, w);
101:
102: while (itr.hasNext()) {
103: try {
104: ItemT item = itr.next();
105: if (item != null) {
106: if (buf.length() > 0)
107: buf.append(' ');
108: buf.append(xducer.print(item));
109: }
110: } catch (JAXBException e) {
111: w.reportError(null, e);
112: }
113: }
114: return buf.toString();
115: }
116:
117: private void processValue(BeanT bean, CharSequence s)
118: throws AccessorException, SAXException {
119: PackT pack = lister.startPacking(bean, acc);
120:
121: int idx = 0;
122: int len = s.length();
123:
124: while (true) {
125: int p = idx;
126: while (p < len
127: && !WhiteSpaceProcessor.isWhiteSpace(s.charAt(p)))
128: p++;
129:
130: CharSequence token = s.subSequence(idx, p);
131: if (!token.equals(""))
132: lister.addToPack(pack, xducer.parse(token));
133:
134: if (p == len)
135: break; // done
136:
137: while (p < len
138: && WhiteSpaceProcessor.isWhiteSpace(s.charAt(p)))
139: p++;
140: if (p == len)
141: break; // done
142:
143: idx = p;
144: }
145:
146: lister.endPacking(pack, bean, acc);
147: }
148:
149: public void parse(BeanT bean, CharSequence lexical)
150: throws AccessorException, SAXException {
151: processValue(bean, lexical);
152: }
153:
154: public boolean hasValue(BeanT bean) throws AccessorException {
155: return acc.get(bean) != null;
156: }
157: }
|