Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
ResourceUtils |
|
| 2.5555555555555554;2.556 |
1 | /* | |
2 | * Licensed to the Apache Software Foundation (ASF) under one | |
3 | * or more contributor license agreements. See the NOTICE file | |
4 | * distributed with this work for additional information | |
5 | * regarding copyright ownership. The ASF licenses this file | |
6 | * to you under the Apache License, Version 2.0 (the | |
7 | * "License"); you may not use this file except in compliance | |
8 | * with the License. You may obtain a copy of the License at | |
9 | * | |
10 | * http://www.apache.org/licenses/LICENSE-2.0 | |
11 | * | |
12 | * Unless required by applicable law or agreed to in writing, | |
13 | * software distributed under the License is distributed on an | |
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
15 | * KIND, either express or implied. See the License for the | |
16 | * specific language governing permissions and limitations | |
17 | * under the License. | |
18 | */ | |
19 | package org.apache.shiro.io; | |
20 | ||
21 | import org.apache.shiro.util.ClassUtils; | |
22 | import org.slf4j.Logger; | |
23 | import org.slf4j.LoggerFactory; | |
24 | ||
25 | import java.io.FileInputStream; | |
26 | import java.io.IOException; | |
27 | import java.io.InputStream; | |
28 | import java.net.URL; | |
29 | ||
30 | /** | |
31 | * Static helper methods for loading {@code Stream}-backed resources. | |
32 | * | |
33 | * @see #getInputStreamForPath(String) | |
34 | * @since 0.2 | |
35 | */ | |
36 | public class ResourceUtils { | |
37 | ||
38 | /** | |
39 | * Resource path prefix that specifies to load from a classpath location, value is <b>{@code classpath:}</b> | |
40 | */ | |
41 | public static final String CLASSPATH_PREFIX = "classpath:"; | |
42 | /** | |
43 | * Resource path prefix that specifies to load from a url location, value is <b>{@code url:}</b> | |
44 | */ | |
45 | public static final String URL_PREFIX = "url:"; | |
46 | /** | |
47 | * Resource path prefix that specifies to load from a file location, value is <b>{@code file:}</b> | |
48 | */ | |
49 | public static final String FILE_PREFIX = "file:"; | |
50 | ||
51 | /** | |
52 | * Private internal log instance. | |
53 | */ | |
54 | 1 | private static final Logger log = LoggerFactory.getLogger(ResourceUtils.class); |
55 | ||
56 | /** | |
57 | * Prevent instantiation. | |
58 | */ | |
59 | 0 | private ResourceUtils() { |
60 | 0 | } |
61 | ||
62 | /** | |
63 | * Returns {@code true} if the resource path is not null and starts with one of the recognized | |
64 | * resource prefixes ({@link #CLASSPATH_PREFIX CLASSPATH_PREFIX}, | |
65 | * {@link #URL_PREFIX URL_PREFIX}, or {@link #FILE_PREFIX FILE_PREFIX}), {@code false} otherwise. | |
66 | * | |
67 | * @param resourcePath the resource path to check | |
68 | * @return {@code true} if the resource path is not null and starts with one of the recognized | |
69 | * resource prefixes, {@code false} otherwise. | |
70 | * @since 0.9 | |
71 | */ | |
72 | @SuppressWarnings({"UnusedDeclaration"}) | |
73 | public static boolean hasResourcePrefix(String resourcePath) { | |
74 | 0 | return resourcePath != null && |
75 | (resourcePath.startsWith(CLASSPATH_PREFIX) || | |
76 | resourcePath.startsWith(URL_PREFIX) || | |
77 | resourcePath.startsWith(FILE_PREFIX)); | |
78 | } | |
79 | ||
80 | /** | |
81 | * Returns {@code true} if the resource at the specified path exists, {@code false} otherwise. This | |
82 | * method supports scheme prefixes on the path as defined in {@link #getInputStreamForPath(String)}. | |
83 | * | |
84 | * @param resourcePath the path of the resource to check. | |
85 | * @return {@code true} if the resource at the specified path exists, {@code false} otherwise. | |
86 | * @since 0.9 | |
87 | */ | |
88 | public static boolean resourceExists(String resourcePath) { | |
89 | 2 | InputStream stream = null; |
90 | 2 | boolean exists = false; |
91 | ||
92 | try { | |
93 | 2 | stream = getInputStreamForPath(resourcePath); |
94 | 0 | exists = true; |
95 | 2 | } catch (IOException e) { |
96 | 2 | stream = null; |
97 | } finally { | |
98 | 2 | if (stream != null) { |
99 | try { | |
100 | 0 | stream.close(); |
101 | 0 | } catch (IOException ignored) { |
102 | 0 | } |
103 | } | |
104 | } | |
105 | ||
106 | 2 | return exists; |
107 | } | |
108 | ||
109 | ||
110 | /** | |
111 | * Returns the InputStream for the resource represented by the specified path, supporting scheme | |
112 | * prefixes that direct how to acquire the input stream | |
113 | * ({@link #CLASSPATH_PREFIX CLASSPATH_PREFIX}, | |
114 | * {@link #URL_PREFIX URL_PREFIX}, or {@link #FILE_PREFIX FILE_PREFIX}). If the path is not prefixed by one | |
115 | * of these schemes, the path is assumed to be a file-based path that can be loaded with a | |
116 | * {@link FileInputStream FileInputStream}. | |
117 | * | |
118 | * @param resourcePath the String path representing the resource to obtain. | |
119 | * @return the InputStraem for the specified resource. | |
120 | * @throws IOException if there is a problem acquiring the resource at the specified path. | |
121 | */ | |
122 | public static InputStream getInputStreamForPath(String resourcePath) throws IOException { | |
123 | ||
124 | InputStream is; | |
125 | 7 | if (resourcePath.startsWith(CLASSPATH_PREFIX)) { |
126 | 7 | is = loadFromClassPath(stripPrefix(resourcePath)); |
127 | ||
128 | 0 | } else if (resourcePath.startsWith(URL_PREFIX)) { |
129 | 0 | is = loadFromUrl(stripPrefix(resourcePath)); |
130 | ||
131 | 0 | } else if (resourcePath.startsWith(FILE_PREFIX)) { |
132 | 0 | is = loadFromFile(stripPrefix(resourcePath)); |
133 | ||
134 | } else { | |
135 | 0 | is = loadFromFile(resourcePath); |
136 | } | |
137 | ||
138 | 7 | if (is == null) { |
139 | 2 | throw new IOException("Resource [" + resourcePath + "] could not be found."); |
140 | } | |
141 | ||
142 | 5 | return is; |
143 | } | |
144 | ||
145 | private static InputStream loadFromFile(String path) throws IOException { | |
146 | 0 | if (log.isDebugEnabled()) { |
147 | 0 | log.debug("Opening file [" + path + "]..."); |
148 | } | |
149 | 0 | return new FileInputStream(path); |
150 | } | |
151 | ||
152 | private static InputStream loadFromUrl(String urlPath) throws IOException { | |
153 | 0 | log.debug("Opening url {}", urlPath); |
154 | 0 | URL url = new URL(urlPath); |
155 | 0 | return url.openStream(); |
156 | } | |
157 | ||
158 | private static InputStream loadFromClassPath(String path) { | |
159 | 7 | log.debug("Opening resource from class path [{}]", path); |
160 | 7 | return ClassUtils.getResourceAsStream(path); |
161 | } | |
162 | ||
163 | private static String stripPrefix(String resourcePath) { | |
164 | 7 | return resourcePath.substring(resourcePath.indexOf(":") + 1); |
165 | } | |
166 | ||
167 | /** | |
168 | * Convenience method that closes the specified {@link InputStream InputStream}, logging any | |
169 | * {@link IOException IOException} that might occur. If the {@code InputStream} | |
170 | * argument is {@code null}, this method does nothing. It returns quietly in all cases. | |
171 | * | |
172 | * @param is the {@code InputStream} to close, logging any {@code IOException} that might occur. | |
173 | */ | |
174 | public static void close(InputStream is) { | |
175 | 1 | if (is != null) { |
176 | try { | |
177 | 1 | is.close(); |
178 | 0 | } catch (IOException e) { |
179 | 0 | log.warn("Error closing input stream.", e); |
180 | 1 | } |
181 | } | |
182 | 1 | } |
183 | } |