View Javadoc

1   /********************************************************************************
2    * InternetCafe is a software solution that helps the management of Cybercafes
3    * according with the ITALIAN DECREE LAW ON ANTI-TERROR MEASURES, 27 JULY 2005.
4    * Copyright (C) 2006  Guido Angelo Ingenito
5   
6    * This program is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU General Public License
8    * as published by the Free Software Foundation; either version 2
9    * 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
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License
17   * along with this program; if not, write to the Free Software
18   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19   *******************************************************************************/
20  package base.backup;
21  
22  import java.io.BufferedInputStream;
23  import java.io.BufferedOutputStream;
24  import java.io.File;
25  import java.io.FileInputStream;
26  import java.io.FileOutputStream;
27  import java.io.IOException;
28  import java.io.InputStream;
29  import java.io.PrintStream;
30  import java.util.Date;
31  import java.util.Enumeration;
32  import java.util.zip.ZipEntry;
33  import java.util.zip.ZipFile;
34  import java.util.zip.ZipInputStream;
35  import java.util.zip.ZipOutputStream;
36  
37  import javax.xml.parsers.DocumentBuilder;
38  import javax.xml.parsers.DocumentBuilderFactory;
39  import javax.xml.transform.Transformer;
40  import javax.xml.transform.TransformerFactory;
41  import javax.xml.transform.dom.DOMSource;
42  import javax.xml.transform.stream.StreamResult;
43  
44  import org.apache.log4j.Logger;
45  import org.w3c.dom.Document;
46  
47  import base.ConfigurationManager;
48  import base.IdManager;
49  
50  public class BackupFactory {
51  	private static final transient Logger logger = Logger
52  			.getLogger(BackupFactory.class.getName());
53  
54  	public static Backup newBackup(String name, String description, Date date,
55  			String dbLocationPath, String zipLocationPath) {
56  		int id = IdManager.getInstance().getNextBackupId();
57  
58  		return new Backup(id, name, description, date, dbLocationPath,
59  				zipLocationPath);
60  	}
61  
62  	public static Backup newBackupFromZipArchive(File backupFile)
63  			throws Exception {
64  		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
65  
66  		factory.setIgnoringComments(true);
67  		factory.setValidating(false);
68  		factory.setIgnoringElementContentWhitespace(true);
69  
70  		DocumentBuilder docBuilder = factory.newDocumentBuilder();
71  		File unzipFolder = new File(backupFile.getParent(), backupFile
72  				.getName().substring(0, backupFile.getName().lastIndexOf(".")));
73  
74  		unzipFolder.mkdir();
75  		unZipFile(new ZipFile(backupFile), unzipFolder);
76  
77  		// Now we must retrieve the details file
78  		File xmlDetailsFile = new File(unzipFolder,
79  				ConfigurationManager.BACKUP_DETAILS_FILE);
80  		Document document = docBuilder
81  				.parse(new FileInputStream(xmlDetailsFile));
82  		Backup backup = new Backup(document);
83  
84  		backup.setZipLocationPath(backupFile.getAbsolutePath());
85  
86  		return backup;
87  	}
88  
89  	public static File createDetailsFile(Backup backup) throws Exception {
90  		Document doc = DocumentBuilderFactory.newInstance()
91  				.newDocumentBuilder().newDocument();
92  
93  		doc.appendChild(backup.toXml(doc));
94  
95  		String detailsfileName = ConfigurationManager.BACKUP_DETAILS_FILE;
96  
97  		if (!detailsfileName.endsWith(".xml")) {
98  			detailsfileName += ".xml";
99  		}
100 
101 		Transformer transformer = TransformerFactory.newInstance()
102 				.newTransformer();
103 		DOMSource source = new DOMSource(doc);
104 		StreamResult streamResult = new StreamResult(new PrintStream(
105 				detailsfileName));
106 
107 		transformer.transform(source, streamResult);
108 
109 		return new File(detailsfileName);
110 	}
111 
112 	public static void backupToZipArchive(Backup backup) throws Exception {
113 		// Create the ZIP file, will be rappresented by the backup's name
114 		// followed by its id.
115 		String outFilename = backup.getName() + backup.getId() + ".zip";
116 		ZipOutputStream out = new ZipOutputStream(new FileOutputStream(
117 				new File(backup.getZipLocationPath(), outFilename)));
118 
119 		out.setComment(backup.getDescription());
120 
121 		// Link the db path to the current zip location
122 		String dbFileName = backup.getDbLocationPath().substring(
123 				backup.getDbLocationPath().lastIndexOf(File.separatorChar),
124 				backup.getDbLocationPath().length());
125 
126 		backup.setDbLocationPath(new File(backup.getZipLocationPath(),
127 				dbFileName).getAbsolutePath());
128 
129 		// We must create the backup's details file (xml)
130 		File details = createDetailsFile(backup);
131 
132 		// We must zip it
133 		zipFile(details, out);
134 
135 		// Lets delete the backup's details file (xml) it doesn't serve anymore
136 		details.delete();
137 
138 		File resourcesFolder = new File(
139 				ConfigurationManager.RESOURCES_DIRECTORY);
140 
141 		zipDirectory(resourcesFolder, out);
142 
143 		// Complete the ZIP file
144 		out.close();
145 	}
146 
147 	public static void zipDirectory(File file, ZipOutputStream out)
148 			throws Exception {
149 		String[] dirList = file.list();
150 		byte[] readBuffer = new byte[1024];
151 		int bytesIn = 0;
152 
153 		for (int i = 0; i < dirList.length; i++) {
154 			File f = new File(file, dirList[i]);
155 
156 			if (f.isDirectory()) {
157 				// if the File object is a directory, call this
158 				// function again to add its content recursively
159 				zipDirectory(f, out);
160 
161 				// loop again
162 				continue;
163 			}
164 
165 			// if we reached here, the File object f was not a directory
166 			// create a FileInputStream on top of f
167 			FileInputStream fis = new FileInputStream(f);
168 
169 			// create a new zip entry
170 			ZipEntry zipEntry = new ZipEntry(f.getPath());
171 
172 			// place the zip entry in the ZipOutputStream object
173 			out.putNextEntry(zipEntry);
174 
175 			// now write the content of the file to the ZipOutputStream
176 			while ((bytesIn = fis.read(readBuffer)) != -1) {
177 				out.write(readBuffer, 0, bytesIn);
178 			}
179 
180 			// close the Stream
181 			fis.close();
182 		}
183 	}
184 
185 	public static void zipFile(File file, ZipOutputStream out) throws Exception {
186 		// Create a buffer for reading the file
187 		byte[] buf = new byte[1024];
188 
189 		out.putNextEntry(new ZipEntry(file.getName()));
190 
191 		FileInputStream in = new FileInputStream(file);
192 
193 		// Transfer bytes from the file to the ZIP file
194 		int len;
195 
196 		while ((len = in.read(buf)) > 0) {
197 			out.write(buf, 0, len);
198 		}
199 
200 		in.close();
201 
202 		// Complete the entry
203 		out.closeEntry();
204 	}
205 
206 	public static void unZipFile(ZipFile zipFile, File destinationDirectory)
207 			throws Exception {
208 		logger.debug("unZipFile: " + zipFile.getName()
209 				+ " destination directory: " + destinationDirectory);
210 
211 		Enumeration enumeration = zipFile.entries();
212 
213 		while (enumeration.hasMoreElements()) {
214 			ZipEntry zipEntry = (ZipEntry) enumeration.nextElement();
215 
216 			File file = new File(destinationDirectory.getCanonicalPath(),
217 					zipEntry.getName().replaceFirst(".." + File.separatorChar,
218 							""));
219 
220 			logger.debug("File: " + file);
221 
222 			if (zipEntry.isDirectory()) {
223 				file.mkdirs();
224 			} else {
225 				InputStream is = zipFile.getInputStream(zipEntry);
226 				BufferedInputStream bis = new BufferedInputStream(is);
227 
228 				if (file.getParent() != null) {
229 					File dir = new File(file.getParent());
230 
231 					dir.mkdirs();
232 				}
233 
234 				FileOutputStream fos = new FileOutputStream(file);
235 				BufferedOutputStream bos = new BufferedOutputStream(fos);
236 
237 				int c;
238 
239 				while ((c = bis.read()) != -1) {
240 					bos.write((byte) c);
241 				}
242 
243 				bos.close();
244 				fos.close();
245 			}
246 
247 			logger.debug(" unzipped.");
248 		}
249 	}
250 
251 	public static void unzip(ZipInputStream zin, String zipEntry,
252 			File destinationFolder) throws IOException {
253 		System.out
254 				.println("unzipping " + zipEntry + " to " + destinationFolder);
255 
256 		FileOutputStream out = new FileOutputStream(new File(destinationFolder,
257 				new File(zipEntry).getName()));
258 		byte[] b = new byte[1024];
259 		int len = 0;
260 
261 		while ((len = zin.read(b)) != -1) {
262 			out.write(b, 0, len);
263 		}
264 
265 		out.close();
266 	}
267 
268 	public static long fileSizeInKB(File file) {
269 		long size = 0;
270 
271 		if (file.isDirectory()) {
272 			File[] filelist = file.listFiles();
273 
274 			for (int i = 0; i < filelist.length; i++) {
275 				if (filelist[i].isDirectory()) {
276 					size += fileSizeInKB(filelist[i]);
277 				} else {
278 					size += filelist[i].length();
279 				}
280 			}
281 		} else {
282 			size += file.length();
283 		}
284 
285 		return size / 1024;
286 	}
287 }