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 26package com.sun.xml.internal.ws.spi.db; 27 28import java.util.HashSet; 29import java.util.Iterator; 30import java.util.Collection; 31import java.util.List; 32import java.util.Set; 33import java.io.InputStream; 34import java.io.OutputStream; 35import java.util.NoSuchElementException; 36 37import javax.xml.bind.JAXBException; 38import javax.xml.bind.attachment.AttachmentMarshaller; 39import javax.xml.bind.attachment.AttachmentUnmarshaller; 40import javax.xml.namespace.NamespaceContext; 41import javax.xml.stream.XMLStreamReader; 42import javax.xml.stream.XMLStreamWriter; 43import javax.xml.transform.Result; 44import javax.xml.transform.Source; 45 46import org.w3c.dom.Node; 47import org.xml.sax.ContentHandler; 48 49/** 50 * RepeatedElementBridge 51 * 52 * @author shih-chang.chen@oracle.com 53 */ 54@SuppressWarnings({"rawtypes", "unchecked"}) 55public class RepeatedElementBridge<T> implements XMLBridge<T> { 56 57 XMLBridge<T> delegate; 58 CollectionHandler collectionHandler; 59 60 public RepeatedElementBridge(TypeInfo typeInfo, XMLBridge xb) { 61 delegate = xb; 62 collectionHandler = create(typeInfo); 63 } 64 65 public CollectionHandler collectionHandler() { 66 return collectionHandler; 67 } 68 69 @Override 70 public BindingContext context() { 71 return delegate.context(); 72 } 73 74 @Override 75 public void marshal(T object, XMLStreamWriter output, AttachmentMarshaller am) throws JAXBException { 76 delegate.marshal(object, output, am); 77 } 78 79 @Override 80 public void marshal(T object, OutputStream output, NamespaceContext nsContext, AttachmentMarshaller am) throws JAXBException { 81 delegate.marshal(object, output, nsContext, am); 82 } 83 84 @Override 85 public void marshal(T object, Node output) throws JAXBException { 86 delegate.marshal(object, output); 87 } 88 89 @Override 90 public void marshal(T object, ContentHandler contentHandler, AttachmentMarshaller am) throws JAXBException { 91 delegate.marshal(object, contentHandler, am); 92 } 93 94 @Override 95 public void marshal(T object, Result result) throws JAXBException { 96 delegate.marshal(object, result); 97 } 98 99 @Override 100 public T unmarshal(XMLStreamReader in, AttachmentUnmarshaller au) throws JAXBException { 101 return delegate.unmarshal(in, au); 102 } 103 104 @Override 105 public T unmarshal(Source in, AttachmentUnmarshaller au) throws JAXBException { 106 return delegate.unmarshal(in, au); 107 } 108 109 @Override 110 public T unmarshal(InputStream in) throws JAXBException { 111 return delegate.unmarshal(in); 112 } 113 114 @Override 115 public T unmarshal(Node n, AttachmentUnmarshaller au) throws JAXBException { 116 return delegate.unmarshal(n, au); 117 } 118 119 @Override 120 public TypeInfo getTypeInfo() { 121 return delegate.getTypeInfo(); 122 } 123 124 @Override 125 public boolean supportOutputStream() { 126 return delegate.supportOutputStream(); 127 } 128 129 static public interface CollectionHandler { 130 int getSize(Object c); 131 Iterator iterator(Object c); 132 Object convert(List list); 133 } 134 135 static class BaseCollectionHandler implements CollectionHandler { 136 Class type; 137 BaseCollectionHandler(Class c) {type = c;} 138 @Override 139 public int getSize(Object c) { return ((Collection) c).size(); } 140 @Override 141 public Object convert(List list) { 142 try { 143 Object o = type.newInstance(); 144 ((Collection)o).addAll(list); 145 return o; 146 } catch (Exception e) { 147 e.printStackTrace(); 148 } 149 return list; 150 } 151 @Override 152 public Iterator iterator(Object c) {return ((Collection)c).iterator();} 153 } 154 155 static final CollectionHandler ListHandler = new BaseCollectionHandler(List.class) { 156 @Override 157 public Object convert(List list) {return list;} 158 }; 159 160 static final CollectionHandler HashSetHandler = new BaseCollectionHandler(HashSet.class) { 161 @Override 162 public Object convert(List list) { return new HashSet(list);} 163 }; 164 165 static public CollectionHandler create(TypeInfo ti) { 166 Class javaClass = (Class) ti.type; 167 if (javaClass.isArray()) { 168 return new ArrayHandler((Class) ti.getItemType().type); 169 } else if (List.class.equals(javaClass) || Collection.class.equals(javaClass)) { 170 return ListHandler; 171 } else if (Set.class.equals(javaClass) || HashSet.class.equals(javaClass)) { 172 return HashSetHandler; 173 } else { 174 return new BaseCollectionHandler(javaClass); 175 } 176 } 177 178 static class ArrayHandler implements CollectionHandler { 179 Class componentClass; 180 public ArrayHandler(Class component) { 181 componentClass = component; 182 } 183 @Override 184 public int getSize(Object c) { 185 return java.lang.reflect.Array.getLength(c); 186 } 187 @Override 188 public Object convert(List list) { 189 Object array = java.lang.reflect.Array.newInstance(componentClass, list.size()); 190 for (int i = 0; i < list.size(); i++) { 191 java.lang.reflect.Array.set(array, i, list.get(i)); 192 } 193 return array; 194 } 195 @Override 196 public Iterator iterator(final Object c) { 197 return new Iterator() { 198 int index = 0; 199 @Override 200 public boolean hasNext() { 201 if (c == null || java.lang.reflect.Array.getLength(c) == 0) { 202 return false; 203 } 204 return (index != java.lang.reflect.Array.getLength(c)); 205 } 206 @Override 207 public Object next() throws NoSuchElementException { 208 Object retVal = null; 209 try { 210 retVal = java.lang.reflect.Array.get(c, index++); 211 } catch (ArrayIndexOutOfBoundsException ex) { 212 throw new NoSuchElementException(); 213 } 214 return retVal; 215 } 216 @Override 217 public void remove() {} 218 }; 219 } 220 } 221} 222