KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > xb > binding > DelegatingObjectModelFactory


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.xb.binding;
23
24 import org.xml.sax.Attributes JavaDoc;
25
26 import java.lang.reflect.Method JavaDoc;
27 import java.util.Map JavaDoc;
28 import java.util.HashMap JavaDoc;
29
30 /**
31  * todo come up with a nicer class name
32  *
33  * @author <a HREF="mailto:alex@jboss.org">Alexey Loubyansky</a>
34  * @version <tt>$Revision: 1958 $</tt>
35  */

36 public class DelegatingObjectModelFactory
37    implements GenericObjectModelFactory
38 {
39    private final ObjectModelFactory typedFactory;
40    private final Map JavaDoc addMethodsByParent = new HashMap JavaDoc();
41
42    public DelegatingObjectModelFactory(ObjectModelFactory typedFactory)
43    {
44       this.typedFactory = typedFactory;
45
46       Method JavaDoc[] methods = typedFactory.getClass().getMethods();
47       for(int i = 0; i < methods.length; ++i)
48       {
49          Method JavaDoc method = methods[i];
50          if("addChild".equals(method.getName()))
51          {
52             Class JavaDoc parent = method.getParameterTypes()[0];
53             AddMethods addMethods = (AddMethods)addMethodsByParent.get(parent);
54             if(addMethods == null)
55             {
56                addMethods = new AddMethods(parent);
57                addMethodsByParent.put(parent, addMethods);
58             }
59             addMethods.addMethod(method);
60          }
61       }
62    }
63
64    public Object JavaDoc newRoot(Object JavaDoc root,
65                          UnmarshallingContext navigator,
66                          String JavaDoc namespaceURI,
67                          String JavaDoc localName,
68                          Attributes JavaDoc attrs)
69    {
70       return typedFactory.newRoot(root, navigator, namespaceURI, localName, attrs);
71    }
72
73    public Object JavaDoc newChild(Object JavaDoc parent, UnmarshallingContext navigator, String JavaDoc namespaceURI, String JavaDoc localName, Attributes JavaDoc attrs)
74    {
75       // Get the newChild method
76
Class JavaDoc objClass = parent.getClass();
77       Class JavaDoc[] classes = new Class JavaDoc[] { objClass, UnmarshallingContext.class, String JavaDoc.class, String JavaDoc.class, Attributes JavaDoc.class };
78       Method JavaDoc method = ObjectModelBuilder.getMethodForElement(typedFactory, "newChild", classes);
79
80       // If null, try to get the newChild method from the super class
81
while (method == null && objClass.getSuperclass() != Object JavaDoc.class)
82       {
83          objClass = objClass.getSuperclass();
84          classes = new Class JavaDoc[] { objClass, UnmarshallingContext.class, String JavaDoc.class, String JavaDoc.class, Attributes JavaDoc.class };
85          method = ObjectModelBuilder.getMethodForElement(typedFactory, "newChild", classes);
86       }
87
88       // invoke the setValue method
89
Object JavaDoc child = null;
90       if (method != null)
91       {
92          Object JavaDoc[] objects = new Object JavaDoc[] { parent, navigator, namespaceURI, localName, attrs };
93          child = ObjectModelBuilder.invokeFactory(typedFactory, method, objects);
94       }
95       return child;
96    }
97
98    public void addChild(Object JavaDoc parent,
99                         Object JavaDoc child,
100                         UnmarshallingContext navigator,
101                         String JavaDoc namespaceURI,
102                         String JavaDoc localName)
103    {
104       /*
105       Method method = ObjectModelBuilder.getMethodForElement(typedFactory,
106          "addChild",
107          new Class[]{
108             parent.getClass(),
109             child.getClass(),
110             ContentNavigator.class,
111             String.class,
112             String.class
113          });
114          */

115       AddMethods addMethods = (AddMethods)addMethodsByParent.get(parent.getClass());
116       if(addMethods != null)
117       {
118          Method JavaDoc method = addMethods.getMethodForChild(child.getClass());
119          if(method != null)
120          {
121             ObjectModelBuilder.invokeFactory(typedFactory,
122                method,
123                new Object JavaDoc[]{
124                   parent,
125                   child,
126                   navigator,
127                   namespaceURI,
128                   localName
129                }
130             );
131          }
132       }
133    }
134
135    public void setValue(Object JavaDoc o, UnmarshallingContext navigator, String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc value)
136    {
137       // Get the setValue method
138
Class JavaDoc objClass = o.getClass();
139       Class JavaDoc[] classes = new Class JavaDoc[] { objClass, UnmarshallingContext.class, String JavaDoc.class, String JavaDoc.class, String JavaDoc.class };
140       Method JavaDoc method = ObjectModelBuilder.getMethodForElement(typedFactory, "setValue", classes);
141       
142       // If null, try to get the setValue method from the super class
143
while (method == null && objClass.getSuperclass() != Object JavaDoc.class)
144       {
145          objClass = objClass.getSuperclass();
146          classes = new Class JavaDoc[] { objClass, UnmarshallingContext.class, String JavaDoc.class, String JavaDoc.class, String JavaDoc.class };
147          method = ObjectModelBuilder.getMethodForElement(typedFactory, "setValue", classes);
148       }
149
150       // invoke the setValue method
151
if (method != null)
152       {
153          Object JavaDoc[] objects = new Object JavaDoc[] { o, navigator, namespaceURI, localName, value };
154          ObjectModelBuilder.invokeFactory(typedFactory, method, objects);
155       }
156    }
157
158    public Object JavaDoc completeRoot(Object JavaDoc root, UnmarshallingContext navigator, String JavaDoc namespaceURI, String JavaDoc localName)
159    {
160       return root;
161    }
162
163    // Inner
164

165    private static class AddMethods
166    {
167       private static final int DEFAULT_METHODS_SIZE = 10;
168
169       public final Class JavaDoc parent;
170       private Method JavaDoc[] methods = new Method JavaDoc[DEFAULT_METHODS_SIZE];
171       private int totalMethods;
172
173       public AddMethods(Class JavaDoc parent)
174       {
175          this.parent = parent;
176       }
177
178       public void addMethod(Method JavaDoc m)
179       {
180          if(totalMethods == methods.length)
181          {
182             Method JavaDoc[] tmp = methods;
183             methods = new Method JavaDoc[methods.length + DEFAULT_METHODS_SIZE];
184             System.arraycopy(tmp, 0, methods, 0, tmp.length);
185          }
186          methods[totalMethods++] = m;
187       }
188
189       public Method JavaDoc getMethodForChild(Class JavaDoc child)
190       {
191          Class JavaDoc closestParam = null;
192          Method JavaDoc closestMethod = null;
193          for(int i = 0; i < totalMethods; ++i)
194          {
195             Method JavaDoc method = methods[i];
196             Class JavaDoc param = method.getParameterTypes()[1];
197             if(param == child)
198             {
199                return method;
200             }
201             else if(param.isAssignableFrom(child) && (closestParam == null || closestParam.isAssignableFrom(param)))
202             {
203                closestParam = param;
204                closestMethod = method;
205             }
206          }
207          return closestMethod;
208       }
209
210       public boolean equals(Object JavaDoc o)
211       {
212          if(this == o)
213          {
214             return true;
215          }
216          if(!(o instanceof AddMethods))
217          {
218             return false;
219          }
220
221          final AddMethods addMethods = (AddMethods)o;
222
223          if(!parent.equals(addMethods.parent))
224          {
225             return false;
226          }
227
228          return true;
229       }
230
231       public int hashCode()
232       {
233          return parent.hashCode();
234       }
235    }
236 }
237
Popular Tags