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