001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.test.blueprint;
018    
019    import java.io.File;
020    import java.io.FileInputStream;
021    import java.io.FileNotFoundException;
022    import java.io.IOException;
023    import java.io.InputStream;
024    import java.net.HttpURLConnection;
025    import java.net.MalformedURLException;
026    import java.net.URL;
027    import java.net.URLConnection;
028    import java.util.Enumeration;
029    
030    import org.apache.camel.spi.ClassResolver;
031    import org.apache.camel.util.ObjectHelper;
032    
033    /**
034     * Helper class for loading resources on the classpath or file system.
035     */
036    public final class ResourceHelper {
037    
038        private ResourceHelper() {
039            // utility class
040        }
041    
042        /**
043         * Determines whether the URI has a scheme (e.g. file:, classpath: or http:)
044         *
045         * @param uri the URI
046         * @return <tt>true</tt> if the URI starts with a scheme
047         */
048        public static boolean hasScheme(String uri) {
049            if (uri == null) {
050                return false;
051            }
052    
053            return uri.startsWith("file:") || uri.startsWith("classpath:") || uri.startsWith("http:");
054        }
055    
056        /**
057         * Resolves the mandatory resource.
058         * <p/>
059         * If possible recommended to use {@link #resolveMandatoryResourceAsUrl(org.apache.camel.spi.ClassResolver, String)}
060         *
061         * @param classResolver the class resolver to load the resource from the classpath
062         * @param uri URI of the resource
063         * @return the resource as an {@link InputStream}.  Remember to close this stream after usage.
064         * @throws java.io.IOException is thrown if the resource file could not be found or loaded as {@link InputStream}
065         */
066        public static InputStream resolveMandatoryResourceAsInputStream(ClassResolver classResolver, String uri) throws IOException {
067            if (uri.startsWith("file:")) {
068                uri = ObjectHelper.after(uri, "file:");
069                return new FileInputStream(uri);
070            } else if (uri.startsWith("http:")) {
071                URL url = new URL(uri);
072                URLConnection con = url.openConnection();
073                con.setUseCaches(false);
074                try {
075                    return con.getInputStream();
076                } catch (IOException e) {
077                    // close the http connection to avoid
078                    // leaking gaps in case of an exception
079                    if (con instanceof HttpURLConnection) {
080                        ((HttpURLConnection) con).disconnect();
081                    }
082                    throw e;
083                }
084            } else if (uri.startsWith("classpath:")) {
085                uri = ObjectHelper.after(uri, "classpath:");
086            }
087    
088            // load from classpath by default
089            InputStream is = classResolver.loadResourceAsStream(uri);
090            if (is == null) {
091                throw new FileNotFoundException("Cannot find resource in classpath for URI: " + uri);
092            } else {
093                return is;
094            }
095        }
096    
097        /**
098         * Resolves the mandatory resource.
099         *
100         * @param classResolver the class resolver to load the resource from the classpath
101         * @param uri uri of the resource
102         * @return the resource as an {@link InputStream}.  Remember to close this stream after usage.
103         * @throws java.io.FileNotFoundException is thrown if the resource file could not be found
104         * @throws java.net.MalformedURLException if the URI is malformed
105         */
106        public static URL resolveMandatoryResourceAsUrl(ClassResolver classResolver, String uri) throws FileNotFoundException, MalformedURLException {
107            if (uri.startsWith("file:")) {
108                // check if file exists first
109                String name = ObjectHelper.after(uri, "file:");
110                File file = new File(name);
111                if (!file.exists()) {
112                    throw new FileNotFoundException("File " + file + " not found");
113                }
114                return new URL(uri);
115            } else if (uri.startsWith("http:")) {
116                return new URL(uri);
117            } else if (uri.startsWith("classpath:")) {
118                uri = ObjectHelper.after(uri, "classpath:");
119            }
120    
121            // load from classpath by default
122            URL url = classResolver.loadResourceAsURL(uri);
123            if (url == null) {
124                throw new FileNotFoundException("Cannot find resource in classpath for URI: " + uri);
125            } else {
126                return url;
127            }
128        }
129    
130        /**
131         * Attempts to load the given resources from the given package name using the thread context
132         * class loader or the class loader used to load this class
133         *
134         * @param packageName the name of the package to load its resources
135         * @return the URLs for the resources or null if it could not be loaded
136         */
137        public static Enumeration<URL> loadResourcesAsURL(String packageName) {
138            Enumeration<URL> url = null;
139    
140            ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
141            if (contextClassLoader != null) {
142                try {
143                    url = contextClassLoader.getResources(packageName);
144                } catch (IOException e) {
145                    // ignore
146                }
147            }
148            if (url == null) {
149                try {
150                    url = ObjectHelper.class.getClassLoader().getResources(packageName);
151                } catch (IOException e) {
152                    // ignore
153                }
154            }
155    
156            return url;
157        }
158    
159    }