001: // Copyright 2004, 2005 The Apache Software Foundation
002: //
003: // Licensed under the Apache License, Version 2.0 (the "License");
004: // you may not use this file except in compliance with the License.
005: // You may obtain a copy of the License at
006: //
007: // http://www.apache.org/licenses/LICENSE-2.0
008: //
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014:
015: package org.apache.hivemind.parse;
016:
017: import java.io.IOException;
018: import java.net.URL;
019:
020: import javax.xml.parsers.FactoryConfigurationError;
021: import javax.xml.parsers.ParserConfigurationException;
022: import javax.xml.parsers.SAXParser;
023: import javax.xml.parsers.SAXParserFactory;
024:
025: import org.apache.commons.logging.Log;
026: import org.apache.commons.logging.LogFactory;
027: import org.apache.hivemind.ApplicationRuntimeException;
028: import org.apache.hivemind.ClassResolver;
029: import org.apache.hivemind.ErrorHandler;
030: import org.apache.hivemind.Resource;
031: import org.xml.sax.InputSource;
032: import org.xml.sax.SAXException;
033:
034: /**
035: * The XmlResourceProcessor processes XML {@link Resource resources} using the
036: * {@link DescriptorParser} which is used as a SAX ContentHandler. The result of
037: * {@link #processResource(Resource) processing a resource} is a {@link ModuleDescriptor}.
038: *
039: * @see org.apache.hivemind.parse.DescriptorParser
040: * @see org.apache.hivemind.ModuleDescriptorProvider
041: * @since 1.1
042: * @author Knut Wannheden
043: */
044: public class XmlResourceProcessor {
045: private static final Log LOG = LogFactory
046: .getLog(XmlResourceProcessor.class);
047:
048: protected ClassResolver _resolver;
049:
050: protected ErrorHandler _errorHandler;
051:
052: private DescriptorParser _contentHandler;
053:
054: private SAXParser _saxParser;
055:
056: public XmlResourceProcessor(ClassResolver resolver,
057: ErrorHandler errorHandler) {
058: _resolver = resolver;
059: _errorHandler = errorHandler;
060: }
061:
062: /**
063: * Initializes the {@link DescriptorParser parser},
064: * {@link #processResource(Resource) processes} the Resource, resets the parser, and finally
065: * returns the parsed {@link ModuleDescriptor}.
066: *
067: * @throws ApplicationRuntimeException
068: * Thrown if errors are encountered while parsing the resource.
069: */
070: public ModuleDescriptor processResource(Resource resource) {
071: if (_contentHandler == null)
072: _contentHandler = new DescriptorParser(_errorHandler);
073:
074: _contentHandler.initialize(resource, _resolver);
075:
076: try {
077: if (LOG.isDebugEnabled())
078: LOG.debug("Parsing " + resource);
079:
080: ModuleDescriptor descriptor = parseResource(resource,
081: getSAXParser(), _contentHandler);
082:
083: if (LOG.isDebugEnabled())
084: LOG.debug("Result: " + descriptor);
085:
086: return descriptor;
087: } catch (ApplicationRuntimeException e) {
088: throw e;
089: } catch (Exception e) {
090: _saxParser = null;
091:
092: throw new ApplicationRuntimeException(ParseMessages
093: .errorReadingDescriptor(resource, e), resource,
094: _contentHandler.getLocation(), e);
095: } finally {
096: _contentHandler.resetParser();
097: }
098: }
099:
100: /**
101: * Returns the ModuleDescriptor obtained by parsing the specified Resource using the given
102: * {@link SAXParser} and {@link DescriptorParser}. Called by {@link #processResource(Resource)}
103: * after the DescriptorParser has been
104: * {@link DescriptorParser#initialize(Resource, ClassResolver) initialized}. Suitable for
105: * overriding by subclasses.
106: */
107: protected ModuleDescriptor parseResource(Resource resource,
108: SAXParser parser, DescriptorParser contentHandler)
109: throws SAXException, IOException {
110: InputSource source = getInputSource(resource);
111:
112: parser.parse(source, contentHandler);
113:
114: return contentHandler.getModuleDescriptor();
115: }
116:
117: private InputSource getInputSource(Resource resource) {
118: try {
119: URL url = resource.getResourceURL();
120:
121: return new InputSource(url.openStream());
122: } catch (Exception e) {
123: throw new ApplicationRuntimeException(ParseMessages
124: .missingResource(resource), resource, null, e);
125: }
126: }
127:
128: private SAXParser getSAXParser()
129: throws ParserConfigurationException, SAXException,
130: FactoryConfigurationError {
131: if (_saxParser == null)
132: _saxParser = SAXParserFactory.newInstance().newSAXParser();
133:
134: return _saxParser;
135: }
136:
137: }
|