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