KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > xb > binding > metadata > unmarshalling > impl > RuntimeDocumentBinding


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.xb.binding.metadata.unmarshalling.impl;
8
9 import org.jboss.xb.binding.metadata.unmarshalling.DocumentBinding;
10 import org.jboss.xb.binding.metadata.unmarshalling.TopElementBinding;
11 import org.jboss.xb.binding.metadata.unmarshalling.NamespaceBinding;
12 import org.jboss.xb.binding.metadata.unmarshalling.ElementBinding;
13 import org.jboss.xb.binding.metadata.unmarshalling.AttributeBinding;
14 import org.jboss.xb.binding.metadata.unmarshalling.BasicElementBinding;
15 import org.jboss.xb.binding.metadata.unmarshalling.XmlValueBinding;
16 import org.jboss.xb.binding.Util;
17 import org.jboss.xb.binding.JBossXBRuntimeException;
18
19 import javax.xml.namespace.QName JavaDoc;
20 import java.lang.reflect.Field JavaDoc;
21 import java.lang.reflect.Method JavaDoc;
22 import java.lang.reflect.Modifier JavaDoc;
23 import java.util.Collection JavaDoc;
24 import java.util.ArrayList JavaDoc;
25
26 /**
27  * @author <a HREF="mailto:alex@jboss.org">Alexey Loubyansky</a>
28  * @version <tt>$Revision: 1.1.2.1 $</tt>
29  */

30 public class RuntimeDocumentBinding
31    extends DocumentBindingFactoryImpl.AbstractDocumentBinding
32 {
33    public RuntimeDocumentBinding(DocumentBinding doc)
34    {
35       super(doc);
36    }
37
38    protected NamespaceBinding getNamespaceLocal(String JavaDoc namespaceUri)
39    {
40       return new RuntimeNamespaceBinding(this, namespaceUri);
41    }
42
43    // Inner
44

45    private static class RuntimeNamespaceBinding
46       extends DocumentBindingFactoryImpl.AbstractNamespaceBinding
47    {
48       private String JavaDoc pkg;
49
50       public RuntimeNamespaceBinding(DocumentBinding doc, String JavaDoc namespaceUri)
51       {
52          super(doc, namespaceUri);
53       }
54
55       protected String JavaDoc getJavaPackageLocal()
56       {
57          if(pkg == null)
58          {
59             pkg = Util.xmlNamespaceToJavaPackage(namespaceUri);
60          }
61          return pkg;
62       }
63
64       protected TopElementBinding getTopElementLocal(String JavaDoc elementName)
65       {
66          return new RuntimeTopElementBinding(this, elementName);
67       }
68    }
69
70    static class RuntimeTopElementBinding
71       extends DocumentBindingFactoryImpl.AbstractTopElementBinding
72    {
73       private Class JavaDoc javaType;
74
75       public RuntimeTopElementBinding(NamespaceBinding ns, String JavaDoc elementName)
76       {
77          super(ns, elementName);
78       }
79
80       protected Class JavaDoc getJavaTypeLocal()
81       {
82          if(javaType == null)
83          {
84             javaType = loadDefaultClass(this);
85             if(javaType == null)
86             {
87                throw new IllegalStateException JavaDoc(
88                   "Failed to bind top element " + name + ": class not found " + getDefaultClassName(this)
89                );
90             }
91          }
92          return javaType;
93       }
94
95       protected ElementBinding getElementLocal(QName JavaDoc elementName)
96       {
97          return new RuntimeElementBinding(this, elementName);
98       }
99
100       protected AttributeBinding getAttributeLocal(QName JavaDoc attributeName)
101       {
102          String JavaDoc fieldName = Util.xmlNameToFieldName(attributeName.getLocalPart(), true);
103          return new AttributeBindingImpl(attributeName, null, getJavaType(), fieldName);
104       }
105
106       protected XmlValueBinding getValueLocal()
107       {
108          // todo: implement getValueLocal
109
throw new UnsupportedOperationException JavaDoc("getValueLocal is not implemented.");
110       }
111    }
112
113    static class RuntimeElementBinding
114       extends DocumentBindingFactoryImpl.AbstractElementBinding
115    {
116       private Field JavaDoc field;
117       private Method JavaDoc getter;
118       private Method JavaDoc setter;
119       private Class JavaDoc fieldType;
120       private Class JavaDoc javaType;
121
122       public RuntimeElementBinding(BasicElementBinding parent, QName JavaDoc elementName)
123       {
124          super(parent, elementName);
125       }
126
127       private void init()
128       {
129          Class JavaDoc parentType = parent.getJavaType();
130          javaType = loadDefaultClass(this);
131
132          if(Collection JavaDoc.class.isAssignableFrom(parentType))
133          {
134             if(javaType == null)
135             {
136                javaType = String JavaDoc.class;
137             }
138          }
139          else
140          {
141             String JavaDoc baseMethodName = Util.xmlNameToClassName(name.getLocalPart(), true);
142             try
143             {
144                getter = parentType.getMethod("get" + baseMethodName, null);
145                setter = parentType.getMethod("set" + baseMethodName, new Class JavaDoc[]{getter.getReturnType()});
146                fieldType = getter.getReturnType();
147             }
148             catch(NoSuchMethodException JavaDoc e)
149             {
150                try
151                {
152                   field = parentType.getField(Util.xmlNameToFieldName(name.getLocalPart(), true));
153                   fieldType = field.getType();
154                }
155                catch(NoSuchFieldException JavaDoc e1)
156                {
157                   throw new JBossXBRuntimeException("Failed to bind " + name + " to any field in " + parentType);
158                }
159             }
160          }
161
162          if(javaType == null)
163          {
164             javaType = fieldType;
165          }
166          else if(fieldType != null && fieldType != javaType && fieldType.isAssignableFrom(javaType))
167          {
168             javaType = fieldType;
169          }
170
171          if(javaType == null)
172          {
173             throw new JBossXBRuntimeException("Failed to bind " +
174                name +
175                " to any Java type: field=" +
176                field +
177                ", getter=" +
178                getter +
179                ", parent=" +
180                parentType
181             );
182          }
183          else if(Collection JavaDoc.class == javaType || Collection JavaDoc.class.isAssignableFrom(javaType))
184          {
185             // todo support other collections
186
javaType = ArrayList JavaDoc.class;
187          }
188          else if(javaType.isInterface() || Modifier.isAbstract(javaType.getModifiers()))
189          {
190             throw new JBossXBRuntimeException("Failed to bind " +
191                name +
192                " to a non-abstract Java type: field=" +
193                field +
194                ", getter=" +
195                getter +
196                ", parent=" +
197                parentType
198             );
199          }
200       }
201
202       protected Field JavaDoc getFieldLocal()
203       {
204          if(javaType == null)
205          {
206             init();
207          }
208          return field;
209       }
210
211       protected Method JavaDoc getGetterLocal()
212       {
213          if(javaType == null)
214          {
215             init();
216          }
217          return getter;
218       }
219
220       protected Method JavaDoc getSetterLocal()
221       {
222          if(javaType == null)
223          {
224             init();
225          }
226          return setter;
227       }
228
229       protected Class JavaDoc getFieldTypeLocal()
230       {
231          if(javaType == null)
232          {
233             init();
234          }
235          return fieldType;
236       }
237
238       protected Class JavaDoc getJavaTypeLocal()
239       {
240          if(javaType == null)
241          {
242             init();
243          }
244          return javaType;
245       }
246
247       protected ElementBinding getElementLocal(QName JavaDoc elementName)
248       {
249          return new RuntimeElementBinding(this, elementName);
250       }
251
252       protected AttributeBinding getAttributeLocal(QName JavaDoc attributeName)
253       {
254          String JavaDoc fieldName = Util.xmlNameToFieldName(attributeName.getLocalPart(), true);
255          return new AttributeBindingImpl(attributeName, null, getJavaType(), fieldName);
256       }
257
258       protected XmlValueBinding getValueLocal()
259       {
260          // todo: implement getValueLocal
261
throw new UnsupportedOperationException JavaDoc("getValueLocal is not implemented.");
262       }
263    }
264
265    private static Class JavaDoc loadDefaultClass(BasicElementBinding element)
266    {
267       Class JavaDoc javaType;
268       String JavaDoc clsName = getDefaultClassName(element);
269       try
270       {
271          javaType = Thread.currentThread().getContextClassLoader().loadClass(clsName);
272       }
273       catch(ClassNotFoundException JavaDoc e)
274       {
275          javaType = null;
276       }
277       return javaType;
278    }
279
280    private static String JavaDoc getDefaultClassName(BasicElementBinding element)
281    {
282       QName JavaDoc elementName = element.getName();
283       NamespaceBinding ns = element.getDocument().getNamespace(elementName.getNamespaceURI());
284       return ns.getJavaPackage() + "." + Util.xmlNameToClassName(elementName.getLocalPart(), true);
285    }
286 }
287
Popular Tags