/* * JBoss, Home of Professional Open Source * Copyright 2011, Red Hat, Inc. and/or its affiliates, and individual * contributors by the @authors tag. See the copyright.txt in the * distribution for a full listing of individual contributors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jboss.solder.resourceLoader; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Properties; import java.util.Set; import org.jboss.solder.resourceLoader.ResourceLoader; import org.jboss.solder.resourceLoader.ResourceProvider; import org.jboss.solder.util.Sortable; import org.jboss.solder.util.service.ServiceLoader; /** * <p> * {@link ResourceLoaderManager} discovers and instantiates all * {@link ResourceLoader}s defined. It also provides accesss to these resources, * either as {@link URL}s or {@link InputStream}s. * </p> * <p/> * <p> * If you are working in a CDI managed environment, you should use * {@link ResourceProvider} instead, as it provides automatic, contextual * management of resources. If you are outside a CDI managed environment, then * instantiating {@link ResourceLoaderManager} provides access to the same * resources. * </p> * * @author Pete Muir * @author Stuart Douglas * @see ResourceLoader * @see ResourceProvider */ public class ResourceLoaderManager { private final List<ResourceLoader> resourceLoaders; /** * Instantiate a new instance, loading any resource loaders from the service * loader, and sorting them by precedence. */ public ResourceLoaderManager() { resourceLoaders = new ArrayList<ResourceLoader>(); for (ResourceLoader resourceLoader : ServiceLoader.load(ResourceLoader.class)) { resourceLoaders.add(resourceLoader); } Collections.sort(resourceLoaders, new Sortable.Comparator()); } /** * The discovered {@link ResourceLoader} instances. * * @return the resource loaders */ public Iterable<ResourceLoader> getResourceLoaders() { return Collections.unmodifiableList(resourceLoaders); } /** * <p> * Load a resource by name. * </p> * <p/> * <p> * The resource loaders will be searched in precedence order, the first * result found being returned. * </p> * * @param name the resource to load * @return a URL pointing to the resource, or <code>null</code> if no * resource can be loaded * @throws RuntimeException if an error occurs loading the resource */ public URL getResource(String name) { for (ResourceLoader loader : resourceLoaders) { URL url = loader.getResource(name); if (url != null) { return url; } } return null; } /** * <p> * Load a properties bundle by name. * </p> * <p/> * <p> * The resource loaders will be searched in precedence order, the first * result found being returned. * </p> * * @param name the name of the properties bundle to load * @return a set of properties, or an empty set if no properties bundle can * be loaded * @throws RuntimeException if an error occurs loading the properties bundle */ public Properties getPropertiesBundle(String name) { return loadProperties(getResourceAsStream(name), name); } private Properties loadProperties(InputStream is, String name) { Properties properties = new Properties(); if (is != null) { try { properties.load(is); } catch (IOException e) { throw new RuntimeException("Error opening stream " + name, e); } finally { try { is.close(); } catch (IOException e) { throw new RuntimeException("Error closing stream " + name, e); } } } return properties; } /** * <p> * Load all properties bundles known to the resource loader by name. * </p> * * @param name the name of the properties bundle to load * @return a collection of properties bundles pointing to the resources, or an empty * collection if no resources are found * @throws RuntimeException if an error occurs loading the properties bundles */ public Collection<Properties> getPropertiesBundles(String name) { Collection<Properties> properties = new HashSet<Properties>(); for (InputStream is : getResourcesAsStream(name)) { properties.add(loadProperties(is, name)); } return properties; } /** * <p> * Load a resource by name. * </p> * <p/> * <p> * The resource loaders will be searched in precedence order, the first * result found being returned. * </p> * * @param name the resource to load * @return an InputStream providing access to the resource, or * <code>null</code> if no resource can be loaded * @throws RuntimeException if an error occurs loading the resource */ public InputStream getResourceAsStream(String name) { for (ResourceLoader loader : resourceLoaders) { InputStream is = loader.getResourceAsStream(name); if (is != null) { return is; } } return null; } /** * <p> * Load all resources known to the resource loader by name. * </p> * * @param name the resource to load * @return a collection of URLs pointing to the resources, or an empty * collection if no resources are found * @throws RuntimeException if an error occurs loading the resource */ public Collection<URL> getResources(String name) { Set<URL> urls = new HashSet<URL>(); for (ResourceLoader loader : resourceLoaders) { urls.addAll(loader.getResources(name)); } return urls; } /** * <p> * Load all resources known to the resource loader by name. * </p> * * @param name the resource to load * @return a collection of input streams pointing to the resources, or an * empty collection if no resources are found * @throws RuntimeException if an error occurs loading the resource */ public Collection<InputStream> getResourcesAsStream(String name) { Set<InputStream> streams = new HashSet<InputStream>(); for (ResourceLoader loader : resourceLoaders) { streams.addAll(loader.getResourcesAsStream(name)); } return streams; } }