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; 27 28 import java.io.IOException; 29 import java.lang.reflect.Array; 30 import java.util.List; 31 32 import javax.xml.bind.JAXBException; 33 import javax.xml.bind.ValidationEvent; 34 import javax.xml.bind.helpers.ValidationEventImpl; 35 import javax.xml.stream.XMLStreamException; 36 37 import com.sun.istack.internal.FinalArrayList; 38 import com.sun.xml.internal.bind.WhiteSpaceProcessor; 39 import com.sun.xml.internal.bind.api.AccessorException; 40 import com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader; 41 import com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext; 42 43 import org.xml.sax.SAXException; 44 45 /** 46 * {@link JaxBeanInfo} implementation that binds T[] to a list of simple types. 47 * 48 * @author Kohsuke Kawaguchi 49 */ 50 final class ValueListBeanInfoImpl extends JaxBeanInfo { 51 52 private final Class itemType; 53 private final Transducer xducer; // for items 54 55 public ValueListBeanInfoImpl(JAXBContextImpl owner, Class arrayType) throws JAXBException { 56 super(owner, null, arrayType, false, true, false); 57 this.itemType = jaxbType.getComponentType(); 58 this.xducer = owner.getBeanInfo(arrayType.getComponentType(),true).getTransducer(); 59 assert xducer!=null; 60 } 61 62 private final Loader loader = new Loader(true) { 63 @Override 64 public void text(UnmarshallingContext.State state, CharSequence text) throws SAXException { 65 List<Object> r = new FinalArrayList<Object>(); 66 67 int idx = 0; 68 int len = text.length(); 69 70 while(true) { 71 int p = idx; 72 while( p<len && !WhiteSpaceProcessor.isWhiteSpace(text.charAt(p)) ) 73 p++; 74 75 CharSequence token = text.subSequence(idx,p); 76 if (!token.equals("")) 77 try { 78 r.add(xducer.parse(token)); 79 } catch (AccessorException e) { 80 handleGenericException(e,true); 81 continue; // move on to next 82 } 83 84 if(p==len) break; // done 85 86 while( p<len && WhiteSpaceProcessor.isWhiteSpace(text.charAt(p)) ) 87 p++; 88 if(p==len) break; // done 89 90 idx = p; 91 } 92 93 state.target = toArray(r); 94 } 95 }; 96 97 private Object toArray( List list ) { 98 int len = list.size(); 99 Object array = Array.newInstance(itemType,len); 100 for( int i=0; i<len; i++ ) 101 Array.set(array,i,list.get(i)); 102 return array; 103 } 104 105 public void serializeBody(Object array, XMLSerializer target) throws SAXException, IOException, XMLStreamException { 106 int len = Array.getLength(array); 107 for( int i=0; i<len; i++ ) { 108 Object item = Array.get(array,i); 109 try { 110 xducer.writeText(target,item,"arrayItem"); 111 } catch (AccessorException e) { 112 target.reportError("arrayItem",e); 113 } 114 } 115 } 116 117 public final void serializeURIs(Object array, XMLSerializer target) throws SAXException { 118 if(xducer.useNamespace()) { 119 int len = Array.getLength(array); 120 for( int i=0; i<len; i++ ) { 121 Object item = Array.get(array,i); 122 try { 123 xducer.declareNamespace(item,target); 124 } catch (AccessorException e) { 125 target.reportError("arrayItem",e); 126 } 127 } 128 } 129 } 130 131 public final String getElementNamespaceURI(Object array) { 132 throw new UnsupportedOperationException(); 133 } 134 135 public final String getElementLocalName(Object array) { 136 throw new UnsupportedOperationException(); 137 } 138 139 public final Object createInstance(UnmarshallingContext context) { 140 throw new UnsupportedOperationException(); 141 } 142 143 public final boolean reset(Object array, UnmarshallingContext context) { 144 return false; 145 } 146 147 public final String getId(Object array, XMLSerializer target) { 148 return null; 149 } 150 151 public final void serializeAttributes(Object array, XMLSerializer target) { 152 // noop 153 } 154 155 public final void serializeRoot(Object array, XMLSerializer target) throws SAXException { 156 target.reportError( 157 new ValidationEventImpl( 158 ValidationEvent.ERROR, 159 Messages.UNABLE_TO_MARSHAL_NON_ELEMENT.format(array.getClass().getName()), 160 null, 161 null)); 162 } 163 164 public final Transducer getTransducer() { 165 return null; 166 } 167 168 public final Loader getLoader(JAXBContextImpl context, boolean typeSubstitutionCapable) { 169 // type substitution impossible 170 return loader; 171 } 172 }