You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

IOUtils.java 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /*
  2. * Sonar Runner
  3. * Copyright (C) 2011 SonarSource
  4. * dev@sonar.codehaus.org
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
  19. */
  20. package org.sonar.runner;
  21. import java.io.Closeable;
  22. import java.io.File;
  23. import java.io.FileNotFoundException;
  24. import java.io.IOException;
  25. import java.io.InputStream;
  26. import java.io.OutputStream;
  27. import java.io.Reader;
  28. import java.io.StringWriter;
  29. import java.io.Writer;
  30. import java.util.regex.Matcher;
  31. import java.util.regex.Pattern;
  32. /**
  33. * Internal class used only by the Runner as we don't want it to depend on third-party libs.
  34. * This class should not be used by Sonar Runner consumers.
  35. */
  36. final class IOUtils {
  37. private IOUtils() {
  38. // only static methods
  39. }
  40. /**
  41. * The default buffer size to use.
  42. */
  43. private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
  44. private static final Pattern CHARSET_PATTERN = Pattern.compile("(?i)\\bcharset=\\s*\"?([^\\s;\"]*)");
  45. /**
  46. * Unconditionally close a <code>Closeable</code>.
  47. */
  48. static void closeQuietly(Closeable closeable) {
  49. try {
  50. if (closeable != null) {
  51. closeable.close();
  52. }
  53. } catch (IOException ioe) {
  54. }
  55. }
  56. /**
  57. * Get the contents of a <code>Reader</code> as a String.
  58. */
  59. static String toString(Reader input) throws IOException {
  60. StringWriter sw = new StringWriter();
  61. copyLarge(input, sw);
  62. return sw.toString();
  63. }
  64. /**
  65. * Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>.
  66. */
  67. static long copyLarge(InputStream input, OutputStream output) throws IOException {
  68. byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
  69. long count = 0;
  70. int n = 0;
  71. while (-1 != (n = input.read(buffer))) {
  72. output.write(buffer, 0, n);
  73. count += n;
  74. }
  75. return count;
  76. }
  77. /**
  78. * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
  79. */
  80. static long copyLarge(Reader input, Writer output) throws IOException {
  81. char[] buffer = new char[DEFAULT_BUFFER_SIZE];
  82. long count = 0;
  83. int n = 0;
  84. while (-1 != (n = input.read(buffer))) {
  85. output.write(buffer, 0, n);
  86. count += n;
  87. }
  88. return count;
  89. }
  90. /**
  91. * Duplicated from Commons IO
  92. */
  93. static boolean deleteQuietly(File file) {
  94. if (file == null) {
  95. return false;
  96. }
  97. try {
  98. if (file.isDirectory()) {
  99. cleanDirectory(file);
  100. }
  101. } catch (Exception ignored) {
  102. }
  103. try {
  104. return file.delete();
  105. } catch (Exception ignored) {
  106. return false;
  107. }
  108. }
  109. private static void cleanDirectory(File directory) throws IOException {
  110. if (!directory.exists()) {
  111. String message = directory + " does not exist";
  112. throw new IllegalArgumentException(message);
  113. }
  114. if (!directory.isDirectory()) {
  115. String message = directory + " is not a directory";
  116. throw new IllegalArgumentException(message);
  117. }
  118. File[] files = directory.listFiles();
  119. // null if security restricted
  120. if (files == null) {
  121. throw new IOException("Failed to list contents of " + directory);
  122. }
  123. IOException exception = null;
  124. for (File file : files) {
  125. try {
  126. forceDelete(file);
  127. } catch (IOException ioe) {
  128. exception = ioe;
  129. }
  130. }
  131. if (null != exception) {
  132. throw exception;
  133. }
  134. }
  135. private static void forceDelete(File file) throws IOException {
  136. if (file.isDirectory()) {
  137. deleteDirectory(file);
  138. } else {
  139. boolean filePresent = file.exists();
  140. if (!file.delete()) {
  141. if (!filePresent) {
  142. throw new FileNotFoundException("File does not exist: " + file);
  143. }
  144. String message =
  145. "Unable to delete file: " + file;
  146. throw new IOException(message);
  147. }
  148. }
  149. }
  150. private static void deleteDirectory(File directory) throws IOException {
  151. if (!directory.exists()) {
  152. return;
  153. }
  154. cleanDirectory(directory);
  155. if (!directory.delete()) {
  156. String message =
  157. "Unable to delete directory " + directory + ".";
  158. throw new IOException(message);
  159. }
  160. }
  161. /**
  162. * Parse out a charset from a content type header.
  163. *
  164. * @param contentType e.g. "text/html; charset=EUC-JP"
  165. * @return "EUC-JP", or null if not found. Charset is trimmed and uppercased.
  166. */
  167. static String getCharsetFromContentType(String contentType) {
  168. if (contentType == null) {
  169. return null;
  170. }
  171. Matcher m = CHARSET_PATTERN.matcher(contentType);
  172. if (m.find()) {
  173. return m.group(1).trim().toUpperCase();
  174. }
  175. return null;
  176. }
  177. }