Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Mylyn » Trac Timing and Estimation Plugin mylyn integration
Trac Timing and Estimation Plugin mylyn integration [message #598016] Sat, 04 July 2009 23:16
phil is currently offline philFriend
Messages: 6
Registered: July 2009
Junior Member
Yesterday I installed mylyn and was blown away. However, what I found to
be lacking was integration with the Trac Timing and Estimation Plugin so
that time tracking happens automatically when a task is de/activated.
Today I started working on a patch for the e_3_3_m_3_x branch and to my
surprise it works. I'm pretty sure my design is ugly as hell, but I don't
have time to dig in right now and do it properly. What I did:

* added a totalhours field and setters/getters to AbstractTask
* when the tooltips are generated in TaskListToolTip I just return the
time stored in AbstractTask if there's any and the standard
TaskActivityManager().getElapsedTime() otherwise
* in TaskActivityManager.de/activateTask() I call a chain of functions
ultimately leading to TracXmlRpcClient.de/activateTask() where a XML-RPC
request is sent to Trac
* in TaskActivityMonitor.stop() i deactivate the currently active task so
that Trac doesn't continue counting the time if somebody forgets to
deactivate the active task before quitting

It's not perfect but it works. The elapsed time stored in Trac is only
visible after a refresh and isn't stored locally. Here's the patch:

### Eclipse Workspace Patch 1.0
#P org.eclipse.mylyn.trac.core
Index:
src/org/eclipse/mylyn/internal/trac/core/client/AbstractTrac Client.java
============================================================ =======
RCS file:
/cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.trac.core /src/org/eclipse/mylyn/internal/trac/core/client/AbstractTra cClient.java,v
retrieving revision 1.9
diff -u -r1.9 AbstractTracClient.java
---
src/org/eclipse/mylyn/internal/trac/core/client/AbstractTrac Client.java 22
Jun 2009 02:00:53 -0000 1.9
+++
src/org/eclipse/mylyn/internal/trac/core/client/AbstractTrac Client.java 4
Jul 2009 22:49:40 -0000
@@ -37,6 +37,7 @@
import org.eclipse.mylyn.internal.trac.core.model.TracTicketStatus;
import org.eclipse.mylyn.internal.trac.core.model.TracTicketType;
import org.eclipse.mylyn.internal.trac.core.model.TracVersion;
+import org.eclipse.mylyn.tasks.core.ITask;

/**
* @author Steffen Pingel
@@ -232,4 +233,9 @@
return null;
}

+ public void activateTask(ITask task) {
+ }
+
+ public void deactivateTask() {
+ }
}
Index:
src/org/eclipse/mylyn/internal/trac/core/client/TracXmlRpcCl ient.java
============================================================ =======
RCS file:
/cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.trac.core /src/org/eclipse/mylyn/internal/trac/core/client/TracXmlRpcC lient.java,v
retrieving revision 1.20
diff -u -r1.20 TracXmlRpcClient.java
---
src/org/eclipse/mylyn/internal/trac/core/client/TracXmlRpcCl ient.java 22
Jun 2009 02:00:53 -0000 1.20
+++
src/org/eclipse/mylyn/internal/trac/core/client/TracXmlRpcCl ient.java 4
Jul 2009 22:49:40 -0000
@@ -80,6 +80,7 @@
import org.eclipse.mylyn.internal.trac.core.util.TracUtil;
import org.eclipse.mylyn.internal.trac.core.util.TracXmlRpcClientRe quest;
import
org.eclipse.mylyn.internal.trac.core.util.TracHttpClientTran sportFactory.TracHttpException;
+import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.osgi.util.NLS;

/**
@@ -1125,10 +1126,10 @@
* An InputStream of the content of the attachment
* @param replace
* whether to overwrite an existing attachment with the same
filename
- * @return The (possibly transformed) filename of the attachment. If
<code>replace</code> is <code>true</code>, the
- * returned name is always the same as the argument
<code>fileName</code>; if <code>replace</code> is
- * <code>false</code> and an attachment with name
<code>fileName</code> already exists, a number is appended
- * to the file name (before suffix) and the generated filename
of the attachment is returned.
+ * @return The (possibly transformed) filename of the attachment. If
<code>replace</code> is <code>true</code>,
+ * the returned name is always the same as the argument
<code>fileName</code>; if <code>replace</code>
+ * is <code>false</code> and an attachment with name
<code>fileName</code> already exists, a number is
+ * appended to the file name (before suffix) and the generated
filename of the attachment is returned.
* @throws TracException
*/
public String putWikiPageAttachmentData(String pageName, String
fileName, String description, InputStream in,
@@ -1146,4 +1147,21 @@
call(monitor, "ticket.delete", ticketId); //$NON-NLS-1$
}

+ @Override
+ public void activateTask(ITask task) {
+ try {
+ call(null, "worklog.startWork", Integer.parseInt(task.getTaskId()));
+ } catch (TracException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void deactivateTask() {
+ try {
+ call(null, "worklog.stopWork", "", 0);
+ } catch (TracException e) {
+ throw new RuntimeException(e);
+ }
+ }
}
\ No newline at end of file
Index: src/org/eclipse/mylyn/internal/trac/core/client/ITracClient. java
============================================================ =======
RCS file:
/cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.trac.core /src/org/eclipse/mylyn/internal/trac/core/client/ITracClient .java,v
retrieving revision 1.10
diff -u -r1.10 ITracClient.java
--- src/org/eclipse/mylyn/internal/trac/core/client/ITracClient. java 20
Jun 2009 07:32:02 -0000 1.10
+++ src/org/eclipse/mylyn/internal/trac/core/client/ITracClient. java 4 Jul
2009 22:49:40 -0000
@@ -29,6 +29,7 @@
import org.eclipse.mylyn.internal.trac.core.model.TracTicketStatus;
import org.eclipse.mylyn.internal.trac.core.model.TracTicketType;
import org.eclipse.mylyn.internal.trac.core.model.TracVersion;
+import org.eclipse.mylyn.tasks.core.ITask;

/**
* Defines the requirements for classes that provide remote access to
Trac repositories.
@@ -209,4 +210,7 @@

void deleteTicket(int ticketId, IProgressMonitor monitor) throws
TracException;

+ public void activateTask(ITask task);
+
+ public void deactivateTask();
}
Index: src/org/eclipse/mylyn/internal/trac/core/TracTaskDataHandler .java
============================================================ =======
RCS file:
/cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.trac.core /src/org/eclipse/mylyn/internal/trac/core/TracTaskDataHandle r.java,v
retrieving revision 1.73
diff -u -r1.73 TracTaskDataHandler.java
--- src/org/eclipse/mylyn/internal/trac/core/TracTaskDataHandler .java 2
Jul 2009 06:52:44 -0000 1.73
+++ src/org/eclipse/mylyn/internal/trac/core/TracTaskDataHandler .java 4
Jul 2009 22:49:40 -0000
@@ -660,4 +660,31 @@
}
}

+ public void activateTask(TaskRepository repository, ITask task) {
+ if (repository == null) {
+ return;
+ }
+
+ ITracClient server =
connector.getClientManager().getTracClient(repository);
+
+ if (server == null) {
+ return;
+ }
+
+ server.activateTask(task);
+ }
+
+ public void deactivateTask(TaskRepository repository) {
+ if (repository == null) {
+ return;
+ }
+
+ ITracClient server =
connector.getClientManager().getTracClient(repository);
+
+ if (server == null) {
+ return;
+ }
+
+ server.deactivateTask();
+ }
}
Index: src/org/eclipse/mylyn/internal/trac/core/TracCorePlugin.java
============================================================ =======
RCS file:
/cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.trac.core /src/org/eclipse/mylyn/internal/trac/core/TracCorePlugin.jav a,v
retrieving revision 1.25
diff -u -r1.25 TracCorePlugin.java
--- src/org/eclipse/mylyn/internal/trac/core/TracCorePlugin.java 13 Jan
2009 07:05:20 -0000 1.25
+++ src/org/eclipse/mylyn/internal/trac/core/TracCorePlugin.java 4 Jul
2009 22:49:39 -0000
@@ -106,8 +106,8 @@
return new RepositoryStatus(IStatus.ERROR, ID_PLUGIN,
RepositoryStatus.ERROR_IO,
Messages.TracCorePlugin_Repository_URL_is_invalid, e);
} else {
- return new RepositoryStatus(IStatus.ERROR, ID_PLUGIN,
RepositoryStatus.ERROR_INTERNAL, Messages.TracCorePlugin_Unexpected_error,
- e);
+ return new RepositoryStatus(IStatus.ERROR, ID_PLUGIN,
RepositoryStatus.ERROR_INTERNAL,
+ Messages.TracCorePlugin_Unexpected_error, e);
}
}

Index:
src/org/eclipse/mylyn/internal/trac/core/TracRepositoryConne ctor.java
============================================================ =======
RCS file:
/cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.trac.core /src/org/eclipse/mylyn/internal/trac/core/TracRepositoryConn ector.java,v
retrieving revision 1.106
diff -u -r1.106 TracRepositoryConnector.java
---
src/org/eclipse/mylyn/internal/trac/core/TracRepositoryConne ctor.java 14
Jun 2009 23:38:26 -0000 1.106
+++
src/org/eclipse/mylyn/internal/trac/core/TracRepositoryConne ctor.java 4
Jul 2009 22:49:39 -0000
@@ -31,6 +31,7 @@
import org.eclipse.mylyn.commons.net.AuthenticationCredentials;
import org.eclipse.mylyn.commons.net.AuthenticationType;
import org.eclipse.mylyn.commons.net.Policy;
+import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
import org.eclipse.mylyn.internal.trac.core.client.AbstractWikiHand ler;
import org.eclipse.mylyn.internal.trac.core.client.ITracClient;
import org.eclipse.mylyn.internal.trac.core.client.ITracWikiClient;
@@ -652,6 +653,18 @@
task.setCompletionDate(null);
}
}
+
+ if (task instanceof AbstractTask) {
+ Map<String, TaskAttribute> attributes =
taskData.getRoot().getAttributes();
+
+ if (attributes.get("totalhours") != null) {
+ AbstractTask atask = (AbstractTask) task;
+ float totalHours =
Float.parseFloat(attributes.get("totalhours").getValue());
+
+ atask.setTotalTimeHours(totalHours);
+ }
+ }
+
task.setUrl(taskRepository.getRepositoryUrl() + ITracClient.TICKET_URL
+ taskData.getTaskId());
if (!taskData.isPartial()) {
task.setAttribute(TASK_KEY_SUPPORTS_SUBTASKS,
Boolean.toString(taskDataHandler.supportsSubtasks(taskData)) );
@@ -696,4 +709,13 @@
return new TracTaskMapper(taskData, client);
}

+ @Override
+ public void activateTask(TaskRepository repository, ITask task) {
+ taskDataHandler.activateTask(repository, task);
+ }
+
+ @Override
+ public void deactivateTask(TaskRepository repository) {
+ taskDataHandler.deactivateTask(repository);
+ }
}
#P org.eclipse.mylyn.tasks.ui
Index: src/org/eclipse/mylyn/internal/tasks/ui/views/TaskListToolTi p.java
============================================================ =======
RCS file:
/cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.tasks.ui/ src/org/eclipse/mylyn/internal/tasks/ui/views/TaskListToolTi p.java,v
retrieving revision 1.69
diff -u -r1.69 TaskListToolTip.java
--- src/org/eclipse/mylyn/internal/tasks/ui/views/TaskListToolTi p.java 22
Jun 2009 21:19:28 -0000 1.69
+++ src/org/eclipse/mylyn/internal/tasks/ui/views/TaskListToolTi p.java 4
Jul 2009 22:49:42 -0000
@@ -183,15 +183,20 @@
for (ITask child : container.getChildren()) {
if (child instanceof AbstractTask) {
estimateTotal += ((AbstractTask) child).getEstimatedTimeHours();
- elapsedTotal +=
TasksUiPlugin.getTaskActivityManager().getElapsedTime(child,
- container.getDateRange());
+
+ if (((AbstractTask) child).getTotalTimeHours() > 0) {
+ elapsedTotal += (long) (((AbstractTask) child).getTotalTimeHours()
* 3600 * 1000);
+ } else {
+ elapsedTotal +=
TasksUiPlugin.getTaskActivityManager().getElapsedTime(child,
+ container.getDateRange());
+ }
}
}
StringBuilder sb = new StringBuilder();
sb.append(NLS.bind(Messages.TaskListToolTip_Estimate, estimateTotal));
- sb.append("\n"); //$NON-NLS-1$
+ sb.append("\n");
sb.append(NLS.bind(Messages.TaskListToolTip_Elapsed,
DateUtil.getFormattedDurationShort(elapsedTotal)));
- sb.append("\n"); //$NON-NLS-1$
+ sb.append("\n");
return sb.toString();
} else if (element instanceof ITask) {
ITask task = (ITask) element;
@@ -204,21 +209,21 @@
}
String key = task.getTaskKey();
if (key != null) {
- sb.append(" "); //$NON-NLS-1$
+ sb.append(" ");
sb.append(key);
}
String taskKind = task.getTaskKind();
if (taskKind != null && taskKind.length() > 0 &&
!taskKind.equals(kindLabel)) {
- sb.append(" ("); //$NON-NLS-1$
+ sb.append(" (");
sb.append(taskKind);
- sb.append(") "); //$NON-NLS-1$
+ sb.append(") ");
}
- sb.append(", "); //$NON-NLS-1$
+ sb.append(", ");
sb.append(task.getPriority());
- sb.append(" ["); //$NON-NLS-1$
+ sb.append(" [");
sb.append(getRepositoryLabel(task.getConnectorKind(),
task.getRepositoryUrl()));
- sb.append("]"); //$NON-NLS-1$
- sb.append("\n"); //$NON-NLS-1$
+ sb.append("]");
+ sb.append("\n");
return sb.toString();
} else {
return null;
@@ -281,8 +286,13 @@
}

long elapsed =
TasksUiPlugin.getTaskActivityManager().getElapsedTime(task);
+
+ if (task.getTotalTimeHours() > 0) {
+ elapsed = (int) (task.getTotalTimeHours() * 3600 * 1000);
+ }
+
sb.append(NLS.bind(Messages.TaskListToolTip_Elapsed,
DateUtil.getFormattedDurationShort(elapsed)));
- sb.append("\n"); //$NON-NLS-1$
+ sb.append("\n");

return sb.toString();
}
Index: src/org/eclipse/mylyn/internal/tasks/ui/TaskActivityMonitor. java
============================================================ =======
RCS file:
/cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.tasks.ui/ src/org/eclipse/mylyn/internal/tasks/ui/TaskActivityMonitor. java,v
retrieving revision 1.22
diff -u -r1.22 TaskActivityMonitor.java
--- src/org/eclipse/mylyn/internal/tasks/ui/TaskActivityMonitor. java 1 May
2009 22:59:22 -0000 1.22
+++ src/org/eclipse/mylyn/internal/tasks/ui/TaskActivityMonitor. java 4 Jul
2009 22:49:41 -0000
@@ -115,6 +115,7 @@
}

public void stop() {
+ taskActivityManager.deactivateActiveTask();
contextManager.removeActivityMetaContextListener(CONTEXT_LIS TENER);
}

#P org.eclipse.mylyn.tasks.core
Index: src/org/eclipse/mylyn/tasks/core/AbstractRepositoryConnector .java
============================================================ =======
RCS file:
/cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.tasks.cor e/src/org/eclipse/mylyn/tasks/core/AbstractRepositoryConnect or.java,v
retrieving revision 1.114
diff -u -r1.114 AbstractRepositoryConnector.java
--- src/org/eclipse/mylyn/tasks/core/AbstractRepositoryConnector .java 17
Dec 2008 00:34:32 -0000 1.114
+++ src/org/eclipse/mylyn/tasks/core/AbstractRepositoryConnector .java 4
Jul 2009 22:49:43 -0000
@@ -29,9 +29,7 @@

/**
* Encapsulates common operations that can be performed on a task
repository. Extend to connect with a Java API or WS
- * API for accessing the repository.
- *
- * Only methods that take a progress monitor can do network I/O.
+ * API for accessing the repository. Only methods that take a progress
monitor can do network I/O.
*
* @author Mik Kersten
* @author Rob Elves
@@ -215,9 +213,8 @@
}

/**
- * Runs <code>query</code> on <code>repository</code>, results are
passed to <code>collector</code>. If a repository
- * does not return the full task data for a result, {@link
TaskData#isPartial()} will return true.
- *
+ * Runs <code>query</code> on <code>repository</code>, results are
passed to <code>collector</code>. If a
+ * repository does not return the full task data for a result, {@link
TaskData#isPartial()} will return true.
* <p>
* Implementors must complete executing <code>query</code> before
returning from this method.
*
@@ -278,4 +275,9 @@
*/
public abstract void updateTaskFromTaskData(TaskRepository
taskRepository, ITask task, TaskData taskData);

+ public void activateTask(TaskRepository repository, ITask task) {
+ }
+
+ public void deactivateTask(TaskRepository repository) {
+ }
}
Index: src/org/eclipse/mylyn/internal/tasks/core/TaskActivityManage r.java
============================================================ =======
RCS file:
/cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.tasks.cor e/src/org/eclipse/mylyn/internal/tasks/core/TaskActivityMana ger.java,v
retrieving revision 1.72
diff -u -r1.72 TaskActivityManager.java
--- src/org/eclipse/mylyn/internal/tasks/core/TaskActivityManage r.java 11
Mar 2009 00:12:44 -0000 1.72
+++ src/org/eclipse/mylyn/internal/tasks/core/TaskActivityManage r.java 4
Jul 2009 22:49:43 -0000
@@ -29,6 +29,7 @@
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.mylyn.commons.core.StatusHandler;
+import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.mylyn.tasks.core.ITaskActivationListener;
import org.eclipse.mylyn.tasks.core.ITaskActivityListener;
@@ -103,7 +104,6 @@
* Set the first day of the week (Calendar.SUNDAY | Calendar.MONDAY)
*
* @see
http://en.wikipedia.org/wiki/Days_of_the_week#First_day_of_t he_week
- *
* @param startDay
* (Calendar.SUNDAY | Calendar.MONDAY)
*/
@@ -417,6 +417,12 @@
activeTask = task;
((AbstractTask) activeTask).setActive(true);

+ AbstractRepositoryConnector connector =
repositoryManager.getRepositoryConnector(task.getConnectorKi nd());
+
+ if (connector != null) {
+ connector.activateTask(repositoryManager.getRepository(task. getRepositoryUrl()),
task);
+ }
+
for (ITaskActivationListener listener : new
ArrayList<ITaskActivationListener>(activationListeners)) {
try {
listener.taskActivated(task);
@@ -452,6 +458,12 @@
((AbstractTask) activeTask).setActive(false);
activeTask = null;

+ AbstractRepositoryConnector connector =
repositoryManager.getRepositoryConnector(task.getConnectorKi nd());
+
+ if (connector != null) {
+ connector.deactivateTask(repositoryManager.getRepository(tas k.getRepositoryUrl()));
+ }
+
for (ITaskActivationListener listener : new
ArrayList<ITaskActivationListener>(activationListeners)) {
try {
listener.taskDeactivated(task);
Index: src/org/eclipse/mylyn/internal/tasks/core/AbstractTask.java
============================================================ =======
RCS file:
/cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.tasks.cor e/src/org/eclipse/mylyn/internal/tasks/core/AbstractTask.jav a,v
retrieving revision 1.34
diff -u -r1.34 AbstractTask.java
--- src/org/eclipse/mylyn/internal/tasks/core/AbstractTask.java 8 May 2009
04:43:30 -0000 1.34
+++ src/org/eclipse/mylyn/internal/tasks/core/AbstractTask.java 4 Jul 2009
22:49:43 -0000
@@ -84,6 +84,8 @@

private int estimatedTimeHours = 1;

+ private float totalTimeHours = -1;
+
private boolean markReadPending;

// TODO 4.0 make private
@@ -303,6 +305,14 @@
this.estimatedTimeHours = estimated;
}

+ public float getTotalTimeHours() {
+ return totalTimeHours;
+ }
+
+ public void setTotalTimeHours(float total) {
+ this.totalTimeHours = total;
+ }
+
void addParentContainer(AbstractTaskContainer container) {
containers.add(container);
}
Index: .refactorings/2009/7/27/refactorings.index
============================================================ =======
RCS file: .refactorings/2009/7/27/refactorings.index
diff -N .refactorings/2009/7/27/refactorings.index
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ .refactorings/2009/7/27/refactorings.index 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,1 @@
+1246743674234 Rename method 'acticateTask'
Index: .refactorings/2009/7/27/refactorings.history
============================================================ =======
RCS file: .refactorings/2009/7/27/refactorings.history
diff -N .refactorings/2009/7/27/refactorings.history
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ .refactorings/2009/7/27/refactorings.history 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<session version="1.0">
+<refactoring comment="Rename method
&apos;org.eclipse.mylyn.tasks.core.AbstractRepositoryCon nector.acticateTask(...)&apos;
to &apos;activateTask&apos;&#x0D;&#x0A;- Original project:
&apos;org.eclipse.mylyn.tasks.core&apos;&#x0D;&a mp;#x0A;- Original element:
&apos;org.eclipse.mylyn.tasks.core.AbstractRepositoryCon nector.acticateTask(...)&apos;&#x0D;&#x0A;-
Renamed element:
&apos;org.eclipse.mylyn.tasks.core.AbstractRepositoryCon nector.activateTask(...)&apos;&#x0D;&#x0A;-
Update references to refactored element" delegate="false"
deprecate="false" description="Rename method &apos;acticateTask&apos;"
flags="589830" id="org.eclipse.jdt.ui.rename.method"
input=" /src&lt;org.eclipse.mylyn.tasks.core{AbstractRepositoryC onnector.java[AbstractRepositoryConnector~acticateTask~QITas k; "
name="activateTask" references="true" stamp="1246743674234" version="1.0"/>
+</session>
Previous Topic:problems updating to the weekly build as of today
Next Topic:superscript rendering
Goto Forum:
  


Current Time: Fri Nov 28 21:42:29 GMT 2014

Powered by FUDForum. Page generated in 0.03049 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software