001/*
002 *  jDTAUS Core Client Container
003 *  Copyright (C) 2005 Christian Schulte
004 *  <cs@schulte.it>
005 *
006 *  This library is free software; you can redistribute it and/or
007 *  modify it under the terms of the GNU Lesser General Public
008 *  License as published by the Free Software Foundation; either
009 *  version 2.1 of the License, or any later version.
010 *
011 *  This library is distributed in the hope that it will be useful,
012 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
013 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 *  Lesser General Public License for more details.
015 *
016 *  You should have received a copy of the GNU Lesser General Public
017 *  License along with this library; if not, write to the Free Software
018 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
019 *
020 */
021package org.jdtaus.core.container.ri.client.test;
022
023import java.io.IOException;
024import java.net.URL;
025import java.util.Collections;
026import java.util.Enumeration;
027import java.util.HashMap;
028import java.util.HashSet;
029import java.util.Map;
030import java.util.Set;
031
032/**
033 * Classloader for providing classpath resources.
034 *
035 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
036 * @version $JDTAUS: ResourceLoader.java 8641 2012-09-27 06:45:17Z schulte $
037 *
038 * @see #addResource(java.lang.String, java.net.URL)
039 * @see #addResources(java.lang.String, java.net.URL[])
040 */
041public class ResourceLoader extends ClassLoader
042{
043
044    /** The classloader delegated to. */
045    private ClassLoader delegate;
046
047    /** Mapping of classpath locations to a list of URLs to provide. */
048    private Map locations = new HashMap();
049
050    /**
051     * Creates a new {@code ResourceLoader} instance taking a classloader
052     * classloading is delegated to.
053     *
054     * @param delegate classloader classloading is delegated to.
055     */
056    public ResourceLoader( final ClassLoader delegate )
057    {
058        super();
059        this.delegate = delegate;
060    }
061
062    /** {@inheritDoc} */
063    protected Class findClass( final String name )
064        throws ClassNotFoundException
065    {
066        return this.delegate.loadClass( name );
067    }
068
069    /**
070     * Finds the resource with the given name by searching the instance for any
071     * resources first, falling back to the classloader classloading is
072     * delegated to.
073     *
074     * @param  name the name of the resource.
075     *
076     * @return  a {@code URL} object for reading the resource, or {@code null}
077     * if the resource could not be found.
078     */
079    protected URL findResource( final String name )
080    {
081        URL thisResource = null;
082
083        if ( this.locations.containsKey( name ) )
084        {
085            final Set resources = ( Set ) this.locations.get( name );
086            thisResource = ( URL ) resources.iterator().next();
087        }
088        else
089        {
090            thisResource = this.delegate.getResource( name );
091        }
092
093        return thisResource;
094    }
095
096    /**
097     * Returns an enumeration of {@link java.net.URL {@code URL}} objects
098     * representing all the resources with the given name by searching the
099     * instance for any resources first, falling back to the classloader
100     * classloading is delegated to.
101     *
102     * @param  name the resource name
103     *
104     * @return  an enumeration of {@link java.net.URL {@code URL}} objects for
105     * the resources.
106     *
107     * @throws  IOException if searching fails.
108     */
109    protected Enumeration findResources( final String name )
110        throws IOException
111    {
112        Enumeration thisResources = null;
113
114        if ( this.locations.containsKey( name ) )
115        {
116            final Set resources = ( Set ) this.locations.get( name );
117            thisResources = Collections.enumeration( resources );
118        }
119        else if ( thisResources == null || !thisResources.hasMoreElements() )
120        {
121            thisResources = this.delegate.getResources( name );
122        }
123
124        return thisResources;
125    }
126
127    /**
128     * Adds a resource to the instance.
129     *
130     * @param name the name of the resource to add.
131     * @param resource the resource to add to the instance.
132     *
133     * @throws NullPointerException if {@code name} or {@code resource} is
134     * {@code null}.
135     */
136    public void addResource( final String name, final URL resource )
137    {
138        if ( name == null )
139        {
140            throw new NullPointerException( "name " );
141        }
142        if ( resource == null )
143        {
144            throw new NullPointerException( "resource" );
145        }
146
147        Set resources = ( Set ) this.locations.get( name );
148        if ( resources == null )
149        {
150            resources = new HashSet();
151            this.locations.put( name, resources );
152        }
153
154        resources.add( resource );
155    }
156
157    /**
158     * Adds an array of resources to the instance.
159     *
160     * @param name the name of the resources to add.
161     * @param resources the resources to add to the instance.
162     *
163     * @throws NullPointerException if {@code name} or {@code resources} is
164     * {@code null}.
165     */
166    public void addResources( final String name, final URL[] resources )
167    {
168        if ( name == null )
169        {
170            throw new NullPointerException( "name" );
171        }
172
173        if ( resources == null )
174        {
175            throw new NullPointerException( "resources" );
176        }
177
178        for ( int i = resources.length - 1; i >= 0; i-- )
179        {
180            this.addResource( name, resources[i] );
181        }
182    }
183
184}