1 /* 2 * Copyright (c) 1997, 2013, 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.property; 27 28 import java.io.IOException; 29 30 import javax.xml.stream.XMLStreamException; 31 32 import com.sun.xml.internal.bind.api.AccessorException; 33 import com.sun.xml.internal.bind.v2.util.QNameMap; 34 import com.sun.xml.internal.bind.v2.model.core.ElementPropertyInfo; 35 import com.sun.xml.internal.bind.v2.model.core.PropertyKind; 36 import com.sun.xml.internal.bind.v2.model.runtime.RuntimeElementPropertyInfo; 37 import com.sun.xml.internal.bind.v2.model.runtime.RuntimeTypeRef; 38 import com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl; 39 import com.sun.xml.internal.bind.v2.runtime.Name; 40 import com.sun.xml.internal.bind.v2.runtime.Transducer; 41 import com.sun.xml.internal.bind.v2.runtime.XMLSerializer; 42 import com.sun.xml.internal.bind.v2.runtime.reflect.ListTransducedAccessorImpl; 43 import com.sun.xml.internal.bind.v2.runtime.reflect.TransducedAccessor; 44 import com.sun.xml.internal.bind.v2.runtime.reflect.Accessor; 45 import com.sun.xml.internal.bind.v2.runtime.unmarshaller.ChildLoader; 46 import com.sun.xml.internal.bind.v2.runtime.unmarshaller.DefaultValueLoaderDecorator; 47 import com.sun.xml.internal.bind.v2.runtime.unmarshaller.LeafPropertyLoader; 48 import com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader; 49 50 import org.xml.sax.SAXException; 51 52 /** 53 * {@link Property} implementation for {@link ElementPropertyInfo} whose 54 * {@link ElementPropertyInfo#isValueList()} is true. 55 * 56 * @author Kohsuke Kawaguchi 57 */ 58 final class ListElementProperty<BeanT,ListT,ItemT> extends ArrayProperty<BeanT,ListT,ItemT> { 59 60 private final Name tagName; 61 private final String defaultValue; 62 63 /** 64 * Converts all the values to a list and back. 65 */ 66 private final TransducedAccessor<BeanT> xacc; 67 68 public ListElementProperty(JAXBContextImpl grammar, RuntimeElementPropertyInfo prop) { 69 super(grammar, prop); 70 71 assert prop.isValueList(); 72 assert prop.getTypes().size()==1; // required by the contract of isValueList 73 RuntimeTypeRef ref = prop.getTypes().get(0); 74 75 tagName = grammar.nameBuilder.createElementName(ref.getTagName()); 76 defaultValue = ref.getDefaultValue(); 77 78 // transducer for each item 79 Transducer xducer = ref.getTransducer(); 80 // transduced accessor for the whole thing 81 xacc = new ListTransducedAccessorImpl(xducer,acc,lister); 82 } 83 84 public PropertyKind getKind() { 85 return PropertyKind.ELEMENT; 86 } 87 88 public void buildChildElementUnmarshallers(UnmarshallerChain chain, QNameMap<ChildLoader> handlers) { 89 Loader l = new LeafPropertyLoader(xacc); 90 l = new DefaultValueLoaderDecorator(l, defaultValue); 91 handlers.put(tagName, new ChildLoader(l,null)); 92 } 93 94 @Override 95 public void serializeBody(BeanT o, XMLSerializer w, Object outerPeer) throws SAXException, AccessorException, IOException, XMLStreamException { 96 ListT list = acc.get(o); 97 98 if(list!=null) { 99 if(xacc.useNamespace()) { 100 w.startElement(tagName,null); 101 xacc.declareNamespace(o,w); 102 w.endNamespaceDecls(list); 103 w.endAttributes(); 104 xacc.writeText(w,o,fieldName); 105 w.endElement(); 106 } else { 107 xacc.writeLeafElement(w, tagName, o, fieldName); 108 } 109 } 110 } 111 112 @Override 113 public Accessor getElementPropertyAccessor(String nsUri, String localName) { 114 if(tagName!=null) { 115 if(tagName.equals(nsUri,localName)) 116 return acc; 117 } 118 return null; 119 } 120 }