Author: echatellier Date: 2012-07-13 11:13:42 +0200 (Fri, 13 Jul 2012) New Revision: 2884 Url: http://chorem.org/repositories/revision/jtimer/2884 Log: refs #498 : begin sql storage Added: branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/storage/ branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/storage/Storage.java branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/storage/StorageException.java branches/2.0.0-evol-499-storage/src/test/java/org/chorem/jtimer/storage/ branches/2.0.0-evol-499-storage/src/test/java/org/chorem/jtimer/storage/StorageTest.java Modified: branches/2.0.0-evol-499-storage/pom.xml branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/JTimerConfig.java branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/data/TimerCore.java branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/data/TimerDataManager.java branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksCellRenderer.java branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksModel.java branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksTable.java Modified: branches/2.0.0-evol-499-storage/pom.xml =================================================================== --- branches/2.0.0-evol-499-storage/pom.xml 2012-07-12 12:51:48 UTC (rev 2883) +++ branches/2.0.0-evol-499-storage/pom.xml 2012-07-13 09:13:42 UTC (rev 2884) @@ -259,7 +259,7 @@ <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> - <version>1.3.163</version> + <version>1.3.167</version> <scope>runtime</scope> </dependency> Modified: branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/JTimerConfig.java =================================================================== --- branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/JTimerConfig.java 2012-07-12 12:51:48 UTC (rev 2883) +++ branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/JTimerConfig.java 2012-07-13 09:13:42 UTC (rev 2884) @@ -96,6 +96,14 @@ } } + public String getStorageDatabaseLocation() { + return appConfig.getOption(JTimerOption.STORAGE_DATABASE_LOCATION.key); + } + + public void setStrorageDatabaseLocation(String location) { + appConfig.setOption(JTimerOption.STORAGE_DATABASE_LOCATION.key, location); + } + public Class getIOSaverClass() { return appConfig.getOptionAsClass(JTimerOption.IO_SAVER_CLASS.key); } @@ -185,6 +193,7 @@ IO_SAVER_CLASS("jtimer.io.saver.class", "org.chorem.jtimer.io.GTimerIncrementalSaver"), IO_SAVER_DIRECTORY("jtimer.io.saver.directory", "${user.home}/.gtimer"), IO_SAVER_AUTOSAVEDELAY("jtimer.io.saver.autosavedelay", "300"), + STORAGE_DATABASE_LOCATION("jtimer.io.saver.directory", "${user.home}/.jtimer/db"), UI_IDLE_TIME("jtimer.ui.idletime", "300"), UI_SHOW_CLOSED("jtimer.ui.showclosed", "false"), UI_CLOSE_TO_SYSTRAY("jtimer.ui.closetosystray", "true"), Modified: branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/data/TimerCore.java =================================================================== --- branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/data/TimerCore.java 2012-07-12 12:51:48 UTC (rev 2883) +++ branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/data/TimerCore.java 2012-07-13 09:13:42 UTC (rev 2884) @@ -32,10 +32,12 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.chorem.jtimer.JTimer; import org.chorem.jtimer.JTimerFactory; import org.chorem.jtimer.entities.TimerProject; import org.chorem.jtimer.io.DataLockingException; import org.chorem.jtimer.io.Saver; +import org.chorem.jtimer.storage.Storage; /** * TimerCore @@ -54,6 +56,8 @@ /** Timer data. */ protected TimerDataManager data; + protected Storage storage; + /** saver io controller. */ protected Saver saver; @@ -65,6 +69,10 @@ // init data data = new TimerDataManager(); + // init storage + storage = new Storage(JTimer.config); + data.addDataEventListener(storage); + // add commmon vetoable CommonVetoable commonVetoable = new CommonVetoable(data); data.addVetoableDataEventListener(commonVetoable); @@ -117,6 +125,15 @@ } /** + * Get task storage. + * + * @return task storage + */ + public Storage getStorage() { + return storage; + } + + /** * Load project list from. */ protected void load() { Modified: branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/data/TimerDataManager.java =================================================================== --- branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/data/TimerDataManager.java 2012-07-12 12:51:48 UTC (rev 2883) +++ branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/data/TimerDataManager.java 2012-07-13 09:13:42 UTC (rev 2884) @@ -5,7 +5,7 @@ * $Id$ * $HeadURL$ * %% - * Copyright (C) 2007 - 2010 CodeLutin, Chatellier Eric + * Copyright (C) 2007 - 2012 CodeLutin, Chatellier Eric * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as @@ -40,7 +40,6 @@ import org.chorem.jtimer.entities.TimerAlert; import org.chorem.jtimer.entities.TimerProject; import org.chorem.jtimer.entities.TimerTask; -import org.nuiton.util.ArrayUtil; /** * Gere les donnees. Des objets peuvent s'enregistrer pour etre notifies des @@ -246,7 +245,9 @@ } // task deletion + if (false) { task.getParent().getSubTasks().remove(task); + } // send notification Iterator<DataEventListener> itDataEventListener = dataEventListeners.iterator(); Added: branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/storage/Storage.java =================================================================== --- branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/storage/Storage.java (rev 0) +++ branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/storage/Storage.java 2012-07-13 09:13:42 UTC (rev 2884) @@ -0,0 +1,407 @@ +package org.chorem.jtimer.storage; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Collection; +import java.util.Date; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.chorem.jtimer.JTimerConfig; +import org.chorem.jtimer.data.DataEventListener; +import org.chorem.jtimer.entities.TimerProject; +import org.chorem.jtimer.entities.TimerTask; + +/** + * Implementation du stockage des taches en base de données basée sur h2. + * + * Le schema est composé des tables: + * <ul> + * <li>Task + * <li>TaskTime + * <li>Version (contenant la version du shema en cas de migration)</li> + * </ul> + * + * @author echatellier + */ +public class Storage implements DataEventListener { + + private static final Log log = LogFactory.getLog(Storage.class); + + protected static final String TABLE_TASK = "task"; + protected static final String TABLE_VERSION = "version"; + + protected JTimerConfig config; + + protected Connection connection; + + public Storage(JTimerConfig config) { + this.config = config; + + try { + if (log.isDebugEnabled()) { + log.debug("Registering jdbc driver"); + } + Class.forName("org.h2.Driver"); + } catch (ClassNotFoundException e) { + if (log.isErrorEnabled()) { + log.fatal("Can't find h2 driver"); + } + } + + try { + connection = getConnection(); + } catch (SQLException ex) { + throw new StorageException("Can't open database", ex); + } + + } + + @Override + protected void finalize() throws Throwable { + connection.close(); + } + + protected Connection getConnection() throws SQLException { + + String url = config.getStorageDatabaseLocation() + "/jtimer"; + if (log.isInfoEnabled()) { + log.info("Opening connection to database : " + url); + } + Connection conn = DriverManager.getConnection("jdbc:h2:" + url, "sa", + ""); + conn.setAutoCommit(true); + + // test to create schema if it not already exists + boolean schemaExists = shemaExists(conn); + if (!schemaExists) { + if (log.isInfoEnabled()) { + log.info("Creating new database schema"); + } + createSchema(conn); + + // set new version in schema + Statement statement = conn.createStatement(); + statement.executeUpdate("INSERT INTO VERSION VALUES('2.0')"); + } + + return conn; + } + + protected void closeConnection(Connection conn) throws SQLException { + if (conn != null) { + conn.close(); + } + } + + protected void closeStatement(Statement stmt) { + if (stmt != null) { + try { + stmt.close(); + } catch (SQLException ex) { + throw new StorageException("Can't close statement", ex); + } + } + } + + /** + * Test if table "version" exists in database list. + * + * @param conn sql connection + * @return schema exists + */ + protected boolean shemaExists(Connection conn) { + boolean found = false; + Statement statement = null; + try { + statement = conn.createStatement(); + ResultSet rs = statement.executeQuery("SELECT table_name FROM information_schema.tables;"); + while (rs.next()) { + String name = rs.getString(1); + if (TABLE_VERSION.equalsIgnoreCase(name)) { + found = true; + } + } + } catch (SQLException ex) { + throw new StorageException("Can't test schema", ex); + } finally { + closeStatement(statement); + } + + return found; + } + + protected void createSchema(Connection conn) { + Statement statement = null; + try { + statement = conn.createStatement(); + statement.executeUpdate("CREATE TABLE " + TABLE_VERSION + + "(VERSION VARCHAR(10))"); + statement.executeUpdate("CREATE TABLE " + TABLE_TASK + + "(ID LONG NOT NULL AUTO_INCREMENT PRIMARY KEY," + + " NAME VARCHAR(255) NOT NULL," + + " PARENT LONG DEFAULT 0," + + " HIDDEN BOOLEAN," + + " NOTE TEXT)"); + } catch (SQLException ex) { + throw new StorageException("Can't create schema", ex); + } finally { + closeStatement(statement); + } + + } + + /** + * Find all project. (task with no parent, parent = 0). + * + * @return all projects + */ + public int getProjectsCount() { + int result = 0; + Statement statement = null; + try { + statement = connection.createStatement(); + ResultSet rs = statement.executeQuery("SELECT count(*) FROM " + TABLE_TASK + + " WHERE parent = 0"); + if (rs.next()) { + result = rs.getInt(1); + } + } catch (SQLException ex) { + throw new StorageException("Can't get project count", ex); + } finally { + closeStatement(statement); + } + return result; + } + + /** + * Find all project. (task with no parent, parent = 0). + * + * @return all projects + */ + public TimerProject getProject(int offset) { + TimerProject project = null; + PreparedStatement statement = null; + try { + statement = connection.prepareStatement("SELECT * FROM " + TABLE_TASK + + " WHERE parent = 0 ORDER BY id LIMIT 1 OFFSET ?"); + statement.setInt(1, offset); + ResultSet rs = statement.executeQuery(); + if (rs.next()) { + project = new TimerProject(); + project.setNumber(rs.getInt("id")); + project.setName(rs.getString("name")); + } + } catch (SQLException ex) { + throw new StorageException("Can't get project", ex); + } finally { + closeStatement(statement); + } + return project; + } + + /** + * Find all project. (task with no parent, parent = 0). + * + * @return all projects + */ + public int getTasksCount(TimerTask parent) { + int result = 0; + PreparedStatement statement = null; + try { + statement = connection.prepareStatement("SELECT count(*) FROM " + TABLE_TASK + + " WHERE parent = ?"); + statement.setInt(1, parent.getNumber()); + ResultSet rs = statement.executeQuery(); + if (rs.next()) { + result = rs.getInt(1); + } + } catch (SQLException ex) { + throw new StorageException("Can't get task count", ex); + } finally { + closeStatement(statement); + } + return result; + } + + public TimerTask getTask(TimerTask parent, int offset) { + TimerTask task = null; + PreparedStatement statement = null; + try { + statement = connection.prepareStatement("SELECT * FROM " + TABLE_TASK + + " WHERE parent = ? ORDER BY ID LIMIT 1 OFFSET ?"); + statement.setLong(1, parent.getNumber()); + statement.setLong(2, offset); + ResultSet rs = statement.executeQuery(); + while (rs.next()) { + task = new TimerTask(); + task.setNumber(rs.getInt("id")); + task.setName(rs.getString("name")); + } + } catch (SQLException ex) { + throw new StorageException("Can't get task", ex); + } finally { + closeStatement(statement); + } + return task; + } + + @Override + public void addProject(TimerProject project) { + PreparedStatement statement = null; + try { + statement = connection.prepareStatement("INSERT INTO " + + TABLE_TASK + "(name, parent, hidden, note)" + + " VALUES (?, ?, ?, ?)"); + statement.setString(1, project.getName()); + statement.setLong(2, 0); + statement.setBoolean(3, project.isClosed()); + statement.setString(4, null /*project.getNote()*/); + statement.executeUpdate(); + + // get generated id + ResultSet rs = statement.getGeneratedKeys(); + if (rs.next()) { + project.setNumber(rs.getInt(1)); + } + } catch (SQLException ex) { + throw new StorageException("Can't add project", ex); + } finally { + closeStatement(statement); + } + } + + @Override + public void addTask(TimerTask task) { + PreparedStatement statement = null; + try { + statement = connection.prepareStatement("INSERT INTO " + + TABLE_TASK + "(name, parent, hidden, note)" + + " VALUES (?, ?, ?, ?)"); + statement.setString(1, task.getName()); + statement.setLong(2, task.getParent().getNumber()); + statement.setBoolean(3, task.isClosed()); + statement.setString(4, null /*project.getNote()*/); + statement.executeUpdate(); + + // get generated id + ResultSet rs = statement.getGeneratedKeys(); + if (rs.next()) { + task.setNumber(rs.getInt(1)); + } + } catch (SQLException ex) { + throw new StorageException("Can't add project", ex); + } finally { + closeStatement(statement); + } + } + + @Override + public void modifyProject(TimerProject project) { + modifyTask(project); + } + + @Override + public void modifyTask(TimerTask task) { + PreparedStatement statement = null; + try { + statement = connection.prepareStatement("UPDATE " + + TABLE_TASK + " SET name=?, parent=?, hidden=?, note=?" + + " WHERE id = ?"); + statement.setString(1, task.getName()); + if (task.getParent() == null) { + statement.setLong(2, 0); + } else { + statement.setLong(2, task.getParent().getNumber()); + } + statement.setBoolean(3, task.isClosed()); + statement.setString(4, null /*project.getNote()*/); + statement.setLong(5, task.getNumber()); + statement.executeUpdate(); + } catch (SQLException ex) { + throw new StorageException("Can't add project", ex); + } finally { + closeStatement(statement); + } + } + + @Override + public void deleteProject(TimerProject project) { + deleteProject(project); + } + + @Override + public void deleteTask(TimerTask task) { + PreparedStatement statement = null; + try { + statement = connection.prepareStatement("DELETE FROM " + + TABLE_TASK + " WHERE id = ?"); + statement.setLong(1, task.getNumber()); + statement.executeUpdate(); + } catch (SQLException ex) { + throw new StorageException("Can't add project", ex); + } finally { + closeStatement(statement); + } + } + + @Override + public void setAnnotation(TimerTask task, Date date, String annotation) { + + } + + @Override + public void setTaskTime(TimerTask task, Date date, Long time) { + + } + + @Override + public void changeClosedState(TimerTask task) { + modifyTask(task); + } + + @Override + public void preMoveTask(TimerTask task) { + + } + + @Override + public void moveTask(TimerTask task) { + modifyTask(task); + } + + @Override + public void preMergeTasks(TimerTask destinationTask, + List<TimerTask> otherTasks) { + + } + + @Override + public void postMergeTasks(TimerTask destinationTask, + List<TimerTask> otherTasks) { + modifyTask(destinationTask); + for (TimerTask task : otherTasks) { + deleteTask(task); + } + } + + @Override + public void startTask(TimerTask task) { + + } + + @Override + public void stopTask(TimerTask task) { + + } + + @Override + public void dataLoaded(Collection<TimerProject> projects) { + + } +} Property changes on: branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/storage/Storage.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/storage/StorageException.java =================================================================== --- branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/storage/StorageException.java (rev 0) +++ branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/storage/StorageException.java 2012-07-13 09:13:42 UTC (rev 2884) @@ -0,0 +1,15 @@ +package org.chorem.jtimer.storage; + +public class StorageException extends RuntimeException { + + /** serialVersionUID. */ + private static final long serialVersionUID = -6544441950983775434L; + + public StorageException(String message, Throwable cause) { + super(message, cause); + } + + public StorageException(String message) { + super(message); + } +} Property changes on: branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/storage/StorageException.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Modified: branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksCellRenderer.java =================================================================== --- branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksCellRenderer.java 2012-07-12 12:51:48 UTC (rev 2883) +++ branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksCellRenderer.java 2012-07-13 09:13:42 UTC (rev 2884) @@ -41,6 +41,7 @@ import javax.swing.ImageIcon; import javax.swing.JTree; +import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import org.apache.commons.logging.Log; @@ -89,7 +90,7 @@ * @param treeTable Tree table reference for image observer * @param core TimerCore */ - public ProjectsAndTasksCellRenderer(JXTreeTable treeTable, TimerCore core) { + public ProjectsAndTasksCellRenderer(JXTreeTable treeTable) { this.treeTable = treeTable; // init @@ -100,9 +101,6 @@ runningIcon = new ImageIcon(runnigIconUrl); nodeObserver = new NodeImageObserver(); runningIcon.setImageObserver(nodeObserver); - - // be notified on events - core.getData().addDataEventListener(this); } /* Modified: branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksModel.java =================================================================== --- branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksModel.java 2012-07-12 12:51:48 UTC (rev 2883) +++ branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksModel.java 2012-07-13 09:13:42 UTC (rev 2884) @@ -34,19 +34,17 @@ import javax.swing.SwingUtilities; import javax.swing.table.TableColumn; +import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreePath; -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.collections.Predicate; import org.apache.commons.lang3.time.DurationFormatUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.chorem.jtimer.data.DataEventListener; -import org.chorem.jtimer.data.TimerCore; -import org.chorem.jtimer.data.TimerDataManager; import org.chorem.jtimer.entities.TimerProject; import org.chorem.jtimer.entities.TimerTask; import org.chorem.jtimer.entities.TimerTaskHelper; +import org.chorem.jtimer.storage.Storage; import org.jdesktop.swingx.treetable.AbstractTreeTableModel; /** @@ -86,12 +84,11 @@ /** Delete Node operation. */ public static final int OPERATION_DELETE = 2; + protected Storage storage; + /** Tree managed by this model. */ protected ProjectsAndTasksTable projectsAndTaskTable; - /** Data. */ - protected TimerDataManager dataManager; - /** Tree column identifiers. */ protected List<String> columnIdentifiers; @@ -109,12 +106,12 @@ * @param columnIdentifiers column identifiers */ public ProjectsAndTasksModel(ProjectsAndTasksTable projectsAndTaskTable, - TimerCore core, List<String> columnIdentifiers) { - super(new TimerProject("root")); + Storage storage, List<String> columnIdentifiers) { + super(new TimerProject()); // remember this.projectsAndTaskTable = projectsAndTaskTable; - this.dataManager = core.getData(); + this.storage = storage; this.columnIdentifiers = columnIdentifiers; taskNameCache = new HashMap<TimerTask, String>(); @@ -154,12 +151,10 @@ value = task.getName(); break; case 1: - value = DurationFormatUtils.formatDuration(TimerTaskHelper - .getTotalTime(task, new Date()), "HH:mm:ss"); + value = DurationFormatUtils.formatDuration(TimerTaskHelper.getTotalTime(task, new Date()), "HH:mm:ss"); break; case 2: - value = DurationFormatUtils.formatDuration(TimerTaskHelper - .getAllTotalTime(task), "HH:mm:ss"); + value = DurationFormatUtils.formatDuration(TimerTaskHelper.getAllTotalTime(task), "HH:mm:ss"); break; } } else { @@ -188,8 +183,16 @@ @Override public Object getChild(Object parent, int index) { - TimerTask t = getFiteredSubListFor(parent).get(index); - return t; + Object child = null; + if (parent == root) { + TimerProject p = storage.getProject(index); + child = p; + } else { + TimerTask parentTask = (TimerTask)parent; + TimerTask t = storage.getTask(parentTask, index); + child = t; + } + return child; } /* @@ -198,73 +201,15 @@ @Override public int getChildCount(Object parent) { - int childCount = getFiteredSubListFor(parent).size(); - return childCount; - } - - /** - * Recupere la sous liste: data.getProjectsList() si parent = root - * getSubTasks() sinon (cache results). - * - * @param parent parent to task sublist - * @return filtered list - */ - protected List<TimerTask> getFiteredSubListFor(Object parent) { - return getFiteredSubListFor(parent, false); - } - - /** - * Recupere la sous liste: data.getProjectsList() si parent = root - * getSubTasks() sinon. - * - * @param parent parent to task sublist - * @param noCache disable use of cached result and result caching - * @return filtered list - */ - protected List<TimerTask> getFiteredSubListFor(Object parent, boolean noCache) { - - List<TimerTask> result = subTasksCache.get(parent); - if (result == null || noCache) { - result = new ArrayList<TimerTask>(); - - // get correct list - if (parent == root) { // case root node - List<TimerProject> projects = dataManager.getProjectsList(); - result.addAll(projects); - } else { // not root node - TimerTask task = (TimerTask) parent; - result.addAll(task.getSubTasks()); - } - - // filter list, if only show closed - if (!showClosedTask) { - CollectionUtils.filter(result, new Predicate() { - @Override - public boolean evaluate(Object object) { - boolean result = false; - if (object instanceof TimerTask) { - TimerTask task = (TimerTask) object; - result = !task.isClosed(); - } - return result; - } - }); - } - - // Since sort is not supported by the table, do a manual sorting. - result = TimerTaskHelper.sortTask(result); - - if (!noCache) { - // cache tasks name - for (TimerTask task : result) { - taskNameCache.put(task, task.getName()); - } - - subTasksCache.put(parent, result); - } + int childCount = 0; + if (parent == root) { + childCount = storage.getProjectsCount(); + } else { + TimerTask parentTask = (TimerTask)parent; + childCount = storage.getTasksCount(parentTask); } - return result; + return childCount; } /* @@ -272,9 +217,7 @@ */ @Override public int getIndexOfChild(Object parent, Object child) { - - int childIndex = getFiteredSubListFor(parent).indexOf(child); - return childIndex; + throw new RuntimeException("Not yet implemented"); } /* @@ -312,10 +255,9 @@ boolean updated = false; // get childreen without cache in case of add operation // delete operation MUST use cached result - List<TimerTask> subTask = getFiteredSubListFor(pathLastComponent, operation == OPERATION_ADD); - int childCount = subTask.size(); + int childCount = getChildCount(pathLastComponent); for (int childIndex = 0; !updated && childIndex < childCount; ++childIndex) { - TimerTask taskUO = subTask.get(childIndex); + TimerTask taskUO = (TimerTask)getChild(pathLastComponent, childIndex); if (task.equals(taskUO)) { Modified: branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksTable.java =================================================================== --- branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksTable.java 2012-07-12 12:51:48 UTC (rev 2883) +++ branches/2.0.0-evol-499-storage/src/main/java/org/chorem/jtimer/ui/treetable/ProjectsAndTasksTable.java 2012-07-13 09:13:42 UTC (rev 2884) @@ -34,6 +34,7 @@ import org.chorem.jtimer.data.TimerCore; import org.chorem.jtimer.entities.TimerProject; import org.chorem.jtimer.entities.TimerTask; +import org.chorem.jtimer.storage.Storage; import org.chorem.jtimer.ui.treetable.dnd.TimerTaskTransferHandler; import org.jdesktop.application.Application; import org.jdesktop.application.ApplicationContext; @@ -76,20 +77,19 @@ // start with init i18n of table column name ApplicationContext ctxt = application.getContext(); ResourceManager mgr = ctxt.getResourceManager(); - ResourceMap resourceMap = mgr - .getResourceMap(ProjectsAndTasksTable.class); + ResourceMap resourceMap = mgr.getResourceMap(ProjectsAndTasksTable.class); + // init list List<String> columnIdentifiers = new ArrayList<String>(); - columnIdentifiers.add(resourceMap - .getString("projectsAndTaskColumnName")); + columnIdentifiers.add(resourceMap.getString("projectsAndTaskColumnName")); columnIdentifiers.add(resourceMap.getString("todayTimeColumnName")); columnIdentifiers.add(resourceMap.getString("totalTimeColumnName")); // set model - treeTableModel = new ProjectsAndTasksModel(this, core, columnIdentifiers); + treeTableModel = new ProjectsAndTasksModel(this, core.getStorage(), columnIdentifiers); // set renderer - treeCellRenderer = new ProjectsAndTasksCellRenderer(this, core); + treeCellRenderer = new ProjectsAndTasksCellRenderer(this); setTreeCellRenderer(treeCellRenderer); setTreeTableModel(treeTableModel); @@ -100,6 +100,7 @@ //treeTableModel.setSortColumn("Projects & Tasks"); core.getData().addDataEventListener(treeTableModel); + core.getData().addDataEventListener(treeCellRenderer); // enable drag n drop setDragEnabled(true); @@ -168,7 +169,7 @@ if (path != null) { Object[] pathWay = path.getPath(); - if (pathWay.length >= 2) { // 1 = root, 2=project , 3+=task + if (pathWay.length >= 2) { // 1= root, 2=project , 3+=task // le last est la derniere feuille selectionnee, donc la // tache TimerTask task = (TimerTask) pathWay[pathWay.length - 1]; Added: branches/2.0.0-evol-499-storage/src/test/java/org/chorem/jtimer/storage/StorageTest.java =================================================================== --- branches/2.0.0-evol-499-storage/src/test/java/org/chorem/jtimer/storage/StorageTest.java (rev 0) +++ branches/2.0.0-evol-499-storage/src/test/java/org/chorem/jtimer/storage/StorageTest.java 2012-07-13 09:13:42 UTC (rev 2884) @@ -0,0 +1,32 @@ +package org.chorem.jtimer.storage; + +import java.io.File; + +import org.chorem.jtimer.AbstractJTimerTest; +import org.chorem.jtimer.JTimer; +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +/** + * Test du stockage sql seulement. + * + * @author echatellier + */ +public class StorageTest extends AbstractJTimerTest { + + protected Storage storage; + + @BeforeMethod + public void setUp() { + String location = System.getProperty("java.io.tmpdir") + File.separator + "jtimer"; + JTimer.config.setStrorageDatabaseLocation(location); + + storage = new Storage(JTimer.config); + } + + @Test + public void testGetSubTask() { + Assert.assertEquals(storage.getProjectsCount(), 0); + } +} Property changes on: branches/2.0.0-evol-499-storage/src/test/java/org/chorem/jtimer/storage/StorageTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL