001    package org.apache.fulcrum.intake.transform;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *   http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import java.io.IOException;
023    import java.io.InputStream;
024    import java.net.URL;
025    
026    import org.apache.commons.logging.Log;
027    import org.apache.commons.logging.LogFactory;
028    
029    import org.xml.sax.EntityResolver;
030    import org.xml.sax.InputSource;
031    
032    /**
033     * A resolver to get the database.dtd file for the XML parser from the jar.
034     * This does not work with jdk1.3 on linux and OSX, see
035     * <a href="http://developer.java.sun.com/developer/bugParade/bugs/4337703.html">
036     * Bug 4337703</a>
037     *
038     * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
039     * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
040     * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
041     * @version $Id: DTDResolver.java 542371 2007-05-29 01:29:44Z seade $
042     */
043    public class DTDResolver implements EntityResolver
044    {
045        private static final String WEB_SITE_DTD =
046                "http://turbine.apache.org/dtd/intake_2_4.dtd";
047    
048        /** InputSource for <code>intake.dtd</code>. */
049        private InputSource intakeDTD = null;
050    
051        /** Logging */
052        private static Log log = LogFactory.getLog(DTDResolver.class);
053    
054        /**
055         * constructor
056         */
057        public DTDResolver()
058        {
059            try
060            {
061                            // Search for DTD
062                            ClassLoader classLoader = this.getClass().getClassLoader();
063    
064                InputStream dtdStream =
065                            classLoader.getResourceAsStream("intake.dtd");
066    
067                // getResource was buggy on many systems including Linux,
068                // OSX, and some versions of windows in jdk1.3.
069                // getResourceAsStream works on linux, maybe others?
070                if (dtdStream != null)
071                {
072                    intakeDTD = new InputSource(dtdStream);
073                }
074                else
075                {
076                    log.warn("Could not locate the intake.dtd");
077                }
078            }
079            catch (Exception ex)
080            {
081                log.error("Could not get stream for dtd", ex);
082            }
083        }
084    
085        /**
086         * called by the XML parser
087         *
088         * @return an InputSource for the intake.dtd file
089         */
090        public InputSource resolveEntity(String publicId, String systemId)
091        {
092            if (intakeDTD != null && WEB_SITE_DTD.equals(systemId))
093            {
094                String pkg = getClass().getName()
095                        .substring(0, getClass().getName().lastIndexOf("."));
096    
097                log.info("Resolver: used intake.dtd from " +
098                        pkg + " package ");
099    
100                return intakeDTD;
101            }
102            else if (systemId == null)
103            {
104                log.info("Resolver: used intake.dtd from Turbine Web site");
105                return getInputSource(WEB_SITE_DTD);
106            }
107            else
108            {
109                log.info("Resolver: used System DTD for " + systemId);
110                return getInputSource(systemId);
111            }
112        }
113    
114        /**
115         * Retrieves a XML input source for the specified URL.
116         *
117         * @param urlString The URL of the input source.
118         * @return <code>InputSource</code> for the URL.
119         */
120        private InputSource getInputSource(String urlString)
121        {
122            try
123            {
124                URL url = new URL(urlString);
125                return new InputSource(url.openStream());
126            }
127            catch (IOException ex)
128            {
129                log.error("Could not get InputSource for " + urlString, ex);
130            }
131            return new InputSource();
132        }
133    }