001 /**
002 * GRANITE DATA SERVICES
003 * Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S.
004 *
005 * This file is part of the Granite Data Services Platform.
006 *
007 * Granite Data Services is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * Granite Data Services is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
015 * General Public License for more details.
016 *
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this library; if not, write to the Free Software
019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
020 * USA, or see <http://www.gnu.org/licenses/>.
021 */
022 package org.granite.util;
023
024 import java.io.BufferedInputStream;
025 import java.io.BufferedReader;
026 import java.io.ByteArrayOutputStream;
027 import java.io.File;
028 import java.io.FileInputStream;
029 import java.io.IOException;
030 import java.io.InputStream;
031 import java.io.InputStreamReader;
032 import java.net.JarURLConnection;
033 import java.net.URI;
034 import java.net.URISyntaxException;
035 import java.net.URL;
036 import java.net.URLConnection;
037 import java.nio.charset.Charset;
038 import java.util.jar.JarEntry;
039 import java.util.regex.Pattern;
040
041 /**
042 * @author Franck WOLFF
043 */
044 public class URIUtil {
045
046 public static final String CLASSPATH_SCHEME = "class";
047 public static final String FILE_SCHEME = "file";
048 public static final Pattern WINDOWS_DRIVE_PATTERN = Pattern.compile("^[a-zA-Z]\\:.*$");
049
050 public static String normalize(String uri) {
051 if (uri == null)
052 return null;
053 uri = uri.replace('\\', '/').replace(" ", "%20");
054 while (uri.indexOf("//") != -1)
055 uri = uri.replace("//", "/");
056 return uri;
057 }
058
059 public static boolean isFileURI(String path) throws URISyntaxException {
060 return isFileURI(new URI(normalize(path)));
061 }
062
063 public static boolean isFileURI(URI uri) {
064 // scheme.length() == 1 -> assume windows drive letter.
065 return uri.getScheme() == null || uri.getScheme().length() <= 1 || FILE_SCHEME.equals(uri.getScheme());
066 }
067
068 public static boolean isAbsolute(String path) throws URISyntaxException {
069 return isAbsolute(new URI(normalize(path)));
070 }
071
072 public static boolean isAbsolute(URI uri) {
073 String schemeSpecificPart = uri.getSchemeSpecificPart();
074 if (schemeSpecificPart == null || schemeSpecificPart.length() == 0)
075 return uri.isAbsolute();
076
077 String scheme = uri.getScheme();
078 if (scheme == null)
079 return schemeSpecificPart.charAt(0) == '/';
080 if (FILE_SCHEME.equals(scheme))
081 return schemeSpecificPart.charAt(0) == '/' || WINDOWS_DRIVE_PATTERN.matcher(schemeSpecificPart).matches();
082 return true;
083 }
084
085 public static String getSchemeSpecificPart(String path) throws URISyntaxException {
086 return getSchemeSpecificPart(new URI(normalize(path)));
087 }
088
089 public static String getSchemeSpecificPart(URI uri) {
090 if (uri.getScheme() != null && uri.getScheme().length() <= 1)
091 return uri.getScheme() + ":" + uri.getSchemeSpecificPart();
092 return uri.getSchemeSpecificPart();
093 }
094
095 public static InputStream getInputStream(URI uri, ClassLoader loader) throws IOException {
096 InputStream is = null;
097
098 String scheme = uri.getScheme();
099 String path = getSchemeSpecificPart(uri);
100 if (CLASSPATH_SCHEME.equals(scheme)) {
101 if (loader != null)
102 is = loader.getResourceAsStream(path);
103 if (is == null) {
104 is = Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
105 if (is == null)
106 throw new IOException("Resource not found exception: " + uri);
107 }
108 }
109 else if (isFileURI(uri))
110 is = new FileInputStream(path);
111 else
112 is = uri.toURL().openStream();
113
114 return is;
115 }
116
117 public static InputStream getInputStream(URI uri) throws IOException {
118 return getInputStream(uri, null);
119 }
120
121 public static String getContentAsString(URI uri) throws IOException {
122 return getContentAsString(uri, Charset.defaultCharset());
123 }
124 public static String getContentAsString(URI uri, Charset charset) throws IOException {
125 InputStream is = null;
126 try {
127 is = getInputStream(uri);
128 BufferedReader reader = new BufferedReader(new InputStreamReader(is, charset));
129
130 StringBuilder sb = new StringBuilder(1024);
131
132 char[] chars = new char[256];
133 int count = -1;
134 while ((count = reader.read(chars)) != -1)
135 sb.append(chars, 0, count);
136
137 return sb.toString();
138 } finally {
139 if (is != null)
140 is.close();
141 }
142 }
143
144 public static byte[] getContentAsBytes(URI uri) throws IOException {
145 InputStream is = null;
146 try {
147 is = new BufferedInputStream(getInputStream(uri));
148
149 ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
150
151 int b = 0;
152 while ((b = is.read()) != -1)
153 baos.write(b);
154
155 return baos.toByteArray();
156 } finally {
157 if (is != null)
158 is.close();
159 }
160 }
161
162 public static long lastModified(URI uri) throws IOException {
163 if (uri == null)
164 return -1L;
165
166 String scheme = uri.getScheme();
167 if (scheme == null || scheme.length() <= 1)
168 return new File(uri).lastModified();
169 return lastModified(uri.toURL());
170 }
171
172 public static long lastModified(URL url) throws IOException {
173 long lastModified = -1L;
174
175 if (url != null) {
176 URLConnection connection = url.openConnection();
177 if (connection instanceof JarURLConnection) {
178 JarEntry entry = ((JarURLConnection)connection).getJarEntry();
179 if (entry != null)
180 lastModified = entry.getTime();
181 }
182 if (lastModified == -1L)
183 lastModified = connection.getLastModified();
184 }
185
186 return (lastModified == 0L ? -1L : lastModified);
187 }
188 }