com.minoritycode.Application.java Source code

Java tutorial

Introduction

Here is the source code for com.minoritycode.Application.java

Source

package com.minoritycode;

import org.codehaus.plexus.util.FileUtils;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.*;
import java.net.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 *  Created by Matt Hall on 19/03/2015.
 *  minorityCode -- Trello backup application released under GNU General Public Licence v3.
 *  This software is open source and is free.  It may be copied and redistributed for free.
 *  Copyright 2015 Matthew Hall - minorityCode
 *
 *  This application is designed to run as a standalone java application wrapped in a windows executable.
 *  Please see config.properties to configure the application for mailer and proxy settings.
 *  Run the application and follow the instructions. A log file and error log and generated and can be
 mailed if using mailer and generated in the same working directory as the executable file.
 *
 *  The config file should be placed in the same directory as the executable file.
 *
 *  exe and jar built using maven and Launch4j
 It is recommended that the app is scheduled to run once a day using Windows scheduler
 To download all organisation boards please make sure you are an Admin for that organisation
 minimum system requirements :       at least Java jre 6 - 512mb PermSize
 internet connection
 recommended system requirements :   at least Java jre 6 - 1024mb PermSize
 *  This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.
 This program 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 this program.  If not, see <http://www.gnu.org/licenses/>
 please report bugs to matthall103@gmail.com or visit the github repository @
 https://github.com/matthall103/TrelloBackup
 */

public class Application implements Runnable {

    private static String url = "https://api.trello.com/1/";
    private static String boardId;
    private static Lock lock;

    public static Lock lockErrorRep;
    public static Lock lockErrorLog;
    public static JSONObject report = new JSONObject();
    public static ArrayList<String> boards;
    public static Properties config = new Properties();
    public static Proxy proxy = null;
    public static String charset = "UTF-8";
    public static DateFormat df = new SimpleDateFormat("yyyyMMdd_HHmmss");
    public static String date = df.format(Calendar.getInstance().getTime());
    public static DateFormat dfReport = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
    public static String backupDate = dfReport.format(Calendar.getInstance().getTime());
    public static Integer boardCountSuc = 0;
    public static HashMap<String, String> errorBoards = new HashMap<String, String>();
    public static SimpleLogger logger = new SimpleLogger();
    public static Integer threadCounter = 0;
    public static String key = null;
    public static String token = null;

    public static File rootDir = null;
    public static File haysDir = null;
    public static File boardsDir = null;

    public static String workingDir = System.getProperty("user.dir");
    public static boolean manualOperation;

    public Application() {
    }

    @Override
    public void run() {

        boolean lockAcquired = false;
        do {
            //Lock and Block + remove file from file list.
            try {
                if (lock.tryLock(10, TimeUnit.MILLISECONDS)) {
                    boardId = boards.get(0);
                    boards.remove(0);
                    lockAcquired = true;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
                logger.logLine(e.getMessage());
            } finally {
                //release lock
                if (lockAcquired) {
                    lock.unlock();
                    lockAcquired = false;
                }
            }

            BoardDownloader downloader = new BoardDownloader();
            downloader.downloadBoard(url, boardId);

            long threadInterval = Long.parseLong(config.getProperty("threadInterval"));
            try {
                Thread.sleep(threadInterval);
            } catch (InterruptedException e) {
                e.printStackTrace();
                logger.logLine(e.getMessage());
            }
        } while (boards.size() > 0);
        threadCounter++;

        //        System.out.println(threadCounter+ " Threads completed");
        if (threadCounter == Integer.parseInt(config.getProperty("numberOfThreads"))) {

            System.out.println(threadCounter + " Threads completed");
            StringBuilder boardsMissed = new StringBuilder();

            Iterator it = errorBoards.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry pair = (Map.Entry) it.next();
                System.out.println(pair.getKey() + " = " + pair.getValue());
                boardsMissed.append(pair.getKey() + " = " + pair.getValue() + "\n");
                it.remove(); // avoids a ConcurrentModificationException
            }

            try {
                report.put("boardNumSuccessful", boardCountSuc);
                report.put("boardsNotDownloaded", boardsMissed.toString());
            } catch (JSONException e) {
                e.printStackTrace();
                logger.logLine(e.getMessage());
            }

            logger.logger(report);
            logger.stopErrorLogger();

            manageBackups(rootDir);

            if (manualOperation) {
                System.out.println("Press enter to exit..........");
                try {
                    System.in.read();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            System.exit(0);

        }
    }

    public static void main(String[] args) {
        System.out.println("Trello Backup Application");

        File configFile = new File(workingDir + "\\config.properties");
        InputStream input = null;
        try {
            input = new FileInputStream(configFile);
            config.load(input);
            input.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //        String workingDir = System.getProperty("user.dir");
        manualOperation = Boolean.parseBoolean(config.getProperty("manualOperation"));

        logger.startErrorLogger();
        setBackupDir();

        try {
            report.put("backupDate", backupDate);
        } catch (JSONException e) {
            e.printStackTrace();
            logger.logLine(e.getMessage());
        }

        lock = new ReentrantLock();
        lockErrorRep = new ReentrantLock();
        lockErrorLog = new ReentrantLock();

        Application.key = config.getProperty("trellokey");
        Application.token = config.getProperty("trellotoken");

        boolean useProxy = Boolean.parseBoolean(config.getProperty("useProxy"));

        boolean proxySet = true;

        if (useProxy) {
            proxySet = setProxy();
        }

        //        GUI  swingContainerDemo = new GUI();
        //        swingContainerDemo.showJPanelDemo();
        if (proxySet) {
            Credentials credentials = new Credentials();
            if (Application.key.isEmpty()) {
                Application.key = credentials.getKey();
            } else {
                Application.key = config.getProperty("trellokey");
            }
            if (token.isEmpty()) {
                Application.token = credentials.getToken();
            } else {
                Application.token = config.getProperty("trellotoken");
            }

            BoardDownloader downloader = new BoardDownloader();

            downloader.downloadMyBoard(url);
            boards = downloader.downloadOrgBoard(url);

            if (boards != null) {
                try {
                    report.put("boardNum", boards.size());
                } catch (JSONException e) {
                    e.printStackTrace();
                    logger.logLine(e.getMessage());
                }

                Integer numberOfThreads = Integer.parseInt(config.getProperty("numberOfThreads"));

                if (numberOfThreads == null) {
                    logger.logLine("error number of threads not set in config file");
                    if (manualOperation) {
                        String message = "How many threads do you want to use (10) is average";
                        numberOfThreads = Integer.parseInt(Credentials.getInput(message));
                        Credentials.saveProperty("numberOfThreads", numberOfThreads.toString());
                    } else {
                        if (Boolean.parseBoolean(config.getProperty("useMailer"))) {
                            Mailer mailer = new Mailer();
                            mailer.SendMail();
                        }
                        System.exit(-1);
                    }
                }

                ArrayList<Thread> threadList = new ArrayList<Thread>();
                for (int i = 0; i < numberOfThreads; i++) {
                    Thread thread = new Thread(new Application(), "BoardDownloadThread");
                    threadList.add(thread);
                    thread.start();
                }
            } else {
                //create empty report
                try {
                    report.put("boardsNotDownloaded", "99999");
                    report.put("boardNum", 0);
                    report.put("boardNumSuccessful", 0);
                } catch (JSONException e) {
                    e.printStackTrace();
                    logger.logLine(e.getMessage());
                }

                if (Boolean.parseBoolean(config.getProperty("useMailer"))) {
                    Mailer mailer = new Mailer();
                    mailer.SendMail();
                }

                logger.logger(report);
            }
        } else {
            //create empty report
            try {
                report.put("boardsNotDownloaded", "99999");
                report.put("boardNum", 0);
                report.put("boardNumSuccessful", 0);
            } catch (JSONException e) {
                e.printStackTrace();
                logger.logLine(e.getMessage());
            }

            if (Boolean.parseBoolean(config.getProperty("useMailer"))) {

                Mailer mailer = new Mailer();
                mailer.SendMail();
            }
        }
    }

    public static URLConnection makeConnection(String url, boolean useProxy) {

        URLConnection connection = null;
        try {
            if (useProxy) {
                connection = new URL(url).openConnection(Application.proxy);
            } else {
                connection = new URL(url).openConnection();
            }
            connection.setRequestProperty("Accept-Charset", charset);
            connection.setConnectTimeout(30000);
        } catch (IOException e) {
            e.printStackTrace();
            Application.errorBoards.put(url, e.getMessage());
            logger.logLine(e.getMessage());
            return null;
        }

        return connection;
    }

    private static void manageBackups(File backupDir) {

        System.out.println("Manage Backups");
        File[] list = backupDir.listFiles();
        ArrayList<File> backupFiles = new ArrayList<File>();
        for (File file : list) {
            if (file.isDirectory() && !file.getName().equals(".") && !file.getName().equals("..")) {
                backupFiles.add(file);
            }
        }

        Collections.sort(backupFiles);

        int numOfBackups = Integer.parseInt(config.getProperty("numOfBackups"));
        for (int i = 0; i < (backupFiles.size() - numOfBackups); i++) {
            File file = backupFiles.get(i);
            //            backupFiles.remove(0);

            try {
                FileUtils.deleteDirectory(file);
            } catch (IOException e) {
                e.printStackTrace();
            }

            if (!file.isDirectory()) {
                System.out.println(file.getName() + " has been deleted!");
            } else {
                System.out.println("Delete operation has failed for " + file.getName());
            }
        }
    }

    public static void setBackupDir() {

        boolean useWorkingDir = Boolean.parseBoolean(Application.config.getProperty("useWorkingDir"));
        String backupFolderName = config.getProperty("backupFolderName");

        if (backupFolderName == null) {
            backupFolderName = "";
        }

        if (useWorkingDir) {
            rootDir = new File(workingDir + "\\JSON");
            haysDir = new File(workingDir + "\\JSON\\" + backupFolderName + "_" + Application.date);
            boardsDir = new File(workingDir + "\\JSON\\" + backupFolderName + "_" + Application.date + "\\boards");
        } else {
            String backupPath = Application.config.getProperty("backupPath");
            rootDir = new File(backupPath);
            haysDir = new File(backupPath + "\\" + backupFolderName + "_" + Application.date);
            boardsDir = new File(backupPath + "\\" + backupFolderName + "_" + Application.date + "\\boards");
        }

        if (!rootDir.exists()) {
            rootDir.mkdir();
        }
        if (!haysDir.exists()) {
            haysDir.mkdir();
        }
        if (!boardsDir.exists()) {
            boardsDir.mkdir();
        }
    }

    private static boolean setProxy() {

        System.out.println("Setting proxy...");

        String host = null;

        host = config.getProperty("proxyHost").trim();

        if (host == null || host.isEmpty() || host.equals("")) {
            logger.logLine("error proxy host not set in config file");
            if (manualOperation) {
                String message = "Please enter your proxy Host address";
                host = Credentials.getInput(message).trim();
                Credentials.saveProperty("proxyHost", host);

                if (host.equals(null)) {
                    System.exit(0);
                }
            } else {
                return false;
            }
        }

        String port = config.getProperty("proxyPort").trim();

        if (port == null || port.isEmpty()) {
            logger.logLine("error proxy port not set in config file");
            if (manualOperation) {
                String message = "Please enter your proxy port";
                port = Credentials.getInput(message).trim();
                Credentials.saveProperty("proxyPort", port);

                if (port.equals(null)) {
                    System.exit(0);
                }
            } else {
                return false;
            }
        }

        String user = config.getProperty("proxyUser").trim();

        if (user == null || user.isEmpty()) {
            logger.logLine("error proxy username not set in config file");
            if (manualOperation) {
                String message = "Please enter your proxy username";
                user = Credentials.getInput(message).trim();

                if (user.equals(null)) {
                    System.exit(0);
                }

                Credentials.saveProperty("proxyUser", user);
            } else {
                return false;
            }
        }

        String password = config.getProperty("proxyPassword").trim();

        if (password == null || password.isEmpty()) {
            logger.logLine("error proxy password not set in config file");
            if (manualOperation) {
                String message = "Please enter your proxy password";
                password = Credentials.getInput(message).trim();
                Credentials.saveProperty("proxyPassword", password);
                if (password.equals(null)) {
                    System.exit(0);
                }
            } else {
                return false;
            }
        }

        Authenticator.setDefault(new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {

                if (getRequestorType() == RequestorType.PROXY) {
                    String prot = getRequestingProtocol().toLowerCase();
                    String host = System.getProperty(prot + ".proxyHost", config.getProperty("proxyHost"));
                    String port = System.getProperty(prot + ".proxyPort", config.getProperty("proxyPort"));
                    String user = System.getProperty(prot + ".proxyUser", config.getProperty("proxyUser"));
                    String password = System.getProperty(prot + ".proxyPassword",
                            config.getProperty("proxyPassword"));

                    if (getRequestingHost().equalsIgnoreCase(host)) {
                        if (Integer.parseInt(port) == getRequestingPort()) {
                            // Seems to be OK.
                            return new PasswordAuthentication(user, password.toCharArray());
                        }
                    }
                }
                return null;
            }
        });

        System.setProperty("http.proxyPort", port);
        System.setProperty("http.proxyHost", host);
        System.setProperty("http.proxyUser", user);
        System.setProperty("http.proxyPassword", password);

        proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(host, Integer.parseInt(port)));

        //        System.out.println(host+":"+port +" "+ user+":"+password);
        System.out.println("Proxy set");
        return true;
    }
}