View Javadoc

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   * Created on 04-Jun-2005
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  	// This method writes a DOM document to a file
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  			// Prepare the DOM document for writing
96  			Source source = new DOMSource(doc);
97  
98  			// Prepare the output file
99  			File file = new File(filename);
100 			FileOutputStream fos = new FileOutputStream(file);
101 			StreamResult result = new StreamResult(fos);
102 
103 			// Write the DOM document to the file
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 		// Create channel on the source
167 		FileChannel srcChannel = new FileInputStream(src).getChannel();
168 		
169 		// Create channel on the destination
170 		FileChannel dstChannel = new FileOutputStream(dest).getChannel();
171 		
172 		// Copy file contents from source to destination
173 		dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
174 		
175 		// Close the channels
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 }