KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xml > utils > XMLReaderManager


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: XMLReaderManager.java,v 1.2 2004/02/17 04:21:14 minchau Exp $
18  */

19 package org.apache.xml.utils;
20
21 import java.util.Hashtable JavaDoc;
22
23 import javax.xml.parsers.FactoryConfigurationError JavaDoc;
24 import javax.xml.parsers.ParserConfigurationException JavaDoc;
25 import javax.xml.parsers.SAXParserFactory JavaDoc;
26
27 import org.xml.sax.XMLReader JavaDoc;
28 import org.xml.sax.helpers.XMLReaderFactory JavaDoc;
29 import org.xml.sax.SAXException JavaDoc;
30
31 /**
32  * Creates XMLReader objects and caches them for re-use.
33  * This class follows the singleton pattern.
34  */

35 public class XMLReaderManager {
36
37     private static final String JavaDoc NAMESPACES_FEATURE =
38                              "http://xml.org/sax/features/namespaces";
39     private static final String JavaDoc NAMESPACE_PREFIXES_FEATURE =
40                              "http://xml.org/sax/features/namespace-prefixes";
41     private static final XMLReaderManager m_singletonManager =
42                                                      new XMLReaderManager();
43
44     /**
45      * Parser factory to be used to construct XMLReader objects
46      */

47     private static SAXParserFactory JavaDoc m_parserFactory;
48
49     /**
50      * Cache of XMLReader objects
51      */

52     private ThreadLocal JavaDoc m_readers;
53
54     /**
55      * Keeps track of whether an XMLReader object is in use.
56      */

57     private Hashtable JavaDoc m_inUse;
58
59     /**
60      * Hidden constructor
61      */

62     private XMLReaderManager() {
63     }
64
65     /**
66      * Retrieves the singleton reader manager
67      */

68     public static XMLReaderManager getInstance() {
69         return m_singletonManager;
70     }
71
72     /**
73      * Retrieves a cached XMLReader for this thread, or creates a new
74      * XMLReader, if the existing reader is in use. When the caller no
75      * longer needs the reader, it must release it with a call to
76      * {@link releaseXMLReader}.
77      */

78     public synchronized XMLReader JavaDoc getXMLReader() throws SAXException JavaDoc {
79         XMLReader JavaDoc reader;
80         boolean readerInUse;
81
82         if (m_readers == null) {
83             // When the m_readers.get() method is called for the first time
84
// on a thread, a new XMLReader will automatically be created.
85
m_readers = new ThreadLocal JavaDoc();
86         }
87
88         if (m_inUse == null) {
89             m_inUse = new Hashtable JavaDoc();
90         }
91
92         // If the cached reader for this thread is in use, construct a new
93
// one; otherwise, return the cached reader.
94
reader = (XMLReader JavaDoc) m_readers.get();
95         boolean threadHasReader = (reader != null);
96         if (!threadHasReader || m_inUse.get(reader) == Boolean.TRUE) {
97             try {
98                 try {
99                     // According to JAXP 1.2 specification, if a SAXSource
100
// is created using a SAX InputSource the Transformer or
101
// TransformerFactory creates a reader via the
102
// XMLReaderFactory if setXMLReader is not used
103
reader = XMLReaderFactory.createXMLReader();
104                 } catch (Exception JavaDoc e) {
105                    try {
106                         // If unable to create an instance, let's try to use
107
// the XMLReader from JAXP
108
if (m_parserFactory == null) {
109                             m_parserFactory = SAXParserFactory.newInstance();
110                             m_parserFactory.setNamespaceAware(true);
111                         }
112
113                         reader = m_parserFactory.newSAXParser().getXMLReader();
114                    } catch (ParserConfigurationException JavaDoc pce) {
115                        throw pce; // pass along pce
116
}
117                 }
118                 try {
119                     reader.setFeature(NAMESPACES_FEATURE, true);
120                     reader.setFeature(NAMESPACE_PREFIXES_FEATURE, false);
121                 } catch (SAXException JavaDoc se) {
122                     // Try to carry on if we've got a parser that
123
// doesn't know about namespace prefixes.
124
}
125             } catch (ParserConfigurationException JavaDoc ex) {
126                 throw new SAXException JavaDoc(ex);
127             } catch (FactoryConfigurationError JavaDoc ex1) {
128                 throw new SAXException JavaDoc(ex1.toString());
129             } catch (NoSuchMethodError JavaDoc ex2) {
130             } catch (AbstractMethodError JavaDoc ame) {
131             }
132
133             // Cache the XMLReader if this is the first time we've created
134
// a reader for this thread.
135
if (!threadHasReader) {
136                 m_readers.set(reader);
137                 m_inUse.put(reader, Boolean.TRUE);
138             }
139         } else {
140             m_inUse.put(reader, Boolean.TRUE);
141         }
142
143         return reader;
144     }
145
146     /**
147      * Mark the cached XMLReader as available. If the reader was not
148      * actually in the cache, do nothing.
149      *
150      * @param reader The XMLReader that's being released.
151      */

152     public synchronized void releaseXMLReader(XMLReader JavaDoc reader) {
153         // If the reader that's being released is the cached reader
154
// for this thread, mark it as no longer being in use.
155
if (m_readers.get() == reader) {
156             m_inUse.put(reader, Boolean.FALSE);
157         }
158     }
159 }
160
Popular Tags