Package com.sun.faban.harness.util

Source Code of com.sun.faban.harness.util.FileHelper

/* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* http://www.sun.com/cddl/cddl.html or
* install_dir/legal/LICENSE
* See the License for the specific language governing
* permission and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at install_dir/legal/LICENSE.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* $Id$
*
* Copyright 2005-2009 Sun Microsystems Inc. All Rights Reserved
*/
package com.sun.faban.harness.util;

import com.sun.faban.harness.agent.CmdAgentImpl;
import com.sun.faban.harness.agent.FileAgent;
import com.sun.faban.harness.agent.FileService;
import com.sun.faban.harness.agent.FileServiceException;
import com.sun.faban.harness.common.Config;

import java.io.*;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.jar.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* File utilities. A collection of static methods to deal with file operations.
*/
public class FileHelper {
   
    private static Logger logger = Logger.getLogger(FileHelper.class.getName());

    /**
     * Copies a file.
     * @param srcFile  - the full pathname of the source file
     * @param destFile  - the full pathname of the destination file
     * @param append - should destination file be appended with source file
     * @return Whether the copy succeeded
     */
    public static boolean copyFile(String srcFile, String destFile,
                                   boolean append) {
        try {
            FileChannel src = (new FileInputStream(srcFile)).getChannel();
            FileChannel dest = (new FileOutputStream(destFile)).getChannel();
            if (append)
                dest.position(dest.size());
            src.transferTo(0, src.size(), dest);
            dest.close();
            src.close();
        } catch (IOException e) {
            logger.log(Level.SEVERE, "Could not copy " + srcFile + " to " +
                                     destFile, e);
            return false;
        }
        return true;
    }

    /**
     * This method opens, traverses through the file and
     * finds the properties and replaces the values
     * This updates only the first occurrence of the prop
     * in the file to eliminate cases where it changes
     * props defined like PROP=$PROP:MYPROP
     * We expect only one prop per line in the file.
     * @param fileName The full pathname of the file
     * @param prop Property names and their new values
     * @param backupFileName The file to save a copy before edit, if any
     * @return Whether the edit succeeded
     */
    public static boolean editPropFile(String fileName, Properties prop, String backupFileName) {

        String tmpFile = Config.TMP_DIR + ".FileHelper";
        //copy the file
        if(backupFileName == null)
            backupFileName = tmpFile;
           
        if(!FileHelper.copyFile(fileName, backupFileName, false))
            return false; // Failed to backup the file

        // Do not modify the passed prop as it may be used by the caller
        // Call by reference pitfalls (:-)
        Properties props = new Properties(prop);

        try {
            BufferedReader in = new BufferedReader(new FileReader(backupFileName));
            BufferedWriter out = new BufferedWriter(new FileWriter(fileName));
            String line;
            while((line = in.readLine()) != null) {
                line = line.trim();
                if((line.length() > 3) && (Character.isLetterOrDigit(line.charAt(0)))) {
                    Enumeration e = props.propertyNames();
                    while (e.hasMoreElements()) {
                        String propName = (String) e.nextElement();
                        if((line.indexOf(propName) != -1) &&
                           (line.charAt(line.indexOf(propName) + propName.length()) == '=')) {
                            StringBuffer sb = new StringBuffer(propName);
                            sb.append("=").append(props.getProperty(propName));
                            line = sb.toString();
                            // Will update only the first instance of the prop
                            props.remove(propName);
                            // We expect only one prop per line
                            break;
                        }
                    }
                }
                // Write the line to file
                out.write(line, 0, line.length());
                out.newLine();
            }
            in.close();
            out.close();          
           
            // Delete the temp file
            if(tmpFile == backupFileName)
                (new File(tmpFile)).delete();
        }
        catch (Exception e) {
            logger.severe("Failed with " + e);
            logger.log(Level.FINE, "Exception", e);
            return false;
        }
        return true;
    }      
   
    /**
     * This method opens, traverses through the file and
     * finds the token and replaces it with new value
     * This method updates only the first occurrence of
     * the token in the file to eliminate cases where it
     * changes props defined like PROP=$PROP:MYPROP.
     * @param fileName The full pathname of the file
     * @param token Token to find
     * @param replacement The replacement string
     * @param backupFileName If needed pass a backup file name
     * @return Whether there is at least one replacement
     */
    public static boolean tokenReplace(String fileName, String token, String replacement, String backupFileName) {

        String tmpFile = System.getProperty("java.io.tmpdir") + File.separator + ".FileHelper";

        //copy the file
        if(backupFileName == null)
            backupFileName = tmpFile;

        if(!FileHelper.copyFile(fileName, backupFileName, false))
            return false; // Failed to backup the file

        logger.finest("Token : " + token);
        logger.finest("Replacement : " + replacement);

        try {
            BufferedReader in = new BufferedReader(new FileReader(backupFileName));
            BufferedWriter out = new BufferedWriter(new FileWriter(fileName));
            String line;
            boolean replaced = false;
            while((line = in.readLine()) != null) {
                // replace only the first occurrence of the token
                if((!replaced) && (line.indexOf(token) != -1)) {
                    System.err.println("FileHelper.tokenReplace : replacing " + token + " with " + replacement);
                    StringBuffer sb = new StringBuffer();
                    // to escape special chars in token
                    for(int i = 0; i < token.length(); i++) {
                        if(Character.isLetterOrDigit(token.charAt(i)))
                            sb.append(token.charAt(i));
                        else
                            sb.append("\\").append(token.charAt(i));
                    }

                    // to escape special chars in replacement string
                    token = sb.toString();
                    sb = new StringBuffer();
                    for(int i = 0; i < replacement.length(); i++) {
                        if(Character.isLetterOrDigit(replacement.charAt(i)))
                            sb.append(replacement.charAt(i));
                        else
                            sb.append("\\").append(replacement.charAt(i));
                    }
                    replacement = sb.toString();

                    line = line.replaceAll(token, replacement);
                    replaced = true;
                }
                // Write the line to file
                out.write(line, 0, line.length());
                out.newLine();
            }
            in.close();
            out.close();

            // Delete the temp file
            if(tmpFile == backupFileName)
                (new File(tmpFile)).delete();
        }
        catch (Exception e) {
            logger.severe("Failed with " + e);
            logger.log(Level.FINE, "Exception", e);
            return false;
        }
        return true;
    }

    /**
     * This method opens, traverses through the file and
     * finds the token, it will avoid comments when searching.
     * @param fileName The full pathname of the file
     * @param token Token to search for
     * @return true if found, false otherwise
     */
    public static boolean isInFile(String fileName, String token) {
        boolean found = false;

        try {
            BufferedReader in = new BufferedReader(new FileReader(fileName));
            String line;
            while((line = in.readLine()) != null) {
                // Avoid comments
                if(line.length() > token.length() &&
                   Character.isLetterOrDigit(line.charAt(0)) && line.indexOf(token) != -1) {
                    found = true;
                    break;
                }
            }
            in.close();
        }
        catch (Exception e) {
            logger.severe("Failed with " + e);
            logger.log(Level.FINE, "Exception", e);
            return false;
        }
        return found;
    }

    /**
     * This  method is used to delete a directory and
     * recursively delete files and subdirectories within it.
     *
     * @param file The file or directory to delete
     * @return Whether the delete succeeded
     */
    public static boolean recursiveDelete(File file) {
        // Does a post-order traversal of the directory hierarchy and deletes
        // all the nodes in its path.
 
        // Logging file deletions at fine so we can turn on if there's
        // anything spooky. We use an exception to capture the stack, but
        // do not really throw the exception. After all, nothing is wrong.
        Exception te = new Exception("Deleting all files in " + file.getName());
        logger.log(Level.FINE, te.getMessage(), te);

        boolean success = true;
      try {
            if (file.isDirectory()) {
                File[] list = file.listFiles();
                for (int i = 0; i < list.length; i++)
                    if (!recursiveDelete(list[i])) {
                        logger.severe("Delete failed for file " +
                                file.getPath());
                        success = false;
                    }
            }
            if (!file.delete()) {
                logger.warning("Delete failed for file " + file.getPath());
                success = false;
            }
        } catch(Exception e) {
            logger.log(Level.SEVERE, "Delete failed", e);
            success = false;
        }
        return success;
    }

    /**
     * Deletes all files matched by the filter in a certain directory.
     * @param dir The directory to look for files to delete
     * @param filter The file name filter
     * @return True if all deletes succeeded, false otherwise
     */
    public static boolean delete(File dir, FileFilter filter) {
        boolean success = true;

        try {
            if (!dir.isDirectory())
                return false;
            File[] list = dir.listFiles(filter);
            for (File file : list)
                if (!recursiveDelete(file)) {
                    logger.severe("Delete failed for file " + file.getPath());
                    success = false;
                }
        } catch (Exception e) {
            logger.log(Level.SEVERE, "Delete failed", e);
            success = false;
        }
        return success;
    }

    /**
     * This method is used to delete a directory and
     * recursively delete files and subdirectories within it.
     *
     * @param parentDir The file object corresponding to the parent directory
     * @param name Name of the directory to be deleted
     * @return Whether the delete succeeded
     */
    public static boolean recursiveDelete(File parentDir, String name) {
        return recursiveDelete(new File(parentDir, name));
    }

    /**
     * Copies a file from source to dest. If src is a directory, the whole
     * directory tree is copied.
     * @param src The source file
     * @param dest The dest file, must not exist before calling method
     * @return true if copy succeeded, false afterwise
     */
    public static boolean recursiveCopy(File src, File dest) {
        if (src.isDirectory()) {
            if (!dest.exists() && !dest.mkdir())
                return false;
            File[] files = src.listFiles();
            for (File s : files) {
                File d = new File(dest, s.getName());
                if (!recursiveCopy(s, d))
                    return false;
            }
        } else {
            return copyFile(src.getAbsolutePath(), dest.getAbsolutePath(),
                            false);
        }
        return true;
    }

    /**
     * Jars up a directory to a given Jar file.
     * @param dir The base directory to jar (not included in output)
     * @param fileNames The file names to jar, can be multiple
     * @param jarPath The pathname of the jar file
     * @throws IOException There is a problem jarring up
     */
    public static void jar(String dir, String[] fileNames, String jarPath)
            throws IOException {

        logger.fine("Jar'ing up " + dir + " to " + jarPath + '.');

        File jarFile = new File(jarPath);
        if (!jarFile.isAbsolute())
            jarFile = new File(dir, jarPath);

        Manifest manifest = new Manifest();
        Attributes attributes = manifest.getMainAttributes();
        attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0");
        attributes.putValue("Created-By", Config.HARNESS_NAME + ' ' +
                            Config.HARNESS_VERSION);
        JarOutputStream out = new JarOutputStream(
                new FileOutputStream(jarFile), manifest);

        byte[] buffer = new byte[8192];
        for (String fileName : fileNames) {
            addEntry(out, dir, fileName, buffer);
        }
        out.flush();
        out.close();
    }

    private static void addEntry(JarOutputStream out, String baseDir,
                                 String name, byte[] buffer)
            throws IOException {
        File input = new File(baseDir + '/' + name);
        if (input.isDirectory()) {
            JarEntry jarEntry = new JarEntry(name + '/');
            jarEntry.setTime(input.lastModified());
            out.putNextEntry(jarEntry);
            out.closeEntry();
            String[] entries = input.list();
            for (String entry : entries)
                addEntry(out, baseDir, name + '/' + entry, buffer);
        } else {
            JarEntry jarEntry = new JarEntry(name);
            jarEntry.setTime(input.lastModified());
            FileInputStream in = new FileInputStream(input);
            out.putNextEntry(jarEntry);
            for (;;) {
                int len = in.read(buffer);
                if (len == -1)
                    break;
                out.write(buffer, 0, len);
            }
            out.closeEntry();
            in.close();
        }
    }

    /**
     * Unjars a jar file into an output directory.
     * @param jarPath The path to the jar file
     * @param outputDir The output directory
     * @throws IOException If there is an error running unjar
     */
    public static void unjar(String jarPath, String outputDir)
            throws IOException {

        logger.fine("Unjar'ing " + jarPath + " to " + outputDir + '.');

        File target;
        FileOutputStream out;

        JarInputStream in =
                new JarInputStream(new FileInputStream(jarPath));

        Manifest manifest = in.getManifest();

        if (manifest != null) {
            target = new File(outputDir + File.separator + "META-INF");
            target.mkdirs();
            out = new FileOutputStream(new File(target, "MANIFEST.MF"));
            manifest.write(out);
            out.close();
        }

        byte[] buffer = new byte[8192];
        for (;;) {
            JarEntry entry = in.getNextJarEntry();
            if (entry == null)
                break;
            target = new File(outputDir + File.separator + entry.getName());
            if (entry.isDirectory()) {
                target.mkdirs();
            } else {
                File parent = target.getParentFile();
                if (!parent.isDirectory())
                    parent.mkdirs();
                out = new FileOutputStream(target);
                for (;;) {
                    int size = in.read(buffer);
                    if (size == -1)
                        break;
                    out.write(buffer, 0, size);
                }
                target.setLastModified(entry.getTime());
                out.flush();
                out.close();
            }
            in.closeEntry();
        }
        in.close();
    }


    /**
     * Unjars a temporary jar file xxxx.jar under the directory
     * xxxx in the same path.
     * @param tmpJarFile The temporary jar file
     * @return The file reference to the resulting directory
     * @throws IOException If there is an error unjaring
     */
    public static File unjarTmp(File tmpJarFile) throws IOException {
        logger.info("Preparing run from " + tmpJarFile.getAbsolutePath() + '.');

        String dirName = tmpJarFile.getName();
        int dotPos = dirName.lastIndexOf('.');
        dirName = dirName.substring(0, dotPos);
        File unjarDir = new File(tmpJarFile.getParent(), dirName);
        unjarDir.mkdir();

        unjar(tmpJarFile.getAbsolutePath(), unjarDir.getAbsolutePath());
        return unjarDir;
    }

    /**
     * Writes a string to a file. Replaces the file if it already exists.
     * @param string The string to be written
     * @param file The target file
     * @throws IOException If the write fails
     */
    public static void writeStringToFile(String string, File file)
            throws IOException {
        file.delete();
        file.createNewFile();
        FileOutputStream out = new FileOutputStream(file);
        out.write(string.getBytes());
        out.flush();
        out.close();
    }

    /**
     * Reads a whole file and obtains the contents as a string.
     * @param file The file to be read
     * @return The string representing the whole content of the file
     * @throws IOException If the read fails
     */
    public static String readStringFromFile(File file) throws IOException {
        String content = null;
        if (file.isFile())
            content = new String(getContent(file.getAbsolutePath()));
        return content;
    }

    /**
     * Writes the entire content to file. Replaces the file if it already exists.
     * @param string
     * @param file
     * @throws java.io.IOException
     */
    public static void writeContentToFile(String string, File file)
            throws IOException {
        //StringTokenizer t = new StringTokenizer(string," \n,\t");
        file.delete();
        file.createNewFile();
        RandomAccessFile rf = new RandomAccessFile(file, "rwd");
        long size = rf.length();
        byte[] buffer = new byte[(int) size];
        rf.readFully(buffer);
        rf.seek(rf.length());
        rf.writeBytes(string);
        //while (t.hasMoreTokens()) {
               // rf.writeBytes(t.nextToken().trim() + "\n");
        //}
        rf.close();
    }

    /**
     * Reads a whole file and obtains the contents as a formatted string with
     * "\n" seperated.
     * @param file
     * @return string
     * @throws java.io.IOException
     */
    public static String readContentFromFile(File file) throws IOException {
        String content = null;
        StringBuilder formattedTags = new StringBuilder();
        if (file.isFile()) {
            content = new String(getContent(file.getAbsolutePath()));
        StringTokenizer t = new StringTokenizer(content,"\n");
            while (t.hasMoreTokens()) {
                formattedTags.append(t.nextToken().trim() + " ");
            }
        }
        return formattedTags.toString();
    }

    /**
     * Obtains the content of a file as a strin array.
     * @param file
     * @return string array
     * @throws java.io.IOException
     */
    public static String[] readArrayContentFromFile(File file)
            throws IOException {
        String content = null;
        ArrayList<String> contentList = new ArrayList<String>();
        if (file.isFile()) {
            content = new String(getContent(file.getAbsolutePath()));
            StringTokenizer t = new StringTokenizer(content, "\n");
            while (t.hasMoreTokens()) {
                contentList.add(t.nextToken().trim());
            }
        }
        return contentList.toArray(new String[contentList.size()]);
    }
    /**
     * Transfers a file from the current host to the Faban master.
     * @param inFile The input file name on the current host
     * @param outFile The output file name on the Faban master
     * @param move Whether to remove the original file or not
     * @return True if the transfer is complete, false otherwise.
     * @deprecated
     */
    @Deprecated public static boolean xferFile(String inFile, String outFile, boolean move) {
        File f = new File(inFile);
        if(!f.exists())
            return false ;

        // Use FileAgent on master machine to copy log
        FileAgent fa = null;
         try {
            String s = Config.FILE_AGENT;
            fa = (FileAgent) CmdAgentImpl.getRegistry().getService(s);
         } catch (Exception e) {
            logger.severe("Unable to get File Service");
             return false;
         }

        logger.fine("Input File = " + inFile + " Output File = "+ outFile);

        try {
            BufferedInputStream in = new BufferedInputStream(new FileInputStream(f));
            byte[] buf = new byte[8192];
            int i = in.read(buf);

            if(i > 0) {
                FileService outfp = fa.open(outFile, FileAgent.WRITE);
                while (i > 0) {
                    outfp.writeBytes(buf, 0, i);
                    i = in.read(buf);
                }
                outfp.close();
            }
            in.close();
        } catch (FileServiceException fe) {
            logger.severe("Error in creating file " + outFile);
            logger.log(Level.FINE, "Exception", fe);
        } catch (IOException e) {
            logger.severe("Error in reading file " + inFile);
            logger.log(Level.FINE, "Exception", e);
        } catch (Exception e) {
            logger.severe("Error Xfering file " + e);
            logger.log(Level.FINE, "Exception", e);
            if(move)
                f.delete();
        }
        return true;
    }

    /**
     * Obtains the whole content of a local file in a byte array.
     * @param file The file name
     * @return The byte content of the file
     * @throws IOException If the file cannot be read.
     */
    public static byte[] getContent(String file) throws IOException {
        return getContent(new File(file));
    }

    /**
     * Obtains the whole content of a local file in a byte array.
     * @param file The file name
     * @return The byte content of the file
     * @throws IOException If the file cannot be read.
     */
    public static byte[] getContent(File file) throws IOException {
        long size = file.length();
        if (size == 0)
            throw new IOException("Cannot determine file size.");
        if (size >= Integer.MAX_VALUE)
            throw new IOException("Cannot handle file size >= 2GB.");
        byte[] content = new byte[(int) size];
        FileInputStream in = null;
        try {
            in = new FileInputStream(file);
            int readLength = 0;
            while (readLength < size) {
                int bytes = in.read(content, readLength,
                            (int) size - readLength);
                if (bytes == -1) // EOS
                    break;
                readLength += bytes;
            }
        } finally {
            if (in != null)
                in.close();
        }
        return content;
    }

    /**
     * Checks a file whether it contains the given string.
     * @param file The file
     * @param string The string
     * @return True if the string is found in the file, false otherwise
     * @throws IOException Problem reading the file
     */
    public static boolean hasString(File file, String string)
            throws IOException {
        boolean retVal = false;
        BufferedReader bufR = new BufferedReader(new FileReader(file));
        String s;
        while ((s = bufR.readLine()) != null) {
            if (s.indexOf(string) != -1) {
                retVal = true;
                break;
            }
        }
        bufR.close();
        return retVal;
    }
    /**
     * Unit test the functionality.
     * @param args The command line arguments
     */
    public static void main(String[] args) {
        if (args.length < 3) {
            System.out.println("Usage: java FileHelper File token replacement");
            return;
        }
        Properties prop = new Properties();
        prop.setProperty(args[1], args[2]);

        //FileHelper.editPropFile(args[0], prop, null);
        // FileHelper.tokenReplace(args[0], args[1], args[2], null);
        //FileHelper.tokenReplace(System.getProperty("java.io.tmpdir") +
        //      "/t", "\"$JAVA_HOME\"/bin/java",
        // "profcmd= \n\\$profcmd \"\\$JAVA_HOME\"/bin/java", null);
        FileHelper.tokenReplace(System.getProperty("java.io.tmpdir") + "/t",
                "\"$JAVA_HOME\"/bin/java",
                "profcmd= \n$profcmd \"$JAVA_HOME\"/bin/java", null);
    }
}
/*
// This code will replace properties which is specified anywhere in the line
// But will messup cases where there are blanks in it.
                        if((line.indexOf(propName)) != -1) {
                            StringBuffer sb = new StringBuffer();
                            StringTokenizer st = new StringTokenizer(line);
                            while (st.hasMoreTokens()) {
                                String tk = st.nextToken();
                                if(tk.indexOf(propName) != -1)
                                    sb.append(propName).append("=")
                                      .append(props.getProperty(propName)).append(" ");
                                else
                                    sb.append(tk).append(" ");
                            }
                            line = sb.toString();
                        }

*/ 
TOP

Related Classes of com.sun.faban.harness.util.FileHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.