001/*
002 *  jDTAUS Core Utilities
003 *  Copyright (C) 2005 Christian Schulte <cs@schulte.it>
004 *
005 *  This library is free software; you can redistribute it and/or
006 *  modify it under the terms of the GNU Lesser General Public
007 *  License as published by the Free Software Foundation; either
008 *  version 2.1 of the License, or any later version.
009 *
010 *  This library is distributed in the hope that it will be useful,
011 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
012 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 *  Lesser General Public License for more details.
014 *
015 *  You should have received a copy of the GNU Lesser General Public
016 *  License along with this library; if not, write to the Free Software
017 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
018 *
019 *  $JDTAUS: EntityResolverChain.java 8716 2012-10-02 23:38:43Z schulte $
020 */
021package org.jdtaus.core.sax.util;
022
023import java.io.IOException;
024import java.util.Locale;
025import org.jdtaus.core.container.ContainerFactory;
026import org.jdtaus.core.logging.spi.Logger;
027import org.xml.sax.EntityResolver;
028import org.xml.sax.InputSource;
029import org.xml.sax.SAXException;
030
031/**
032 * {@code EntityResolver} implementation backed by a chain of resolvers used
033 * for resolving entities.
034 *
035 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
036 * @version $JDTAUS: EntityResolverChain.java 8716 2012-10-02 23:38:43Z schulte $
037 */
038public final class EntityResolverChain implements EntityResolver
039{
040    //--EntityResolver----------------------------------------------------------
041
042    /**
043     * Resolves entities by querying all resolvers of the instance stopping at
044     * the first one not returning {@code null}.
045     *
046     * @param publicId The public identifier of the external entity being
047     * referenced, or {@code null} if none was supplied.
048     * @param systemId The system identifier of the external entity being
049     * referenced.
050     *
051     * @return An {@code InputSource} object describing the new input source, or
052     * {@code null} to request that the parser open a regular URI connection to
053     * the system identifier.
054     *
055     * @throws SAXException Any SAX exception, possibly wrapping another
056     * exception.
057     * @throws IOException A Java-specific IO exception, possibly the result of
058     * creating a new {@code InputStream} or {@code Reader} for the
059     * {@code InputSource}.
060     *
061     * @see EntityResolver#resolveEntity(java.lang.String, java.lang.String)
062     */
063    public InputSource resolveEntity( final String publicId,
064                                      final String systemId )
065        throws SAXException, IOException
066    {
067        InputSource inputSource = null;
068        for ( int i = this.getResolvers().length - 1;
069              i >= 0 && inputSource == null; i-- )
070        {
071            final EntityResolver resolver = this.getResolvers()[i];
072            inputSource = resolver.resolveEntity( publicId, systemId );
073        }
074
075        return inputSource;
076    }
077
078    //----------------------------------------------------------EntityResolver--
079    //--EntityResolverChain-----------------------------------------------------
080
081    /** Chain of resolvers to use. */
082    private EntityResolver[] resolvers;
083
084    /**
085     * Creates a new {@code EntityResolverChain} instance backed by any
086     * available {@code EntityResolver} implementation in the system.
087     */
088    public EntityResolverChain()
089    {
090        this( null );
091    }
092
093    /**
094     * Creates a new {@code EntityResolverChain} instance taking an array of
095     * resolvers to use for resolving entities.
096     *
097     * @param resolvers The resolvers to use for resolving entities.
098     */
099    public EntityResolverChain( final EntityResolver[] resolvers )
100    {
101        super();
102
103        if ( resolvers != null && resolvers.length > 0 )
104        {
105            this.resolvers = resolvers;
106        }
107    }
108
109    /**
110     * Gets the resolvers of the instance.
111     *
112     * @return the resolvers used for resolving entities.
113     */
114    public EntityResolver[] getResolvers()
115    {
116        if ( this.resolvers == null )
117        {
118            this.resolvers = this.getDefaultResolvers();
119
120            if ( this.resolvers.length == 0 )
121            {
122                this.getLogger().warn(
123                    this.getNoEntityResolversMessage( this.getLocale() ) );
124
125            }
126        }
127
128        return this.resolvers;
129    }
130
131    //-----------------------------------------------------EntityResolverChain--
132    //--Dependencies------------------------------------------------------------
133
134// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausDependencies
135    // This section is managed by jdtaus-container-mojo.
136
137    /**
138     * Gets the configured <code>Logger</code> implementation.
139     *
140     * @return The configured <code>Logger</code> implementation.
141     */
142    private Logger getLogger()
143    {
144        return (Logger) ContainerFactory.getContainer().
145            getDependency( this, "Logger" );
146
147    }
148
149    /**
150     * Gets the configured <code>Locale</code> implementation.
151     *
152     * @return The configured <code>Locale</code> implementation.
153     */
154    private Locale getLocale()
155    {
156        return (Locale) ContainerFactory.getContainer().
157            getDependency( this, "Locale" );
158
159    }
160
161    /**
162     * Gets the configured <code>DefaultResolvers</code> implementation.
163     *
164     * @return The configured <code>DefaultResolvers</code> implementation.
165     */
166    private EntityResolver[] getDefaultResolvers()
167    {
168        return (EntityResolver[]) ContainerFactory.getContainer().
169            getDependency( this, "DefaultResolvers" );
170
171    }
172
173// </editor-fold>//GEN-END:jdtausDependencies
174
175    //------------------------------------------------------------Dependencies--
176    //--Messages----------------------------------------------------------------
177
178// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausMessages
179    // This section is managed by jdtaus-container-mojo.
180
181    /**
182     * Gets the text of message <code>noEntityResolvers</code>.
183     * <blockquote><pre>Keine ''EntityResolver'' gefunden. Java XML-Parser öffnen standardmäßig reguläre - eventuell entfernte - URI-Verbindungen. Sie sollten mindestens eine ''EntityResolver''-Implementierung (z.B. jdtaus-core-entity-resolver-1.13.jar) zur Verfügung stellen.</pre></blockquote>
184     * <blockquote><pre>No entity resolvers found. Standard Java XML parsers fall back to opening regular - possibly remote - URI connections. You should provide at least one ''EntityResolver'' implementation (e.g. jdtaus-core-entity-resolver-1.13.jar).</pre></blockquote>
185     *
186     * @param locale The locale of the message instance to return.
187     *
188     * @return the text of message <code>noEntityResolvers</code>.
189     */
190    private String getNoEntityResolversMessage( final Locale locale )
191    {
192        return ContainerFactory.getContainer().
193            getMessage( this, "noEntityResolvers", locale, null );
194
195    }
196
197// </editor-fold>//GEN-END:jdtausMessages
198
199    //----------------------------------------------------------------Messages--
200}