Package cu.ftpd.modules.requests

Source Code of cu.ftpd.modules.requests.RequestLog

/**
* 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.modules.requests;

import cu.ftpd.logging.Logging;
import cu.ftpd.user.User;
import cu.ftpd.modules.requests.Request;

import java.io.*;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.text.MessageFormat;

/**
* @author Markus Jevring <markus@jevring.net>
* @since 2007-okt-10 : 12:21:05
* @version $Id: RequestLog.java 292 2009-03-04 19:44:36Z jevring $
*/
public class RequestLog {
    private final File log;
    private final boolean autoApprove;
    private final List<Request> requests = Collections.synchronizedList(new LinkedList<Request>());

    // request, req_user, req_group, req_tagline,
    protected static final MessageFormat request = new MessageFormat("REQUEST: \"{0}\" \"{1}\" \"{2}\" \"{3}\"");
    // request, fill_user, fill_group, fill_tagline, requester
    protected static final MessageFormat reqfilled = new MessageFormat("REQFILLED: \"{0}\" \"{1}\" \"{2}\" \"{3}\" \"{4}\"");
    //  request, approve_user, approve_group, approve_tagline
    protected static final MessageFormat approveRequest = new MessageFormat("REQAPPROVE: \"{0}\" \"{1}\" \"{2}\" \"{3}\"");


    public RequestLog(String logfile, boolean autoApprove) throws IOException {
        if (logfile == null || "".equals(logfile)) {
            throw new IllegalArgumentException("'logfile' parameter to RequestLog() cannot be null or \"\"");
        }
        log = new File(logfile);
        this.autoApprove = autoApprove;
        load();
    }

    public void request(User user, String request) {
        Request r = new Request(System.currentTimeMillis(), user.getUsername(), request);
        requests.add(r);
        if (autoApprove) {
            r.setApproved(true);
        }
        save();
        // _todo: make a reqdel command
        // _todo: allow setting for dirs to be automatically created (for this we need a pattern (user setable? heaven forbid) as well as a setting in the settings)(as well as WHERE these dirs should be created)
        // if we do this, do we auto-rename directories that are filled?
        // do we also auto-del directories that are reqdelled (requests, yes, but what about filled requests?)
        // no, if people want that kind of advanced request system, they can build it as a module
        logRequestToEventLog(user, r);
    }

    public boolean fillRequest(User filler, int requestNumber) {
        // even though doing .get(int) isn't particularly effective on a LinkedList, this operation happens rarely, and we don't need to shift the entire array down, which would be even more costly
        synchronized (requests) { // added this lock here to keep .remove() from throwing an IndexOutOfBoundsException.
            if (requestNumber <= requests.size() - 1 && requestNumber >= 0) {
                Request r = requests.remove(requestNumber);
                save();
                logRequestFilledToEventLog(filler, r);
                return true;
            } else {
                return false;
            }
        }
    }

    public boolean approve(User approver, int requestNumber, boolean approved) {
        synchronized (requests) {
            if (requestNumber <= requests.size() - 1 && requestNumber >= 0) {
                Request r = requests.get(requestNumber);
                r.setApproved(approved);
                save();
                logRequestApprovedToEventLog(approver, r);
                return true;
            } else {
                return false;
            }
        }
    }

    public List<Request> getRequests() {
        return requests;
    }

    public void logRequestToEventLog(User user, Request r) {
        Logging.getEventLog().log(request.format(new String[]{r.getDescription(), user.getUsername(), user.getPrimaryGroup(), user.getTagline()}));
    }
    public void logRequestFilledToEventLog(User filler, Request request) {
        Logging.getEventLog().log(reqfilled.format(new String[]{request.getDescription(), filler.getUsername(), filler.getPrimaryGroup(), filler.getTagline(), request.getRequester()}));
    }
    public void logRequestApprovedToEventLog(User user, Request request) {
        Logging.getEventLog().log(approveRequest.format(new String[]{request.getDescription(), user.getUsername(), user.getPrimaryGroup(), user.getTagline()}));
    }

    private void load() throws IOException {
        if (!requests.isEmpty()) {
            throw new IllegalStateException("Cannot load the requestlog more than once!");
        }
        BufferedReader in = null;
        if (!log.exists()) {
            System.out.println("Request log not found, creating...");
            if (!log.createNewFile()) {
                throw new IOException("Could not create new request log!");
            }
            return; // we might as well return here since we don't want to read an empty file anyway
        }
        try {
            in = new BufferedReader(new InputStreamReader(new FileInputStream(log)));
            String line;
            while ((line = in.readLine()) != null) {
                String[] request = line.split(";");
                // time + ";" + requester + ";" + approved + ";" + description;
                Request r = new Request(Long.parseLong(request[0]), request[1], request[3]);
                r.setApproved(Boolean.parseBoolean(request[2]));
                requests.add(r);
            }
        } catch (IOException e) {
            // should we even report this?
            Logging.getErrorLog().reportCritical("Error while loading request log: " + e.getMessage());
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    Logging.getErrorLog().reportException("Failed to close input stream", e);
                    //e.printStackTrace();
                }
            }
        }

    }

    public void save() {
        synchronized(requests) {
            PrintWriter out = null;
            try {
                out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(log))));
                // create the log
                for (Request r : requests) {
                    // write it to the log
                    out.println(r);
                }
                out.flush();
            } catch (IOException e) {
                Logging.getErrorLog().reportCritical("Could not write request log to file: " + e.getMessage());
            } finally {
                if (out != null) {
                    out.close();
                }
            }
        }
    }
}
TOP

Related Classes of cu.ftpd.modules.requests.RequestLog

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.