| 
68
 | 
     1 /*
 | 
| 
 | 
     2 Copyright (c) 2008  Franklin Schmidt <fschmidt@gmail.com>
 | 
| 
 | 
     3 
 | 
| 
 | 
     4 Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
| 
 | 
     5 of this software and associated documentation files (the "Software"), to deal
 | 
| 
 | 
     6 in the Software without restriction, including without limitation the rights
 | 
| 
 | 
     7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
| 
 | 
     8 copies of the Software, and to permit persons to whom the Software is
 | 
| 
 | 
     9 furnished to do so, subject to the following conditions:
 | 
| 
 | 
    10 
 | 
| 
 | 
    11 The above copyright notice and this permission notice shall be included in
 | 
| 
 | 
    12 all copies or substantial portions of the Software.
 | 
| 
 | 
    13 
 | 
| 
 | 
    14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
| 
 | 
    15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
| 
 | 
    16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
| 
 | 
    17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
| 
 | 
    18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
| 
 | 
    19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
| 
 | 
    20 THE SOFTWARE.
 | 
| 
 | 
    21 */
 | 
| 
 | 
    22 
 | 
| 
 | 
    23 package fschmidt.util.java;
 | 
| 
 | 
    24 
 | 
| 
 | 
    25 import java.io.BufferedInputStream;
 | 
| 
 | 
    26 import java.io.BufferedOutputStream;
 | 
| 
 | 
    27 import java.io.ByteArrayInputStream;
 | 
| 
 | 
    28 import java.io.ByteArrayOutputStream;
 | 
| 
 | 
    29 import java.io.File;
 | 
| 
 | 
    30 import java.io.FileInputStream;
 | 
| 
 | 
    31 import java.io.FileOutputStream;
 | 
| 
 | 
    32 import java.io.IOException;
 | 
| 
 | 
    33 import java.io.InputStream;
 | 
| 
 | 
    34 import java.io.InputStreamReader;
 | 
| 
 | 
    35 import java.io.OutputStream;
 | 
| 
 | 
    36 import java.io.OutputStreamWriter;
 | 
| 
 | 
    37 import java.io.Reader;
 | 
| 
 | 
    38 import java.io.Writer;
 | 
| 
 | 
    39 import java.net.HttpURLConnection;
 | 
| 
 | 
    40 import java.net.MalformedURLException;
 | 
| 
 | 
    41 import java.net.URL;
 | 
| 
 | 
    42 import java.nio.charset.Charset;
 | 
| 
 | 
    43 import java.util.Collections;
 | 
| 
 | 
    44 import java.util.Enumeration;
 | 
| 
 | 
    45 import java.util.Iterator;
 | 
| 
 | 
    46 import java.util.NoSuchElementException;
 | 
| 
 | 
    47 import java.util.jar.JarEntry;
 | 
| 
 | 
    48 import java.util.jar.JarFile;
 | 
| 
 | 
    49 
 | 
| 
 | 
    50 
 | 
| 
 | 
    51 public final class IoUtils {
 | 
| 
 | 
    52 	private IoUtils() {}  // never
 | 
| 
 | 
    53 
 | 
| 
 | 
    54 	private static final int bufSize = 8192;
 | 
| 
 | 
    55 
 | 
| 
 | 
    56 	public static String readAll(Reader in)
 | 
| 
 | 
    57 		throws IOException
 | 
| 
 | 
    58 	{
 | 
| 
 | 
    59 		char[] a = new char[bufSize];
 | 
| 
 | 
    60 		StringBuilder buf = new StringBuilder();
 | 
| 
 | 
    61 		int n;
 | 
| 
 | 
    62 		while( (n=in.read(a)) != -1 ) {
 | 
| 
 | 
    63 			buf.append(a,0,n);
 | 
| 
 | 
    64 		}
 | 
| 
 | 
    65 		return buf.toString();
 | 
| 
 | 
    66 	}
 | 
| 
 | 
    67 
 | 
| 
 | 
    68 	public static void copyAll(InputStream in,OutputStream out)
 | 
| 
 | 
    69 		throws IOException
 | 
| 
 | 
    70 	{
 | 
| 
 | 
    71 		byte[] a = new byte[bufSize];
 | 
| 
 | 
    72 		int n;
 | 
| 
 | 
    73 		while( (n=in.read(a)) != -1 ) {
 | 
| 
 | 
    74 			out.write(a,0,n);
 | 
| 
 | 
    75 		}
 | 
| 
 | 
    76 	}
 | 
| 
 | 
    77 
 | 
| 
 | 
    78 	public static int copyAllAndCount(InputStream in,OutputStream out)
 | 
| 
 | 
    79 		throws IOException
 | 
| 
 | 
    80 	{
 | 
| 
 | 
    81 		byte[] a = new byte[bufSize];
 | 
| 
 | 
    82 		int n;
 | 
| 
 | 
    83 		int count = 0;
 | 
| 
 | 
    84 		while( (n=in.read(a)) != -1 ) {
 | 
| 
 | 
    85 			out.write(a,0,n);
 | 
| 
 | 
    86 			count += n;
 | 
| 
 | 
    87 		}
 | 
| 
 | 
    88 		return count;
 | 
| 
 | 
    89 	}
 | 
| 
 | 
    90 
 | 
| 
 | 
    91 	public static void copyAvailable(InputStream in,OutputStream out)
 | 
| 
 | 
    92 		throws IOException
 | 
| 
 | 
    93 	{
 | 
| 
 | 
    94 		byte[] a = new byte[bufSize];
 | 
| 
 | 
    95 		while( in.available() > 0 ) {
 | 
| 
 | 
    96 			out.write(a,0,in.read(a));
 | 
| 
 | 
    97 		}
 | 
| 
 | 
    98 	}
 | 
| 
 | 
    99 
 | 
| 
 | 
   100 	public static byte[] readAll(InputStream in)
 | 
| 
 | 
   101 		throws IOException
 | 
| 
 | 
   102 	{
 | 
| 
 | 
   103 		ByteArrayOutputStream out = new ByteArrayOutputStream();
 | 
| 
 | 
   104 		copyAll(in,out);
 | 
| 
 | 
   105 		return out.toByteArray();
 | 
| 
 | 
   106 	}
 | 
| 
 | 
   107 
 | 
| 
 | 
   108 	public static void writeAll(byte[] a,OutputStream out)
 | 
| 
 | 
   109 		throws IOException
 | 
| 
 | 
   110 	{
 | 
| 
 | 
   111 		copyAll(new ByteArrayInputStream(a),out);
 | 
| 
 | 
   112 	}
 | 
| 
 | 
   113 
 | 
| 
 | 
   114 	public static byte[] readAll(File file)
 | 
| 
 | 
   115 		throws IOException
 | 
| 
 | 
   116 	{
 | 
| 
 | 
   117 		int len = (int)file.length();
 | 
| 
 | 
   118 		ByteArrayOutputStream out = new ByteArrayOutputStream(len) {
 | 
| 
 | 
   119 			public byte[] toByteArray() {
 | 
| 
 | 
   120 				return buf;
 | 
| 
 | 
   121 			}
 | 
| 
 | 
   122 		};
 | 
| 
 | 
   123 		FileInputStream in = new FileInputStream(file);
 | 
| 
 | 
   124 		copyAll(in,out);
 | 
| 
 | 
   125 		in.close();
 | 
| 
 | 
   126 		return out.toByteArray();
 | 
| 
 | 
   127 	}
 | 
| 
 | 
   128 
 | 
| 
 | 
   129 	public static void writeAll(byte[] a,File file)
 | 
| 
 | 
   130 		throws IOException
 | 
| 
 | 
   131 	{
 | 
| 
 | 
   132 		FileOutputStream fos = new FileOutputStream(file);
 | 
| 
 | 
   133 		writeAll(a,fos);
 | 
| 
 | 
   134 		fos.close();
 | 
| 
 | 
   135 	}
 | 
| 
 | 
   136 
 | 
| 
 | 
   137 	public static String readPage(String url)
 | 
| 
 | 
   138 		throws IOException
 | 
| 
 | 
   139 	{
 | 
| 
 | 
   140 		return new UrlCall(url).get();
 | 
| 
 | 
   141 	}
 | 
| 
 | 
   142 
 | 
| 
 | 
   143 	public static String read(URL url)
 | 
| 
 | 
   144 		throws IOException
 | 
| 
 | 
   145 	{
 | 
| 
 | 
   146 		return new UrlCall(url).get();
 | 
| 
 | 
   147 	}
 | 
| 
 | 
   148 
 | 
| 
 | 
   149 	public static String post(String urlS,String postS)
 | 
| 
 | 
   150 		throws IOException
 | 
| 
 | 
   151 	{
 | 
| 
 | 
   152 		return new UrlCall(urlS).post(postS);
 | 
| 
 | 
   153 	}
 | 
| 
 | 
   154 
 | 
| 
 | 
   155 	public static String hideNull(String s) {
 | 
| 
 | 
   156 		return s==null ? "" : s;
 | 
| 
 | 
   157 	}
 | 
| 
 | 
   158 
 | 
| 
 | 
   159 	public static boolean delete(File file) {
 | 
| 
 | 
   160 		if( file.isDirectory() ) {
 | 
| 
 | 
   161 			File[] files = file.listFiles();
 | 
| 
 | 
   162 			for( int i=0; i<files.length; i++ ) {
 | 
| 
 | 
   163 				delete(files[i]);
 | 
| 
 | 
   164 			}
 | 
| 
 | 
   165 		}
 | 
| 
 | 
   166 		return file.delete();
 | 
| 
 | 
   167 	}
 | 
| 
 | 
   168 
 | 
| 
 | 
   169 	public static URL getUrlFromResource(String resourceName) {
 | 
| 
 | 
   170 /*
 | 
| 
 | 
   171 		ClassLoader loader = IoUtils.class.getClassLoader();
 | 
| 
 | 
   172 		return loader.getResource(resourceName);
 | 
| 
 | 
   173 */
 | 
| 
 | 
   174 		return ClassLoader.getSystemResource(resourceName);
 | 
| 
 | 
   175 	}
 | 
| 
 | 
   176 
 | 
| 
 | 
   177 	public static String getContentFromResource(String resourceName)
 | 
| 
 | 
   178 		throws IOException
 | 
| 
 | 
   179 	{
 | 
| 
 | 
   180 		URL url = getUrlFromResource(resourceName);
 | 
| 
 | 
   181 		return url==null ? null : read(url);
 | 
| 
 | 
   182 	}
 | 
| 
 | 
   183 
 | 
| 
 | 
   184 	public static String read(File file)
 | 
| 
 | 
   185 		throws IOException
 | 
| 
 | 
   186 	{
 | 
| 
 | 
   187 		Reader in = newFileReader(file);
 | 
| 
 | 
   188 		String s = readAll(in);
 | 
| 
 | 
   189 		in.close();
 | 
| 
 | 
   190 		return s;
 | 
| 
 | 
   191 	}
 | 
| 
 | 
   192 
 | 
| 
 | 
   193 	public static void write(File file,String s)
 | 
| 
 | 
   194 		throws IOException
 | 
| 
 | 
   195 	{
 | 
| 
 | 
   196 		Writer out = newFileWriter(file);
 | 
| 
 | 
   197 		out.write(s);
 | 
| 
 | 
   198 		out.close();
 | 
| 
 | 
   199 	}
 | 
| 
 | 
   200 
 | 
| 
 | 
   201 	public static Reader newFileReader(File file)
 | 
| 
 | 
   202 		throws IOException
 | 
| 
 | 
   203 	{
 | 
| 
 | 
   204 		return new InputStreamReader(new FileInputStream(file),Charset.forName("utf-8"));
 | 
| 
 | 
   205 	}
 | 
| 
 | 
   206 
 | 
| 
 | 
   207 	public static Reader newFileReader(String file)
 | 
| 
 | 
   208 		throws IOException
 | 
| 
 | 
   209 	{
 | 
| 
 | 
   210 		return new InputStreamReader(new FileInputStream(file),Charset.forName("utf-8"));
 | 
| 
 | 
   211 	}
 | 
| 
 | 
   212 
 | 
| 
 | 
   213 	public static Writer newFileWriter(File file)
 | 
| 
 | 
   214 		throws IOException
 | 
| 
 | 
   215 	{
 | 
| 
 | 
   216 		return new OutputStreamWriter(new FileOutputStream(file),Charset.forName("utf-8"));
 | 
| 
 | 
   217 	}
 | 
| 
 | 
   218 
 | 
| 
 | 
   219 	public static Writer newFileWriter(String file)
 | 
| 
 | 
   220 		throws IOException
 | 
| 
 | 
   221 	{
 | 
| 
 | 
   222 		return new OutputStreamWriter(new FileOutputStream(file),Charset.forName("utf-8"));
 | 
| 
 | 
   223 	}
 | 
| 
 | 
   224 
 | 
| 
 | 
   225 	public static int hashCode(InputStream in)
 | 
| 
 | 
   226 		throws IOException
 | 
| 
 | 
   227 	{
 | 
| 
 | 
   228 		int h = 0;
 | 
| 
 | 
   229 		int c;
 | 
| 
 | 
   230 		while( (c=in.read()) != -1 ) {
 | 
| 
 | 
   231 			h = 31*h + c;
 | 
| 
 | 
   232 		}
 | 
| 
 | 
   233 		return h;
 | 
| 
 | 
   234 	}
 | 
| 
 | 
   235 
 | 
| 
 | 
   236 	public static int hashCode(File file)
 | 
| 
 | 
   237 		throws IOException
 | 
| 
 | 
   238 	{
 | 
| 
 | 
   239 		InputStream in = new BufferedInputStream(new FileInputStream(file));
 | 
| 
 | 
   240 		int r = hashCode(in);
 | 
| 
 | 
   241 		in.close();
 | 
| 
 | 
   242 		return r;
 | 
| 
 | 
   243 	}
 | 
| 
 | 
   244 
 | 
| 
 | 
   245 	public static int compare(InputStream in1,InputStream in2)
 | 
| 
 | 
   246 		throws IOException
 | 
| 
 | 
   247 	{
 | 
| 
 | 
   248 		while(true) {
 | 
| 
 | 
   249 			int c1 = in1.read();
 | 
| 
 | 
   250 			int c2 = in2.read();
 | 
| 
 | 
   251 			if( c1 == -1 && c2 == -1 )
 | 
| 
 | 
   252 				return 0;
 | 
| 
 | 
   253 			if( c1 != c2 )
 | 
| 
 | 
   254 				return c1 - c2;
 | 
| 
 | 
   255 		}
 | 
| 
 | 
   256 	}
 | 
| 
 | 
   257 
 | 
| 
 | 
   258 	public static int compare(File file1,File file2)
 | 
| 
 | 
   259 		throws IOException
 | 
| 
 | 
   260 	{
 | 
| 
 | 
   261 		InputStream in1 = new BufferedInputStream(new FileInputStream(file1));
 | 
| 
 | 
   262 		InputStream in2 = new BufferedInputStream(new FileInputStream(file2));
 | 
| 
 | 
   263 		int r = compare(in1,in2);
 | 
| 
 | 
   264 		in2.close();
 | 
| 
 | 
   265 		in1.close();
 | 
| 
 | 
   266 		return r;
 | 
| 
 | 
   267 	}
 | 
| 
 | 
   268 
 | 
| 
 | 
   269 	public static void copy(File file1,File file2)
 | 
| 
 | 
   270 		throws IOException
 | 
| 
 | 
   271 	{
 | 
| 
 | 
   272 		InputStream in = new BufferedInputStream(new FileInputStream(file1));
 | 
| 
 | 
   273 		OutputStream out = new BufferedOutputStream(new FileOutputStream(file2));
 | 
| 
 | 
   274 		copyAll(in,out);
 | 
| 
 | 
   275 		out.close();
 | 
| 
 | 
   276 		in.close();
 | 
| 
 | 
   277 	}
 | 
| 
 | 
   278 
 | 
| 
 | 
   279 	public static Iterable<URL> getResources(Class classInJarOrDir) {
 | 
| 
 | 
   280 		String classFile = classInJarOrDir.getName().replace('.','/') + ".class";
 | 
| 
 | 
   281 		return getResources(classFile);
 | 
| 
 | 
   282 	}
 | 
| 
 | 
   283 
 | 
| 
 | 
   284 	public static Iterable<URL> getResources(String fileName) {
 | 
| 
 | 
   285 		URL classUrl = ClassLoader.getSystemResource(fileName);
 | 
| 
 | 
   286 		String protocol = classUrl.getProtocol();
 | 
| 
 | 
   287 		if( protocol.equals("file") ) {
 | 
| 
 | 
   288 			File f = new File(classUrl.getFile()).getParentFile();
 | 
| 
 | 
   289 			for( int i = -1; (i = fileName.indexOf('/',i+1)) != -1; ) {
 | 
| 
 | 
   290 				f = f.getParentFile();
 | 
| 
 | 
   291 			}
 | 
| 
 | 
   292 			return new FileIterator(f);
 | 
| 
 | 
   293 		}
 | 
| 
 | 
   294 		if( protocol.equals("jar") ) {
 | 
| 
 | 
   295 			String s = classUrl.getFile();
 | 
| 
 | 
   296 			if( !s.startsWith("file:") )
 | 
| 
 | 
   297 				throw new RuntimeException("jar isn't file: "+classUrl);
 | 
| 
 | 
   298 			File f = new File(s.substring(5,s.indexOf('!')));
 | 
| 
 | 
   299 			try {
 | 
| 
 | 
   300 				JarFile jar = new JarFile(f);
 | 
| 
 | 
   301 				return new JarIterator(jar);
 | 
| 
 | 
   302 			} catch(IOException e) {
 | 
| 
 | 
   303 				throw new RuntimeException(e);
 | 
| 
 | 
   304 			}
 | 
| 
 | 
   305 		}
 | 
| 
 | 
   306 		throw new RuntimeException("can't handle protocol: "+protocol);
 | 
| 
 | 
   307 	}
 | 
| 
 | 
   308 
 | 
| 
 | 
   309 	private static class FileIterator implements Iterator<URL>, Iterable<URL> {
 | 
| 
 | 
   310 		private final File[] files;
 | 
| 
 | 
   311 		private Iterator<URL> childIter = Collections.<URL>emptyList().iterator();
 | 
| 
 | 
   312 		private URL next;
 | 
| 
 | 
   313 		private int i = -1;
 | 
| 
 | 
   314 
 | 
| 
 | 
   315 		FileIterator(File dir) {
 | 
| 
 | 
   316 			this.files = dir.listFiles();
 | 
| 
 | 
   317 		}
 | 
| 
 | 
   318 
 | 
| 
 | 
   319 		public Iterator<URL> iterator() {
 | 
| 
 | 
   320 			return this;
 | 
| 
 | 
   321 		}
 | 
| 
 | 
   322 
 | 
| 
 | 
   323 		public boolean hasNext() {
 | 
| 
 | 
   324 			if( next!=null )
 | 
| 
 | 
   325 				return true;
 | 
| 
 | 
   326 			if( childIter.hasNext() ) {
 | 
| 
 | 
   327 				next = childIter.next();
 | 
| 
 | 
   328 				return true;
 | 
| 
 | 
   329 			}
 | 
| 
 | 
   330 			while( ++i < files.length ) {
 | 
| 
 | 
   331 				File f = files[i];
 | 
| 
 | 
   332 				if( f.isFile() ) {
 | 
| 
 | 
   333 					try {
 | 
| 
 | 
   334 						next = f.toURL();
 | 
| 
 | 
   335 					} catch(MalformedURLException e) {
 | 
| 
 | 
   336 						throw new RuntimeException(e);
 | 
| 
 | 
   337 					}
 | 
| 
 | 
   338 					return true;
 | 
| 
 | 
   339 				}
 | 
| 
 | 
   340 				if( f.isDirectory() ) {
 | 
| 
 | 
   341 					childIter = new FileIterator(f);
 | 
| 
 | 
   342 					if( childIter.hasNext() ) {
 | 
| 
 | 
   343 						next = childIter.next();
 | 
| 
 | 
   344 						return true;
 | 
| 
 | 
   345 					}
 | 
| 
 | 
   346 				}
 | 
| 
 | 
   347 			}
 | 
| 
 | 
   348 			return false;
 | 
| 
 | 
   349 		}
 | 
| 
 | 
   350 
 | 
| 
 | 
   351 		public URL next() {
 | 
| 
 | 
   352 			if( next==null )
 | 
| 
 | 
   353 				throw new NoSuchElementException();
 | 
| 
 | 
   354 			try {
 | 
| 
 | 
   355 				return next;
 | 
| 
 | 
   356 			} finally {
 | 
| 
 | 
   357 				next = null;
 | 
| 
 | 
   358 			}
 | 
| 
 | 
   359 		}
 | 
| 
 | 
   360 
 | 
| 
 | 
   361 		public void remove() {
 | 
| 
 | 
   362 			throw new UnsupportedOperationException();
 | 
| 
 | 
   363 		}
 | 
| 
 | 
   364 	}
 | 
| 
 | 
   365 
 | 
| 
 | 
   366 	private static class JarIterator implements Iterator<URL>, Iterable<URL> {
 | 
| 
 | 
   367 		private final Enumeration<JarEntry> entries;
 | 
| 
 | 
   368 		private final String urlBase;
 | 
| 
 | 
   369 
 | 
| 
 | 
   370 		JarIterator(JarFile jar) {
 | 
| 
 | 
   371 			this.entries = jar.entries();
 | 
| 
 | 
   372 			try {
 | 
| 
 | 
   373 				this.urlBase = "jar:" + new File(jar.getName()).toURL().toString() + "!/";
 | 
| 
 | 
   374 			} catch(MalformedURLException e) {
 | 
| 
 | 
   375 				throw new RuntimeException(e);
 | 
| 
 | 
   376 			}
 | 
| 
 | 
   377 		}
 | 
| 
 | 
   378 
 | 
| 
 | 
   379 		public Iterator<URL> iterator() {
 | 
| 
 | 
   380 			return this;
 | 
| 
 | 
   381 		}
 | 
| 
 | 
   382 
 | 
| 
 | 
   383 		public boolean hasNext() {
 | 
| 
 | 
   384 			return entries.hasMoreElements();
 | 
| 
 | 
   385 		}
 | 
| 
 | 
   386 
 | 
| 
 | 
   387 		public URL next() {
 | 
| 
 | 
   388 			try {
 | 
| 
 | 
   389 				return new URL( urlBase + entries.nextElement() );
 | 
| 
 | 
   390 			} catch(MalformedURLException e) {
 | 
| 
 | 
   391 				throw new RuntimeException(e);
 | 
| 
 | 
   392 			}
 | 
| 
 | 
   393 		}
 | 
| 
 | 
   394 
 | 
| 
 | 
   395 		public void remove() {
 | 
| 
 | 
   396 			throw new UnsupportedOperationException();
 | 
| 
 | 
   397 		}
 | 
| 
 | 
   398 	}
 | 
| 
 | 
   399 
 | 
| 
 | 
   400 }
 |