1 /**************************************************************************
2 Copyright 2005 Webstersmalley
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 *************************************************************************/
16
17
18
19 package com.webstersmalley.picweb.utils;
20
21 import java.io.BufferedOutputStream;
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.FileNotFoundException;
25 import java.io.FileOutputStream;
26 import java.io.IOException;
27 import java.io.OutputStreamWriter;
28 import java.io.PrintWriter;
29 import java.nio.channels.FileChannel;
30 import java.util.Date;
31
32 import javax.xml.transform.Source;
33 import javax.xml.transform.Transformer;
34 import javax.xml.transform.TransformerFactory;
35 import javax.xml.transform.dom.DOMSource;
36 import javax.xml.transform.stream.StreamResult;
37
38 import org.apache.commons.logging.Log;
39 import org.apache.commons.logging.LogFactory;
40 import org.w3c.dom.Document;
41
42 /***
43 * Utility class for the basic file/IO related functions (eg
44 * write out an {@link org.w3c.dom.Document} as an XML file)
45 *
46 * @author Matthew Smalley
47 */
48 public class IOUtils
49 {
50 /*** Logger for the class. */
51 private static Log log = LogFactory.getLog(IOUtils.class);
52
53 /***
54 * Private constructor - should only used via static utilities methods
55 *
56 */
57 private IOUtils()
58 {
59
60 }
61
62 /***
63 * Writes out a string as a file.
64 * Will create parent directories in order to succeed.
65 *
66 * @param filename the name of the new file
67 * @param contents the contents of the new file
68 * @throws FileNotFoundException File wasn't found
69 */
70 public static void writeFile(String filename, String contents) throws FileNotFoundException
71 {
72 File output = new File(filename);
73 File parent = output.getParentFile();
74 parent.mkdirs();
75 PrintWriter out = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(output))));
76 out.println(contents);
77 out.flush();
78 out.close();
79 }
80
81
82
83
84 /***
85 * Writes out a {@link org.w3c.dom.Document} as an XML file.
86 *
87 * @param filename the filename of the new XML file
88 * @param doc the document to write
89 * @throws Exception wraps up exceptions from the IO and the transformation
90 */
91 public static void writeXmlFile(String filename, Document doc) throws Exception
92 {
93 try
94 {
95
96 Source source = new DOMSource(doc);
97
98
99 File file = new File(filename);
100 FileOutputStream fos = new FileOutputStream(file);
101 StreamResult result = new StreamResult(fos);
102
103
104 Transformer xformer = TransformerFactory.newInstance().newTransformer();
105 xformer.transform(source, result);
106 fos.flush();
107 fos.close();
108 }
109 catch (Exception e)
110 {
111 throw new Exception("Error - unable to write XML File: " + e.toString(), e);
112 }
113 }
114
115 /***
116 * Copies the contents of one folder into another.
117 * e.g. consider the following tree:
118 * <code>
119 * src\file1
120 * src\dir1\file2
121 * src\dir1\file3
122 * </code>
123 * If we called copyFolderContents("src", "dest") we'd end up with:
124 * <code>
125 * dest\file1
126 * dest\dir1\file2
127 * dest\dir2\file3
128 * </code>
129 *
130 * @param src Source folder
131 * @param dest Destination folder
132 * @throws IOException
133 */
134 public static void copyFolderContents(String src, String dest) throws IOException
135 {
136 log.debug("Copying contents of: '" + src + "' to '" + dest + "'");
137 File srcDir = new File(src);
138 File destDir = new File(dest);
139 destDir.mkdirs();
140 File[] children = srcDir.listFiles();
141 for (int i = 0; i < children.length; i++)
142 {
143 File child = children[i];
144 String destinationChild = destDir.getAbsolutePath() + File.separator + child.getName();
145 if (child.isDirectory())
146 {
147 copyFolderContents(child.getAbsolutePath(), destinationChild);
148 }
149 else
150 {
151 copyFile(child, new File(destinationChild));
152 }
153 }
154 }
155
156 /***
157 * Copies the contents of a file to a new one, creating subdirectories
158 * as necessary.
159 * @param src Source file
160 * @param dest Destination file
161 * @throws IOException
162 */
163 public static void copyFile(File src, File dest) throws IOException
164 {
165 log.debug("Copying file: '" + src + "' to '" + dest + "'");
166
167 FileChannel srcChannel = new FileInputStream(src).getChannel();
168
169
170 FileChannel dstChannel = new FileOutputStream(dest).getChannel();
171
172
173 dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
174
175
176 srcChannel.close();
177 dstChannel.close();
178 }
179
180 /***
181 * Deletes the contents of a folder, leaving that folder intact.
182 *
183 * @param folder the folder to purge
184 * @throws IOException
185 */
186 public static void purgeFolder(File folder) throws IOException
187 {
188 File[] children = folder.listFiles();
189 for (int i = 0; i < children.length; i++)
190 {
191 File child = children[i];
192 if (child.isDirectory())
193 {
194 purgeFolder(child);
195 log.debug("Deleting: " + child.getAbsolutePath());
196 if (!child.delete())
197 {
198 throw new IOException("Error - couldn't delete: " + child.getAbsolutePath());
199 }
200 }
201 else
202 {
203 log.debug("Deleting: " + child.getAbsolutePath());
204 if (!child.delete())
205 {
206 throw new IOException("Error - couldn't delete: " + child.getAbsolutePath());
207 }
208 }
209 }
210 }
211
212 /***
213 * Creates a blank (0-byte) file, creating folders as necessary.
214 * If the file already exists, updates the lastModified time.
215 * If the file exists but is not a regular file, throws an IOException.
216 *
217 * @param file the file to create
218 * @throws IOException
219 */
220 public static void touch(File file) throws IOException
221 {
222 if (file.exists())
223 {
224 if (file.isDirectory())
225 {
226 throw new IOException("Error touching file " + file.getAbsolutePath() + ". Already exists as a directory.");
227 }
228 else
229 {
230 file.setLastModified(new Date().getTime());
231 }
232 }
233 else
234 {
235 file.getParentFile().mkdirs();
236 file.createNewFile();
237 }
238 }
239 }