/********************************************************************************** * $URL: https://source.sakaiproject.org/svn/search/trunk/search-util/src/java/org/sakaiproject/search/util/FileUtils.java $ * $Id: FileUtils.java 105078 2012-02-24 23:00:38Z ottenhoff@longsight.com $ *********************************************************************************** * * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008 The Sakai Foundation * * Licensed under the Educational Community License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.opensource.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **********************************************************************************/ package org.sakaiproject.search.util; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.GeneralSecurityException; import java.security.MessageDigest; import java.util.Date; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * @author ieb */ public class FileUtils { /** * @author ieb */ public interface RecurseAction { /** * @param file * @throws IOException */ void doFile(File file) throws IOException; /** * @param f */ void doBeforeFile(File f); /** * @param f */ void doAfterFile(File f); } private static final Log log = LogFactory.getLog(FileUtils.class); /** * delete all files under this file and including this file * * @param f * @throws IOException */ public static void deleteAll(File f) throws IOException { recurse(f, new RecurseAction() { public void doFile(File file) throws IOException { if (file != null) { if (!file.delete() && file.exists()) { throw new IOException("Failed to delete " + file.getPath()); } } } public void doBeforeFile(File f) { } public void doAfterFile(File f) { } }); } public static void recurse(File f, RecurseAction action) throws IOException { action.doBeforeFile(f); if (f !=null && f.isDirectory()) { File[] files = f.listFiles(); if (files != null) { for (int i = 0; i < files.length; i++) { if (files[i].isDirectory()) { recurse(files[i], action); } else { action.doFile(files[i]); } } } } action.doFile(f); } public static void recurseGrouped(File f, RecurseAction action) throws IOException { action.doBeforeFile(f); if (f.isDirectory()) { File[] files = f.listFiles(); if (files != null) { for (int i = 0; i < files.length; i++) { if (!files[i].isDirectory()) { action.doFile(files[i]); } } action.doAfterFile(f); for (int i = 0; i < files.length; i++) { if (files[i].isDirectory()) { recurseGrouped(files[i], action); } } } } action.doFile(f); } /** * pack a segment into the zip * @param compress * * @param addsi * @return * @throws IOException */ public static void pack(File source,final String basePath, final String replacePath, OutputStream output, boolean compress) throws IOException { log.debug("Packing "+source+" repacing "+basePath+" with "+replacePath); final ZipOutputStream zout = new ZipOutputStream(output); if ( compress ) { zout.setLevel(ZipOutputStream.DEFLATED); } else { zout.setLevel(ZipOutputStream.STORED); } final byte[] buffer = new byte[1024 * 100]; try { recurse(source, new RecurseAction() { public void doFile(File file) throws IOException { if (!file.isDirectory()) { log.debug(" Add " + file.getPath()); addSingleFile(basePath, replacePath, file, zout, buffer); } else { log.debug(" Ignore " + file.getPath()); } } public void doBeforeFile(File f) { } public void doAfterFile(File f) { } }); } finally { zout.flush(); try { zout.close(); } catch (Exception e) { log.warn("Exception closing output zip", e); } } } private static void addSingleFile(String basePath, String replacePath, File file, ZipOutputStream zout, byte[] buffer) throws IOException { String path = file.getPath(); if (path.startsWith(basePath)) { path = replacePath + path.substring(basePath.length()); } ZipEntry ze = new ZipEntry(path); ze.setTime(file.lastModified()); zout.putNextEntry(ze); try { InputStream fin = new FileInputStream(file); try { int len = 0; while ((len = fin.read(buffer)) > 0) { zout.write(buffer, 0, len); } } finally { fin.close(); } } finally { zout.closeEntry(); } } /** * unpack a segment from a zip * * @param addsi * @param packetStream * @param version */ public static void unpack(InputStream source, File destination) throws IOException { ZipInputStream zin = new ZipInputStream(source); ZipEntry zipEntry = null; FileOutputStream fout = null; try { byte[] buffer = new byte[4096]; while ((zipEntry = zin.getNextEntry()) != null) { long ts = zipEntry.getTime(); // the zip entry needs to be a full path from the // searchIndexDirectory... hence this is correct File f = new File(destination, zipEntry.getName()); if (log.isDebugEnabled()) log.debug(" Unpack " + f.getAbsolutePath()); if (!f.getParentFile().exists()) { if (!f.getParentFile().mkdirs()) { log.warn("unpack(): Failed to create parent folder: " + f.getParentFile().getPath()); } } fout = new FileOutputStream(f); int len; while ((len = zin.read(buffer)) > 0) { fout.write(buffer, 0, len); } zin.closeEntry(); fout.close(); if (!f.setLastModified(ts)) { log.warn("upack(): failes to set modified date on " + f.getPath()); } } } finally { try { fout.close(); } catch (Exception ex) { log.warn("Exception closing file output stream", ex); } } } public static String digest(String token) throws GeneralSecurityException, IOException { MessageDigest sha1 = MessageDigest.getInstance("SHA1"); return byteArrayToHexStr(sha1.digest(token.getBytes("UTF-8"))); } private static String byteArrayToHexStr(byte[] data) { char[] chars = new char[data.length * 2]; for (int i = 0; i < data.length; i++) { byte current = data[i]; int hi = (current & 0xF0) >> 4; int lo = current & 0x0F; chars[2 * i] = (char) (hi < 10 ? ('0' + hi) : ('A' + hi - 10)); chars[2 * i + 1] = (char) (lo < 10 ? ('0' + lo) : ('A' + lo - 10)); } return new String(chars); } /** * @param parentFile * @throws IOException */ public static void listDirectory(File f) throws IOException { recurseGrouped(f, new RecurseAction() { long total = 0; public void doFile(File file) throws IOException { if (!file.isDirectory()) { listFile(file); total += file.length(); } } private void listFile(File file) { char[] c = new char[4]; c[0] = '-'; c[0] = file.isDirectory() ? 'd' : c[0]; c[0] = file.isFile() ? 'f' : c[0]; c[1] = file.isHidden() ? 'h' : '-'; c[2] = file.canRead() ? 'r' : '-'; c[3] = file.canWrite() ? 'w' : '-'; log.info(new String(c) + " " + getSizeStr(file.length()) + " " + file.getName()); } private String getSizeStr(long size) { String sizeStr = String.valueOf(size) + "B"; if (size > (1024L * 1024L * 1024L * 10L)) { sizeStr = String.valueOf(size / (1024L * 1024L * 1024L)) + "G"; } else if (size > (1024L * 1024L * 10L)) { sizeStr = String.valueOf(size / (1024L * 1024L)) + "M"; } else if (size > (1024L * 10L)) { sizeStr = String.valueOf(size / (1024L)) + "K"; } return sizeStr; } public void doBeforeFile(File f) { if (f.isDirectory()) { char[] c = new char[4]; c[0] = '-'; c[0] = f.isDirectory() ? 'd' : c[0]; c[0] = f.isFile() ? 'f' : c[0]; c[1] = f.isHidden() ? 'h' : '-'; c[2] = f.canRead() ? 'r' : '-'; c[3] = f.canWrite() ? 'w' : '-'; log.info(new String(c) + " " + f.getAbsolutePath()); log.info("--------------------------------------------------------"); } } public void doAfterFile(File f) { if (f.isDirectory()) { log .info("Total :" + getSizeStr(total) + " " + f.getAbsolutePath()); log.info("--------------------------------------------------------"); total = 0; } else { log.info("Not A Directory "+f.getAbsolutePath()); } } }); // TODO Auto-generated method stub } /** * @param file * @throws IOException */ public static void createMarkerFile(File file) throws IOException { FileWriter fw = null; try { fw = new FileWriter(file); fw.write("File Touched at "+(new Date())); } finally { fw.close(); } } }