KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > xml > binding > MappingObjectModelProvider


1 /*
2  * JBoss, the OpenSource J2EE webOS
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7 package org.jboss.xml.binding;
8
9 import org.jboss.logging.Logger;
10 import org.jboss.util.Classes;
11
12 import java.lang.reflect.Method JavaDoc;
13 import java.lang.reflect.Field JavaDoc;
14 import java.util.Map JavaDoc;
15 import java.util.HashMap JavaDoc;
16
17 /**
18  * @author <a HREF="mailto:alex@jboss.org">Alexey Loubyansky</a>
19  * @version <tt>$Revision: 1.1.2.6 $</tt>
20  */

21 public class MappingObjectModelProvider
22    implements GenericObjectModelProvider
23 {
24    private static final Logger log = Logger.getLogger(MappingObjectModelProvider.class);
25    
26    private final Map JavaDoc classMappings = new HashMap JavaDoc();
27    private final Map JavaDoc fieldMappings = new HashMap JavaDoc();
28
29    public void mapClassToElement(Class JavaDoc cls, String JavaDoc namespaceURI, String JavaDoc localName, ObjectModelProvider provider)
30    {
31       ClassToElementMapping mapping = new ClassToElementMapping(cls, namespaceURI, localName,
32          provider instanceof GenericObjectModelProvider ?
33          (GenericObjectModelProvider)provider : new DelegatingObjectModelProvider(provider)
34       );
35       classMappings.put(mapping.cls, mapping);
36    }
37
38    public void mapFieldToElement(Class JavaDoc cls,
39                                  String JavaDoc field,
40                                  String JavaDoc namespaceURI,
41                                  String JavaDoc localName,
42                                  TypeConverter converter)
43    {
44       FieldToElementMapping mapping = new FieldToElementMapping(cls, field, namespaceURI, localName, converter);
45       fieldMappings.put(mapping.localName, mapping);
46    }
47
48    // GenericObjectModelProvider implementation
49

50    public Object JavaDoc getChildren(Object JavaDoc o, String JavaDoc namespaceURI, String JavaDoc localName)
51    {
52       Object JavaDoc children = null;
53       if(!writeAsValue(o.getClass()))
54       {
55          children = getJavaValue(localName, o, true);
56       }
57       return children;
58    }
59
60    public Object JavaDoc getElementValue(Object JavaDoc o, String JavaDoc namespaceURI, String JavaDoc localName)
61    {
62       Object JavaDoc value = null;
63       if(writeAsValue(o.getClass()))
64       {
65          value = o;
66       }
67       else
68       {
69          value = getJavaValue(localName, o, false);
70       }
71       return value;
72    }
73
74    public Object JavaDoc getAttributeValue(Object JavaDoc o, String JavaDoc namespaceURI, String JavaDoc localName)
75    {
76       Object JavaDoc value = null;
77       if(writeAsValue(o.getClass()))
78       {
79          value = o;
80       }
81       else
82       {
83          value = getJavaValue(localName, o, false);
84       }
85       return value;
86    }
87
88    public Object JavaDoc getRoot(Object JavaDoc o, String JavaDoc namespaceURI, String JavaDoc localName)
89    {
90       String JavaDoc correspCls = Util.xmlNameToClassName(localName, true);
91       String JavaDoc shortName = Classes.stripPackageName(o.getClass());
92       return correspCls.equals(shortName) ? o : null;
93    }
94
95    // Private
96

97    private Object JavaDoc getJavaValue(String JavaDoc localName, Object JavaDoc o, boolean forComplexType)
98    {
99       Method JavaDoc getter = null;
100       Field JavaDoc field = null;
101
102       final FieldToElementMapping mapping = (FieldToElementMapping)fieldMappings.get(localName);
103       if(mapping != null)
104       {
105          getter = mapping.getter;
106       }
107       else
108       {
109          String JavaDoc getterStr = Util.xmlNameToGetMethodName(localName, true);
110          try
111          {
112             getter = o.getClass().getMethod(getterStr, null);
113          }
114          catch(NoSuchMethodException JavaDoc e)
115          {
116             String JavaDoc attr = Util.xmlNameToClassName(localName, true);
117             attr = Character.toLowerCase(attr.charAt(0)) + attr.substring(1);
118             try
119             {
120                field = o.getClass().getField(attr);
121             }
122             catch(NoSuchFieldException JavaDoc e1)
123             {
124                if(log.isDebugEnabled())
125                {
126                   log.debug("getChildren: found neither getter nor field for " + localName + " in " + o.getClass());
127                }
128             }
129          }
130       }
131
132       Object JavaDoc value = null;
133       try
134       {
135          if(getter != null && (!forComplexType || forComplexType && !writeAsValue(getter.getReturnType())))
136          {
137             value = getter.invoke(o, null);
138          }
139          else if(field != null && (!forComplexType || forComplexType && !writeAsValue(field.getType())))
140          {
141             value = field.get(o);
142          }
143       }
144       catch(Exception JavaDoc e)
145       {
146          log.error("Failed to provide value for " + localName + " from " + o, e);
147       }
148
149       if(value != null && mapping != null)
150       {
151          value = mapping.converter.marshal(value);
152       }
153
154       return value;
155    }
156
157    private boolean writeAsValue(final Class JavaDoc type)
158    {
159       return Classes.isPrimitive(type) ||
160          type == String JavaDoc.class ||
161          type == java.util.Date JavaDoc.class;
162    }
163
164    // Inner
165

166    private class ClassToElementMapping
167    {
168       public final Class JavaDoc cls;
169       public final String JavaDoc namespaceURI;
170       public final String JavaDoc localName;
171       public final GenericObjectModelProvider provider;
172
173       public ClassToElementMapping(Class JavaDoc cls,
174                                    String JavaDoc namespaceURI,
175                                    String JavaDoc localName,
176                                    GenericObjectModelProvider provider)
177       {
178          this.cls = cls;
179          this.namespaceURI = namespaceURI;
180          this.localName = localName;
181          this.provider = provider;
182       }
183
184       public boolean equals(Object JavaDoc o)
185       {
186          if(this == o)
187          {
188             return true;
189          }
190          if(!(o instanceof ClassToElementMapping))
191          {
192             return false;
193          }
194
195          final ClassToElementMapping classToElementMapping = (ClassToElementMapping)o;
196
197          if(cls != null ? !cls.equals(classToElementMapping.cls) : classToElementMapping.cls != null)
198          {
199             return false;
200          }
201          if(localName != null ?
202             !localName.equals(classToElementMapping.localName) :
203             classToElementMapping.localName != null)
204          {
205             return false;
206          }
207          if(namespaceURI != null ?
208             !namespaceURI.equals(classToElementMapping.namespaceURI) :
209             classToElementMapping.namespaceURI != null)
210          {
211             return false;
212          }
213
214          return true;
215       }
216
217       public int hashCode()
218       {
219          int result;
220          result = (cls != null ? cls.hashCode() : 0);
221          result = 29 * result + (namespaceURI != null ? namespaceURI.hashCode() : 0);
222          result = 29 * result + (localName != null ? localName.hashCode() : 0);
223          return result;
224       }
225    }
226
227    private class FieldToElementMapping
228    {
229       public final Class JavaDoc cls;
230       public final String JavaDoc field;
231       public final String JavaDoc namespaceURI;
232       public final String JavaDoc localName;
233       public final TypeConverter converter;
234       public final Method JavaDoc getter;
235       public final Method JavaDoc setter;
236
237       public FieldToElementMapping(Class JavaDoc cls,
238                                    String JavaDoc field,
239                                    String JavaDoc namespaceURI,
240                                    String JavaDoc localName,
241                                    TypeConverter converter)
242       {
243          this.cls = cls;
244          this.field = field;
245          this.namespaceURI = namespaceURI;
246          this.localName = localName;
247          this.converter = converter;
248
249          try
250          {
251             getter = Classes.getAttributeGetter(cls, field);
252          }
253          catch(NoSuchMethodException JavaDoc e)
254          {
255             throw new IllegalStateException JavaDoc("Getter not found for " + field + " in class " + cls.getName());
256          }
257
258          try
259          {
260             setter = Classes.getAttributeSetter(cls, field, getter.getReturnType());
261          }
262          catch(NoSuchMethodException JavaDoc e)
263          {
264             throw new IllegalStateException JavaDoc("Setter not found for " + field + " in class " + cls.getName());
265          }
266       }
267
268       public boolean equals(Object JavaDoc o)
269       {
270          if(this == o)
271          {
272             return true;
273          }
274          if(!(o instanceof FieldToElementMapping))
275          {
276             return false;
277          }
278
279          final FieldToElementMapping fieldToElementMapping = (FieldToElementMapping)o;
280
281          if(cls != null ? !cls.equals(fieldToElementMapping.cls) : fieldToElementMapping.cls != null)
282          {
283             return false;
284          }
285          if(field != null ? !field.equals(fieldToElementMapping.field) : fieldToElementMapping.field != null)
286          {
287             return false;
288          }
289          if(localName != null ?
290             !localName.equals(fieldToElementMapping.localName) :
291             fieldToElementMapping.localName != null)
292          {
293             return false;
294          }
295          if(namespaceURI != null ?
296             !namespaceURI.equals(fieldToElementMapping.namespaceURI) :
297             fieldToElementMapping.namespaceURI != null)
298          {
299             return false;
300          }
301
302          return true;
303       }
304
305       public int hashCode()
306       {
307          int result;
308          result = (cls != null ? cls.hashCode() : 0);
309          result = 29 * result + (field != null ? field.hashCode() : 0);
310          result = 29 * result + (namespaceURI != null ? namespaceURI.hashCode() : 0);
311          result = 29 * result + (localName != null ? localName.hashCode() : 0);
312          return result;
313       }
314    }
315 }
316
Popular Tags