synergyj.ListController.java Source code

Java tutorial

Introduction

Here is the source code for synergyj.ListController.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package synergyj;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.io.File;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import nwd.tools.FileSystemHandler;
import org.apache.commons.io.FilenameUtils;

/**
 *
 * @author Brent
 */
class ListController implements IController {

    private final FileSystemHandler fsh = new FileSystemHandler();

    private JTextArea taDetail;
    private JFileChooser dlgFileChooser;

    private final Map<Integer, String> listIdsToNameMap = new HashMap<>();

    //key is for list name
    private final MultiMap<String, ToDoItem> items = new MultiMap<>();

    private final MultiMap<String, ToDoItem> staging = new MultiMap<>();

    private Connection conn = null;
    private PreparedStatement pSt = null;

    //private final File defaultExportDir = 
    //        new File("C:/NWD-SYNC/sandbox/tablet/synergy/");
    private final File defaultImportDir = new File("C:/NWD/synergy/toBeImported/");

    private final List<File> exportDirectories = new ArrayList<>();
    private final List<File> filesForConsumption = new ArrayList<>();

    public ListController() {
        exportDirectories.add(new File("C:/NWD-SYNC/tablet/NWD/synergy/"));
        exportDirectories.add(new File("C:/NWD-SYNC/phone/NWD/synergy/"));
    }

    private String removeTimeStamp(String fileNameWithoutExt) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        sdf.setLenient(false);

        int idx = fileNameWithoutExt.lastIndexOf("-");
        String timestamp = fileNameWithoutExt.substring(idx + 1);

        try {
            //validate date by parsing it
            sdf.parse(timestamp);
            //if parse didn't error, we're good
            fileNameWithoutExt = fileNameWithoutExt.substring(0, idx);

        } catch (ParseException ex) {
            Logger.log(ex.getMessage());
        }

        return fileNameWithoutExt;
    }

    private void importFile(File f) {

        try {

            String listName = FilenameUtils.removeExtension(f.getName());
            listName = removeTimeStamp(listName);

            filesForConsumption.add(f);

            List<String> lines = fsh.getLines(f.getAbsolutePath(), "UTF-8");

            for (String l : lines) {

                String item = l.trim();
                if (item.startsWith("completed={") && item.endsWith("}")) {

                    item = item.replace("completed={", "");
                    item = item.replace("}", "");

                    ToDoItem i = new ToDoItem();
                    i.setText(item);
                    i.setCompleted(true);
                    i.setListName(listName);
                    items.add(listName, i);

                } else {

                    ToDoItem i = new ToDoItem();
                    i.setText(item);
                    i.setCompleted(false);
                    i.setListName(listName);
                    items.add(listName, i);
                }
            }

            displayItemsWithHeader(items, "imported from: " + f.getAbsolutePath());
        } catch (Exception ex) {
            Logger.log(ex.getMessage());
        }
    }

    @Override
    public void performImport() {

        dlgFileChooser.setCurrentDirectory(defaultImportDir);
        dlgFileChooser.setMultiSelectionEnabled(true);

        if (dlgFileChooser.showOpenDialog(null) == javax.swing.JFileChooser.APPROVE_OPTION) {
            //
            //            File f = dlgFileChooser.getSelectedFile();
            //            
            //            importFile(f);

            for (File f : dlgFileChooser.getSelectedFiles()) {
                importFile(f);
            }
        }
    }

    @Override
    public void performExport() {

        String fNames = "";

        for (File exportDir : exportDirectories) {

            for (String listName : staging.keySet()) {

                dlgFileChooser.setCurrentDirectory(exportDir);

                String fName = listName + ".txt";
                dlgFileChooser.setSelectedFile(new File(exportDir, fName));

                if (dlgFileChooser.showOpenDialog(null) == javax.swing.JFileChooser.APPROVE_OPTION) {

                    File f = dlgFileChooser.getSelectedFile();

                    fsh.writeLines(f.getAbsolutePath(), toStringList(staging.get(listName)));

                    //in case a different file name was selected
                    fName = f.getName();

                    if (fNames.length() > 0) {
                        fNames += ", ";
                    }

                    fNames += fName;
                }
            }

        }
        displayItemsWithHeader(staging, "exported to: " + fNames);

    }

    private List<String> toStringList(List<ToDoItem> lst) {

        List<String> strLst = new ArrayList<>();

        for (ToDoItem tdi : lst) {
            strLst.add(tdi.getText());
        }

        return strLst;
    }

    @Override
    public void performExportStaging() {

        staging.clear();

        for (ToDoItem tdi : getPendingItems()) {
            staging.add(tdi.getListName(), tdi);
        }

        displayItemsWithHeader(staging, "staged for export:");
    }

    @Override
    public void initController(JTextArea taDetail, JFileChooser dlgFileChooser) {

        this.taDetail = taDetail;
        this.dlgFileChooser = dlgFileChooser;
    }

    private void displayItemsWithHeader(MultiMap<String, ToDoItem> itemsMap, String itemPathHeader) {

        String output = itemPathHeader;

        for (String listName : itemsMap.keySet()) {

            output += "\n\nListName={" + listName + "}:\n\n";

            for (ToDoItem tdi : itemsMap.get(listName)) {
                output += tdi + "\n";
            }
        }

        taDetail.setText(output);
    }

    @Override
    public void performDbSyncNew() {

        for (ToDoItem tdi : items.getAllValues()) {
            if (!existsInDatabase(tdi)) {
                addToDatabase(tdi);
            }
        }
    }

    private Connection getDbConnection() throws ClassNotFoundException, SQLException {

        // This will load the MySQL driver, each DB has its own driver
        Class.forName("com.mysql.jdbc.Driver");

        // Setup the connection with the DB
        return DriverManager
                .getConnection("jdbc:mysql://localhost/nwd?" + "user=swingaccess&" + "password=vbtjJAmU7QsYMEZH");
    }

    private int getEnsuredIdForListName(String listName) {
        if (getIdForListName(listName) < 0) {
            addListToDatabase(listName);
        }
        return getIdForListName(listName);
    }

    private int getIdForListName(String listName) {

        int id = -1;

        try {
            conn = getDbConnection();

            String stmt = "SELECT ListId, ListName FROM todolists WHERE ListName = ?";
            pSt = conn.prepareStatement(stmt);

            pSt.setString(1, listName);
            ResultSet rs = pSt.executeQuery();

            if (rs.next()) {
                id = rs.getInt("ListId");
            }

        } catch (ClassNotFoundException | SQLException ex) {
            Logger.log(ex.getMessage());
        } finally {
            try {
                if (pSt != null) {
                    pSt.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException ex) {
                Logger.log(ex.getMessage());
            }
        }

        return id;
    }

    private List<String> getIdList(ToDoItem item) {

        List<String> lst = new ArrayList<>();

        try {
            int listId = getEnsuredIdForListName(item.getListName());

            conn = getDbConnection();

            String stmt = "SELECT ToDoItemId FROM todoitems " + "WHERE ToDoItemText = ? " + "AND ListId = ?";
            pSt = conn.prepareStatement(stmt);

            pSt.setString(1, item.getText());
            pSt.setInt(2, listId);
            ResultSet rs = pSt.executeQuery();

            while (rs.next()) {
                lst.add(rs.getString("ToDoItemId"));
            }

        } catch (ClassNotFoundException | SQLException ex) {
            Logger.log(ex.getMessage());
        } finally {
            try {
                if (pSt != null) {
                    pSt.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException ex) {
                Logger.log(ex.getMessage());
            }
        }

        return lst;
    }

    private boolean existsInDatabase(ToDoItem item) {

        try {
            int listId = getEnsuredIdForListName(item.getListName());

            conn = getDbConnection();

            String stmt = "SELECT * FROM todoitems " + "WHERE ToDoItemText = ? " + "AND ListId = ? ";
            pSt = conn.prepareStatement(stmt);

            pSt.setString(1, item.getText());
            pSt.setInt(2, listId);
            ResultSet rs = pSt.executeQuery();

            //per javadoc, returns false if no rows
            if (rs.isBeforeFirst()) {
                Logger.log("ToDoItemText={" + item.getText() + "} ListName={" + item.getListName()
                        + "} found in database.");
            } else {
                Logger.log("ToDoItemText={" + item.getText() + "} ListName={" + item.getListName()
                        + "} not found in database.");
                return false;
            }
        } catch (ClassNotFoundException | SQLException ex) {
            Logger.log(ex.getMessage());
        } finally {
            try {
                if (pSt != null) {
                    pSt.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException ex) {
                Logger.log(ex.getMessage());
            }
        }

        return true;
    }

    private void addListToDatabase(String listName) {

        Logger.log("adding ListName={" + listName + "}");

        try {
            conn = getDbConnection();

            String stmt = "INSERT INTO todolists (ListName) Values (?)";
            pSt = conn.prepareStatement(stmt);

            pSt.setString(1, listName);
            pSt.executeUpdate();

        } catch (ClassNotFoundException | SQLException ex) {
            Logger.log(ex.getMessage());
        } finally {
            try {
                if (pSt != null) {
                    pSt.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException ex) {
                Logger.log(ex.getMessage());
            }
        }
    }

    private void addToDatabase(ToDoItem item) {

        Logger.log("adding ToDoItemText={" + item + "}");

        try {

            int listId = getEnsuredIdForListName(item.getListName());

            conn = getDbConnection();

            String stmt = "INSERT INTO todoitems (ToDoItemText, ListId) " + "VALUES (?, ?)";
            pSt = conn.prepareStatement(stmt);

            pSt.setString(1, item.getText());
            pSt.setInt(2, listId);
            pSt.executeUpdate();

        } catch (ClassNotFoundException | SQLException ex) {
            Logger.log(ex.getMessage());
        } finally {
            try {
                if (pSt != null) {
                    pSt.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException ex) {
                Logger.log(ex.getMessage());
            }
        }
    }

    @Override
    public void performDbSyncCompleted() {

        for (ToDoItem item : items.getAllValues()) {

            if (item.isCompleted()) {

                List<String> lst = getIdList(item);
                if (lst.isEmpty()) {
                    Logger.log("ToDoItemText={" + item + "} not found in db");
                } else if (lst.size() > 1) {
                    Logger.log("completion request ambiguous for " + "ToDoItemText={" + item + "}, "
                            + "too many rows");
                } else if (lst.size() == 1) {
                    markCompleted(lst.get(0));
                }
            }
        }
    }

    void markCompleted(String toDoItemId) {

        Logger.log("completing item with ToDoItemId={" + toDoItemId + "}");

        try {
            conn = getDbConnection();

            String stmt = "UPDATE todoitems " + "SET ToDoItemCompleted = 1 " + "WHERE ToDoItemId = ?";
            pSt = conn.prepareStatement(stmt);

            pSt.setString(1, toDoItemId);
            pSt.executeUpdate();

        } catch (ClassNotFoundException | SQLException ex) {
            Logger.log(ex.getMessage());
        } finally {
            try {
                if (pSt != null) {
                    pSt.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException ex) {
                Logger.log(ex.getMessage());
            }
        }
    }

    private void refreshListIdsToNameMap() {

        listIdsToNameMap.clear();

        try {
            conn = getDbConnection();

            String stmt = "SELECT ListId, ListName " + "FROM todolists";
            pSt = conn.prepareStatement(stmt);

            ResultSet rs = pSt.executeQuery();

            while (rs.next()) {

                listIdsToNameMap.put(rs.getInt("ListId"), rs.getString("ListName"));
            }

        } catch (ClassNotFoundException | SQLException ex) {
            Logger.log(ex.getMessage());
        } finally {
            try {
                if (pSt != null) {
                    pSt.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException ex) {
                Logger.log(ex.getMessage());
            }
        }

    }

    List<ToDoItem> getPendingItems() {

        List<ToDoItem> lst = new ArrayList<>();

        try {
            refreshListIdsToNameMap();

            conn = getDbConnection();

            String stmt = "SELECT ToDoItemText, ListId " + "FROM todoitems " + "WHERE ToDoItemCompleted = 0";
            pSt = conn.prepareStatement(stmt);

            ResultSet rs = pSt.executeQuery();

            while (rs.next()) {
                ToDoItem tdi = new ToDoItem();
                tdi.setText(rs.getString("ToDoItemText"));
                tdi.setCompleted(false);
                tdi.setListName(listIdsToNameMap.get(rs.getInt("ListId")));
                lst.add(tdi);
            }

        } catch (ClassNotFoundException | SQLException ex) {
            Logger.log(ex.getMessage());
        } finally {
            try {
                if (pSt != null) {
                    pSt.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException ex) {
                Logger.log(ex.getMessage());
            }
        }

        return lst;
    }

    @Override
    public void consume() {

        String filesList = "";

        for (File f : filesForConsumption) {

            f.delete();

            if (filesList.length() > 0) {
                filesList += ", ";
            }

            filesList += f.getName();
        }

        taDetail.setText("consumed: " + filesList);

        filesForConsumption.clear();
    }

}