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.util;
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.URI;
027    import java.net.URISyntaxException;
028    import java.net.URL;
029    import java.net.URLConnection;
030    import java.util.Map;
031    
032    import org.apache.camel.spi.ClassResolver;
033    
034    /**
035     * Helper class for loading resources on the classpath or file system.
036     */
037    public final class ResourceHelper {
038    
039        private ResourceHelper() {
040            // utility class
041        }
042    
043        /**
044         * Determines whether the URI has a scheme (e.g. file:, classpath: or http:)
045         *
046         * @param uri the URI
047         * @return <tt>true</tt> if the URI starts with a scheme
048         */
049        public static boolean hasScheme(String uri) {
050            if (uri == null) {
051                return false;
052            }
053    
054            return uri.startsWith("file:") || uri.startsWith("classpath:") || uri.startsWith("http:");
055        }
056    
057        /**
058         * Resolves the mandatory resource.
059         * <p/>
060         * If possible recommended to use {@link #resolveMandatoryResourceAsUrl(org.apache.camel.spi.ClassResolver, String)}
061         *
062         * @param classResolver the class resolver to load the resource from the classpath
063         * @param uri URI of the resource
064         * @return the resource as an {@link InputStream}.  Remember to close this stream after usage.
065         * @throws java.io.IOException is thrown if the resource file could not be found or loaded as {@link InputStream}
066         */
067        public static InputStream resolveMandatoryResourceAsInputStream(ClassResolver classResolver, String uri) throws IOException {
068            if (uri.startsWith("file:")) {
069                uri = ObjectHelper.after(uri, "file:");
070                return new FileInputStream(uri);
071            } else if (uri.startsWith("http:")) {
072                URL url = new URL(uri);
073                URLConnection con = url.openConnection();
074                con.setUseCaches(false);
075                try {
076                    return con.getInputStream();
077                } catch (IOException e) {
078                    // close the http connection to avoid
079                    // leaking gaps in case of an exception
080                    if (con instanceof HttpURLConnection) {
081                        ((HttpURLConnection) con).disconnect();
082                    }
083                    throw e;
084                }
085            } else if (uri.startsWith("classpath:")) {
086                uri = ObjectHelper.after(uri, "classpath:");
087            }
088    
089            // load from classpath by default
090            InputStream is = classResolver.loadResourceAsStream(uri);
091            if (is == null) {
092                throw new FileNotFoundException("Cannot find resource in classpath for URI: " + uri);
093            } else {
094                return is;
095            }
096        }
097    
098        /**
099         * Resolves the mandatory resource.
100         *
101         * @param classResolver the class resolver to load the resource from the classpath
102         * @param uri uri of the resource
103         * @return the resource as an {@link InputStream}.  Remember to close this stream after usage.
104         * @throws java.io.FileNotFoundException is thrown if the resource file could not be found
105         * @throws java.net.MalformedURLException if the URI is malformed
106         */
107        public static URL resolveMandatoryResourceAsUrl(ClassResolver classResolver, String uri) throws FileNotFoundException, MalformedURLException {
108            if (uri.startsWith("file:")) {
109                // check if file exists first
110                String name = ObjectHelper.after(uri, "file:");
111                File file = new File(name);
112                if (!file.exists()) {
113                    throw new FileNotFoundException("File " + file + " not found");
114                }
115                return new URL(uri);
116            } else if (uri.startsWith("http:")) {
117                return new URL(uri);
118            } else if (uri.startsWith("classpath:")) {
119                uri = ObjectHelper.after(uri, "classpath:");
120            }
121    
122            // load from classpath by default
123            URL url = classResolver.loadResourceAsURL(uri);
124            if (url == null) {
125                throw new FileNotFoundException("Cannot find resource in classpath for URI: " + uri);
126            } else {
127                return url;
128            }
129        }
130    
131        /**
132         * Is the given uri a http uri?
133         *
134         * @param uri the uri
135         * @return <tt>true</tt> if the uri starts with <tt>http:</tt> or <tt>https:</tt>
136         */
137        public static boolean isHttpUri(String uri) {
138            if (uri == null) {
139                return false;
140            }
141            return uri.startsWith("http:") || uri.startsWith("https:");
142        }
143    
144        /**
145         * Appends the parameters to the given uri
146         *
147         * @param uri the uri
148         * @param parameters the additional parameters (will clear the map)
149         * @return a new uri with the additional parameters appended
150         * @throws URISyntaxException is thrown if the uri is invalid
151         */
152        public static String appendParameters(String uri, Map<String, Object> parameters) throws URISyntaxException {
153            // add additional parameters to the resource uri
154            if (!parameters.isEmpty()) {
155                String query = URISupport.createQueryString(parameters);
156                URI u = new URI(uri);
157                u = URISupport.createURIWithQuery(u, query);
158                parameters.clear();
159                return u.toString();
160            } else {
161                return uri;
162            }
163        }
164    }