View Javadoc
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.ws.spi.db;
27  
28  import java.util.HashSet;
29  import java.util.Iterator;
30  import java.util.Collection;
31  import java.util.List;
32  import java.util.Set;
33  import java.io.InputStream;
34  import java.io.OutputStream;
35  import java.util.NoSuchElementException;
36  
37  import javax.xml.bind.JAXBException;
38  import javax.xml.bind.attachment.AttachmentMarshaller;
39  import javax.xml.bind.attachment.AttachmentUnmarshaller;
40  import javax.xml.namespace.NamespaceContext;
41  import javax.xml.stream.XMLStreamReader;
42  import javax.xml.stream.XMLStreamWriter;
43  import javax.xml.transform.Result;
44  import javax.xml.transform.Source;
45  
46  import org.w3c.dom.Node;
47  import org.xml.sax.ContentHandler;
48  
49  /**
50   * RepeatedElementBridge
51   *
52   * @author shih-chang.chen@oracle.com
53   */
54  @SuppressWarnings({"rawtypes", "unchecked"})
55  public 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 }