Clover coverage report - QedeqKernelSe Coverage Report
Coverage timestamp: Do Mai 10 2007 03:16:40 CEST
file stats: LOC: 673   Methods: 30
NCLOC: 362   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
IoUtility.java 34% 57,1% 50% 49,5%
coverage coverage
 1    /* $Id: IoUtility.java,v 1.10 2007/04/01 07:59:50 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.File;
 25    import java.io.FileInputStream;
 26    import java.io.FileOutputStream;
 27    import java.io.FileReader;
 28    import java.io.FileWriter;
 29    import java.io.IOException;
 30    import java.io.InputStream;
 31    import java.io.InputStreamReader;
 32    import java.io.Reader;
 33    import java.io.UnsupportedEncodingException;
 34    import java.net.MalformedURLException;
 35    import java.net.URL;
 36    import java.util.Arrays;
 37    import java.util.Enumeration;
 38    import java.util.Properties;
 39   
 40   
 41    /**
 42    * A collection of useful static methods for input and output.
 43    *
 44    * LATER mime 20070101: use StringBuilder instead of StringBuffer if working under JDK 1.5
 45    *
 46    * @version $Revision: 1.10 $
 47    * @author Michael Meyling
 48    */
 49    public final class IoUtility {
 50   
 51    /**
 52    * Constructor, should never be called.
 53    */
 54  0 private IoUtility() {
 55    // don't call me
 56    }
 57   
 58    /**
 59    * Reads a file and returns the contents as a <code>String</code>.
 60    *
 61    * @param filename Name of the file (could include path).
 62    * @return Contents of file.
 63    * @throws IOException File exception occurred.
 64    */
 65  0 public static String loadFile(final String filename)
 66    throws IOException {
 67   
 68  0 final StringBuffer buffer = new StringBuffer();
 69  0 loadFile(filename, buffer);
 70  0 return buffer.toString();
 71    }
 72   
 73    /**
 74    * Reads contents of a file into a string buffer.
 75    *
 76    * @param filename Name of the file (could include path).
 77    * @param buffer Buffer to fill with file contents.
 78    * @throws IOException File exception occurred.
 79    */
 80  0 public static void loadFile(final String filename,
 81    final StringBuffer buffer)
 82    throws IOException {
 83  0 loadFile(new File(filename), buffer);
 84    }
 85   
 86    /**
 87    * Reads contents of a stream into a string buffer.
 88    *
 89    * @param in This stream will be loaded.
 90    * @param buffer Buffer to fill with file contents.
 91    * @throws IOException File exception occurred.
 92    */
 93  0 public static void loadStream(final InputStream in,
 94    final StringBuffer buffer)
 95    throws IOException {
 96   
 97  0 buffer.setLength(0);
 98  0 int c;
 99  0 while ((c = in.read()) >= 0) {
 100  0 buffer.append((char) c);
 101    }
 102    }
 103   
 104    /**
 105    * Reads contents of a file into a string buffer.
 106    *
 107    * @param file This file will be loaded.
 108    * @param buffer Buffer to fill with file contents.
 109    * @throws IOException File exception occurred.
 110    */
 111  28963 public static void loadFile(final File file,
 112    final StringBuffer buffer)
 113    throws IOException {
 114   
 115  28963 final int size = (int) file.length();
 116  28963 buffer.setLength(0);
 117  28963 final FileReader in = new FileReader(file);
 118  28963 final char[] data = new char[size];
 119  28963 int charsread = 0;
 120  28963 while (charsread < size) {
 121  28963 charsread += in.read(data, charsread, size - charsread);
 122    }
 123  28963 in.close();
 124  28963 buffer.insert(0, data);
 125    }
 126   
 127    /**
 128    * Reads a file and returns the contents as a <code>String</code>.
 129    *
 130    * @param file File to load from.
 131    * @return Contents of file.
 132    * @throws IOException File exception occurred.
 133    */
 134  0 public static final byte[] loadFileBinary(final File file) throws IOException {
 135  0 final int size = (int) file.length();
 136  0 final FileInputStream in = new FileInputStream(file);
 137  0 try {
 138  0 final byte[] data = new byte[size];
 139  0 int charsread = 0;
 140  0 while (charsread < size) {
 141  0 final int read = in.read(data, charsread, size - charsread);
 142  0 if (read == -1) {
 143  0 final byte[] result = new byte[charsread];
 144  0 System.arraycopy(data, 0, result, 0, charsread);
 145  0 return result;
 146    }
 147  0 charsread += read;
 148    }
 149  0 in.close();
 150  0 return data;
 151    } finally {
 152  0 closeStream(in);
 153    }
 154    }
 155   
 156    /**
 157    * Reads contents of an URL into a string buffer. The filling is character set dependent.
 158    *
 159    * @param url This URL will be loaded.
 160    * @param buffer Buffer to fill with file contents.
 161    * @throws IOException Reading failed.
 162    */
 163  4 public static void loadFile(final URL url, final StringBuffer buffer) throws IOException {
 164  4 InputStream in = null;
 165  4 BufferedReader dis = null;
 166  4 try {
 167  4 in = url.openStream();
 168  4 dis = new BufferedReader(new InputStreamReader(in));
 169  4 int i;
 170  ? while ((i = dis.read()) != -1) {
 171  34193 buffer.append((char) i);
 172    }
 173    } finally {
 174  4 closeStream(in);
 175  4 closeReader(dis);
 176    }
 177    }
 178   
 179    /**
 180    * Convert String into a {@link Reader}.
 181    *
 182    * <a href="http://bugs.sun.com/bugdatabase/view_bug.do;:WuuT?bug_id=4094886">
 183    * Bug ID: 4094886</a>
 184    *
 185    * @param data Convert this.
 186    * @return Resulting reader.
 187    */
 188  0 public static final Reader stringToReader(final String data) {
 189  0 try {
 190  0 return new InputStreamReader(new ByteArrayInputStream(data.getBytes("ISO-8859-1")));
 191    } catch (UnsupportedEncodingException e) {
 192  0 throw new RuntimeException(e);
 193    }
 194    }
 195   
 196    /**
 197    * Saves a <code>String</code> into a file.
 198    *
 199    * @param filename Name of the file (could include path).
 200    * @param text Data to save in the file.
 201    * @throws IOException File exception occurred.
 202    */
 203  0 public static void saveFile(final String filename, final String text)
 204    throws IOException {
 205  0 saveFile(new File(filename), text);
 206    }
 207   
 208    /**
 209    * Saves a <code>StringBuffer</code> in a file.
 210    *
 211    * @param filename Name of the file (could include path).
 212    * @param text Data to save in the file.
 213    * @throws IOException File exception occurred.
 214    */
 215  0 public static void saveFile(final String filename, final StringBuffer text)
 216    throws IOException {
 217  0 saveFile(new File(filename), text.toString());
 218    }
 219   
 220   
 221    /**
 222    * Saves a <code>StringBuffer</code> in a file.
 223    *
 224    * @param file File to save into.
 225    * @param text Data to save in the file.
 226    * @throws IOException File exception occurred.
 227    */
 228  0 public static void saveFile(final File file, final StringBuffer text)
 229    throws IOException {
 230  0 saveFile(file, text.toString());
 231    }
 232   
 233   
 234    /**
 235    * Saves a <code>String</code> in a file.
 236    *
 237    * @param file File to save the data in.
 238    * @param text Data to save in the file.
 239    * @throws IOException File exception occurred.
 240    */
 241  1 public static void saveFile(final File file, final String text)
 242    throws IOException {
 243  1 BufferedWriter out = new BufferedWriter(
 244    new FileWriter(file));
 245  1 out.write(text);
 246  1 out.close();
 247    }
 248   
 249    /**
 250    * Saves a <code>String</code> in a file.
 251    *
 252    * @param file File to save the data in.
 253    * @param data Data to save in the file.
 254    * @throws IOException File exception occurred.
 255    */
 256  0 public static void saveFileBinary(final File file, final byte[] data)
 257    throws IOException {
 258  0 BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
 259  0 out.write(data);
 260  0 out.close();
 261    }
 262   
 263    /**
 264    * Copies a file to a different location.
 265    *
 266    * @param from Copy source.
 267    * @param to Copy destination.
 268    * @throws IOException File exception occurred.
 269    */
 270  20 public static void copyFile(final File from, final File to)
 271    throws IOException {
 272   
 273  20 if (from.getAbsoluteFile().equals(to.getAbsoluteFile())) {
 274  0 return;
 275    }
 276  20 FileInputStream in = new FileInputStream(from);
 277  20 FileOutputStream out = new FileOutputStream(to);
 278   
 279  20 byte[] data = new byte[8 * 1024];
 280  20 int length;
 281   
 282  ? while ((length = in.read(data)) != -1) {
 283  150 out.write(data, 0, length);
 284    }
 285  20 in.close();
 286  20 out.close();
 287    }
 288   
 289   
 290    /**
 291    * Compare two files.
 292    *
 293    * @param from Compare source.
 294    * @param with Compare with this file.
 295    * @return Is the contents of the two files equal?
 296    * @throws IOException File exception occurred.
 297    */
 298  3 public static boolean compareFiles(final File from, final File with)
 299    throws IOException {
 300  3 if (from == null && with == null) {
 301  0 return true;
 302    }
 303  3 if (from == null || with == null) {
 304  0 return false;
 305    }
 306  3 if (from.getAbsoluteFile().equals(with.getAbsoluteFile())) {
 307  0 return true;
 308    }
 309  3 if (from.length() != with.length()) {
 310  0 return false;
 311    }
 312  3 byte[] dataOne = new byte[8 * 1024];
 313  3 byte[] dataTwo = new byte[8 * 1024];
 314  3 int length;
 315   
 316  3 FileInputStream one = null;
 317  3 FileInputStream two = null;
 318  3 try {
 319  3 one = new FileInputStream(from);
 320  3 two = new FileInputStream(with);
 321   
 322  ? while ((length = one.read(dataOne)) != -1) {
 323  36 if (length != two.read(dataTwo)) {
 324  0 return false;
 325    }
 326  36 if (!Arrays.equals(dataOne, dataTwo)) {
 327  0 return false;
 328    }
 329    }
 330  3 return true;
 331    } finally {
 332  3 closeStream(one);
 333  3 closeStream(two);
 334    }
 335    }
 336   
 337   
 338    /**
 339    * Quotes a <code>String</code>. If no quotes exist in the
 340    * <code>String</code>, a quote character is appended at the
 341    * beginning and the end of the <code>String</code>.
 342    *
 343    * @param unquoted the unquoted <code>String</code>
 344    * @return quoted <code>String</code>
 345    * @throws NullPointerException if <code>unquoted == null</code>
 346    */
 347  321 public static String quote(final String unquoted) {
 348   
 349  321 String result = "\"";
 350   
 351  321 for (int i = 0; i < unquoted.length(); i++) {
 352  469 if (unquoted.charAt(i) == '\"') {
 353  0 result += "\"\"";
 354    } else {
 355  469 result += unquoted.charAt(i);
 356    }
 357    }
 358  321 result += '\"';
 359  321 return result;
 360    }
 361   
 362    /**
 363    * Tests if given <code>String</code> begins with a letter and contains
 364    * only letters and digits.
 365    *
 366    * @param text test this
 367    * @return is <code>text</code> only made of letters and digits and has
 368    * a leading letter?
 369    * @throws NullPointerException if <code>text == null</code>
 370    */
 371  0 public static boolean isLetterDigitString(final String text) {
 372  0 if (text.length() <= 0) {
 373  0 return false;
 374    }
 375  0 if (!Character.isLetter(text.charAt(0))) {
 376  0 return false;
 377    }
 378  0 for (int i = 1; i < text.length(); i++) {
 379  0 if (!Character.isLetterOrDigit(text.charAt(i))) {
 380  0 return false;
 381    }
 382    }
 383  0 return true;
 384    }
 385   
 386    /**
 387    * Delete file directory recursive.
 388    *
 389    * @param directory Directory to delete.
 390    * @return Was deletion successful?
 391    */
 392  0 public static boolean deleteDir(final File directory) {
 393    // to see if this directory is actually a symbolic link to a directory,
 394    // we want to get its canonical path - that is, we follow the link to
 395    // the file it's actually linked to
 396  0 File candir;
 397  0 try {
 398  0 candir = directory.getCanonicalFile();
 399    } catch (IOException e) {
 400  0 return false;
 401    }
 402   
 403    // a symbolic link has a different canonical path than its actual path,
 404    // unless it's a link to itself
 405  0 if (!candir.equals(directory.getAbsoluteFile())) {
 406    // this file is a symbolic link, and there's no reason for us to
 407    // follow it, because then we might be deleting something outside of
 408    // the directory we were told to delete
 409  0 return false;
 410    }
 411   
 412    // now we go through all of the files and subdirectories in the
 413    // directory and delete them one by one
 414  0 File[] files = candir.listFiles();
 415  0 if (files != null) {
 416  0 for (int i = 0; i < files.length; i++) {
 417  0 File file = files[i];
 418   
 419    // in case this directory is actually a symbolic link, or it's
 420    // empty, we want to try to delete the link before we try
 421    // anything
 422  0 boolean deleted = file.delete();
 423  0 if (!deleted) {
 424    // deleting the file failed, so maybe it's a non-empty
 425    // directory
 426  0 if (file.isDirectory()) {
 427  0 deleteDir(file);
 428    }
 429   
 430    // otherwise, there's nothing else we can do
 431    }
 432    }
 433    }
 434   
 435    // now that we tried to clear the directory out, we can try to delete it
 436    // again
 437  0 return directory.delete();
 438    }
 439   
 440   
 441    /**
 442    * Get amount of spaces.
 443    *
 444    * @param length number of spaces
 445    * @return String contains exactly <code>number</code> spaces
 446    */
 447  774 public static StringBuffer getSpaces(final int length) {
 448  774 final StringBuffer buffer = new StringBuffer(length >= 0 ? length : 0);
 449  774 for (int i = 0; i < length; i++) {
 450  474 buffer.append(' ');
 451    }
 452  774 return buffer;
 453    }
 454   
 455    /**
 456    * Get non qualified class name.
 457    *
 458    * @param clazz Class.
 459    * @return Non qualified class name.
 460    */
 461  19646 public static String getClassName(final Class clazz) {
 462  19646 return clazz.getName().substring(clazz.getName().lastIndexOf('.') + 1);
 463    }
 464   
 465    /**
 466    * Print current system properties to System.out.
 467    */
 468  0 public static void printAllSystemProperties() {
 469  0 Properties sysprops = System.getProperties();
 470  0 for (Enumeration e = sysprops.propertyNames(); e.hasMoreElements(); ) {
 471  0 String key = (String) e.nextElement();
 472  0 String value = sysprops.getProperty(key);
 473  0 System.out.println(key + "=" + value);
 474    }
 475    }
 476   
 477    /**
 478    * Get home directory of user.
 479    *
 480    * @return Home directory of user.
 481    */
 482  0 public static File getUserHomeDirectory() {
 483  0 return new File((String) System.getProperties().get("user.home"));
 484    }
 485   
 486    /**
 487    * Convert file in URL.
 488    *
 489    * @param file File.
 490    * @return URL.
 491    */
 492  22 public static URL toUrl(final File file) {
 493  22 try {
 494  22 return file.toURI().toURL();
 495    } catch (MalformedURLException e) { // should only happen if there is a bug in the JDK
 496  0 throw new RuntimeException(e);
 497    }
 498    }
 499   
 500    /**
 501    * Creates necessary parent directories for a file.
 502    *
 503    * @param file File.
 504    */
 505  16 public static void createNecessaryDirectories(final File file) {
 506  16 if (file.getParentFile() != null) {
 507  16 file.getParentFile().mkdirs();
 508    }
 509    }
 510   
 511    /**
 512    * Create relative address from <code>orgin</code> to <code>next</code>.
 513    *
 514    * @param orgin this is the original location
 515    * @param next this should be the next location
 516    * @return relative (or if necessary absolute) file path
 517    */
 518  1 public static final String createRelativePath(final File orgin, final File next) {
 519  1 try {
 520  1 if (orgin.equals(next)) {
 521  0 return "";
 522    }
 523  1 try {
 524  1 String org = orgin.getCanonicalPath().replace('\\', '/');
 525  1 if (orgin.isDirectory() && !org.endsWith("/")) {
 526  1 org += "/";
 527    }
 528  1 String nex = next.getCanonicalPath().replace('\\', '/');
 529  1 if (next.isDirectory() && !nex.endsWith("/")) {
 530  0 nex += "/";
 531    }
 532  1 int i = -1; // position of next '/'
 533  1 int j = 0; // position of last '/'
 534  ? while (0 <= (i = org.indexOf("/", j))) {
 535  7 if (i >= 0 && nex.length() > i
 536    && org.substring(j, i).equals(
 537    nex.substring(j, i))) {
 538  6 j = i + 1;
 539    } else {
 540  1 break;
 541    }
 542    }
 543  1 if (j > 0) {
 544  1 i = j;
 545  1 StringBuffer result = new StringBuffer(nex.length());
 546  ? while (0 <= (i = org.indexOf("/", i))) {
 547  1 i++;
 548  1 result.append("../");
 549    }
 550  1 result.append(nex.substring(j));
 551  1 return result.toString();
 552    }
 553  0 return "/" + nex;
 554    } catch (RuntimeException e) {
 555  0 return next.toString();
 556    }
 557    } catch (IOException e) {
 558  0 return next.toString();
 559    }
 560    }
 561   
 562    /**
 563    * Waits until a '\n' was read from System.in.
 564    */
 565  0 public static void waitln() {
 566  0 System.out.println("\n..press <return> to continue");
 567  0 try {
 568  0 (new java.io.BufferedReader(new java.io.InputStreamReader(
 569    System.in))).readLine();
 570    } catch (IOException e) {
 571    // ignore
 572    }
 573    }
 574   
 575    /**
 576    * Closes input stream without exception.
 577    *
 578    * @param in Input stream, maybe <code>null</code>.
 579    */
 580  10 public static void closeStream(final InputStream in) {
 581  10 if (in != null) {
 582  10 try {
 583  10 in.close();
 584    } catch (Exception e) {
 585    // ignore
 586    }
 587    }
 588    }
 589   
 590    /**
 591    * Closes input reader without exception.
 592    *
 593    * @param reader Reader, maybe <code>null</code>.
 594    */
 595  4 public static void closeReader(final Reader reader) {
 596  4 if (reader != null) {
 597  4 try {
 598  4 reader.close();
 599    } catch (Exception e) {
 600    // ignore
 601    }
 602    }
 603    }
 604   
 605    /**
 606    * Search for first line followed by whitespace and delete this string within the whole
 607    * text.
 608    * <p>
 609    * For example the following text
 610    *<pre>
 611    * Do you know the muffin man,
 612    * The muffin man, the muffin man,
 613    * Do you know the muffin man,
 614    * Who lives on Drury Lane?
 615    *</pre>
 616    * will be converted into:
 617    *<pre>
 618    *Do you know the muffin man,
 619    *The muffin man, the muffin man,
 620    *Do you know the muffin man,
 621    *Who lives on Drury Lane?
 622    *</pre>
 623    *
 624    * @param buffer Work on this text.
 625    */
 626  1095 public static void deleteLineLeadingWhitespace(final StringBuffer buffer) {
 627  1095 int start = -1;
 628  ? while (0 <= (start = buffer.indexOf("\n", start + 1))) {
 629  280 if (start + 1 < buffer.length() && '\n' != buffer.charAt(start + 1)) {
 630  247 break;
 631    }
 632    }
 633  1095 if (start >= 0) {
 634  247 int next = start + 1;
 635  247 while (next < buffer.length() && Character.isWhitespace(buffer.charAt(next))
 636    && '\n' != buffer.charAt(next)) {
 637  3350 next++;
 638    }
 639  247 final String empty = buffer.substring(start, next);
 640  247 if (empty.length() > 0) {
 641  247 ReplaceUtility.replace(buffer, empty, "\n");
 642    }
 643    }
 644    }
 645   
 646    /**
 647    * Get start directory for application. If this is no Java Webstart version
 648    * the result is <code>new File(".")</code>.
 649    *
 650    * @param application Application name, used for Java Webstart version. Should
 651    * be written in lowercase letters. A "." is automatically appended at
 652    * the beginning.
 653    * @return Start directory for application.
 654    */
 655  3 public static final File getStartDirectory(final String application) {
 656    // get start directory for config location
 657  3 final String webStart = (String) System.getProperties().get("javawebstart.version");
 658  3 final File startDirectory;
 659  3 if (webStart != null) {
 660  0 final String userHomeWS = System.getProperties().get("jnlpx.deployment.user.home")
 661    != null ? (String) System.getProperties().get("jnlpx.deployment.user.home")
 662    : "";
 663  0 final String userHome = System.getProperties().get("user.home") != null
 664    ? (String) System.getProperties().get("user.home") : "";
 665  0 startDirectory = new File(
 666  0 new File((userHomeWS.length() != 0 ? userHomeWS : userHome)), "." + application);
 667    } else {
 668  3 startDirectory = new File(".");
 669    }
 670  3 return startDirectory;
 671    }
 672   
 673    }