1 /* 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.xml.internal.bind.v2.runtime.reflect; 27 28 import javax.xml.bind.JAXBException; 29 30 import com.sun.xml.internal.bind.WhiteSpaceProcessor; 31 import com.sun.xml.internal.bind.api.AccessorException; 32 import com.sun.xml.internal.bind.v2.runtime.Transducer; 33 import com.sun.xml.internal.bind.v2.runtime.XMLSerializer; 34 35 import org.xml.sax.SAXException; 36 37 /** 38 * {@link TransducedAccessor} for a list simple type. 39 * 40 * @author Kohsuke Kawaguchi 41 */ 42 public final class ListTransducedAccessorImpl<BeanT,ListT,ItemT,PackT> extends DefaultTransducedAccessor<BeanT> { 43 /** 44 * {@link Transducer} for each item type. 45 */ 46 private final Transducer<ItemT> xducer; 47 /** 48 * {@link Lister} for handling list of tokens. 49 */ 50 private final Lister<BeanT,ListT,ItemT,PackT> lister; 51 /** 52 * {@link Accessor} to get/set the list. 53 */ 54 private final Accessor<BeanT,ListT> acc; 55 56 public ListTransducedAccessorImpl(Transducer<ItemT> xducer, Accessor<BeanT,ListT> acc, Lister<BeanT,ListT,ItemT,PackT> lister) { 57 this.xducer = xducer; 58 this.lister = lister; 59 this.acc = acc; 60 } 61 62 public boolean useNamespace() { 63 return xducer.useNamespace(); 64 } 65 66 public void declareNamespace(BeanT bean, XMLSerializer w) throws AccessorException, SAXException { 67 ListT list = acc.get(bean); 68 69 if(list!=null) { 70 ListIterator<ItemT> itr = lister.iterator(list, w); 71 72 while(itr.hasNext()) { 73 try { 74 ItemT item = itr.next(); 75 if (item != null) { 76 xducer.declareNamespace(item,w); 77 } 78 } catch (JAXBException e) { 79 w.reportError(null,e); 80 } 81 } 82 } 83 } 84 85 // TODO: this is inefficient, consider a redesign 86 // perhaps we should directly write to XMLSerializer, 87 // or maybe add more methods like writeLeafElement. 88 public String print(BeanT o) throws AccessorException, SAXException { 89 ListT list = acc.get(o); 90 91 if(list==null) 92 return null; 93 94 StringBuilder buf = new StringBuilder(); 95 XMLSerializer w = XMLSerializer.getInstance(); 96 ListIterator<ItemT> itr = lister.iterator(list, w); 97 98 while(itr.hasNext()) { 99 try { 100 ItemT item = itr.next(); 101 if (item != null) { 102 if(buf.length()>0) buf.append(' '); 103 buf.append(xducer.print(item)); 104 } 105 } catch (JAXBException e) { 106 w.reportError(null,e); 107 } 108 } 109 return buf.toString(); 110 } 111 112 private void processValue(BeanT bean, CharSequence s) throws AccessorException, SAXException { 113 PackT pack = lister.startPacking(bean,acc); 114 115 int idx = 0; 116 int len = s.length(); 117 118 while(true) { 119 int p = idx; 120 while( p<len && !WhiteSpaceProcessor.isWhiteSpace(s.charAt(p)) ) 121 p++; 122 123 CharSequence token = s.subSequence(idx,p); 124 if (!token.equals("")) 125 lister.addToPack(pack,xducer.parse(token)); 126 127 if(p==len) break; // done 128 129 while( p<len && WhiteSpaceProcessor.isWhiteSpace(s.charAt(p)) ) 130 p++; 131 if(p==len) break; // done 132 133 idx = p; 134 } 135 136 lister.endPacking(pack,bean,acc); 137 } 138 139 public void parse(BeanT bean, CharSequence lexical) throws AccessorException, SAXException { 140 processValue(bean,lexical); 141 } 142 143 public boolean hasValue(BeanT bean) throws AccessorException { 144 return acc.get(bean)!=null; 145 } 146 }