Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/objectstyle/cayenne/util/AbstractHandler.java


1   /* ====================================================================
2    * 
3    * The ObjectStyle Group Software License, Version 1.0 
4    *
5    * Copyright (c) 2002-2003 The ObjectStyle Group 
6    * and individual authors of the software.  All rights reserved.
7    *
8    * Redistribution and use in source and binary forms, with or without
9    * modification, are permitted provided that the following conditions
10   * are met:
11   *
12   * 1. Redistributions of source code must retain the above copyright
13   *    notice, this list of conditions and the following disclaimer. 
14   *
15   * 2. Redistributions in binary form must reproduce the above copyright
16   *    notice, this list of conditions and the following disclaimer in
17   *    the documentation and/or other materials provided with the
18   *    distribution.
19   *
20   * 3. The end-user documentation included with the redistribution, if
21   *    any, must include the following acknowlegement:  
22   *       "This product includes software developed by the 
23   *        ObjectStyle Group (http://objectstyle.org/)."
24   *    Alternately, this acknowlegement may appear in the software itself,
25   *    if and wherever such third-party acknowlegements normally appear.
26   *
27   * 4. The names "ObjectStyle Group" and "Cayenne" 
28   *    must not be used to endorse or promote products derived
29   *    from this software without prior written permission. For written 
30   *    permission, please contact andrus@objectstyle.org.
31   *
32   * 5. Products derived from this software may not be called "ObjectStyle"
33   *    nor may "ObjectStyle" appear in their names without prior written
34   *    permission of the ObjectStyle Group.
35   *
36   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39   * DISCLAIMED.  IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
40   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47   * SUCH DAMAGE.
48   * ====================================================================
49   *
50   * This software consists of voluntary contributions made by many
51   * individuals on behalf of the ObjectStyle Group.  For more
52   * information on the ObjectStyle Group, please see
53   * <http://objectstyle.org/>.
54   *
55   */
56  package org.objectstyle.cayenne.util;
57  
58  import org.xml.sax.Attributes;
59  import org.xml.sax.ContentHandler;
60  import org.xml.sax.SAXException;
61  import org.xml.sax.XMLReader;
62  import org.xml.sax.helpers.DefaultHandler;
63  
64  
65  /**
66   * The common superclass for all SAX event handlers used to parse
67   * the configuration file. Each method just throws an exception, 
68   * so subclasses should override what they can handle.
69   *
70   * Each type of XML element (map, node, etc.) has
71   * a specific subclass.
72   *
73   * In the constructor, this class takes over the handling of SAX
74   * events from the parent handler and returns
75   * control back to the parent in the endElement method.
76   * <p>
77   * The idea to use nested handlers for XML document parsing
78   * (and code to implement it) were taken from org.apache.tools.ant.ProjectHelper 
79   * from Jakarta-Ant project (Copyright: Apache Software Foundation).
80   * This may not be the best way to build objects from XML, but it is rather 
81   * consistent. For each nested element in the XML tree a dedicated handler
82   * is created (subclass of this AbstractHandler). Once the element is parsed, 
83   * control is handled back to the parent handler.
84   * </p>
85   *
86   * @author Andrei Adamchik 
87   */
88  public class AbstractHandler extends DefaultHandler {
89      /** Current parser. */
90      protected XMLReader parser;
91  
92      /** Previous handler for the document.
93       * When the next element is finished, control returns
94       * to this handler. */
95      protected ContentHandler parentHandler;
96  
97      /**
98       * Creates a handler and sets the parser to use it
99       * for the current element.
100      * 
101      * @param parser  Currently used XML parser. 
102      *                Must not be <code>null</code>.
103      * @param parentHandler The handler which should be restored to the 
104      *                      parser at the end of the element. 
105      *                      Must not be <code>null</code>.
106      */
107     public AbstractHandler(XMLReader parser, ContentHandler parentHandler) {
108         this.parentHandler = parentHandler;
109         this.parser = parser;
110 
111         // Start handling SAX events
112         parser.setContentHandler(this);
113     }
114 
115     /** Returns currently used XMLReader. */
116     public XMLReader getParser() {
117         return parser;
118     }
119 
120 
121     /**
122      * Handles the start of an element. This base implementation just
123      * throws an exception.
124      * 
125      * @param tag The name of the element being started. 
126      *            Will not be <code>null</code>.
127      * @param attrs Attributes of the element being started.
128      *              Will not be <code>null</code>.
129      * 
130      * @exception SAXException if this method is not overridden, or in
131      *                              case of error in an overridden version
132      */
133     public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
134     throws SAXException {
135         throw new SAXException(this.getClass().getName() + ": unexpected element \"" + localName + "\"");
136     }
137 
138     /**
139      * Handles text within an element. This base implementation just
140      * throws an exception.
141      * 
142      * @param buf A character array of the text within the element.
143      *            Will not be <code>null</code>.
144      * @param start The start element in the array.
145      * @param count The number of characters to read from the array.
146      * 
147      * @exception SAXException if this method is not overridden, or in
148      *                              case of error in an overridden version
149      */
150     public void characters(char[] buf, int start, int count) throws SAXException {
151         String s = new String(buf, start, count).trim();
152 
153         if (s.length() > 0) {
154             throw new SAXException(this.getClass().getName() + ": unexpected text \"" + s + "\"");
155         }
156     }
157 
158     /**
159      * Called when this element and all elements nested into it have been
160      * handled.
161      */
162     protected void finished() {}
163 
164 
165     /**
166      * Handles the end of an element. Any required clean-up is performed
167      * by the finished() method and then the original handler is restored to
168      * the parser.
169      * 
170      * @see #finished()
171      */
172     public void endElement(String namespaceURI, String localName, String qName)
173     throws SAXException {
174         finished();
175         // Let parent resume handling SAX events
176         parser.setContentHandler(parentHandler);
177     }
178 }
179