Clover coverage report - QedeqKernelSe Coverage Report
Coverage timestamp: Sa Jan 26 2008 14:11:34 CET
file stats: LOC: 751   Methods: 34
NCLOC: 409   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
IoUtility.java 38% 54,8% 47,1% 49,3%
coverage coverage
 1    /* $Id: IoUtility.java,v 1.14 2008/01/26 12:39:10 m31 Exp $
 2    *
 3    * This file is part of the project "Hilbert II" - http://www.qedeq.org
 4    *
 5    * Copyright 2000-2007, Michael Meyling <mime@qedeq.org>.
 6    *
 7    * "Hilbert II" is free software; you can redistribute
 8    * it and/or modify it under the terms of the GNU General Public
 9    * License as published by the Free Software Foundation; either
 10    * version 2 of the License, or (at your option) any later version.
 11    *
 12    * This program is distributed in the hope that it will be useful,
 13    * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15    * GNU General Public License for more details.
 16    */
 17   
 18    package org.qedeq.kernel.utility;
 19   
 20    import java.io.BufferedOutputStream;
 21    import java.io.BufferedReader;
 22    import java.io.BufferedWriter;
 23    import java.io.ByteArrayInputStream;
 24    import java.io.ByteArrayOutputStream;
 25    import java.io.File;
 26    import java.io.FileInputStream;
 27    import java.io.FileOutputStream;
 28    import java.io.FileReader;
 29    import java.io.FileWriter;
 30    import java.io.IOException;
 31    import java.io.InputStream;
 32    import java.io.InputStreamReader;
 33    import java.io.Reader;
 34    import java.io.UnsupportedEncodingException;
 35    import java.net.MalformedURLException;
 36    import java.net.URL;
 37    import java.util.Arrays;
 38    import java.util.Enumeration;
 39    import java.util.Properties;
 40   
 41   
 42    /**
 43    * A collection of useful static methods for input and output.
 44    *
 45    * LATER mime 20070101: use StringBuilder instead of StringBuffer if working under JDK 1.5
 46    *
 47    * FIXME mime 20070926: load* and loadBinary are mixed. loarUrl should be binary load!
 48    *
 49    * @version $Revision: 1.14 $
 50    * @author Michael Meyling
 51    */
 52    public final class IoUtility {
 53   
 54    /**
 55    * Constructor, should never be called.
 56    */
 57  0 private IoUtility() {
 58    // don't call me
 59    }
 60   
 61    /**
 62    * Reads a file and returns the contents as a <code>String</code>.
 63    *
 64    * @param filename Name of the file (could include path).
 65    * @return Contents of file.
 66    * @throws IOException File exception occurred.
 67    */
 68  0 public static String loadFile(final String filename)
 69    throws IOException {
 70   
 71  0 final StringBuffer buffer = new StringBuffer();
 72  0 loadFile(filename, buffer);
 73  0 return buffer.toString();
 74    }
 75   
 76    /**
 77    * Reads contents of a file into a string buffer.
 78    *
 79    * @param filename Name of the file (could include path).
 80    * @param buffer Buffer to fill with file contents.
 81    * @throws IOException File exception occurred.
 82    */
 83  0 public static void loadFile(final String filename,
 84    final StringBuffer buffer)
 85    throws IOException {
 86  0 loadFile(new File(filename), buffer);
 87    }
 88   
 89    /**
 90    * Reads contents of a stream into a string buffer.
 91    *
 92    * @param in This stream will be loaded.
 93    * @param buffer Buffer to fill with file contents.
 94    * @throws IOException File exception occurred.
 95    */
 96  0 public static void loadStream(final InputStream in,
 97    final StringBuffer buffer)
 98    throws IOException {
 99   
 100  0 buffer.setLength(0);
 101  0 int c;
 102  0 while ((c = in.read()) >= 0) {
 103  0 buffer.append((char) c);
 104    }
 105    }
 106   
 107    /**
 108    * Reads contents of a file into a string buffer.
 109    *
 110    * @param file This file will be loaded.
 111    * @param buffer Buffer to fill with file contents.
 112    * @throws IOException File exception occurred.
 113    */
 114  32167 public static void loadFile(final File file,
 115    final StringBuffer buffer)
 116    throws IOException {
 117   
 118  32167 final int size = (int) file.length();
 119  32167 buffer.setLength(0);
 120  32167 final FileReader in = new FileReader(file);
 121  32167 final char[] data = new char[size];
 122  32167 int charsread = 0;
 123  32167 while (charsread < size) {
 124  32167 charsread += in.read(data, charsread, size - charsread);
 125    }
 126  32167 in.close();
 127  32167 buffer.insert(0, data);
 128    }
 129   
 130    /**
 131    * Reads a file and returns the contents as a <code>String</code>.
 132    *
 133    * @param file File to load from.
 134    * @return Contents of file.
 135    * @throws IOException File exception occurred.
 136    */
 137  0 public static final byte[] loadFileBinary(final File file) throws IOException {
 138  0 final int size = (int) file.length();
 139  0 final FileInputStream in = new FileInputStream(file);
 140  0 try {
 141  0 final byte[] data = new byte[size];
 142  0 int charsread = 0;
 143  0 while (charsread < size) {
 144  0 final int read = in.read(data, charsread, size - charsread);
 145  0 if (read == -1) {
 146  0 final byte[] result = new byte[charsread];
 147  0 System.arraycopy(data, 0, result, 0, charsread);
 148  0 return result;
 149    }
 150  0 charsread += read;
 151    }
 152  0 in.close();
 153  0 return data;
 154    } finally {
 155  0 closeStream(in);
 156    }
 157    }
 158   
 159    /**
 160    * Reads contents of an URL into a string buffer. The filling is character set dependent.
 161    * FIXME mime 20071230: what about binary load?
 162    * @param url This URL will be loaded.
 163    * @param buffer Buffer to fill with file contents.
 164    * @throws IOException Reading failed.
 165    */
 166  0 public static void loadFile(final URL url, final StringBuffer buffer) throws IOException {
 167  0 InputStream in = null;
 168  0 BufferedReader dis = null;
 169  0 try {
 170  0 in = url.openStream();
 171  0 dis = new BufferedReader(new InputStreamReader(in));
 172  0 int i;
 173  0 while ((i = dis.read()) != -1) {
 174  0 buffer.append((char) i);
 175    }
 176    } finally {
 177  0 closeStream(in);
 178  0 closeReader(dis);
 179    }
 180    }
 181   
 182    /**
 183    * Save contents of an URL into a file.
 184    *
 185    * @param url This URL will be loaded.
 186    * @param file Write into this file.
 187    * @throws IOException Reading or writing failed.
 188    */
 189  1 public static void saveFile(final URL url, final File file) throws IOException {
 190  1 final InputStream in = url.openStream();
 191  1 final FileOutputStream out = new FileOutputStream(file);
 192   
 193  1 byte[] data = new byte[8 * 1024];
 194  1 int length;
 195   
 196  ? while ((length = in.read(data)) != -1) {
 197  1 out.write(data, 0, length);
 198    }
 199  1 in.close();
 200  1 out.close();
 201    }
 202   
 203    /**
 204    * Convert String into a {@link Reader}.
 205    *
 206    * <a href="http://bugs.sun.com/bugdatabase/view_bug.do;:WuuT?bug_id=4094886">
 207    * Bug ID: 4094886</a>
 208    *
 209    * @param data Convert this.
 210    * @return Resulting reader.
 211    */
 212  0 public static final Reader stringToReader(final String data) {
 213  0 try {
 214  0 return new InputStreamReader(new ByteArrayInputStream(data.getBytes("ISO-8859-1")));
 215    } catch (UnsupportedEncodingException e) {
 216  0 throw new RuntimeException(e);
 217    }
 218    }
 219   
 220    /**
 221    * Saves a <code>String</code> into a file.
 222    *
 223    * @param filename Name of the file (could include path).
 224    * @param text Data to save in the file.
 225    * @throws IOException File exception occurred.
 226    */
 227  0 public static void saveFile(final String filename, final String text)
 228    throws IOException {
 229  0 saveFile(new File(filename), text);
 230    }
 231   
 232    /**
 233    * Saves a <code>StringBuffer</code> in a file.
 234    *
 235    * @param filename Name of the file (could include path).
 236    * @param text Data to save in the file.
 237    * @throws IOException File exception occurred.
 238    */
 239  0 public static void saveFile(final String filename, final StringBuffer text)
 240    throws IOException {
 241  0 saveFile(new File(filename), text.toString());
 242    }
 243   
 244   
 245    /**
 246    * Saves a <code>StringBuffer</code> in a file.
 247    *
 248    * @param file File to save into.
 249    * @param text Data to save in the file.
 250    * @throws IOException File exception occurred.
 251    */
 252  0 public static void saveFile(final File file, final StringBuffer text)
 253    throws IOException {
 254  0 saveFile(file, text.toString());
 255    }
 256   
 257   
 258    /**
 259    * Saves a <code>String</code> in a file.
 260    *
 261    * @param file File to save the data in.
 262    * @param text Data to save in the file.
 263    * @throws IOException File exception occurred.
 264    */
 265  1 public static void saveFile(final File file, final String text)
 266    throws IOException {
 267  1 BufferedWriter out = new BufferedWriter(
 268    new FileWriter(file));
 269  1 out.write(text);
 270  1 out.close();
 271    }
 272   
 273    /**
 274    * Saves a <code>String</code> in a file.
 275    *
 276    * @param file File to save the data in.
 277    * @param data Data to save in the file.
 278    * @throws IOException File exception occurred.
 279    */
 280  0 public static void saveFileBinary(final File file, final byte[] data)
 281    throws IOException {
 282  0 BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
 283  0 out.write(data);
 284  0 out.close();
 285    }
 286   
 287    /**
 288    * Copies a file to a different location.
 289    *
 290    * @param from Copy source.
 291    * @param to Copy destination.
 292    * @throws IOException File exception occurred.
 293    */
 294  18 public static void copyFile(final File from, final File to)
 295    throws IOException {
 296   
 297  18 if (from.getCanonicalFile().equals(to.getCanonicalFile())) {
 298  0 return;
 299    }
 300  18 FileInputStream in = new FileInputStream(from);
 301  18 FileOutputStream out = new FileOutputStream(to);
 302   
 303  18 byte[] data = new byte[8 * 1024];
 304  18 int length;
 305   
 306  ? while ((length = in.read(data)) != -1) {
 307  152 out.write(data, 0, length);
 308    }
 309  18 in.close();
 310  18 out.close();
 311    }
 312   
 313    /**
 314    * Compare two files.
 315    *
 316    * @param from Compare source.
 317    * @param with Compare with this file.
 318    * @return Is the contents of the two files binary equal?
 319    * @throws IOException File exception occurred.
 320    */
 321  3 public static boolean compareFilesBinary(final File from, final File with)
 322    throws IOException {
 323  3 if (from == null && with == null) {
 324  0 return true;
 325    }
 326  3 if (from == null || with == null) {
 327  0 return false;
 328    }
 329  3 if (from.getAbsoluteFile().equals(with.getAbsoluteFile())) {
 330  0 return true;
 331    }
 332  3 if (from.length() != with.length()) {
 333  0 return false;
 334    }
 335  3 byte[] dataOne = new byte[8 * 1024];
 336  3 byte[] dataTwo = new byte[8 * 1024];
 337  3 int length;
 338   
 339  3 FileInputStream one = null;
 340  3 FileInputStream two = null;
 341  3 try {
 342  3 one = new FileInputStream(from);
 343  3 two = new FileInputStream(with);
 344   
 345  ? while ((length = one.read(dataOne)) != -1) {
 346  36 if (length != two.read(dataTwo)) {
 347  0 return false;
 348    }
 349  36 if (!Arrays.equals(dataOne, dataTwo)) {
 350  0 return false;
 351    }
 352    }
 353  3 return true;
 354    } finally {
 355  3 closeStream(one);
 356  3 closeStream(two);
 357    }
 358    }
 359   
 360    /**
 361    * Quotes a <code>String</code>. If no quotes exist in the
 362    * <code>String</code>, a quote character is appended at the
 363    * beginning and the end of the <code>String</code>.
 364    *
 365    * @param unquoted the unquoted <code>String</code>
 366    * @return quoted <code>String</code>
 367    * @throws NullPointerException if <code>unquoted == null</code>
 368    */
 369  321 public static String quote(final String unquoted) {
 370   
 371  321 String result = "\"";
 372   
 373  321 for (int i = 0; i < unquoted.length(); i++) {
 374  469 if (unquoted.charAt(i) == '\"') {
 375  0 result += "\"\"";
 376    } else {
 377  469 result += unquoted.charAt(i);
 378    }
 379    }
 380  321 result += '\"';
 381  321 return result;
 382    }
 383   
 384    /**
 385    * Tests if given <code>String</code> begins with a letter and contains
 386    * only letters and digits.
 387    *
 388    * @param text test this
 389    * @return is <code>text</code> only made of letters and digits and has
 390    * a leading letter?
 391    * @throws NullPointerException if <code>text == null</code>
 392    */
 393  0 public static boolean isLetterDigitString(final String text) {
 394  0 if (text.length() <= 0) {
 395  0 return false;
 396    }
 397  0 if (!Character.isLetter(text.charAt(0))) {
 398  0 return false;
 399    }
 400  0 for (int i = 1; i < text.length(); i++) {
 401  0 if (!Character.isLetterOrDigit(text.charAt(i))) {
 402  0 return false;
 403    }
 404    }
 405  0 return true;
 406    }
 407   
 408    /**
 409    * Delete file directory recursive.
 410    *
 411    * @param directory Directory to delete.
 412    * @param deleteDir Delete directory itself too?
 413    * @return Was deletion successful?
 414    */
 415  2 public static boolean deleteDir(final File directory, final boolean deleteDir) {
 416    // to see if this directory is actually a symbolic link to a directory,
 417    // we want to get its canonical path - that is, we follow the link to
 418    // the file it's actually linked to
 419  2 File candir;
 420  2 try {
 421  2 candir = directory.getCanonicalFile();
 422    } catch (IOException e) {
 423  0 return false;
 424    }
 425   
 426    // a symbolic link has a different canonical path than its actual path,
 427    // unless it's a link to itself
 428  2 if (!candir.equals(directory.getAbsoluteFile())) {
 429    // this file is a symbolic link, and there's no reason for us to
 430    // follow it, because then we might be deleting something outside of
 431    // the directory we were told to delete
 432  0 return false;
 433    }
 434   
 435    // now we go through all of the files and subdirectories in the
 436    // directory and delete them one by one
 437  2 boolean success = true;
 438  2 File[] files = candir.listFiles();
 439  2 if (files != null) {
 440  2 for (int i = 0; i < files.length; i++) {
 441  36 File file = files[i];
 442   
 443    // in case this directory is actually a symbolic link, or it's
 444    // empty, we want to try to delete the link before we try
 445    // anything
 446  36 boolean deleted = file.delete();
 447  36 if (!deleted) {
 448    // deleting the file failed, so maybe it's a non-empty
 449    // directory
 450  0 if (file.isDirectory()) {
 451  0 deleted = deleteDir(file, true);
 452    }
 453   
 454    // otherwise, there's nothing else we can do
 455    }
 456  36 success = success && deleted;
 457    }
 458    }
 459   
 460    // now that we tried to clear the directory out, we can try to delete it
 461    // again
 462  2 if (deleteDir) {
 463  0 return directory.delete();
 464    }
 465  2 return success;
 466    }
 467   
 468    /**
 4