001/*
002 * Copyright (c) 2004-2012, Willem Cazander
003 * All rights reserved.
004 *
005 * Redistribution and use in source and binary forms, with or without modification, are permitted provided
006 * that the following conditions are met:
007 * 
008 * * Redistributions of source code must retain the above copyright notice, this list of conditions and the
009 *   following disclaimer.
010 * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
011 *   the following disclaimer in the documentation and/or other materials provided with the distribution.
012 * 
013 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
014 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
015 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
016 * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
018 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
019 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
020 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
021 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
022 */
023
024package org.x4o.xml.sax;
025
026import  java.io.ByteArrayInputStream;
027import java.io.File;
028import  java.io.FileInputStream;
029import  java.io.FileNotFoundException;
030import  java.io.IOException;
031import  java.io.InputStream;
032import java.net.URL;
033
034import  org.xml.sax.SAXException;
035import  javax.xml.parsers.ParserConfigurationException;
036
037/**
038 * This is a base class for building an SAX XML parser.
039 * It adds methode's for parsing different input types of 
040 * xml data which gets wrapped into an InputStream for parsing.
041 * 
042 * @author Willem Cazander
043 * @version 1.0 Aug 11, 2005
044 */
045abstract public class AbstractXMLParser {
046        
047        /**
048         * Method to parse the xml data.
049         * @param input The inputStream to parse.
050         * @throws ParserConfigurationException
051         * @throws SAXException
052         * @throws IOException
053         */
054        abstract public void parse(InputStream input,String systemId,URL basePath) throws ParserConfigurationException,SAXException,IOException;
055        
056        /**
057         * Reads the file fileName and parses it as an InputStream.
058         * @param fileName      The file name to parse.
059         * @throws ParserConfigurationException
060         * @throws FileNotFoundException
061         * @throws SecurityException
062         * @throws NullPointerException
063         * @throws SAXException
064         * @throws IOException
065         * @see org.x4o.xml.sax.AbstractXMLParser#parse(java.io.InputStream,java.lang.String,java.net.URL)
066         */
067        public void parseFile(String fileName) throws ParserConfigurationException,FileNotFoundException,SecurityException,NullPointerException,SAXException,IOException {
068                if (fileName==null) {
069                        throw new NullPointerException("Can't convert null fileName to file object.");
070                }               
071                parseFile(new File(fileName));
072        }
073        
074        /**
075         * Reads the file and parses it as an InputStream.
076         * @param file  The file to parse.
077         * @throws ParserConfigurationException
078         * @throws FileNotFoundException
079         * @throws SecurityException
080         * @throws NullPointerException
081         * @throws SAXException
082         * @throws IOException
083         * @see org.x4o.xml.sax.AbstractXMLParser#parse(java.io.InputStream,java.lang.String,java.net.URL)
084         */
085        public void parseFile(File file) throws ParserConfigurationException,FileNotFoundException,SecurityException,NullPointerException,SAXException,IOException {
086                if (file==null) {
087                        throw new NullPointerException("Can't load null file.");
088                }
089                if (file.exists()==false) {
090                        throw new FileNotFoundException("File does not exists; "+file);
091                }
092                if (file.canRead()==false) {
093                        throw new IOException("File exists but can't read file: "+file);
094                }
095                URL basePath = new File(file.getAbsolutePath()).toURI().toURL();
096                InputStream inputStream = new FileInputStream(file);
097                try {
098                        parse(inputStream,file.getAbsolutePath(),basePath);
099                } finally {
100                        if(inputStream!=null) {
101                                inputStream.close();
102                        }
103                }
104        }
105        
106        /**
107         * Parses an resource locaction.
108         * @param resourceName  The resource to parser.
109         * @throws ParserConfigurationException
110         * @throws FileNotFoundException
111         * @throws SecurityException
112         * @throws NullPointerException
113         * @throws SAXException
114         * @throws IOException
115         */
116        public void parseResource(String resourceName) throws ParserConfigurationException,FileNotFoundException,SecurityException,NullPointerException,SAXException,IOException {
117                if (resourceName==null) {
118                        throw new NullPointerException("Can't load null resourceName from classpath.");
119                }
120                ClassLoader cl = Thread.currentThread().getContextClassLoader();
121                if (cl == null) cl = getClass().getClassLoader(); // fallback
122                URL url = cl.getResource(resourceName);
123                if (url==null) {
124                        throw new NullPointerException("Could not find resource on classpath: "+resourceName);
125                }
126                String baseUrl = url.toExternalForm();
127                int lastSlash = baseUrl.lastIndexOf('/');
128                if (lastSlash > 0 && (lastSlash+1) < baseUrl.length()) {
129                        baseUrl = baseUrl.substring(0,lastSlash+1);
130                }
131                URL basePath = new URL(baseUrl);
132                InputStream inputStream = cl.getResourceAsStream(resourceName);
133                try {
134                        parse(inputStream,url.toExternalForm(),basePath);
135                } finally {
136                        if(inputStream!=null) {
137                                inputStream.close();
138                        }
139                }
140        }
141        
142        /**
143         * Converts a String to a InputStream to is can me parsed by SAX.
144         * @param xmlString     The xml as String to parse.
145         * @throws ParserConfigurationException
146         * @throws SAXException
147         * @throws IOException
148         * @throws NullPointerException
149         * @see org.x4o.xml.sax.AbstractXMLParser#parse(java.io.InputStream,java.lang.String,java.net.URL)
150         */
151        public void parseXml(String xmlString) throws ParserConfigurationException,SAXException,IOException,NullPointerException {
152                if (xmlString==null) {
153                        throw new NullPointerException("Can't parse null xml string.");
154                }
155                URL basePath = new File(System.getProperty("user.dir")).toURI().toURL();
156                parse(new ByteArrayInputStream(xmlString.getBytes()),"inline-xml",basePath);
157        }
158        
159        /**
160         * Fetched the data direct from remote url to a InputStream to is can me parsed by SAX.
161         * @param url   The url to parse.
162         * @throws ParserConfigurationException
163         * @throws SAXException
164         * @throws IOException
165         * @throws NullPointerException
166         * @see org.x4o.xml.sax.AbstractXMLParser#parse(java.io.InputStream,java.lang.String,java.net.URL)
167         */
168        public void parseUrl(URL url) throws ParserConfigurationException,SAXException,IOException,NullPointerException {
169                if (url==null) {
170                        throw new NullPointerException("Can't parse null url.");
171                }
172                URL basePath = new URL(url.toExternalForm().substring(0,url.toExternalForm().length()-url.getFile().length()));
173                parse(url.openStream(),url.toExternalForm(),basePath);
174        }
175}