KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > directwebremoting > convert > CollectionConverter


1 /*
2  * Copyright 2005 Joe Walker
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.directwebremoting.convert;
17
18 import java.lang.reflect.Modifier JavaDoc;
19 import java.util.ArrayList JavaDoc;
20 import java.util.Collection JavaDoc;
21 import java.util.HashSet JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.List JavaDoc;
24 import java.util.Set JavaDoc;
25 import java.util.SortedSet JavaDoc;
26 import java.util.StringTokenizer JavaDoc;
27 import java.util.TreeSet JavaDoc;
28
29 import org.directwebremoting.dwrp.ArrayOutboundVariable;
30 import org.directwebremoting.dwrp.ErrorOutboundVariable;
31 import org.directwebremoting.dwrp.ParseUtil;
32 import org.directwebremoting.dwrp.ProtocolConstants;
33 import org.directwebremoting.extend.Converter;
34 import org.directwebremoting.extend.ConverterManager;
35 import org.directwebremoting.extend.InboundContext;
36 import org.directwebremoting.extend.InboundVariable;
37 import org.directwebremoting.extend.MarshallException;
38 import org.directwebremoting.extend.OutboundContext;
39 import org.directwebremoting.extend.OutboundVariable;
40 import org.directwebremoting.extend.TypeHintContext;
41 import org.directwebremoting.util.LocalUtil;
42 import org.directwebremoting.util.Logger;
43 import org.directwebremoting.util.Messages;
44
45 /**
46  * An implementation of Converter for Collections of Strings.
47  * @author Joe Walker [joe at eireneh dot com]
48  * @version $Id: StringConverter.java,v 1.2 2004/11/04 15:54:07 joe_walker Exp $
49  */

50 public class CollectionConverter extends BaseV20Converter implements Converter
51 {
52     /* (non-Javadoc)
53      * @see org.directwebremoting.convert.BaseV20Converter#setConverterManager(org.directwebremoting.ConverterManager)
54      */

55     public void setConverterManager(ConverterManager newConfig)
56     {
57         this.config = newConfig;
58     }
59
60     /* (non-Javadoc)
61      * @see org.directwebremoting.Converter#convertInbound(java.lang.Class, org.directwebremoting.InboundVariable, org.directwebremoting.InboundContext)
62      */

63     public Object JavaDoc convertInbound(Class JavaDoc paramType, InboundVariable iv, InboundContext inctx) throws MarshallException
64     {
65         String JavaDoc value = iv.getValue();
66
67         // If the text is null then the whole bean is null
68
if (value.trim().equals(ProtocolConstants.INBOUND_NULL))
69         {
70             return null;
71         }
72
73         if (!value.startsWith(ProtocolConstants.INBOUND_ARRAY_START))
74         {
75             throw new MarshallException(paramType, Messages.getString("CollectionConverter.FormatError", ProtocolConstants.INBOUND_ARRAY_START));
76         }
77
78         if (!value.endsWith(ProtocolConstants.INBOUND_ARRAY_END))
79         {
80             throw new MarshallException(paramType, Messages.getString("CollectionConverter.FormatError", ProtocolConstants.INBOUND_ARRAY_END));
81         }
82
83         value = value.substring(1, value.length() - 1);
84
85         try
86         {
87             TypeHintContext icc = inctx.getCurrentTypeHintContext();
88
89             TypeHintContext subthc = icc.createChildContext(0);
90             Class JavaDoc subtype = subthc.getExtraTypeInfo();
91
92             // subtype.getMethod("h", null).getTypeParameters();
93
Collection JavaDoc col;
94
95             // If they want an iterator then just use an array list and fudge
96
// at the end.
97
if (Iterator JavaDoc.class.isAssignableFrom(paramType))
98             {
99                 col = new ArrayList JavaDoc();
100             }
101             // If paramType is concrete then just use whatever we've got.
102
else if (!paramType.isInterface() && !Modifier.isAbstract(paramType.getModifiers()))
103             {
104                 // If there is a problem creating the type then we have no way
105
// of completing this - they asked for a specific type and we
106
// can't create that type. I don't know of a way of finding
107
// subclasses that might be instaniable so we accept failure.
108
col = (Collection JavaDoc) paramType.newInstance();
109             }
110             // If they want a SortedSet then use TreeSet
111
else if (SortedSet JavaDoc.class.isAssignableFrom(paramType))
112             {
113                 col = new TreeSet JavaDoc();
114             }
115             // If they want a Set then use HashSet
116
else if (Set JavaDoc.class.isAssignableFrom(paramType))
117             {
118                 col = new HashSet JavaDoc();
119             }
120             // If they want a List then use an ArrayList
121
else if (List JavaDoc.class.isAssignableFrom(paramType))
122             {
123                 col = new ArrayList JavaDoc();
124             }
125             // If they just want a Collection then just use an ArrayList
126
else if (Collection JavaDoc.class.isAssignableFrom(paramType))
127             {
128                 col = new ArrayList JavaDoc();
129             }
130             else
131             {
132                 throw new MarshallException(paramType);
133             }
134
135             // We should put the new object into the working map in case it
136
// is referenced later nested down in the conversion process.
137
inctx.addConverted(iv, paramType, col);
138
139             StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(value, ProtocolConstants.INBOUND_ARRAY_SEPARATOR);
140             int size = st.countTokens();
141             for (int i = 0; i < size; i++)
142             {
143                 String JavaDoc token = st.nextToken();
144
145                 String JavaDoc[] split = ParseUtil.splitInbound(token);
146                 String JavaDoc splitType = split[LocalUtil.INBOUND_INDEX_TYPE];
147                 String JavaDoc splitValue = split[LocalUtil.INBOUND_INDEX_VALUE];
148
149                 InboundVariable nested = new InboundVariable(iv.getLookup(), null, splitType, splitValue);
150
151                 Object JavaDoc output = config.convertInbound(subtype, nested, inctx, subthc);
152                 col.add(output);
153             }
154
155             // If they wanted an Iterator then give them one otherwise use
156
// the type we created
157
if (Iterator JavaDoc.class.isAssignableFrom(paramType))
158             {
159                 return col.iterator();
160             }
161             else
162             {
163                 return col;
164             }
165         }
166         catch (Exception JavaDoc ex)
167         {
168             throw new MarshallException(paramType, ex);
169         }
170     }
171
172     /* (non-Javadoc)
173      * @see org.directwebremoting.Converter#convertOutbound(java.lang.Object, org.directwebremoting.OutboundContext)
174      */

175     public OutboundVariable convertOutbound(Object JavaDoc data, OutboundContext outctx) throws MarshallException
176     {
177         // First we need to get ourselves the collection data
178
Iterator JavaDoc it;
179         if (data instanceof Collection JavaDoc)
180         {
181             Collection JavaDoc col = (Collection JavaDoc) data;
182             it = col.iterator();
183         }
184         else if (data instanceof Iterator JavaDoc)
185         {
186             it = (Iterator JavaDoc) data;
187         }
188         else
189         {
190             throw new MarshallException(data.getClass());
191         }
192
193         // Stash this bit of data to cope with recursion
194
ArrayOutboundVariable ov = new ArrayOutboundVariable(outctx);
195         outctx.put(data, ov);
196
197         // Convert all the data members
198
List JavaDoc ovs = new ArrayList JavaDoc();
199         while (it.hasNext())
200         {
201             Object JavaDoc member = it.next();
202             OutboundVariable nested;
203
204             try
205             {
206                 nested = config.convertOutbound(member, outctx);
207             }
208             catch (Exception JavaDoc ex)
209             {
210                 String JavaDoc errorMessage = "Conversion error for " + data.getClass().getName() + ".";
211                 log.warn(errorMessage, ex);
212
213                 nested = new ErrorOutboundVariable(outctx, errorMessage, true);
214             }
215
216             ovs.add(nested);
217         }
218
219         // Group the list of converted objects into this OutboundVariable
220
ov.init(ovs);
221
222         return ov;
223     }
224
225     /**
226      * For nested conversions
227      */

228     private ConverterManager config = null;
229
230     /**
231      * The log stream
232      */

233     private static final Logger log = Logger.getLogger(CollectionConverter.class);
234 }
235
Popular Tags