View Javadoc
1   /*
2    * Redistribution and use of this software and associated documentation
3    * ("Software"), with or without modification, are permitted provided
4    * that the following conditions are met:
5    *
6    * 1. Redistributions of source code must retain copyright
7    *    statements and notices.  Redistributions must also contain a
8    *    copy of this document.
9    *
10   * 2. Redistributions in binary form must reproduce the
11   *    above copyright notice, this list of conditions and the
12   *    following disclaimer in the documentation and/or other
13   *    materials provided with the distribution.
14   *
15   * 3. The name "Exolab" must not be used to endorse or promote
16   *    products derived from this Software without prior written
17   *    permission of Intalio, Inc.  For written permission,
18   *    please contact info@exolab.org.
19   *
20   * 4. Products derived from this Software may not be called "Exolab"
21   *    nor may "Exolab" appear in their names without prior written
22   *    permission of Intalio, Inc. Exolab is a registered
23   *    trademark of Intalio, Inc.
24   *
25   * 5. Due credit should be given to the Exolab Project
26   *    (http://www.exolab.org/).
27   *
28   * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
29   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
32   * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39   * OF THE POSSIBILITY OF SUCH DAMAGE.
40   *
41   * Copyright 2004 (C) Intalio, Inc. All Rights Reserved.
42   *
43   *
44   */
45  package org.exolab.castor.xml.util;
46  
47  import org.exolab.castor.xml.Namespaces;
48  import org.exolab.castor.xml.NamespacesStack;
49  import org.xml.sax.Attributes;
50  import org.xml.sax.ContentHandler;
51  import org.xml.sax.DocumentHandler;
52  import org.xml.sax.Locator;
53  import org.xml.sax.SAXException;
54  import org.xml.sax.helpers.AttributeListImpl;
55  
56  /**
57   * A ContentHandler implementation that wraps a DocumentHandler. This
58   * ContentHandler was written for the Marshaller and expects that QNames
59   * are non-null in calls to startElement and endElement methods as well
60   * as inside the Attributes list.
61   *
62   * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
63   * @version $Revision$ $Date: 2004-09-10 12:15:10 -0600 (Fri, 10 Sep 2004) $
64   */
65  public class DocumentHandlerAdapter implements ContentHandler {
66  
67      private static final String CDATA = "CDATA";
68  
69      private DocumentHandler _handler = null;
70  
71      /**
72       * Represents the namespaces stack.
73       */
74      private NamespacesStack namespacesStack = null;
75  
76      private boolean _createNamespaceScope = true;
77  
78      /**
79       * Creates a new DocumentHandlerAdapter
80       *
81       * @param handler the DocumentHandler to wrap (non-null).
82       */
83      public DocumentHandlerAdapter(DocumentHandler handler) {
84          if (handler == null) {
85              throw new IllegalArgumentException("The argument 'handler' must not be null.");
86          }
87          _handler = handler;
88          namespacesStack = new NamespacesStack();
89      }
90  
91      /**
92       * @see org.xml.sax.ContentHandler#characters(char[], int, int)
93       */
94      public void characters(char[] chars, int start, int length)
95          throws SAXException
96      {
97          _handler.characters(chars, start, length);
98      }
99  
100     /**
101      * @see org.xml.sax.ContentHandler#endDocument()
102      */
103     public void endDocument()
104         throws SAXException
105     {
106         _handler.endDocument();
107     }
108 
109     /**
110      * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String,
111      *      java.lang.String)
112      */
113     public void endElement(String uri, String localName, String qName)
114         throws SAXException
115     {
116         _handler.endElement(qName);
117         namespacesStack.removeNamespaceScope();
118     }
119 
120     /**
121      * @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
122      */
123     public void endPrefixMapping(String prefix)
124         throws SAXException
125     {
126         //-- do nothing here, this is handled in endElement
127         //-- by simply removing the current namespace scope
128 
129     }
130 
131     /**
132      * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
133      */
134     public void ignorableWhitespace(char[] chars, int start, int length)
135         throws SAXException
136     {
137         _handler.ignorableWhitespace(chars, start, length);
138     }
139 
140     /**
141      * @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String, java.lang.String)
142      */
143     public void processingInstruction(String target, String data)
144             throws SAXException
145     {
146         _handler.processingInstruction(target, data);
147     }
148 
149     /**
150      * @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
151      */
152     public void setDocumentLocator(Locator locator)
153     {
154         _handler.setDocumentLocator(locator);
155     }
156 
157     /**
158      * @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
159      */
160     public void skippedEntity(String arg0)
161         throws SAXException
162     {
163         //-- do nothing
164     }
165 
166     /**
167      * @see org.xml.sax.ContentHandler#startDocument()
168      */
169     public void startDocument()
170         throws SAXException
171     {
172         _handler.startDocument();
173     }
174 
175     /**
176      * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
177      */
178     public void startElement(String uri, String localName, String qName, Attributes atts)
179         throws SAXException
180     {
181         AttributeListImpl attList = new AttributeListImpl();
182 
183         //-- Create a new namespace scope if necessary and
184         //-- make sure the flag is reset to true
185         if (_createNamespaceScope) {
186             //-- no current namespaces, but we create a new scope
187             //-- to make things easier in the endElement method
188             namespacesStack.addNewNamespaceScope();
189         }
190         else {
191             _createNamespaceScope = true;
192             namespacesStack.declareAsAttributes(attList, true);
193         }
194 
195         //-- copy Attributes to AttributeList
196         for (int i = 0; i < atts.getLength(); i++) {
197             attList.addAttribute(atts.getQName(i), CDATA, atts.getValue(i));
198         }
199 
200         _handler.startElement(qName, attList);
201 
202     }
203 
204     /**
205      * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String)
206      */
207     public void startPrefixMapping(String prefix, String uri)
208         throws SAXException
209     {
210         if (_createNamespaceScope) {
211             namespacesStack.addNewNamespaceScope();
212             _createNamespaceScope = false;
213         }
214 
215         namespacesStack.addNamespace(prefix, uri);
216     }
217 }