KickJava   Java API By Example, From Geeks To Geeks.

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


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.xml.sax.Attributes JavaDoc;
10 import org.jboss.logging.Logger;
11 import org.jboss.xml.binding.parser.JBossXBParser;
12 import org.apache.xerces.xs.XSTypeDefinition;
13
14 import javax.xml.namespace.QName JavaDoc;
15 import java.util.Map JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.Collections JavaDoc;
18 import java.util.LinkedList JavaDoc;
19 import java.util.StringTokenizer JavaDoc;
20 import java.lang.reflect.InvocationTargetException JavaDoc;
21 import java.lang.reflect.Method JavaDoc;
22
23 /**
24  * An instance of this class translates SAX events into org.jboss.xml.binding.GenericObjectModelFactory calls
25  * such as newChild, addChild and setValue.
26  * WARN: this implementation is not thread-safe!
27  *
28  * @author <a HREF="mailto:alex@jboss.org">Alexey Loubyansky</a>
29  * @version <tt>$Revision: 1.16.2.5 $</tt>
30  */

31 public class ObjectModelBuilder
32    implements ContentNavigator, JBossXBParser.ContentHandler
33 {
34    /**
35     * logger
36     */

37    private static final Logger log = Logger.getLogger(ObjectModelBuilder.class);
38
39    /**
40     * the object that is pushed in the stack when the element read from the XML field is ignored by the
41     * metadata factory
42     */

43    private static final Object JavaDoc IGNORED = new Object JavaDoc();
44
45    private Object JavaDoc root;
46
47    /**
48     * the stack of all the metadata objects including IGNORED
49     */

50    private Stack all = new StackImpl();
51    /**
52     * the stack of only accepted metadata objects
53     */

54    private Stack accepted = new StackImpl();
55
56    private GenericObjectModelFactory curFactory;
57    private String JavaDoc curNameSwitchingFactory;
58    private String JavaDoc curNsSwitchingFactory;
59    private Stack nameSwitchingFactory;
60    private Stack nsSwitchingFactory;
61
62    /**
63     * default object model factory
64     */

65    private GenericObjectModelFactory defaultFactory;
66    /**
67     * factories mapped to namespace URIs
68     */

69    private Map JavaDoc factoriesToNs = Collections.EMPTY_MAP;
70
71    private Map JavaDoc prefixToUri = new HashMap JavaDoc();
72
73    /**
74     * the value of a simple element (i.e. the element that does not contain nested elements) being read
75     */

76    private StringBuffer JavaDoc value = new StringBuffer JavaDoc();
77
78    private XSTypeDefinition currentType;
79
80    // Public
81

82    public void mapFactoryToNamespace(GenericObjectModelFactory factory, String JavaDoc namespaceUri)
83    {
84       if(factoriesToNs == Collections.EMPTY_MAP)
85       {
86          factoriesToNs = new HashMap JavaDoc();
87       }
88       factoriesToNs.put(namespaceUri, factory);
89    }
90
91    public void init(GenericObjectModelFactory defaultFactory, Object JavaDoc root)
92    {
93       this.defaultFactory = defaultFactory;
94
95       all.clear();
96       accepted.clear();
97       value.delete(0, value.length());
98       this.root = root;
99    }
100
101    /*
102    public Object build(GenericObjectModelFactory defaultFactory, Object root, Content content)
103       throws Exception
104    {
105       this.defaultFactory = defaultFactory;
106       this.content = content;
107
108       all.clear();
109       accepted.clear();
110       value.delete(0, value.length());
111
112       boolean popRoot = false;
113       if(root != null)
114       {
115          all.push(root);
116          accepted.push(root);
117          popRoot = true;
118       }
119
120       content.build(this);
121
122       if(popRoot)
123       {
124          root = all.pop();
125          accepted.pop();
126       }
127
128       return this.root;
129    }
130    */

131
132    // ContentNavigator implementation
133

134    public Map JavaDoc getPrefixToNamespaceMap()
135    {
136       return Collections.unmodifiableMap(prefixToUri);
137    }
138
139    public String JavaDoc resolveNamespacePrefix(String JavaDoc prefix)
140    {
141       String JavaDoc uri;
142       LinkedList JavaDoc prefixStack = (LinkedList JavaDoc) prefixToUri.get(prefix);
143       if(prefixStack != null && !prefixStack.isEmpty())
144       {
145          uri = (String JavaDoc) prefixStack.getFirst();
146       }
147       else
148       {
149          uri = null;
150       }
151       return uri;
152    }
153
154    /**
155     * Construct a QName from a value
156     *
157     * @param value A value that is of the form [prefix:]localpart
158     */

159    public QName JavaDoc resolveQName(String JavaDoc value)
160    {
161       StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(value, ":");
162       if(st.countTokens() == 1)
163       {
164          return new QName JavaDoc(value);
165       }
166
167       if(st.countTokens() != 2)
168       {
169          throw new IllegalArgumentException JavaDoc("Illegal QName: " + value);
170       }
171
172       String JavaDoc prefix = st.nextToken();
173       String JavaDoc local = st.nextToken();
174       String JavaDoc nsURI = resolveNamespacePrefix(prefix);
175
176       return new QName JavaDoc(nsURI, local);
177    }
178
179    public String JavaDoc getChildContent(String JavaDoc namespaceURI, String JavaDoc qName)
180    {
181       // todo reimplement later
182
throw new UnsupportedOperationException JavaDoc();
183       //return content.getChildContent(namespaceURI, qName);
184
}
185
186    public XSTypeDefinition getType()
187    {
188       return currentType;
189    }
190    
191    // Public
192

193    public void startPrefixMapping(String JavaDoc prefix, String JavaDoc uri)
194    {
195       LinkedList JavaDoc prefixStack = (LinkedList JavaDoc) prefixToUri.get(prefix);
196       if(prefixStack == null || prefixStack.isEmpty())
197       {
198          prefixStack = new LinkedList JavaDoc();
199          prefixToUri.put(prefix, prefixStack);
200       }
201       prefixStack.addFirst(uri);
202    }
203
204    public void endPrefixMapping(String JavaDoc prefix)
205    {
206       LinkedList JavaDoc prefixStack = (LinkedList JavaDoc) prefixToUri.get(prefix);
207       if(prefixStack != null)
208       {
209          prefixStack.removeFirst();
210       }
211    }
212
213    public Object JavaDoc getRoot()
214    {
215       if(!all.isEmpty())
216       {
217          all.pop();
218          accepted.pop();
219       }
220       return root;
221    }
222
223    public void startElement(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qName, Attributes JavaDoc atts, XSTypeDefinition type)
224    {
225       Object JavaDoc parent = accepted.isEmpty() ? root : accepted.peek();
226
227       // todo currentType assignment
228
currentType = type;
229
230       Object JavaDoc element;
231       if(!namespaceURI.equals(curNsSwitchingFactory))
232       {
233          if(curNsSwitchingFactory != null)
234          {
235             if(nsSwitchingFactory == null)
236             {
237                nsSwitchingFactory = new StackImpl();
238                nameSwitchingFactory = new StackImpl();
239             }
240             nsSwitchingFactory.push(curNsSwitchingFactory);
241             nameSwitchingFactory.push(curNameSwitchingFactory);
242          }
243          curNsSwitchingFactory = namespaceURI;
244          curNameSwitchingFactory = localName;
245          curFactory = getFactory(namespaceURI);
246
247          element = curFactory.newRoot(parent, this, namespaceURI, localName, atts);
248       }
249       else
250       {
251          element = curFactory.newChild(parent, this, namespaceURI, localName, atts);
252       }
253
254       if(element == null)
255       {
256          all.push(IGNORED);
257
258          if(log.isTraceEnabled())
259          {
260             log.trace("ignored " + namespaceURI + ':' + qName);
261          }
262       }
263       else
264       {
265          all.push(element);
266          accepted.push(element);
267
268          if(log.isTraceEnabled())
269          {
270             log.trace("accepted " + namespaceURI + ':' + qName);
271          }
272       }
273    }
274
275    public void endElement(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qName)
276    {
277       if(value.length() > 0)
278       {
279          Object JavaDoc element;
280          try
281          {
282             element = accepted.peek();
283          }
284          catch(java.util.NoSuchElementException JavaDoc e)
285          {
286             log.error("value=" + value, e);
287             throw e;
288          }
289          curFactory.setValue(element, this, namespaceURI, localName, value.toString().trim());
290          value.delete(0, value.length());
291       }
292
293       if(localName.equals(curNameSwitchingFactory) && namespaceURI.equals(curNsSwitchingFactory))
294       {
295          if(nsSwitchingFactory == null || nsSwitchingFactory.isEmpty())
296          {
297             curNameSwitchingFactory = null;
298             curNsSwitchingFactory = null;
299          }
300          else
301          {
302             curNameSwitchingFactory = (String JavaDoc)nameSwitchingFactory.pop();
303             curNsSwitchingFactory = (String JavaDoc)nsSwitchingFactory.pop();
304          }
305
306          curFactory = getFactory(curNsSwitchingFactory);
307       }
308
309       Object JavaDoc element = all.pop();
310       if(element != IGNORED)
311       {
312          element = accepted.pop();
313          Object JavaDoc parent = (accepted.isEmpty() ? null : accepted.peek());
314
315          if(parent != null)
316          {
317             curFactory.addChild(parent, element, this, namespaceURI, localName);
318          }
319          else
320          {
321             root = curFactory.completedRoot(element, this, namespaceURI, localName);
322          }
323       }
324    }
325
326    public void characters(char[] ch, int start, int length)
327    {
328       value.append(ch, start, length);
329    }
330
331    // Private
332

333    private GenericObjectModelFactory getFactory(String JavaDoc namespaceUri)
334    {
335       GenericObjectModelFactory factory = (GenericObjectModelFactory)factoriesToNs.get(namespaceUri);
336       if(factory == null)
337       {
338          factory = defaultFactory;
339       }
340       return factory;
341    }
342
343    static Object JavaDoc invokeFactory(Object JavaDoc factory, Method JavaDoc method, Object JavaDoc[] args)
344    {
345       try
346       {
347          return method.invoke(factory, args);
348       }
349       catch(InvocationTargetException JavaDoc e)
350       {
351          log.error("Failed to invoke method " + method.getName(), e.getTargetException());
352          throw new IllegalStateException JavaDoc("Failed to invoke method " + method.getName());
353       }
354       catch(Exception JavaDoc e)
355       {
356          log.error("Failed to invoke method " + method.getName(), e);
357          throw new IllegalStateException JavaDoc("Failed to invoke method " + method.getName());
358       }
359    }
360
361    static Method JavaDoc getMethodForElement(Object JavaDoc factory, String JavaDoc name, Class JavaDoc[] params)
362    {
363       Method JavaDoc method = null;
364       try
365       {
366          method = factory.getClass().getMethod(name, params);
367       }
368       catch(NoSuchMethodException JavaDoc e)
369       {
370       }
371       catch(SecurityException JavaDoc e)
372       {
373          throw new IllegalStateException JavaDoc(e.getMessage());
374       }
375
376       return method;
377    }
378
379    private static interface Stack
380    {
381       void clear();
382
383       void push(Object JavaDoc o);
384
385       Object JavaDoc pop();
386
387       Object JavaDoc peek();
388
389       boolean isEmpty();
390    }
391
392    private static class StackImpl
393       implements Stack
394    {
395       private LinkedList JavaDoc list = new LinkedList JavaDoc();
396
397       public void clear()
398       {
399          list.clear();
400       }
401
402       public void push(Object JavaDoc o)
403       {
404          list.addLast(o);
405       }
406
407       public Object JavaDoc pop()
408       {
409          return list.removeLast();
410       }
411
412       public Object JavaDoc peek()
413       {
414          return list.getLast();
415       }
416
417       public boolean isEmpty()
418       {
419          return list.isEmpty();
420       }
421    }
422 }
423
Popular Tags