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 */ 022package org.granite.util; 023 024import java.io.BufferedInputStream; 025import java.io.BufferedReader; 026import java.io.ByteArrayOutputStream; 027import java.io.File; 028import java.io.FileInputStream; 029import java.io.IOException; 030import java.io.InputStream; 031import java.io.InputStreamReader; 032import java.net.JarURLConnection; 033import java.net.URI; 034import java.net.URISyntaxException; 035import java.net.URL; 036import java.net.URLConnection; 037import java.nio.charset.Charset; 038import java.util.jar.JarEntry; 039import java.util.regex.Pattern; 040 041/** 042 * @author Franck WOLFF 043 */ 044public 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}