File D:\maven-qcr-plugin-testsunitaires\qcr4java\jenkins-master\target\site\qc\core\src\main\java\hudson\util\CompressedFile.java.html

1 /*
2 * The MIT License
3 *
4 * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24 package hudson.util;
25
26 import hudson.Util;
27
28 import java.io.File;
29 import java.io.FileInputStream;
30 import java.io.FileNotFoundException;
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.Reader;
37 import java.util.concurrent.ExecutorService;
38 import java.util.concurrent.LinkedBlockingQueue;
39 import java.util.concurrent.ThreadPoolExecutor;
40 import java.util.concurrent.TimeUnit;
41 import java.util.logging.Level;
42 import java.util.logging.Logger;
43 import java.util.zip.GZIPInputStream;
44 import java.util.zip.GZIPOutputStream;
45
46 /**
47 * Represents write-once read-many file that can be optiionally compressed
48 * to save disk space. This is used for console output and other bulky data.
49 *
50 * <p>
51 * In this class, the data on the disk can be one of two states:
52 * <ol>
53 * <li>Uncompressed, in which case the original data is available in the specified file name.
54 * <li>Compressed, in which case the gzip-compressed data is available in the specifiled file name + ".gz" extension.
55 * </ol>
56 *
57 * Once the file is written and completed, it can be compressed asynchronously
58 * by {@link #compress()}.
59 *
60 * @author Kohsuke Kawaguchi
61 */
62 public class CompressedFile {
63 /**
64 * The name of the raw file.
65 */
66 private final File file;
67
68 /**
69 * The name of the compressed file.
70 */
71 private final File gz;
72
73 public CompressedFile(File file) {
74 this.file = file;
75 this.gz = new File(file.getParentFile(),file.getName()+".gz");
76 }
77
78 /**
79 * Gets the OutputStream to write to the file.
80 */
81 public OutputStream write() throws FileNotFoundException {
82 if(gz.exists())
83 gz.delete();
84 return new FileOutputStream(file);
85 }
86
87 /**
88 * Reads the contents of a file.
89 */
90 public InputStream read() throws IOException {
91 if(file.exists())
92 return new FileInputStream(file);
93
94 // check if the compressed file exists
95 if(gz.exists())
96 return new GZIPInputStream(new FileInputStream(gz));
97
98 // no such file
99 throw new FileNotFoundException(file.getName());
100 }
101
102 /**
103 * Loads the file content as a string.
104 */
105 public String loadAsString() throws IOException {
106 long sizeGuess;
107 if(file.exists())
108 sizeGuess = file.length();
109 else
110 if(gz.exists())
111 sizeGuess = gz.length()*2;
112 else
113 return "";
114
115 StringBuilder str = new StringBuilder((int)sizeGuess);
116
117 Reader r = new InputStreamReader(read());
118 char[] buf = new char[8192];
119 int len;
120 while((len=r.read(buf,0,buf.length))>0)
121 str.append(buf,0,len);
122 r.close();
123
124 return str.toString();
125 }
126
127 /**
128 * Asynchronously schedules the compression of this file.
129 *
130 * <p>
131 * Once the file is compressed, the original will be removed and
132 * the further reading will be done from the compressed stream.
133 */
134 public void compress() {
135 compressionThread.submit(new Runnable() {
136 public void run() {
137 try {
138 InputStream in = read();
139 OutputStream out = new GZIPOutputStream(new FileOutputStream(gz));
140 try {
141 Util.copyStream(in,out);
142 } finally {
143 in.close();
144 out.close();
145 }
146 // if the compressed file is created successfully, remove the original
147 file.delete();
148 } catch (IOException e) {
149 LOGGER.log(Level.WARNING, "Failed to compress "+file,e);
150 gz.delete(); // in case a processing is left in the middle
151 }
152 }
153 });
154 }
155
156 /**
157 * Executor used for compression. Limited up to one thread since
158 * this should be a fairly low-priority task.
159 */
160 private static final ExecutorService compressionThread = new ThreadPoolExecutor(
161 0, 1, 5L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(),
162 new ExceptionCatchingThreadFactory(new DaemonThreadFactory()));
163
164 private static final Logger LOGGER = Logger.getLogger(CompressedFile.class.getName());
165 }
166