This is an automated email from the git hooks/post-receive script. New commit to branch 1.6-database-h2 in repository jtimer. See https://gitlab.nuiton.org/chorem/jtimer.git commit 1ba22e309cf05fde30e6139f13115301aeb3b552 Author: Eric Chatellier <chatellier@codelutin.com> Date: Fri Jun 1 17:19:54 2018 +0200 refs #142: Resolve all compile errors --- pom.xml | 18 +- src/main/java/org/chorem/jtimer/JTimer.java | 96 +-- .../org/chorem/jtimer/core/ApplicationContext.java | 18 +- .../java/org/chorem/jtimer/core/Configuration.java | 2 + src/main/java/org/chorem/jtimer/core/Context.java | 41 ++ src/main/java/org/chorem/jtimer/db/Database.java | 11 +- .../java/org/chorem/jtimer/db/DbDataMigration.java | 11 +- src/main/java/org/chorem/jtimer/db/DbManager.java | 3 +- .../chorem/jtimer/entities/TimerTaskHelper.java | 2 + .../java/org/chorem/jtimer/io/AbstractSaver.java | 6 +- .../java/org/chorem/jtimer/io/BackupUtils.java | 113 --- .../org/chorem/jtimer/io/DataLockingException.java | 58 -- .../chorem/jtimer/io/GTimerIncrementalSaver.java | 768 +-------------------- .../java/org/chorem/jtimer/io/GTimerTimeUtil.java | 2 +- src/main/java/org/chorem/jtimer/io/Saver.java | 25 +- .../jtimer/{entities => io}/TimerProject.java | 4 +- .../java/org/chorem/jtimer/io/package-info.java | 2 +- .../org/chorem/jtimer/services/AlertService.java | 13 +- .../chorem/jtimer/services/ContextableService.java | 17 + .../org/chorem/jtimer/services/ReportService.java | 8 +- .../org/chorem/jtimer/services/TaskService.java | 65 +- .../org/chorem/jtimer/services/TimeService.java | 14 +- .../java/org/chorem/jtimer/ui/NewTaskView.java | 8 +- .../java/org/chorem/jtimer/ui/TimerTaskEditor.java | 43 +- .../org/chorem/jtimer/ui/alert/AlertEditor.java | 3 +- .../chorem/jtimer/ui/report/ReportGenerator.java | 2 +- .../org/chorem/jtimer/ui/report/ReportView.java | 3 +- .../chorem/jtimer/ui/systray/SystrayManager.java | 1 - .../org/chorem/jtimer/ui/tasks/IdleDialog.java | 2 +- .../chorem/jtimer/ui/tasks/RefreshTreeTask.java | 2 +- .../org/chorem/jtimer/ui/tasks/RunTaskJob.java | 7 +- .../org/chorem/jtimer/ui/tree/TaskTreeModel.java | 1 - .../jtimer/ui/treetable/ProjectsAndTasksModel.java | 6 +- .../jtimer/ui/treetable/ProjectsAndTasksTable.java | 5 +- .../ui/treetable/dnd/TimerTaskTransferHandler.java | 17 +- src/main/resources/log4j2.xml | 38 - src/main/resources/logback.xml | 16 + 37 files changed, 266 insertions(+), 1185 deletions(-) diff --git a/pom.xml b/pom.xml index 718cd0c..ee1c8ec 100644 --- a/pom.xml +++ b/pom.xml @@ -175,10 +175,21 @@ <artifactId>slf4j-api</artifactId> <version>1.8.0-beta2</version> </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + <version>1.8.0-beta2</version> + </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.3.0-alpha4</version> + <exclusions> + <exclusion> + <groupId>com.sun.mail</groupId> + <artifactId>javax.mail</artifactId> + </exclusion> + </exclusions> </dependency> <dependency> <groupId>org.freemarker</groupId> @@ -200,11 +211,6 @@ <artifactId>commons-lang3</artifactId> <version>3.7</version> </dependency> - <dependency> - <groupId>commons-logging</groupId> - <artifactId>commons-logging</artifactId> - <version>1.2</version> - </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> @@ -336,7 +342,7 @@ <plugin> <groupId>com.akathist.maven.plugins.launch4j</groupId> <artifactId>launch4j-maven-plugin</artifactId> - <version>1.7.21</version> + <version>1.7.22</version> <executions> <execution> <id>launch4j</id> diff --git a/src/main/java/org/chorem/jtimer/JTimer.java b/src/main/java/org/chorem/jtimer/JTimer.java index f4283f5..957f419 100644 --- a/src/main/java/org/chorem/jtimer/JTimer.java +++ b/src/main/java/org/chorem/jtimer/JTimer.java @@ -25,7 +25,7 @@ package org.chorem.jtimer; import org.apache.commons.lang3.StringUtils; import org.chorem.jtimer.core.ApplicationContext; import org.chorem.jtimer.core.Context; -import org.chorem.jtimer.entities.TimerProject; +import org.chorem.jtimer.io.TimerProject; import org.chorem.jtimer.entities.TimerTask; import org.chorem.jtimer.system.SystemInfo; import org.chorem.jtimer.system.SystemInfoFactory; @@ -528,16 +528,12 @@ public class JTimer extends SingleFrameApplication implements TreeSelectionListe // remove unneeded spaces projectName = projectName.trim(); - TimerProject p = new TimerProject(projectName); + TimerTask p = new TimerTask(projectName); // add creation date p.setCreationDate(new Date()); - try { - core.getData().addProject(p); - } catch (DataViolationException e) { - displayErrorMessage(e.getExceptionKey()); - } + context.getTaskService().createProject(p); } } @@ -560,11 +556,7 @@ public class JTimer extends SingleFrameApplication implements TreeSelectionListe // remove unneeded spaces newProjectName = newProjectName.trim(); - try { - core.getData().editProject(project, newProjectName); - } catch (DataViolationException e) { - displayErrorMessage(e.getExceptionKey()); - } + context.getTaskService().editProject(project, newProjectName); } } @@ -622,29 +614,11 @@ public class JTimer extends SingleFrameApplication implements TreeSelectionListe TimerTask task = projectsAndTasksTable.getSelectedTasks().get(0); RunTaskJob jobToRun = new RunTaskJob(this, task, context); - core.getData().startTask(task); + context.getTaskService().startTask(task); return jobToRun; } - /** - * Start task pointed by taskPath. - * - * @param taskPath task path to start (from root to task) - */ - public void startTask(String taskPath) { - TimerTask task = core.getData().getTaskForPath(taskPath); - if (task != null) { - RunTaskJob jobToRun = new RunTaskJob(this, task, core.getData()); - getContext().getTaskService().execute(jobToRun); - core.getData().startTask(task); - } else { - if (log.isWarnEnabled()) { - log.warn("Can't find task '" + taskPath + "'"); - } - } - } - /** * Called by task job manager when task as been started. * @@ -703,7 +677,7 @@ public class JTimer extends SingleFrameApplication implements TreeSelectionListe // test if task is already running if (rtt != null) { rtt.wantToStop(); - core.getData().stopTask(task); + context.getTaskService().stopTask(task); // re-enable/disable buttons setSelectedSingleRunningTask(false); @@ -731,7 +705,7 @@ public class JTimer extends SingleFrameApplication implements TreeSelectionListe public void closeProject() { TimerProject project = projectsAndTasksTable.getSelectedProjects().get(0); - core.getData().changeProjectCloseState(project); + context.getTaskService().closeProject(project); } /** @@ -741,7 +715,7 @@ public class JTimer extends SingleFrameApplication implements TreeSelectionListe public void closeTask() { TimerTask task = projectsAndTasksTable.getSelectedTasks().get(0); - core.getData().changeTaskCloseState(task); + context.getTaskService().closeTask(task); } /** @@ -768,11 +742,7 @@ public class JTimer extends SingleFrameApplication implements TreeSelectionListe if (confirm == JOptionPane.YES_OPTION) { // approved for (TimerProject project : projects) { - try { - core.getData().deleteProject(project); - } catch (DataViolationException e) { - displayErrorMessage(e.getExceptionKey()); - } + context.getTaskService().deleteProject(project); } } @@ -802,12 +772,8 @@ public class JTimer extends SingleFrameApplication implements TreeSelectionListe if (confirm == JOptionPane.YES_OPTION) { // approved for (TimerTask task : tasks) { - try { - stopTask(task); - core.getData().deleteTask(task); - } catch (DataViolationException e) { - displayErrorMessage(e.getExceptionKey()); - } + stopTask(task); + context.getTaskService().deleteTask(task); } } } @@ -822,7 +788,7 @@ public class JTimer extends SingleFrameApplication implements TreeSelectionListe JCheckBoxMenuItem source = (JCheckBoxMenuItem) event.getSource(); boolean showClosed = source.isSelected(); projectsAndTasksTable.setShowClosed(showClosed); - config.setShowClosed(showClosed); + context.getConfig().setShowClosed(showClosed); } /** @@ -834,7 +800,7 @@ public class JTimer extends SingleFrameApplication implements TreeSelectionListe public void isCloseToSystray(ActionEvent event) { JCheckBoxMenuItem source = (JCheckBoxMenuItem) event.getSource(); boolean closeToSystray = source.isSelected(); - config.setCloseToSystray(closeToSystray); + context.getConfig().setCloseToSystray(closeToSystray); } /** @@ -949,8 +915,7 @@ public class JTimer extends SingleFrameApplication implements TreeSelectionListe * @param increment increment in ms */ protected void incrementTaskTime(long increment) { - TimerTask selectedTask = projectsAndTasksTable.getSelectedTasks() - .get(0); + TimerTask selectedTask = projectsAndTasksTable.getSelectedTasks().get(0); // task is not running Date now = new Date(); @@ -958,17 +923,12 @@ public class JTimer extends SingleFrameApplication implements TreeSelectionListe long newTodayTime = todayTime + increment; - try { - // check if + negative increment still positive - if (newTodayTime > 0) { - core.getData().changeTaskTime(selectedTask, now, - newTodayTime); - } else { - // force to 0 - core.getData().changeTaskTime(selectedTask, now, 0L); - } - } catch (DataViolationException e) { - displayErrorMessage(e.getExceptionKey()); + // check if + negative increment still positive + if (newTodayTime > 0) { + context.getTimeService().changeTaskTime(selectedTask, now, newTodayTime); + } else { + // force to 0 + context.getTimeService().changeTaskTime(selectedTask, now, 0L); } } @@ -994,11 +954,7 @@ public class JTimer extends SingleFrameApplication implements TreeSelectionListe resourceMap.getString("input.mergeTaskMessage", tasks.size(), destinationTask.getName()), resourceMap.getString("input.mergeTaskTitle"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (confirm == JOptionPane.YES_OPTION) { - try { - core.getData().mergeTasks(destinationTask, otherTasks); - } catch (DataViolationException e) { - displayErrorMessage(e.getExceptionKey()); - } + context.getTaskService().mergeTasks(destinationTask, otherTasks); } } @@ -1008,8 +964,7 @@ public class JTimer extends SingleFrameApplication implements TreeSelectionListe @Action(enabledProperty = "selectedSingleTask") public void addAnnotation() { // select task to add new annotation - TimerTask selectedTask = projectsAndTasksTable.getSelectedTasks() - .get(0); + TimerTask selectedTask = projectsAndTasksTable.getSelectedTasks().get(0); String annotation = JOptionPane.showInputDialog(getMainFrame(), resourceMap.getString("input.addAnnotationMessage", @@ -1021,12 +976,7 @@ public class JTimer extends SingleFrameApplication implements TreeSelectionListe // remove useless spaces annotation = annotation.trim(); - try { - core.getData().addAnnotation(selectedTask, new Date(), - annotation); - } catch (DataViolationException e) { - displayErrorMessage(e.getExceptionKey()); - } + context.getTaskService().addAnnotation(selectedTask, new Date(), annotation); } } diff --git a/src/main/java/org/chorem/jtimer/core/ApplicationContext.java b/src/main/java/org/chorem/jtimer/core/ApplicationContext.java index 89784d4..31ec9cf 100644 --- a/src/main/java/org/chorem/jtimer/core/ApplicationContext.java +++ b/src/main/java/org/chorem/jtimer/core/ApplicationContext.java @@ -44,14 +44,6 @@ public class ApplicationContext { protected DbManager dbManager; - protected ReportService reportService; - - protected TaskService taskService; - - protected TimeService timeService; - - protected AlertService alertService; - public Configuration getConfig() { return config; } @@ -60,7 +52,6 @@ public class ApplicationContext { loadConfiguration(args); migratePre15Directories(); initDatabase(); - initServices(); } /** @@ -131,14 +122,11 @@ public class ApplicationContext { dbManager = new DbManager(database); DbMigration dbMigration = new DbMigration(database); dbMigration.init(); - DbDataMigration dbDataMigration = new DbDataMigration(dbManager); + DbDataMigration dbDataMigration = new DbDataMigration(dbManager, config); dbDataMigration.init(); } - protected void initServices() { - alertService = new AlertService(); - taskService = new TaskService(); - reportService = new ReportService(); - timeService = new TimeService(); + public DbManager getDbManager() { + return dbManager; } } diff --git a/src/main/java/org/chorem/jtimer/core/Configuration.java b/src/main/java/org/chorem/jtimer/core/Configuration.java index 016fbcd..2c6383b 100644 --- a/src/main/java/org/chorem/jtimer/core/Configuration.java +++ b/src/main/java/org/chorem/jtimer/core/Configuration.java @@ -119,7 +119,9 @@ public class Configuration { * * @since 1.5 * @return jtimer 1.5 data directory + * @deprecated old plain file data directory before database */ + @Deprecated public File getDataDirectory() { return appConfig.getOptionAsFile(JTimerOption.DATA_DIRECTORY.key); } diff --git a/src/main/java/org/chorem/jtimer/core/Context.java b/src/main/java/org/chorem/jtimer/core/Context.java index 2631ec5..3234f90 100644 --- a/src/main/java/org/chorem/jtimer/core/Context.java +++ b/src/main/java/org/chorem/jtimer/core/Context.java @@ -21,10 +21,23 @@ */ package org.chorem.jtimer.core; +import org.chorem.jtimer.services.AlertService; +import org.chorem.jtimer.services.ReportService; +import org.chorem.jtimer.services.TaskService; +import org.chorem.jtimer.services.TimeService; + public class Context { protected ApplicationContext applicationContext; + protected ReportService reportService; + + protected TaskService taskService; + + protected TimeService timeService; + + protected AlertService alertService; + public Context(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } @@ -40,4 +53,32 @@ public class Context { public boolean exit() { return false; } + + public TaskService getTaskService() { + if (taskService == null) { + taskService = new TaskService(applicationContext.getDbManager(), this); + } + return taskService; + } + + public TimeService getTimeService() { + if (timeService == null) { + timeService = new TimeService(applicationContext.getDbManager(), this); + } + return timeService; + } + + public ReportService getReportService() { + if (reportService == null) { + reportService = new ReportService(applicationContext.getDbManager(), this); + } + return reportService; + } + + public AlertService getAlertService() { + if (alertService == null) { + alertService = new AlertService(applicationContext.getDbManager(), this); + } + return alertService; + } } diff --git a/src/main/java/org/chorem/jtimer/db/Database.java b/src/main/java/org/chorem/jtimer/db/Database.java index 243f829..b8f4f1f 100644 --- a/src/main/java/org/chorem/jtimer/db/Database.java +++ b/src/main/java/org/chorem/jtimer/db/Database.java @@ -30,14 +30,11 @@ import java.sql.SQLException; public class Database { protected String connectionUrl; - protected String connectionUsername; - protected String connectionPassword; + protected String connectionUsername = "sa"; + protected String connectionPassword = ""; - public Database(Configuration config) { - - connectionUrl = String.format("jdbc:h2:%s/jtimer", config.getDatabaseDirectory()); - connectionUsername = "sa"; - connectionPassword = ""; + public Database(Configuration configuration) { + connectionUrl = String.format("jdbc:h2:%s/jtimer", configuration.getDatabaseDirectory()); try { Class.forName("org.h2.Driver"); diff --git a/src/main/java/org/chorem/jtimer/db/DbDataMigration.java b/src/main/java/org/chorem/jtimer/db/DbDataMigration.java index fe055c1..f5992cd 100644 --- a/src/main/java/org/chorem/jtimer/db/DbDataMigration.java +++ b/src/main/java/org/chorem/jtimer/db/DbDataMigration.java @@ -21,9 +21,10 @@ */ package org.chorem.jtimer.db; -import org.chorem.jtimer.JTimerFactory; -import org.chorem.jtimer.entities.TimerProject; +import org.chorem.jtimer.core.Configuration; +import org.chorem.jtimer.io.TimerProject; import org.chorem.jtimer.entities.TimerTask; +import org.chorem.jtimer.io.GTimerIncrementalSaver; import org.chorem.jtimer.io.Saver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,9 +36,11 @@ public class DbDataMigration { private static Logger logger = LoggerFactory.getLogger(DbDataMigration.class); protected DbManager dbm; + protected Configuration config; - public DbDataMigration(DbManager dbm) { + public DbDataMigration(DbManager dbm, Configuration config) { this.dbm = dbm; + this.config = config; } public void init() { @@ -49,7 +52,7 @@ public class DbDataMigration { protected void performDataMigration() { logger.info("Performing data migration"); - Saver fileSaver = JTimerFactory.getFileSaver(); + Saver fileSaver = new GTimerIncrementalSaver(config); Collection<TimerProject> projects = fileSaver.load(); projects.forEach(this::migrateTask); } diff --git a/src/main/java/org/chorem/jtimer/db/DbManager.java b/src/main/java/org/chorem/jtimer/db/DbManager.java index 5b49671..7a4d9e5 100644 --- a/src/main/java/org/chorem/jtimer/db/DbManager.java +++ b/src/main/java/org/chorem/jtimer/db/DbManager.java @@ -24,7 +24,7 @@ package org.chorem.jtimer.db; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.chorem.jtimer.JTimerUtils; -import org.chorem.jtimer.entities.TimerProject; +import org.chorem.jtimer.io.TimerProject; import org.chorem.jtimer.entities.TimerTask; import java.sql.Connection; @@ -32,7 +32,6 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; -import java.sql.Types; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; diff --git a/src/main/java/org/chorem/jtimer/entities/TimerTaskHelper.java b/src/main/java/org/chorem/jtimer/entities/TimerTaskHelper.java index d782c1a..b2deaec 100644 --- a/src/main/java/org/chorem/jtimer/entities/TimerTaskHelper.java +++ b/src/main/java/org/chorem/jtimer/entities/TimerTaskHelper.java @@ -22,6 +22,8 @@ package org.chorem.jtimer.entities; +import org.chorem.jtimer.io.TimerProject; + import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; diff --git a/src/main/java/org/chorem/jtimer/io/AbstractSaver.java b/src/main/java/org/chorem/jtimer/io/AbstractSaver.java index e1a7c9b..0f140a3 100644 --- a/src/main/java/org/chorem/jtimer/io/AbstractSaver.java +++ b/src/main/java/org/chorem/jtimer/io/AbstractSaver.java @@ -2,7 +2,7 @@ * #%L * jTimer * %% - * Copyright (C) 2009 - 2016 CodeLutin + * Copyright (C) 2009 - 2018 CodeLutin * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as @@ -22,8 +22,6 @@ package org.chorem.jtimer.io; -import java.util.TimerTask; - /** * Abstract saver class. * @@ -35,6 +33,6 @@ import java.util.TimerTask; * Last update : $Date$ * By : $Author$ */ -public abstract class AbstractSaver extends TimerTask implements Saver { +public abstract class AbstractSaver implements Saver { } diff --git a/src/main/java/org/chorem/jtimer/io/BackupUtils.java b/src/main/java/org/chorem/jtimer/io/BackupUtils.java deleted file mode 100644 index 1f65181..0000000 --- a/src/main/java/org/chorem/jtimer/io/BackupUtils.java +++ /dev/null @@ -1,113 +0,0 @@ -/*- - * #%L - * jTimer - * %% - * Copyright (C) 2007 - 2016 CodeLutin - * %% - * 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/gpl-3.0.html>. - * #L% - */ -package org.chorem.jtimer.io; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.StandardCopyOption; - -/** - * Saver with backup support. - */ -public class BackupUtils { - - /** log. */ - private static Log log = LogFactory.getLog(BackupUtils.class); - - /** Backup file extension. */ - public static final String BACKUP_EXTENSION = ".tmp"; - - /** - * Make to backup of file if exists. - * <p> - * Copy file to filename + ".tmp" - * - * @param file file to backup - * @return backup file or {@code null} if input file doesn't exist - * @throws IOException - */ - public static File makeBackupFile(File file) throws IOException { - - // if not exist, don't do anything - if (!file.exists()) { - return null; - } - - File backupFile = new File(file.getAbsoluteFile() + BACKUP_EXTENSION); - - if (log.isDebugEnabled()) { - log.debug("Backuping file " + file.getName() + " to " + backupFile.getName()); - } - - backupFile.delete(); - FileUtils.copyFile(file, backupFile); - return backupFile; - } - - /** - * Rename backup file to original file name; - * - * @param backupFile backup file - * @return if backup file has been restored - */ - public static boolean restoreBackupFile(File backupFile) { - - String fileName = backupFile.getAbsolutePath(); - if (!fileName.endsWith(BACKUP_EXTENSION)) { - throw new IllegalArgumentException("Not a valid backup file" + backupFile); - } - - fileName = fileName.substring(0, fileName.length() - BACKUP_EXTENSION.length()); - File file = new File(fileName); - - if (log.isDebugEnabled()) { - log.debug("Renaming " + backupFile.getName() + " to " + file.getName()); - } - - boolean done; - try { - Files.move(backupFile.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING); - done = true; - } catch (IOException ex) { - done = false; - } - return done; - } - - /** - * Delete backup file. - * <p> - * This function NEVER throw IOException. - * - * @param backupFile backup file (can be {@code null}) - */ - public static void deleteBackupFile(File backupFile) { - if (backupFile != null) { - backupFile.delete(); - } - } -} diff --git a/src/main/java/org/chorem/jtimer/io/DataLockingException.java b/src/main/java/org/chorem/jtimer/io/DataLockingException.java deleted file mode 100644 index 0b158a4..0000000 --- a/src/main/java/org/chorem/jtimer/io/DataLockingException.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * #%L - * jTimer - * %% - * Copyright (C) 2008 - 2011 CodeLutin - * %% - * 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/gpl-3.0.html>. - * #L% - */ - -package org.chorem.jtimer.io; - -/** - * Exception thrown when saver directory has already been locked. - * - * @author chatellier - * @version $Revision$ - * - * Last update : $Date$ - * By : $Author$ - */ -public class DataLockingException extends Exception { - - /** serialVersionUID */ - private static final long serialVersionUID = 3535577909976711886L; - - /** - * Constructor with text message. - * - * @param message text message - */ - public DataLockingException(String message) { - super(message); - } - - /** - * Constructor with text message and cause. - * - * @param message text message - * @param cause parent cause - */ - public DataLockingException(String message, Throwable cause) { - super(message, cause); - } - -} diff --git a/src/main/java/org/chorem/jtimer/io/GTimerIncrementalSaver.java b/src/main/java/org/chorem/jtimer/io/GTimerIncrementalSaver.java index 4c545a8..f666c96 100644 --- a/src/main/java/org/chorem/jtimer/io/GTimerIncrementalSaver.java +++ b/src/main/java/org/chorem/jtimer/io/GTimerIncrementalSaver.java @@ -24,50 +24,27 @@ package org.chorem.jtimer.io; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.chorem.jtimer.JTimer; +import org.chorem.jtimer.core.Configuration; import org.chorem.jtimer.entities.TimerAlert; -import org.chorem.jtimer.entities.TimerAlert.Type; -import org.chorem.jtimer.entities.TimerProject; import org.chorem.jtimer.entities.TimerTask; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStreamWriter; -import java.io.RandomAccessFile; -import java.io.Writer; -import java.nio.channels.FileChannel; -import java.nio.channels.FileLock; -import java.nio.file.DirectoryIteratorException; -import java.nio.file.DirectoryStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.Date; import java.util.HashMap; -import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.Properties; import java.util.SortedMap; -import java.util.Timer; import java.util.TreeMap; import java.util.regex.Matcher; import java.util.regex.Pattern; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; /** * Charge et sauve les fichiers au format gTimer. @@ -123,46 +100,13 @@ public class GTimerIncrementalSaver extends AbstractSaver implements Saver { */ protected File dataSaveDirectory; - /** Resource used by lock. */ - protected FileLock lock; - - /** Resource used by lock. */ - protected RandomAccessFile raf; - - /** Resource used by lock. */ - protected FileChannel channel; - - /** Timer used for autosave. */ - protected Timer autoSaveTimer; - - /** - * Auto save delay. (default value is 5min) - */ - protected long autoSaveDelay = 1000 * 60 * 5; // 5 min - - /** Running task list. */ - protected final Collection<TimerTask> runningTasks; - /** * Constructor. */ - public GTimerIncrementalSaver() { - - dataSaveDirectory = JTimer.config.getDataDirectory(); + public GTimerIncrementalSaver(Configuration config) { - // make implementation synchronized - runningTasks = Collections.synchronizedCollection(new ArrayList<>()); + dataSaveDirectory = config.getDataDirectory(); - autoSaveTimer = new Timer(); - } - - @Override - public void setAutoSaveDelay(long autoSaveDelay) { - - // autoSaveDelay is in ms - if (autoSaveDelay > 0) { - this.autoSaveDelay = autoSaveDelay; - } } /** @@ -175,73 +119,6 @@ public class GTimerIncrementalSaver extends AbstractSaver implements Saver { } } - @Override - public void lock() throws DataLockingException { - - try { - // be sure that directory exists - checkSaveDirectory(); - - // try to get lock - raf = new RandomAccessFile(dataSaveDirectory + File.separator - + LOCK_FILE_NAME, "rw"); - - channel = raf.getChannel(); - - // lock request - // use tryLock, lock() is blocking - lock = channel.tryLock(); - - // can't get lock - if (lock == null) { - throw new DataLockingException("Cannot get lock"); - } - - // clear task list - runningTasks.clear(); - - // start timer - // FIXME doesn't work if lock() is called twice - autoSaveTimer.schedule(this, autoSaveDelay, autoSaveDelay); - } catch (IOException e) { - if (log.isErrorEnabled()) { - log.error("Cannot get lock", e); - } - throw new DataLockingException("Cannot get lock", e); - } - } - - @Override - public void unlock() throws DataLockingException { - - if (lock != null) { - try { - // release lock - lock.release(); - - // cancel timer - cancel(); - autoSaveTimer.purge(); - autoSaveTimer.cancel(); - - // save running tasks - //saveRunningTasks(); - - // clear task list - runningTasks.clear(); - - // release resources - channel.close(); - raf.close(); - } catch (IOException e) { - if (log.isErrorEnabled()) { - log.error("Cannot release lock", e); - } - throw new DataLockingException("Cannot release lock", e); - } - } - } - @Override public Collection<TimerProject> load() { @@ -361,11 +238,6 @@ public class GTimerIncrementalSaver extends AbstractSaver implements Saver { // post process tasks parseTaskFromSavedMap(taskToPostManaged); - // manage backup - if (backupGTimerFiles()) { - cleanBackupFiles(); - } - // collection to return Collection<TimerProject> projects = mapNumberProject.values(); @@ -723,109 +595,6 @@ public class GTimerIncrementalSaver extends AbstractSaver implements Saver { return result; } - /** - * For development. - * - * Save gtimer files (because project collection is sometimes erased) - * - * @return success flag fro creating backup - */ - protected boolean backupGTimerFiles() { - - boolean result = false; - - // build date string format = YYYYMMDDHHMMSS - DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); - String nowString = dateFormat.format(new Date()); - - // backup directory - String backupDir = JTimer.config.getBackupDirectory().getAbsolutePath(); - - // build file name - String zipFileName = backupDir + File.separator + "backup-" + nowString - + ".zip"; - - // log - if (log.isDebugEnabled()) { - log.debug("Creating backup archive : " + zipFileName); - } - - // create dir if not exists - File backupDirFile = new File(backupDir); - if (!backupDirFile.exists()) { - backupDirFile.mkdirs(); - } - - // - try (ZipOutputStream outZip = new ZipOutputStream(new FileOutputStream(zipFileName))) { - - // Create a buffer for reading the files - byte[] buffer = new byte[1024]; - - // add in this archive only gtimer files - File[] filesInIt = dataSaveDirectory.listFiles(); - - for (File fileInIt : filesInIt) { - String filename = fileInIt.getName(); - if (isGTimerFile(filename)) { - - try (FileInputStream inFileStream = new FileInputStream(fileInIt)) { - outZip.putNextEntry(new ZipEntry(filename)); - - // Transfer bytes from the file to the ZIP file - int len; - while ((len = inFileStream.read(buffer)) > 0) { - outZip.write(buffer, 0, len); - } - - // Complete the entry - outZip.closeEntry(); - } - } - } - - result = true; - - } catch (IOException e) { - if (log.isErrorEnabled()) { - log.error("Can't create archive", e); - } - } - - return result; - } - - /** - * Clean backup files older than one week. - */ - protected void cleanBackupFiles() { - - // compute date from one week ago - LocalDateTime oneWeekAgo = LocalDateTime.now().minusWeeks(2); - String oneWeekString = oneWeekAgo.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); - Pattern pattern = Pattern.compile("backup-(\\d{14})\\.zip"); - - // collect each file in backup dir - Path backupDir = JTimer.config.getBackupDirectory().toPath(); - try (DirectoryStream<Path> stream = Files.newDirectoryStream(backupDir, "backup-*.zip")) { - for (Path file : stream) { - String name = file.getFileName().toString(); - Matcher m = pattern.matcher(name); - m.matches(); - String backupDate = m.group(1); - - // delete all files older than two weeks - if (backupDate.compareTo(oneWeekString) < 0) { - Files.delete(file); - } - } - } catch (DirectoryIteratorException | IOException ex) { - if (log.isErrorEnabled()) { - log.error("Can't create backup", ex); - } - } - } - /** * Check if a file denoted by his name is a gtimer file. * @@ -846,535 +615,4 @@ public class GTimerIncrementalSaver extends AbstractSaver implements Saver { return result; } - - /** - * Save a unique project. - * - * @param project project to save - */ - protected void saveProject(TimerProject project) { - - if (log.isDebugEnabled()) { - log.debug("Save project : " + project.getName()); - } - - // build full file name - String filename = dataSaveDirectory + File.separator + project.getNumber() - + "." + GTIMER_PROJECT_EXTENSION; - - if (log.isDebugEnabled()) { - log.debug("Save project in " + filename); - } - - File backupfile = null; - File projectfile = new File(filename); - - // encode it to iso-8859-1, because props.load() use this encoding - try (Writer out = new OutputStreamWriter(new FileOutputStream(projectfile), "ISO-8859-1")) { - - // first try to make backup - backupfile = BackupUtils.makeBackupFile(projectfile); - - // get creation date - long mscreatedtime = project.getCreationDate().getTime(); - String createdTime = String.valueOf(mscreatedtime / 1000); - - // file content - out.write("Format: " + GTIMER_FILE_VERSION + "\n"); - out.write("Name: " + project.getName() + "\n"); - out.write("Created: " + createdTime + "\n"); - out.write("Options: " + (project.isClosed() ? "1" : "0") + "\n"); - - BackupUtils.deleteBackupFile(backupfile); - } catch (IOException e) { - if (log.isDebugEnabled()) { - log.error("Can't save project information, restore backup file", e); - } - - // can be null if backup throw the exception - if (backupfile != null) { - BackupUtils.restoreBackupFile(backupfile); - } - } - } - - /** - * Save task, found correct prefix, and project. - * - * Then call {@link #saveTask(TimerTask, int, String)} - * - * @param task task to save - */ - protected void saveTask(TimerTask task) { - - // Try to find project - // And prefix - String taskPrefixName = ""; - - TimerTask currentTask = task; - while (currentTask.getParent() != null) { - currentTask = currentTask.getParent(); - if (currentTask.getParent() != null) { - // currentTask is styll a task - taskPrefixName = currentTask.getName() - + GTIMER_SUBTASK_SEPARATOR + taskPrefixName; - } - } - int associatedToProject = currentTask.getNumber(); - - // then save task - saveTask(task, associatedToProject, taskPrefixName); - } - - /** - * Save a task. - * - * taskPrefixName represents the task prefix is case, it is represented in - * jTimer as a subtask. It is saved in gTimer format in a new task, which - * name is composed of parents task name. - * - * @param task task to save - * @param associatedToProject associated project number - * @param taskPrefixName task prefix name - */ - protected void saveTask(TimerTask task, int associatedToProject, String taskPrefixName) { - - // check project number - if (associatedToProject < 0) { - throw new IllegalArgumentException( - "Task project number is invalid : " + associatedToProject); - } - - // check prefix - if (taskPrefixName == null) { - throw new IllegalArgumentException("Task prefix is null"); - } - - if (log.isDebugEnabled()) { - log.debug("Save task : " + task.getName()); - } - - // build full file name - String filename = dataSaveDirectory + File.separator + task.getNumber() - + "." + GTIMER_TASK_EXTENSION; - - if (log.isDebugEnabled()) { - log.debug("Save task in " + filename); - } - - File backupfile = null; - File taskfile = new File(filename); - - // encode it to iso-8859-1, because props.load() use this encoding - try (Writer out = new OutputStreamWriter(new FileOutputStream(taskfile), "ISO-8859-1")) { - - // first make backup - backupfile = BackupUtils.makeBackupFile(taskfile); - - // Format: 1.2 - // Name: Test Tache 1.2 - // Created: 1180944724 - // Options: 0 - // Project: 0 - // Data: - // 20070603 750 - // 20070604 366 - - // get creation date - long mscreatedtime = task.getCreationDate().getTime(); - String createdTime = String.valueOf(mscreatedtime / 1000); - - // file content - out.write("Format: " + GTIMER_FILE_VERSION + "\n"); - out.write("Name: " + taskPrefixName + task.getName() + "\n"); - out.write("Created: " + createdTime + "\n"); - out.write("Options: " + (task.isClosed() ? "1" : "0") + "\n"); - out.write("Project: " + associatedToProject + "\n"); - out.write("Data:\n"); - - // save time of each day - for (Entry<Date, Long> entry : task.getAllDaysAndTimes().entrySet()) { - - Date date = entry.getKey(); - long value = entry.getValue() / 1000; - if (value > 0) { - String gtimerDate = GTimerTimeUtil.date2yyyyMMdd(date); - out.write(gtimerDate + " " + value + "\n"); - } - } - - BackupUtils.deleteBackupFile(backupfile); - } catch (IOException e) { - if (log.isErrorEnabled()) { - log.error("Can't save task", e); - } - - // can be null if backup throw the exception - if (backupfile != null) { - BackupUtils.restoreBackupFile(backupfile); - } - } - } - - /** - * Save annotation for a task. - * - * @param task task to save annotation - */ - protected void saveTaskAnnotation(TimerTask task) { - - int taskNumber = task.getNumber(); - - File annotationTaskFile = new File(dataSaveDirectory + File.separator - + taskNumber + "." + GTIMER_ANNOTATION_EXTENSION); - - if (task.getAllDaysAnnotations() != null - && !task.getAllDaysAnnotations().isEmpty()) { - - File backupfile = null; - try (Writer out = new OutputStreamWriter(new FileOutputStream(annotationTaskFile), "ISO-8859-1")) { - - // first make backup - backupfile = BackupUtils.makeBackupFile(annotationTaskFile); - - // save time of each day - for (Entry<Date, String> entry : task.getAllDaysAnnotations() - .entrySet()) { - - Date date = entry.getKey(); - String gtimerTS = String.valueOf(date.getTime() / 1000); - - out.write(gtimerTS + " " + entry.getValue() + "\n"); - } - - BackupUtils.deleteBackupFile(backupfile); - } catch (IOException e) { - if (log.isErrorEnabled()) { - log.debug("Can't save task", e); - } - - // can be null if backup throw the exception - if (backupfile != null) { - BackupUtils.restoreBackupFile(backupfile); - } - } - } else { - annotationTaskFile.delete(); - } - } - - /** - * Save task alerts. - * - * @param task task to save alert - */ - protected void saveAlerts(TimerTask task) { - - int taskNumber = task.getNumber(); - - File alertTaskFile = new File(dataSaveDirectory + File.separator - + taskNumber + "." + GTIMER_ALERT_EXTENSION); - - if (task.getAlerts() != null && !task.getAlerts().isEmpty()) { - - File backupfile = null; - try (Writer out = new OutputStreamWriter(new FileOutputStream(alertTaskFile), "ISO-8859-1")) { - - // first make backup - backupfile = BackupUtils.makeBackupFile(alertTaskFile); - - out.write("Format: " + GTIMER_FILE_VERSION + "\n"); - - // save each alert - for (TimerAlert alert : task.getAlerts()) { - - Type type = alert.getType(); - long duration = alert.getDuration() / 1000; - - switch (type) { - case REACH_DAILY_TIME: - out.write("reachdailytime " + duration + "\n"); - break; - case REACH_TOTAL_TIME: - out.write("reachtotaltime " + duration + "\n"); - break; - } - } - - BackupUtils.deleteBackupFile(backupfile); - } catch (IOException e) { - if (log.isErrorEnabled()) { - log.debug("Can't save task", e); - } - - // can be null if backup throw the exception - if (backupfile != null) { - BackupUtils.restoreBackupFile(backupfile); - } - } - } else { - alertTaskFile.delete(); - } - - } - - /*public void addProject(TimerProject project) { - - // searching for good project number - int projectNumber = getUnusedNumber("." + GTIMER_PROJECT_EXTENSION); - project.setNumber(projectNumber); - - if (log.isDebugEnabled()) { - log.debug("Setting project number for " + project.getName() - + " to " + projectNumber); - } - - saveProject(project); - - // loop on subtasks to set correct task number (only on add) - project.getSubTasks().forEach(this::addTask); - }*/ - - /*public void addTask(TimerTask task) { - - // searching for good task number - int taskNumber = getUnusedNumber("." + GTIMER_TASK_EXTENSION); - task.setNumber(taskNumber); - - if (log.isDebugEnabled()) { - log.debug("Setting task number for " + task.getName() + " to " - + taskNumber); - } - - saveTask(task); - - // loop on subtasks to set correct task number (only on add) - task.getSubTasks().forEach(this::addTask); - }*/ - - /** - * Explore directory and find a non used number for project. - * - * @param extension to check (ie ".project" or ".task") - * - * @return a non used project number - */ - protected int getUnusedNumber(String extension) { - - // init -1, ++ start with 0 - int foundProjectNumber = -1; - - File aGtimerFile; - - // en esperant que sera pas infini :) - do { - ++foundProjectNumber; - aGtimerFile = new File(dataSaveDirectory + File.separator - + foundProjectNumber + extension); - } while (aGtimerFile.exists()); - - return foundProjectNumber; - } - - /*public void deleteProject(TimerProject project) { - deleteTaskOrProject(project, GTIMER_PROJECT_EXTENSION); - } - - public void deleteTask(TimerTask task) { - deleteTaskOrProject(task, GTIMER_TASK_EXTENSION); - } - - /* - * Delete associated file or project files on disk. - * - * @param taskOrProject task or project to delete file - * @param extension extension without . - * - protected void deleteTaskOrProject(TimerTask taskOrProject, String extension) { - - // and then manage current file - int fileNumber = taskOrProject.getNumber(); - - // first, delete task annotation file - if (extension.equals(GTIMER_TASK_EXTENSION)) { - File annfileToDelete = new File(dataSaveDirectory + File.separator - + fileNumber + "." + GTIMER_ANNOTATION_EXTENSION); - if (annfileToDelete.exists()) { - annfileToDelete.delete(); - if (log.isDebugEnabled()) { - log.debug("Annotation file deleted for " - + taskOrProject.getName() + "(" - + annfileToDelete.getPath() + ")"); - } - } - - File alertFileToDelete = new File(dataSaveDirectory + File.separator - + fileNumber + "." + GTIMER_ALERT_EXTENSION); - if (alertFileToDelete.exists()) { - alertFileToDelete.delete(); - if (log.isDebugEnabled()) { - log.debug("Alert file deleted for " - + taskOrProject.getName() + "(" - + alertFileToDelete.getPath() + ")"); - } - } - } - - // second, go recursively on subtasks - for (TimerTask subtask : taskOrProject.getSubTasks()) { - deleteTaskOrProject(subtask, GTIMER_TASK_EXTENSION); - } - - // then manage current task file - File fileToDelete = new File(dataSaveDirectory + File.separator - + fileNumber + "." + extension); - if (fileToDelete.exists()) { - fileToDelete.delete(); - if (log.isDebugEnabled()) { - log.debug("File deleted for " + taskOrProject.getName() + "(" - + fileToDelete.getPath() + ")"); - } - } else { - if (log.isWarnEnabled()) { - log.warn("Try to delete non existing file " - + fileToDelete.getAbsolutePath()); - } - } - }*/ - - /*public void modifyProject(TimerProject project) { - saveProject(project); - } - - public void modifyTask(TimerTask task) { - - // ne sauve la tache que si elle n'est pas - // en cours d'execution - if (!runningTasks.contains(task)) { - saveTask(task); - } - - // on a besoin de sauver les annotations - // seulement dans le cas d'un merge - // si le merge a merger les annotations par - // exemple. - // Potentiellement aussi lors d'un move. - saveTaskAnnotation(task); - saveAlerts(task); - - // fix a bug with the gtimer subtask - // save format du to composed task name - // subtasks have to be resaved - task.getSubTasks().forEach(this::modifyTask); - }*/ - - /*public void setAnnotation(TimerTask task, Date date, String annotation) { - saveTaskAnnotation(task); - } - - public void setTaskTime(TimerTask task, Date date, Long time) { - // ne sauve la tache que si elle n'est pas - // en cours d'execution - if (!runningTasks.contains(task)) { - saveTask(task); - } - } - - public void changeClosedState(TimerTask task) { - if (task instanceof TimerProject) { - saveProject((TimerProject) task); - } else { - // ne sauve la tache que si elle n'est pas - // en cours d'execution - if (!runningTasks.contains(task)) { - saveTask(task); - } - } - }*/ - - /*public void moveTask(TimerTask task) { - - if (log.isDebugEnabled()) { - log.debug("postMoveTask event received"); - } - - modifyTask(task); - } - - public void postMergeTasks(TimerTask destinationTask, List<TimerTask> otherTasks) { - // destination task need to be updated - modifyTask(destinationTask); - - // delete all others - // for (TimerTask otherTask : otherTasks) { - // deleteTask(otherTask); - // } - // better if deleted here - // but deleted by another event - // some otherTasks subtasks must be deleted too - }*/ - - /*public void startTask(TimerTask task) { - - if (log.isDebugEnabled()) { - log.debug("startTask event received"); - } - - runningTasks.add(task); - - } - - public void stopTask(TimerTask task) { - - if (log.isDebugEnabled()) { - log.debug("stopTask event received"); - } - - // remove task from running task and force save - runningTasks.remove(task); - saveTask(task); - }*/ - - public void run() { - - if (log.isDebugEnabled()) { - log.debug("Saver wake up"); - } - - //saveRunningTasks(); - } - - /* - * Save runing tasks and their synchronization info - * - protected void saveRunningTasks() { - synchronized (runningTasks) { - runningTasks.forEach(this::saveTask); - } - } - - public void checkAddProject(TimerProject project) { - checkName(project); - } - - public void checkAddTask(TimerTask parent, TimerTask task) { - checkName(task); - } - - /* - * Check task name. - * - * @param task task to check - * - protected void checkName(TimerTask task) { - String name = task.getName(); - - if (name.trim().length() <= 0) { - throw new DataViolationException("Can't add task", "vetoable.saver.empty.name"); - } - - if (name.contains(GTIMER_SUBTASK_SEPARATOR)) { - throw new DataViolationException("Can't add task", "vetoable.saver.invalid.characters"); - } - }*/ } diff --git a/src/main/java/org/chorem/jtimer/io/GTimerTimeUtil.java b/src/main/java/org/chorem/jtimer/io/GTimerTimeUtil.java index 1ac8775..444e4b0 100644 --- a/src/main/java/org/chorem/jtimer/io/GTimerTimeUtil.java +++ b/src/main/java/org/chorem/jtimer/io/GTimerTimeUtil.java @@ -2,7 +2,7 @@ * #%L * jTimer * %% - * Copyright (C) 2008 - 2016 CodeLutin + * Copyright (C) 2008 - 2018 CodeLutin * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as diff --git a/src/main/java/org/chorem/jtimer/io/Saver.java b/src/main/java/org/chorem/jtimer/io/Saver.java index 48690ee..b1b1d31 100644 --- a/src/main/java/org/chorem/jtimer/io/Saver.java +++ b/src/main/java/org/chorem/jtimer/io/Saver.java @@ -2,7 +2,7 @@ * #%L * jTimer * %% - * Copyright (C) 2007 - 2012 CodeLutin + * Copyright (C) 2007 - 2018 CodeLutin * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as @@ -22,8 +22,6 @@ package org.chorem.jtimer.io; -import org.chorem.jtimer.entities.TimerProject; - import java.util.Collection; /** @@ -37,27 +35,6 @@ import java.util.Collection; */ public interface Saver { - /** - * Set auto save delay (in milliseconds). - * - * @param autoSaveDelay delay in milliseconds - */ - void setAutoSaveDelay(long autoSaveDelay); - - /** - * Try to lock current saver directory. - * - * @throws DataLockingException if can't obtain lock - */ - void lock() throws DataLockingException; - - /** - * Try to unlock current saver directory. - * - * @throws DataLockingException if there is no lock - */ - void unlock() throws DataLockingException; - /** * Load a project list. * diff --git a/src/main/java/org/chorem/jtimer/entities/TimerProject.java b/src/main/java/org/chorem/jtimer/io/TimerProject.java similarity index 95% rename from src/main/java/org/chorem/jtimer/entities/TimerProject.java rename to src/main/java/org/chorem/jtimer/io/TimerProject.java index 4eb8c78..fa57e9f 100644 --- a/src/main/java/org/chorem/jtimer/entities/TimerProject.java +++ b/src/main/java/org/chorem/jtimer/io/TimerProject.java @@ -20,7 +20,9 @@ * #L% */ -package org.chorem.jtimer.entities; +package org.chorem.jtimer.io; + +import org.chorem.jtimer.entities.TimerTask; /** * Represent a project. diff --git a/src/main/java/org/chorem/jtimer/io/package-info.java b/src/main/java/org/chorem/jtimer/io/package-info.java index 0e9eb28..e182fc1 100644 --- a/src/main/java/org/chorem/jtimer/io/package-info.java +++ b/src/main/java/org/chorem/jtimer/io/package-info.java @@ -2,7 +2,7 @@ * #%L * jTimer * %% - * Copyright (C) 2007 - 2011 CodeLutin + * Copyright (C) 2007 - 2018 CodeLutin * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as diff --git a/src/main/java/org/chorem/jtimer/services/AlertService.java b/src/main/java/org/chorem/jtimer/services/AlertService.java index 25d8b48..9083989 100644 --- a/src/main/java/org/chorem/jtimer/services/AlertService.java +++ b/src/main/java/org/chorem/jtimer/services/AlertService.java @@ -1,4 +1,15 @@ package org.chorem.jtimer.services; -public class AlertService { +import org.chorem.jtimer.core.Context; +import org.chorem.jtimer.db.DbManager; +import org.chorem.jtimer.entities.TimerTask; + +public class AlertService extends ContextableService { + + public AlertService(DbManager dbManager, Context context) { + super(dbManager, context); + } + + public void modifyAlert(TimerTask task) { + } } diff --git a/src/main/java/org/chorem/jtimer/services/ContextableService.java b/src/main/java/org/chorem/jtimer/services/ContextableService.java new file mode 100644 index 0000000..f6a5d16 --- /dev/null +++ b/src/main/java/org/chorem/jtimer/services/ContextableService.java @@ -0,0 +1,17 @@ +package org.chorem.jtimer.services; + +import org.chorem.jtimer.core.Context; +import org.chorem.jtimer.db.DbManager; + +public abstract class ContextableService { + + protected Context context; + + protected DbManager dbManager; + + protected ContextableService(DbManager dbManager, Context context) { + this.dbManager = dbManager; + this.context = context; + } + +} diff --git a/src/main/java/org/chorem/jtimer/services/ReportService.java b/src/main/java/org/chorem/jtimer/services/ReportService.java index 2159f47..f73f381 100644 --- a/src/main/java/org/chorem/jtimer/services/ReportService.java +++ b/src/main/java/org/chorem/jtimer/services/ReportService.java @@ -1,4 +1,10 @@ package org.chorem.jtimer.services; -public class ReportService { +import org.chorem.jtimer.core.Context; +import org.chorem.jtimer.db.DbManager; + +public class ReportService extends ContextableService { + public ReportService(DbManager dbManager, Context context) { + super(dbManager, context); + } } diff --git a/src/main/java/org/chorem/jtimer/services/TaskService.java b/src/main/java/org/chorem/jtimer/services/TaskService.java index 2211371..c72b519 100644 --- a/src/main/java/org/chorem/jtimer/services/TaskService.java +++ b/src/main/java/org/chorem/jtimer/services/TaskService.java @@ -1,5 +1,68 @@ package org.chorem.jtimer.services; -public class TaskService { +import org.chorem.jtimer.core.Context; +import org.chorem.jtimer.db.DbManager; +import org.chorem.jtimer.entities.TimerTask; +import org.chorem.jtimer.io.TimerProject; +import java.util.Date; +import java.util.List; + +public class TaskService extends ContextableService { + + public TaskService(DbManager dbManager, Context context) { + super(dbManager, context); + } + + public void createProject(TimerTask p) { + + } + + public void addTask(TimerTask task) { + dbManager.createTask(task); + } + + public void editProject(TimerProject project, String newProjectName) { + } + + public void startTask(TimerTask task) { + } + + public void stopTask(TimerTask task) { + } + + public void closeProject(TimerProject project) { + } + + public void closeTask(TimerTask task) { + } + + public void deleteProject(TimerProject project) { + } + + public void deleteTask(TimerTask task) { + } + + public void mergeTasks(TimerTask destinationTask, List<TimerTask> otherTasks) { + } + + public void addAnnotation(TimerTask selectedTask, Date date, String annotation) { + } + + public void addTask(TimerTask selectedTask, TimerTask t, String taskTemplate) { + } + + public void editTask(TimerTask task, String name) { + } + + public void moveTask(TimerTask destinationTask, List<TimerTask> movedTasks) { + } + + public List<TimerTask> getProjectsList() { + return null; + } + + public List<TimerTask> getSubTasks(TimerTask parent) { + return null; + } } diff --git a/src/main/java/org/chorem/jtimer/services/TimeService.java b/src/main/java/org/chorem/jtimer/services/TimeService.java index 217ae4d..d28a0cf 100644 --- a/src/main/java/org/chorem/jtimer/services/TimeService.java +++ b/src/main/java/org/chorem/jtimer/services/TimeService.java @@ -1,4 +1,16 @@ package org.chorem.jtimer.services; -public class TimeService { +import org.chorem.jtimer.core.Context; +import org.chorem.jtimer.db.DbManager; +import org.chorem.jtimer.entities.TimerTask; + +import java.util.Date; + +public class TimeService extends ContextableService { + public TimeService(DbManager dbManager, Context context) { + super(dbManager, context); + } + + public void changeTaskTime(TimerTask selectedTask, Date now, long newTodayTime) { + } } diff --git a/src/main/java/org/chorem/jtimer/ui/NewTaskView.java b/src/main/java/org/chorem/jtimer/ui/NewTaskView.java index 42e8cff..edd0d43 100644 --- a/src/main/java/org/chorem/jtimer/ui/NewTaskView.java +++ b/src/main/java/org/chorem/jtimer/ui/NewTaskView.java @@ -155,12 +155,8 @@ public class NewTaskView extends DialogView { // Fix creation date t.setCreationDate(new Date()); - try { - core.getData().addTask(selectedTask, t, taskTemplate); - parent.selectTask(t); - } catch (DataViolationException e) { - parent.displayErrorMessage(e.getExceptionKey()); - } + context.getTaskService().addTask(selectedTask, t, taskTemplate); + parent.selectTask(t); } @Action diff --git a/src/main/java/org/chorem/jtimer/ui/TimerTaskEditor.java b/src/main/java/org/chorem/jtimer/ui/TimerTaskEditor.java index f88947a..e178380 100644 --- a/src/main/java/org/chorem/jtimer/ui/TimerTaskEditor.java +++ b/src/main/java/org/chorem/jtimer/ui/TimerTaskEditor.java @@ -26,9 +26,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.chorem.jtimer.JTimer; import org.chorem.jtimer.core.Context; -import org.chorem.jtimer.data.DataViolationException; -import org.chorem.jtimer.data.TimerCore; -import org.chorem.jtimer.data.TimerDataManager; import org.chorem.jtimer.entities.TimerTask; import org.chorem.jtimer.entities.TimerTaskHelper; import org.chorem.jtimer.ui.widget.DialogView; @@ -585,37 +582,27 @@ public class TimerTaskEditor extends DialogView { getApplication().hide(this); - try { - // title - if (isTitleChanged) { - dataManager.editTask(task, cloneTask.getName()); + // title + if (isTitleChanged) { + context.getTaskService().editTask(task, cloneTask.getName()); + } + for (Date date : dateChanged) { + if (log.isDebugEnabled()) { + log.debug("Applying changes on: " + date); } - for (Date date : dateChanged) { - if (log.isDebugEnabled()) { - log.debug("Applying changes on: " + date); - } - // time - dataManager.changeTaskTime(task, date, cloneTask.getTime(date)); + // time + context.getTimeService().changeTaskTime(task, date, cloneTask.getTime(date)); - // annotation - if (annotationChanged.contains(date)) { - TimerTaskHelper.removeAnnotation(task, date); + // annotation + if (annotationChanged.contains(date)) { + TimerTaskHelper.removeAnnotation(task, date); - Map<Date, String> annotations = TimerTaskHelper.getAnnotationMap(cloneTask, date); - for (Date date2 : annotations.keySet()) { - dataManager.addAnnotation(task, date2, annotations.get(date2)); - } + Map<Date, String> annotations = TimerTaskHelper.getAnnotationMap(cloneTask, date); + for (Date date2 : annotations.keySet()) { + context.getTaskService().addAnnotation(task, date2, annotations.get(date2)); } } - - /*dateChanged.clear(); - annotationChanged.clear(); - setDataChanged(false); - isTitleChanged = false; - isAnnotationChanged = false;*/ - } catch (DataViolationException ex) { - parent.displayErrorMessage(ex.getExceptionKey()); } } diff --git a/src/main/java/org/chorem/jtimer/ui/alert/AlertEditor.java b/src/main/java/org/chorem/jtimer/ui/alert/AlertEditor.java index 9cfa98f..589a818 100644 --- a/src/main/java/org/chorem/jtimer/ui/alert/AlertEditor.java +++ b/src/main/java/org/chorem/jtimer/ui/alert/AlertEditor.java @@ -23,7 +23,6 @@ package org.chorem.jtimer.ui.alert; import org.chorem.jtimer.core.Context; -import org.chorem.jtimer.data.TimerDataManager; import org.chorem.jtimer.entities.TimerAlert; import org.chorem.jtimer.entities.TimerAlert.Type; import org.chorem.jtimer.entities.TimerTask; @@ -197,7 +196,7 @@ public class AlertEditor extends FrameView implements ListSelectionListener { // filter null type alert (forbidden) task.setAlert(alerts); - timerDataManager.modifyAlert(task); + context.getAlertService().modifyAlert(task); getApplication().hide(this); } diff --git a/src/main/java/org/chorem/jtimer/ui/report/ReportGenerator.java b/src/main/java/org/chorem/jtimer/ui/report/ReportGenerator.java index 323c853..493092f 100644 --- a/src/main/java/org/chorem/jtimer/ui/report/ReportGenerator.java +++ b/src/main/java/org/chorem/jtimer/ui/report/ReportGenerator.java @@ -29,7 +29,7 @@ import freemarker.template.Template; import freemarker.template.TemplateException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.chorem.jtimer.entities.TimerProject; +import org.chorem.jtimer.io.TimerProject; import java.io.IOException; import java.io.StringWriter; diff --git a/src/main/java/org/chorem/jtimer/ui/report/ReportView.java b/src/main/java/org/chorem/jtimer/ui/report/ReportView.java index 6418c89..234cc23 100644 --- a/src/main/java/org/chorem/jtimer/ui/report/ReportView.java +++ b/src/main/java/org/chorem/jtimer/ui/report/ReportView.java @@ -25,8 +25,7 @@ package org.chorem.jtimer.ui.report; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.chorem.jtimer.core.Context; -import org.chorem.jtimer.data.TimerCore; -import org.chorem.jtimer.entities.TimerProject; +import org.chorem.jtimer.io.TimerProject; import org.chorem.jtimer.entities.TimerTask; import org.chorem.jtimer.ui.report.ReportGenerator.Type; import org.chorem.jtimer.ui.tree.CheckBoxTreeCellEditor; diff --git a/src/main/java/org/chorem/jtimer/ui/systray/SystrayManager.java b/src/main/java/org/chorem/jtimer/ui/systray/SystrayManager.java index d78263b..8a94066 100644 --- a/src/main/java/org/chorem/jtimer/ui/systray/SystrayManager.java +++ b/src/main/java/org/chorem/jtimer/ui/systray/SystrayManager.java @@ -26,7 +26,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.chorem.jtimer.JTimer; import org.chorem.jtimer.core.Context; -import org.chorem.jtimer.data.DataEventListener; import org.chorem.jtimer.entities.TimerTask; import org.chorem.jtimer.ui.widget.JPopupTrayIcon; import org.jdesktop.application.ApplicationContext; diff --git a/src/main/java/org/chorem/jtimer/ui/tasks/IdleDialog.java b/src/main/java/org/chorem/jtimer/ui/tasks/IdleDialog.java index 846fce8..28353bc 100644 --- a/src/main/java/org/chorem/jtimer/ui/tasks/IdleDialog.java +++ b/src/main/java/org/chorem/jtimer/ui/tasks/IdleDialog.java @@ -26,12 +26,12 @@ import org.apache.commons.lang3.time.DurationFormatUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.chorem.jtimer.core.Context; -import org.chorem.jtimer.data.TimerCore; import org.chorem.jtimer.entities.TimerTask; import org.chorem.jtimer.ui.tree.ProjectsAndTasksTree; import org.chorem.jtimer.ui.tree.TaskTreeModel; import org.chorem.jtimer.ui.treetable.ProjectsAndTasksCellRenderer; import org.jdesktop.application.Action; +import org.jdesktop.application.ApplicationContext; import org.jdesktop.application.ResourceManager; import org.jdesktop.application.ResourceMap; import org.jdesktop.application.SingleFrameApplication; diff --git a/src/main/java/org/chorem/jtimer/ui/tasks/RefreshTreeTask.java b/src/main/java/org/chorem/jtimer/ui/tasks/RefreshTreeTask.java index 915e5da..0e33752 100644 --- a/src/main/java/org/chorem/jtimer/ui/tasks/RefreshTreeTask.java +++ b/src/main/java/org/chorem/jtimer/ui/tasks/RefreshTreeTask.java @@ -89,7 +89,7 @@ public class RefreshTreeTask extends java.util.TimerTask { Date now = new Date(); // TODO find a better way to do that ! // Only useful for UI listeners - dataManager.changeTaskTime(task, now, task.getTime(now)); + context.getTimeService().changeTaskTime(task, now, task.getTime(now)); } } diff --git a/src/main/java/org/chorem/jtimer/ui/tasks/RunTaskJob.java b/src/main/java/org/chorem/jtimer/ui/tasks/RunTaskJob.java index 1ce4bee..cd7ead8 100644 --- a/src/main/java/org/chorem/jtimer/ui/tasks/RunTaskJob.java +++ b/src/main/java/org/chorem/jtimer/ui/tasks/RunTaskJob.java @@ -28,7 +28,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.chorem.jtimer.JTimer; import org.chorem.jtimer.core.Context; -import org.chorem.jtimer.data.TimerDataManager; import org.chorem.jtimer.entities.TimerAlert; import org.chorem.jtimer.entities.TimerAlert.Type; import org.chorem.jtimer.entities.TimerTask; @@ -91,7 +90,7 @@ public class RunTaskJob extends Task<Void, Void> { * * @param parentApp parent application * @param managedTask task - * @param dataManager data + * @param context context */ public RunTaskJob(JTimer parentApp, TimerTask managedTask, Context context) { super(parentApp); @@ -264,7 +263,7 @@ public class RunTaskJob extends Task<Void, Void> { long toRemove = Math.min(-localDelta, msToMidnight); // FIXME there is a little bug in the algorithm. Can set a time to -1 in some case long newTaskTime = Math.max(0, task.getTime(currentDate) - toRemove); - dataManager.changeTaskTime(task, currentDate, newTaskTime); + context.getTimeService().changeTaskTime(task, currentDate, newTaskTime); if (log.isDebugEnabled()) { log.debug(" remove delta to task on " + currentDate + " : " + toRemove); } @@ -280,7 +279,7 @@ public class RunTaskJob extends Task<Void, Void> { today235959 = DateUtils.addMilliseconds(today235959, -1); long msToMidnight = today235959.getTime() - currentDate.getTime(); long toAdd = Math.min(localDelta, msToMidnight); - dataManager.changeTaskTime(task, currentDate, task.getTime(currentDate) + toAdd); + context.getTimeService().changeTaskTime(task, currentDate, task.getTime(currentDate) + toAdd); if (log.isDebugEnabled()) { log.debug(" adding delta to task on " + currentDate + " : " + toAdd); } diff --git a/src/main/java/org/chorem/jtimer/ui/tree/TaskTreeModel.java b/src/main/java/org/chorem/jtimer/ui/tree/TaskTreeModel.java index 811b1ce..8f438a5 100644 --- a/src/main/java/org/chorem/jtimer/ui/tree/TaskTreeModel.java +++ b/src/main/java/org/chorem/jtimer/ui/tree/TaskTreeModel.java @@ -25,7 +25,6 @@ package org.chorem.jtimer.ui.tree; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.chorem.jtimer.core.Context; -import org.chorem.jtimer.data.TimerCore; import org.chorem.jtimer.entities.TimerTask; import org.chorem.jtimer.entities.TimerTaskHelper; import org.jdesktop.swingx.tree.TreeModelSupport; diff --git a/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksModel.java b/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksModel.java index 6a60cf1..8b70595 100644 --- a/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksModel.java +++ b/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksModel.java @@ -26,7 +26,7 @@ import org.apache.commons.lang3.time.DurationFormatUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.chorem.jtimer.core.Context; -import org.chorem.jtimer.entities.TimerProject; +import org.chorem.jtimer.io.TimerProject; import org.chorem.jtimer.entities.TimerTask; import org.jdesktop.swingx.treetable.AbstractTreeTableModel; @@ -199,10 +199,10 @@ public class ProjectsAndTasksModel extends AbstractTreeTableModel { // get correct list if (parent == root) { // case root node - List<TimerTask> projects = dataManager.getProjectsList(); + List<TimerTask> projects = context.getTaskService().getProjectsList(); result.addAll(projects); } else { // not root node - List<TimerTask> tasks = dataManager.getSubTasks((TimerTask)parent); + List<TimerTask> tasks = context.getTaskService().getSubTasks((TimerTask)parent); result.addAll(tasks); } diff --git a/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksTable.java b/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksTable.java index 4f2dc37..9f7be91 100644 --- a/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksTable.java +++ b/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksTable.java @@ -23,8 +23,7 @@ package org.chorem.jtimer.ui.treetable; import org.chorem.jtimer.core.Context; -import org.chorem.jtimer.data.TimerCore; -import org.chorem.jtimer.entities.TimerProject; +import org.chorem.jtimer.io.TimerProject; import org.chorem.jtimer.entities.TimerTask; import org.chorem.jtimer.entities.TimerTaskHelper; import org.chorem.jtimer.ui.treetable.dnd.TimerTaskTransferHandler; @@ -72,7 +71,7 @@ public class ProjectsAndTasksTable extends JXTreeTable { * Constructor. * * @param application application - * @param core timer core + * @param context context */ public ProjectsAndTasksTable(Application application, Context context) { diff --git a/src/main/java/org/chorem/jtimer/ui/treetable/dnd/TimerTaskTransferHandler.java b/src/main/java/org/chorem/jtimer/ui/treetable/dnd/TimerTaskTransferHandler.java index e79e1a3..8f80576 100644 --- a/src/main/java/org/chorem/jtimer/ui/treetable/dnd/TimerTaskTransferHandler.java +++ b/src/main/java/org/chorem/jtimer/ui/treetable/dnd/TimerTaskTransferHandler.java @@ -26,8 +26,6 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.chorem.jtimer.core.Context; -import org.chorem.jtimer.data.DataViolationException; -import org.chorem.jtimer.data.TimerDataManager; import org.chorem.jtimer.entities.TimerTask; import org.chorem.jtimer.entities.TimerTaskHelper; import org.chorem.jtimer.ui.treetable.ProjectsAndTasksTable; @@ -186,20 +184,7 @@ public class TimerTaskTransferHandler extends TransferHandler { .getTransferData(TimerTaskTranferable.myData); List<TimerTask> movedTasks = (List<TimerTask>) myObject; - try { - dataManager.moveTask(destinationTask, movedTasks); - } catch (DataViolationException e) { - String title = resourceMap - .getString("action.invalidActionTitle"); - String message = resourceMap.getString(e - .getExceptionKey()); - if (StringUtils.isEmpty(message)) { - message = resourceMap.getString( - "action.missingErrorMessage", e.getExceptionKey()); - } - JOptionPane.showMessageDialog(cp, message, title, - JOptionPane.ERROR_MESSAGE); - } + context.getTaskService().moveTask(destinationTask, movedTasks); } } catch (IOException | UnsupportedFlavorException e) { if (log.isErrorEnabled()) { diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml deleted file mode 100644 index 2b970c9..0000000 --- a/src/main/resources/log4j2.xml +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - #%L - jTimer - %% - Copyright (C) 2016 - 2018 CodeLutin - %% - 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/gpl-3.0.html>. - #L% - --> -<Configuration> - - <Appenders> - <Console name="Console" target="SYSTEM_OUT"> - <PatternLayout pattern="%d{yyyy/MM/dd HH:mm:ss} %5p (%c:%L) - %m%n"/> - </Console> - </Appenders> - - <Loggers> - <Logger name="org.chorem.jtimer" level="info"/> - - <Root level="warn"> - <AppenderRef ref="Console"/> - </Root> - </Loggers> -</Configuration> diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 0000000..ccae27e --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,16 @@ +<configuration> + + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <!-- encoders are assigned the type + ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> + <encoder> + <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> + </encoder> + </appender> + + <logger name="org.chorem.jtimer" level="INFO"/> + + <root level="error"> + <appender-ref ref="STDOUT" /> + </root> +</configuration> -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.