001: /*
002: Copyright (c) 2005, Dennis M. Sosnoski.
003: All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without modification,
006: are permitted provided that the following conditions are met:
007:
008: * Redistributions of source code must retain the above copyright notice, this
009: list of conditions and the following disclaimer.
010: * Redistributions in binary form must reproduce the above copyright notice,
011: this list of conditions and the following disclaimer in the documentation
012: and/or other materials provided with the distribution.
013: * Neither the name of JiBX nor the names of its contributors may be used
014: to endorse or promote products derived from this software without specific
015: prior written permission.
016:
017: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
018: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
019: WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
020: DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
021: ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
022: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023: LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
024: ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
026: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: */
028:
029: package org.jibx.runtime.impl;
030:
031: import java.io.InputStream;
032: import java.io.Reader;
033:
034: import javax.xml.stream.FactoryConfigurationError;
035: import javax.xml.stream.XMLInputFactory;
036: import javax.xml.stream.XMLStreamException;
037: import javax.xml.stream.XMLStreamReader;
038:
039: import org.jibx.runtime.IXMLReader;
040: import org.jibx.runtime.JiBXException;
041:
042: /**
043: * Factory for creating XMLPull parser instances.
044: *
045: * @author Dennis M. Sosnoski
046: * @version 1.0
047: */
048: public class StAXReaderFactory implements IXMLReaderFactory {
049: /** Singleton instance of class. */
050: private static final StAXReaderFactory s_instance = new StAXReaderFactory();
051:
052: /** Factory used for constructing parser instances. */
053: private final XMLInputFactory m_factory;
054:
055: /** Namespace processing state configured on factory. */
056: private boolean m_isNamespaceEnabled;
057:
058: /**
059: * Internal constructor.
060: */
061: private StAXReaderFactory() {
062: XMLInputFactory factory;
063: try {
064: factory = XMLInputFactory.newInstance();
065: } catch (FactoryConfigurationError e) {
066: Thread thread = Thread.currentThread();
067: ClassLoader cl = thread.getContextClassLoader();
068: thread.setContextClassLoader(StAXReaderFactory.class
069: .getClassLoader());
070: try {
071: factory = XMLInputFactory.newInstance();
072: } finally {
073: thread.setContextClassLoader(cl);
074: }
075: }
076: m_factory = factory;
077: m_isNamespaceEnabled = true;
078: }
079:
080: /**
081: * Get instance of factory.
082: *
083: * @return factory instance
084: */
085: public static StAXReaderFactory getInstance() {
086: return s_instance;
087: }
088:
089: /**
090: * Create new parser instance. In order to avoid thread safety issues the
091: * caller must have a lock on the factory object.
092: *
093: * @param nsf enable namespace processing on parser flag
094: * @throws JiBXException on error creating parser
095: */
096: private void setNamespacesState(boolean nsf) throws JiBXException {
097: if (nsf != m_isNamespaceEnabled) {
098: try {
099: m_factory.setProperty(
100: XMLInputFactory.IS_NAMESPACE_AWARE,
101: nsf ? Boolean.TRUE : Boolean.FALSE);
102: m_isNamespaceEnabled = nsf;
103: } catch (IllegalArgumentException e) {
104: throw new JiBXException(
105: "Unable to create parser with required namespace handling");
106: }
107: }
108: }
109:
110: /* (non-Javadoc)
111: * @see org.jibx.runtime.impl.IXMLReaderFactory#createReader(java.io.InputStream, java.lang.String, java.lang.String, boolean)
112: */
113: public IXMLReader createReader(InputStream is, String name,
114: String enc, boolean nsf) throws JiBXException {
115: try {
116: synchronized (m_factory) {
117: setNamespacesState(nsf);
118: if (enc == null) {
119: XMLStreamReader rdr = m_factory
120: .createXMLStreamReader(is);
121: return new StAXReaderWrapper(rdr, name, nsf);
122: } else {
123: XMLStreamReader rdr = m_factory
124: .createXMLStreamReader(is, enc);
125: return new StAXReaderWrapper(rdr, name, nsf);
126: }
127: }
128: } catch (XMLStreamException e) {
129: throw new JiBXException("Error creating parser", e);
130: }
131: }
132:
133: /* (non-Javadoc)
134: * @see org.jibx.runtime.impl.IXMLReaderFactory#createReader(java.io.Reader, java.lang.String, boolean)
135: */
136: public IXMLReader createReader(Reader rdr, String name, boolean nsf)
137: throws JiBXException {
138: try {
139: synchronized (m_factory) {
140: setNamespacesState(nsf);
141: return new StAXReaderWrapper(m_factory
142: .createXMLStreamReader(rdr), name, nsf);
143: }
144: } catch (XMLStreamException e) {
145: throw new JiBXException("Error creating parser", e);
146: }
147: }
148:
149: /* (non-Javadoc)
150: * @see org.jibx.runtime.impl.IXMLReaderFactory#recycleReader(org.jibx.runtime.IXMLReader, java.io.InputStream, java.lang.String, java.lang.String)
151: */
152: public IXMLReader recycleReader(IXMLReader old, InputStream is,
153: String name, String enc) throws JiBXException {
154: return createReader(is, name, enc, old.isNamespaceAware());
155: }
156:
157: /* (non-Javadoc)
158: * @see org.jibx.runtime.impl.IXMLReaderFactory#recycleReader(org.jibx.runtime.IXMLReader, java.io.Reader, java.lang.String)
159: */
160: public IXMLReader recycleReader(IXMLReader old, Reader rdr,
161: String name) throws JiBXException {
162: return createReader(rdr, name, old.isNamespaceAware());
163: }
164: }
|