View Javadoc

1   /*
2   
3       stax  Stack API for XML.
4       Copyright (c) 2001-2006 held jointly by the individual authors.
5   
6       This library is free software; you can redistribute it and/or modify it
7       under the terms of the GNU Lesser General Public License as published
8       by the Free Software Foundation; either version 2.1 of the License, or (at
9       your option) any later version.
10  
11      This library is distributed in the hope that it will be useful, but WITHOUT
12      ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
13      FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14      License for more details.
15  
16      You should have received a copy of the GNU Lesser General Public License
17      along with this library;  if not, write to the Free Software Foundation,
18      Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA.
19  
20      > http://www.gnu.org/copyleft/lesser.html
21      > http://www.opensource.org/licenses/lgpl-license.php
22  
23  */
24  package net.sf.stax;
25  
26  import java.util.Map;
27  import java.util.HashMap;
28  
29  import org.xml.sax.Attributes;
30  import org.xml.sax.SAXException;
31  
32  /***
33   * On-element dispatch.
34   *
35   * <p>Select from one of the concrete subclasses <b>ByNsURI</b>,
36   * <b>ByLocalName</b>, or <b>ByQName</b>.</p>
37   *
38   * @see DispatchOnElement.ByNsURI
39   * @see DispatchOnElement.ByLocalName
40   * @see DispatchOnElement.ByQName
41   *
42   * @author  Thomas Down
43   * @author  Matthew Pocock
44   * @author  Michael Heuer
45   * @version $Revision: 1.2 $ $Date: 2006/01/02 20:37:34 $
46   */
47  public abstract class DispatchOnElement
48      extends StAXContentHandlerBase
49  {
50      /*** Return value. */
51      private Object retVal;
52  
53      /*** Map of names to handlers. */
54      private Map nameToHandler;
55  
56      /*** Default handler. */
57      private StAXContentHandler defaultHandler;
58  
59  
60      /***
61       * Create a new on-element dispatch.
62       */
63      protected DispatchOnElement()
64      {
65          nameToHandler = new HashMap();
66      }
67  
68  
69      /***
70       * Choose a handler for the specified namespace URI, local
71       * name, and qualified XML name.
72       *
73       * @param nsURI namespace URI
74       * @param localName local name (without prefix)
75       * @param qName qualified XML name (with prefix)
76       * @return a handler for the specified namespare URI, local
77       *    name, and qualified XML name
78       * @throws SAXException any SAX exception, possibly wrapping another exception
79       */
80      protected abstract StAXContentHandler chooseHandler(final String nsURI,
81                                                          final String localName,
82                                                          final String qName)
83          throws SAXException;
84  
85      /*** @see StAXContentHandlerBase */
86      public final void startElement(final String nsURI,
87                                     final String localName,
88                                     final String qName,
89                                     final Attributes attrs,
90                                     final StAXDelegationContext dctx)
91          throws SAXException
92      {
93          StAXContentHandler handler = chooseHandler(nsURI, localName, qName);
94  
95          if (handler == null)
96          {
97              handler = defaultHandler;
98          }
99          if (handler == null)
100         {
101             throw new SAXException(this + " Can't find handler for " + nsURI + " " + localName
102                                    + " " + qName + " among " + nameToHandler.keySet());
103         }
104         else
105         {
106             dctx.delegate(handler);
107         }
108     }
109 
110     /*** @see StAXContentHandlerBase */
111     public final void endElement(final String nsURI,
112                                  final String localName,
113                                  final String qName,
114                                  final Object retVal,
115                                  final StAXContext ctx)
116         throws SAXException
117     {
118         this.retVal = retVal;
119     }
120 
121     /*** @see StAXContentHandlerBase */
122     public final Object endTree(final StAXContext ctx)
123     {
124         return retVal;
125     }
126 
127     /***
128      * Add the specified named handler.
129      *
130      * @param name name
131      * @param handler handler
132      */
133     public final void setHandler(final String name, final StAXContentHandler handler)
134     {
135         nameToHandler.put(name, handler);
136     }
137 
138     /***
139      * Set the default handler for this on-element dispatch
140      * to <code>handler</code>.
141      *
142      * @param handler default handler
143      */
144     public final void setDefaultHandler(final StAXContentHandler handler)
145     {
146         this.defaultHandler = handler;
147     }
148 
149     /***
150      * Return the default handler for this on-element dispatch.
151      *
152      * @return the default handler for this on-element dispatch
153      */
154     public final StAXContentHandler getDefaultHandler()
155     {
156         return defaultHandler;
157     }
158 
159     /***
160      * Return the handler associated with the specified name.
161      *
162      * @param name name
163      * @return the handler associated with the specified name
164      */
165     public final StAXContentHandler getHandler(final String name)
166     {
167         return (StAXContentHandler) nameToHandler.get(name);
168     }
169 
170 
171     /***
172      * On-element dispatch that chooses handlers by namespace URI.
173      *
174      * <p>This class replaces
175      * <pre>
176      * class FooHandler
177      *     extends StAXContentHandlerBase
178      * {
179      *     public void startElement(..., StAXDelegationContext dctx)
180      *     {
181      *         if ("urn:net.sf.stax:bar".equals(nsURI))
182      *         {
183      *             dctx.delegate(barHandler);
184      *         }
185      *         else if ("urn:net.sf.stax:baz".equals(nsURI))
186      *         {
187      *             dctx.delegate.(bazHandler);
188      *         }
189      *     }
190      * }
191      * </pre>
192      * with
193      * <pre>
194      * DispatchOnElement dispatch = new DispatchOnElement.ByNsURI();
195      * dispatch.setHandler("urn:net.sf.stax:bar", barHandler);
196      * dispatch.setHandler("urn:net.sf.stax:baz", bazHandler);
197      * </pre></p>
198      */
199     public static final class ByNsURI
200         extends DispatchOnElement
201     {
202 
203         /*** @see DispatchOnElement */
204         protected StAXContentHandler chooseHandler(final String nsURI,
205                                                    final String localName,
206                                                    final String qName)
207             throws SAXException
208         {
209             return getHandler(nsURI);
210         }
211     }
212 
213     /***
214      * On-element dispatch that chooses handlers by local name.
215      *
216      * <p>This class replaces
217      * <pre>
218      * class FooHandler
219      *     extends StAXContentHandlerBase
220      * {
221      *     public void startElement(..., StAXDelegationContext dctx)
222      *     {
223      *         if ("bar".equals(localName))
224      *         {
225      *             dctx.delegate(barHandler);
226      *         }
227      *         else if ("baz".equals(localName))
228      *         {
229      *             dctx.delegate.(bazHandler);
230      *         }
231      *     }
232      * }
233      * </pre>
234      * with
235      * <pre>
236      * DispatchOnElement dispatch = new DispatchOnElement.ByLocalName();
237      * dispatch.setHandler("bar", barHandler);
238      * dispatch.setHandler("baz", bazHandler);
239      * </pre></p>
240      */
241     public static final class ByLocalName
242         extends DispatchOnElement
243     {
244 
245         /*** @see DispatchOnElement */
246         protected StAXContentHandler chooseHandler(final String nsURI,
247                                                    final String localName,
248                                                    final String qName)
249             throws SAXException
250         {
251             return getHandler(localName);
252         }
253     }
254 
255     /***
256      * On-element dispatch that chooses handlers by qualified XML name.
257      *
258      * <p>This class replaces
259      * <pre>
260      * class FooHandler
261      *     extends StAXContentHandlerBase
262      * {
263      *     public void startElement(..., StAXDelegationContext dctx)
264      *     {
265      *         if ("bar".equals(qName))
266      *         {
267      *             dctx.delegate(barHandler);
268      *         }
269      *         else if ("baz".equals(qName))
270      *         {
271      *             dctx.delegate.(bazHandler);
272      *         }
273      *     }
274      * }
275      * </pre>
276      * with
277      * <pre>
278      * DispatchOnElement dispatch = new DispatchOnElement.ByQName();
279      * dispatch.setHandler("bar", barHandler);
280      * dispatch.setHandler("baz", bazHandler);
281      * </pre></p>
282      */
283     public static final class ByQName
284         extends DispatchOnElement
285     {
286 
287         /*** @see DispatchOnElement */
288         protected StAXContentHandler chooseHandler(final String nsURI,
289                                                    final String localName,
290                                                    final String qName)
291             throws SAXException
292         {
293             return getHandler(qName);
294         }
295     }
296 }