Package cu.ftpd.logging

Source Code of cu.ftpd.logging.LogCreator

/**
* Copyright (c) 2007, Markus Jevring <markus@jevring.net>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
* 3. The names of the contributors may not be used to endorse or promote
*    products derived from this software without specific prior written
*    permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
package cu.ftpd.logging;

import cu.ftpd.filesystem.metadata.MetadataHandler;
import cu.ftpd.modules.dirlog.Dirlog;
import cu.ftpd.modules.dupecheck.Dupelog;

import java.io.IOException;
import java.io.File;
import java.util.Deque;
import java.util.LinkedList;

/**
* This class will traverse a directory structure and populate a dirlog and dupelog with it's content.
* @author Markus Jevring <markus@jevring.net>
* @since 2008-jan-31 - 15:11:18
* @version $Id: LogCreator.java 307 2011-02-27 19:10:52Z jevring $
*/
public class LogCreator {
    // NOTE: if we start adding from the leaf, then we can propagate the size up recursively to when we add in the dirlog
    private Dirlog dirlog;
    private Dupelog dupelog;
    private String rcp;
    public long totalSize;
    public long totalDirs;
    public long totalFiles;
    private MetadataHandler mh = new MetadataHandler();

    public LogCreator(String dirlogPath, String dupelogPath, boolean append) throws IOException {
        dirlog = new Dirlog(dirlogPath);
        dupelog = new Dupelog(dupelogPath, Integer.MAX_VALUE, false, "*");
        if (append) {
            dirlog.load();
            dupelog.load();
        }
    }

    private String resolve(File file) {
        // we created our own resolve so we don't have to initialize the filesystem
        String s;
        try {
            s = file.getCanonicalPath();
            s = s.substring(rcp.length());
            String t;
            if (s.length() == 0) {
                t = "/";
            } else {
                t = s;
            }
            if (File.separatorChar != '/') { // this will happen on windows and older versions of mac
                t = t.replace(File.separatorChar, '/');
            }
            return t;
        } catch (IOException e) {
            // There is a pretty good reason that something is terribly wrong if we end up here
            System.err.println("We were unable to get the canonical path for " + file.getAbsolutePath());
            // NOTE: returning null here is fine, it is in the specified behavior.
            return null;
        }
    }

    public void start(File root) {
        try {
            rcp = root.getCanonicalPath();
            addToLog(root);
            dirlog.shutdown();
            dupelog.shutdown();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void addToLog(File entity) {
        final Deque<File> queue = new LinkedList<File>();
        queue.push(entity);
        // since we don't care about consecutive dirlog accesses, all we want to do is minimize the size of the queue at any time
        // removeFirst keeps the size to its smallest
        int max = 0;
        while (!queue.isEmpty()) {
//            max = Math.max(queue.size(), max);
//            System.out.println("size: " + queue.size());
            File file = queue.removeFirst();
            String username = "cuftpd";
/*
            File parent = file.getParentFile();
            File metadata = new File(parent, ".metadata");
            if (metadata.exists()) {
                Directory d = mh.getDirectory(file.getParentFile());
                if (d != null) {
                    Metadata m = d.getMetadata(file.getName());
                    if (m != null) {
                        username = m.getUsername();
                    }
                }
            }
*/           
            if (file.isFile()) {
                // we want to have as few objects in memory at a time as possible, so prioritize leaves rather than branches

                // _todo: we don't want to write it to disk except at the end, preferably.
                // to do this we could write a memory-only dirlog subclass that overrides save(), and puts the real save in something else.
                // Ahh, but it doesn't save, that's done by the timer, awesome!
                if (!file.getName().equals(".metadata") && !file.getName().equals(".raceinfo")) {

                    dirlog.update(resolve(file.getParentFile()), file.length(), username);
                    dupelog.addDupe(username, file.getName());
                    totalFiles++;
                    totalSize += file.length();
                }
            } else {
                totalDirs++;
                // _todo: ideally we don't want this to include the COMPLETE* dirs, but there's little we can do, since we do't really want to provide a skiplist
                dirlog.create(resolve(file), username);
                File[] files = file.listFiles();
                if (files != null) {
                    for (File f : files) {
                        queue.push(f);
                    }
                } else {
                    System.out.println("Could not index: " + file.getAbsolutePath() + ", skipping...");
                }
            }
        }
//        System.out.println("max: " + max);
    }

    public static void main(String[] args) {
        /*
        for (int i = 0; i < args.length; i++) {
            String arg = args[i];
            System.out.println(i + " = " + arg);
        }
        */
        if (args.length == 4) {
            LogCreator lc;
            try {
                long start = System.currentTimeMillis();
                lc = new LogCreator(args[0], args[1], Boolean.parseBoolean(args[2]));
                File root = new File(args[3]);
                if (root.exists() && root.isDirectory()) {
                    lc.start(new File(args[3]));
                    double timeTaken = ((double)(System.currentTimeMillis() - start))/ 1000.0d;
                    System.out.println("Complete!");
                    System.out.println("Directories: " + lc.totalDirs);
                    System.out.println("Files: " + lc.totalFiles);
                    System.out.println("Size: " + Formatter.size(lc.totalSize));
                    System.out.println("Time: " + timeTaken + " seconds");
                } else {
                    System.err.println(root.getAbsolutePath() + " either does not exist or is not a directory.");
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            usage();
        }
    }

    private static void usage() {
        System.out.println("Usage: java -jar logcreator.jar dirlogpath dupelogpath append root");
        System.out.println();
        System.out.println("where append is a boolean, and thus the only accepted values are: true or false");
        System.out.println("and root indicates the directory that we want to index, which will also serve as");
        System.out.println("the root of the ftpd, as far as the dirlog is concerned.");
        System.out.println("This would typically be /cuftpd/site");
        System.out.println("set append to true if you want the dupelog and dirlog to be appended, rather than overwritten");
        System.out.println("any argument with spaces in them need to be enclosed in quotation marks");
    }
}
TOP

Related Classes of cu.ftpd.logging.LogCreator

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.