KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xml > internal > 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 com.sun.org.apache.xml.internal.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 unless it isn't an
94
// instance of the class set in the 'org.xml.sax.driver' property
95
reader = (XMLReader JavaDoc) m_readers.get();
96         boolean threadHasReader = (reader != null);
97         String JavaDoc factory = SecuritySupport.getInstance().getSystemProperty("org.xml.sax.driver");
98         if (!threadHasReader || m_inUse.get(reader) == Boolean.TRUE ||
99               !reader.getClass().getName().equals(factory)) {
100             try {
101                 try {
102                     // According to JAXP 1.2 specification, if a SAXSource
103
// is created using a SAX InputSource the Transformer or
104
// TransformerFactory creates a reader via the
105
// XMLReaderFactory if setXMLReader is not used
106
reader = XMLReaderFactory.createXMLReader();
107                 } catch (Exception JavaDoc e) {
108                    try {
109                         // If unable to create an instance, let's try to use
110
// the XMLReader from JAXP
111
if (m_parserFactory == null) {
112                             m_parserFactory = SAXParserFactory.newInstance();
113                             m_parserFactory.setNamespaceAware(true);
114                         }
115
116                         reader = m_parserFactory.newSAXParser().getXMLReader();
117                    } catch (ParserConfigurationException JavaDoc pce) {
118                        throw pce; // pass along pce
119
}
120                 }
121                 try {
122                     reader.setFeature(NAMESPACES_FEATURE, true);
123                     reader.setFeature(NAMESPACE_PREFIXES_FEATURE, false);
124                 } catch (SAXException JavaDoc se) {
125                     // Try to carry on if we've got a parser that
126
// doesn't know about namespace prefixes.
127
}
128             } catch (ParserConfigurationException JavaDoc ex) {
129                 throw new SAXException JavaDoc(ex);
130             } catch (FactoryConfigurationError JavaDoc ex1) {
131                 throw new SAXException JavaDoc(ex1.toString());
132             } catch (NoSuchMethodError JavaDoc ex2) {
133             } catch (AbstractMethodError JavaDoc ame) {
134             }
135
136             // Cache the XMLReader if this is the first time we've created
137
// a reader for this thread.
138
if (!threadHasReader) {
139                 m_readers.set(reader);
140                 m_inUse.put(reader, Boolean.TRUE);
141             }
142         } else {
143             m_inUse.put(reader, Boolean.TRUE);
144         }
145
146         return reader;
147     }
148
149     /**
150      * Mark the cached XMLReader as available. If the reader was not
151      * actually in the cache, do nothing.
152      *
153      * @param reader The XMLReader that's being released.
154      */

155     public synchronized void releaseXMLReader(XMLReader JavaDoc reader) {
156         // If the reader that's being released is the cached reader
157
// for this thread, remove it from the m_isUse list.
158
if (m_readers.get() == reader && reader != null) {
159             m_inUse.remove(reader);
160         }
161     }
162 }
163
Popular Tags