package org.sakaiproject.search.util; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.sakaiproject.search.api.SearchService; public class DigestStorageUtil { private static final Log log = LogFactory.getLog(DigestStorageUtil.class); private SearchService searchService; public DigestStorageUtil(SearchService searchService) { this.searchService = searchService; if (searchService == null) { throw new IllegalArgumentException("SearchService can't be null"); } } private String getHashOfFile(String ref) { return DigestUtils.md5Hex(ref); } public String getPath(String reference) { log.debug("getPath(" + reference); String ret = ""; reference = getHashOfFile(reference); ret = reference.substring(0, 1) + "/" + reference.substring(0, 3) + "/" + reference; return ret; } public StringBuilder getFileContents(String ref, String digestCount) { StringBuilder sb = new StringBuilder(); BufferedReader input = null; try { String storePath = searchService.getDigestStoragePath(); if (storePath == null) { return null; } String digestFilePath = storePath + getPath(ref) + "/digest." + digestCount; log.debug("opening: " + digestFilePath); input = new BufferedReader(new FileReader(digestFilePath)); String line = null; //not declared within while loop /* * readLine is a bit quirky : * it returns the content of a line MINUS the newline. * it returns null only for the END of the stream. * it returns an empty String if two newlines appear in a row. */ while (( line = input.readLine()) != null){ sb.append(line); sb.append(System.getProperty("line.separator")); } } catch (FileNotFoundException e) { log.warn("Unable to open digest for item: " + SearchService.FIELD_REFERENCE + " with count " + digestCount + " fileNotFound"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (input != null) { try { input.close(); } catch (IOException iox) { log.debug("exeption in final block!"); } } } return sb; } /** * Save the digested content to a disc store * @param ref * @param content */ public void saveContentToStore(String ref, String content, int version) { //there must be some content if (content == null) { return; } String storePath = searchService.getDigestStoragePath(); if (storePath != null ) { FileOutputStream fileOutput = null; try { if (!new File(storePath).exists()) if (!new File(storePath).mkdirs()) { log.error("error creating digestStorePath: " + storePath); return; } String exPath = getPath(ref); String filePath = storePath + exPath; if (!new File(filePath).exists()) { log.debug("creating folder" + filePath); if (!new File(filePath).mkdirs()) { log.error("error creating digest file path " + filePath); return; } } log.debug("filePath: " + filePath); fileOutput = new FileOutputStream(filePath + "/digest." + version); fileOutput.write(content.getBytes("UTF8")); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { if(fileOutput != null) fileOutput.close(); } catch (IOException e) { log.error("Exception in finally block: "+e); } } } } public int getDocCount(String ref) { String storePath = searchService.getDigestStoragePath(); int count = 0; if (storePath != null ) { String exPath = getPath(ref); String filePath = storePath + exPath; if (new File(filePath).exists()) { File dir = new File(filePath); String[] children = dir.list(); if (children == null) { return 0; } else { for (int i=0; i<children.length; i++) { String fileName = children[i]; if (fileName.contains(".")) { Integer countIn = getCountFromFileName(fileName); if (countIn.intValue() > count) { count = countIn.intValue(); } } } return count; } } } return 0; } private Integer getCountFromFileName(String fileName) { if (!fileName.contains(".")) { return null; } Integer countIn = null; String countStr = fileName.substring(fileName.lastIndexOf('.') + 1 , fileName.length()); log.debug("count string is: " + countStr); try { countIn = Integer.valueOf(countStr); } catch (NumberFormatException nfe) { log.warn("filename: " + fileName + "has nonNumeric exension"); } return countIn; } public void cleanOldDigests(String ref) { String storePath = searchService.getDigestStoragePath(); int docCount = getDocCount(ref); Calendar cal = new GregorianCalendar(); cal.add(Calendar.DAY_OF_MONTH, -1); Date yesterDay = cal.getTime(); if (storePath != null ) { String exPath = getPath(ref); String filePath = storePath + exPath; if (new File(filePath).exists()) { File dir = new File(filePath); String[] children = dir.list(); if (children == null) { return; } else { for (int i=0; i<children.length; i++) { String fileName = children[i]; if (docCount > getCountFromFileName(fileName)) { File file = new File(filePath + "/" + fileName); if (file.exists()) { Date lastMod = new Date(file.lastModified()); //is this more than a day old? if (lastMod.before(yesterDay)) { if (!file.delete()) { log.warn("cleanOldDigests: unable to delete digest: " +filePath + "/" + fileName); } } } } } } } } } public void deleteAllDigests(String reference) { String storePath = searchService.getDigestStoragePath(); if (storePath != null ) { String exPath = getPath(reference); String filePath = storePath + exPath; File dir = new File(filePath); if (dir.exists()) { //delete the files in the dir String[] children = dir.list(); if (children != null) { for (int i=0; i<children.length; i++) { String fileName = children[i]; File file = new File(filePath + "/" + fileName); if (!file.delete()) { log.warn("unable to delete file: " + filePath + "/" + fileName); } } } log.debug("about to delete: " + filePath); if (!dir.delete()) { log.warn("unable to delete: " + filePath); } } } } }