/* * Copyright (C) 2000 - 2011 TagServlet Ltd * * This file is part of Open BlueDragon (OpenBD) CFML Server Engine. * * OpenBD is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * Free Software Foundation,version 3. * * OpenBD is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenBD. If not, see http://www.gnu.org/licenses/ * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or combining * it with any of the JARS listed in the README.txt (or a modified version of * (that library), containing parts covered by the terms of that JAR, the * licensors of this Program grant you additional permission to convey the * resulting work. * README.txt @ http://www.openbluedragon.org/license/README.txt * * http://www.openbluedragon.org/ * $Id: JavaFileIO.java 1767 2011-11-04 08:08:07Z alan $ */ package com.bluedragon.platform.java; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.OutputStream; import java.io.Writer; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import org.apache.commons.vfs.FileObject; import org.apache.commons.vfs.FileSystemException; import org.apache.commons.vfs.FileSystemManager; import org.apache.commons.vfs.VFS; import org.apache.commons.vfs.impl.StandardFileSystemManager; import com.bluedragon.platform.FileIO; import com.nary.io.FileUtils; import com.nary.util.Date; import com.naryx.tagfusion.cfm.engine.cfEngine; public class JavaFileIO implements FileIO { public static final String DEFAULT_RUNTIME_LOGGING = "true"; public static final String DEFAULT_RUNTIME_LOGGING_MAX = "100"; private File workingDirectory, tempDirectory, rteDirectory; private boolean bRunTimeLogging = true; private int runTimeLoggingMax = 100; private FileSystemManager fsManager; public JavaFileIO(ServletConfig config) throws ServletException{ try { fsManager = VFS.getManager(); ((StandardFileSystemManager)fsManager).addProvider( "s3", new com.intridea.io.vfs.provider.s3.S3FileProvider() ); ((StandardFileSystemManager)fsManager).addOperationProvider("s3", new com.intridea.io.vfs.provider.s3.acl.AclOperationsProvider() ); } catch (Exception e1) { cfEngine.log("Failed to register the s3:// name space: " + e1.getMessage()); } // Set the working directory try { if (!setWorkingDirectory(config.getInitParameter("BLUEDRAGON_WORKING_DIRECTORY"))) { throw new Exception(config.getInitParameter("BLUEDRAGON_WORKING_DIRECTORY") + " could not be created"); } } catch (Exception E) { System.out.println( cfEngine.PRODUCT_NAME + ": Init Parameter BLUEDRAGON_WORKING_DIRECTORY Error: " + E); throw new ServletException( cfEngine.PRODUCT_NAME + ": Init Parameter BLUEDRAGON_WORKING_DIRECTORY Error: " + E); } // Setup the logging com.nary.Debug.SystemOff(); File logFile = new File( getWorkingDirectory(), "bluedragon.log"); rolloverLogFile(logFile); com.nary.Debug.setFilename(logFile.toString()); setTempDirectory(); setupRuntimeLogging(); cfEngine.log(cfEngine.PRODUCT_NAME + " WorkingDirectory=[" + getWorkingDirectory() + "]"); cfEngine.log(cfEngine.PRODUCT_NAME + " TempDirectory=[" + getTempDirectory() + "]"); } public void engineAdminUpdate(){ setupRuntimeLogging(); } private void rolloverLogFile(File logFile) { // delete the oldest (10th) backup; increment the numbers of the remaining backups for (int backupNo = 10; backupNo > 0; backupNo--) { File backupFile = new File(logFile + "." + backupNo); if (backupFile.exists()) { if (backupNo == 10) { backupFile.delete(); } else { backupFile.renameTo(new File(logFile + "." + (backupNo + 1))); } } } if (logFile.exists()) { // Try 3 times to rename bluedragon.log, sleeping 500ms between each attempt. int numAttempts = 0; while ((numAttempts < 3) && !logFile.renameTo(new File(logFile + ".1"))) { numAttempts++; try { Thread.sleep(500); } catch (InterruptedException ignore) { } } } } private boolean setWorkingDirectory(String directory) { if (directory == null) { directory = System.getProperty("bluedragon.workdir"); if (directory != null) { workingDirectory = new File(directory); } } else { workingDirectory = cfEngine.getResolvedFile(directory); } if (workingDirectory == null) { workingDirectory = (java.io.File)cfEngine.thisServletContext.getAttribute("javax.servlet.context.tempdir"); workingDirectory = new File(workingDirectory, "bluedragon"); } // --[ Check to see if the directory exists, if not, create it if (!workingDirectory.isDirectory() && !workingDirectory.mkdirs()) return false; else return true; } private void setTempDirectory() { // --[ if the property exists tempDirectory = cfEngine.getResolvedFile( cfEngine.thisInstance.getSystemParameters().getString("server.system.tempdirectory")); if (tempDirectory == null) { tempDirectory = new File(workingDirectory, "temp"); } if (!tempDirectory.isDirectory() && !tempDirectory.mkdirs()) { tempDirectory = new File(workingDirectory, "temp"); } // delete temporary native library files File[] tempFiles = tempDirectory.listFiles(); for (int i = 0; i < tempFiles.length; i++) { if (tempFiles[i].isFile() && tempFiles[i].getName().startsWith("LIB")) { tempFiles[i].delete(); } } } private void setupRuntimeLogging() { rteDirectory = new File(tempDirectory, "rtelogs"); if (!rteDirectory.isDirectory() && !rteDirectory.mkdirs()) rteDirectory = tempDirectory; bRunTimeLogging = cfEngine.thisInstance.getSystemParameters().getBoolean("server.system.runtimelogging", Boolean.valueOf(DEFAULT_RUNTIME_LOGGING).booleanValue()); runTimeLoggingMax = cfEngine.thisInstance.getSystemParameters().getInt("server.system.runtimeloggingmax", Integer.valueOf(DEFAULT_RUNTIME_LOGGING_MAX).intValue() ); if (bRunTimeLogging) cfEngine.log("RunTimeError Directory=[" + rteDirectory + "], Max=[" + runTimeLoggingMax + "]"); } public OutputStream getFileOutputStream(File tempFile) throws IOException { return new FileOutputStream( tempFile ); } public Writer getFileWriter(File outFile) throws IOException{ return new FileWriter( outFile ); } public File getWorkingDirectory(){ return workingDirectory; } public File getTempDirectory(){ return tempDirectory; } public void writeLogFile(File _outFile, String body) { try { cfEngine.log("RTE: " + _outFile); FileUtils.writeFile(_outFile, body); } catch (Exception E) {} /* Write out to the constant file */ synchronized ( rteDirectory ) { try { FileUtils.writeFile( new File( rteDirectory, "bderror-latest.html" ), body); } catch (Exception E) {} } // See if writing this log file caused us to go over the max limit if ( rteDirectory.listFiles().length > runTimeLoggingMax ) { // Perform the deletion of the oldest log file within a sync block so we don't delete too many log files synchronized ( rteDirectory ) { // Re-check the number of files since another thread might have deleted one File[] files = rteDirectory.listFiles(); if ( files.length > runTimeLoggingMax ){ // Find the oldest log file int oldest = 0; for ( int i = 1; i < files.length; i++ ){ if ( files[i].lastModified() < files[oldest].lastModified() ) oldest = i; } // Delete the oldest log file files[oldest].delete(); } } } } public boolean isRunTimeLoggingEnabled(){ return bRunTimeLogging; } public File getRunTimeLoggingFile() { try { return File.createTempFile("bderror-" + Date.formatNow( "yyyy-MM-dd-HHmmss" ) + "_", ".html", rteDirectory); } catch (IOException E) { cfEngine.log("Failed to create error log file: " + E.getMessage()); return null; } } @Override public FileSystemManager vfsManager() { return fsManager; } @Override public FileObject vfsGetTempDirectory() { try { return fsManager.resolveFile( getTempDirectory().getAbsolutePath() ); } catch (FileSystemException e) { cfEngine.log("vfsGetTempDirectory: Failed to create temp directory: " + e.getMessage() ); return null; } } }