Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 117517 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/mylar/team/MylarTeamPlugin.java (-62 / +86 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004 - 2006 University Of British Columbia and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     University Of British Columbia - initial API and implementation
10
 *     Eike Stepper - template based commit templates
11
 *******************************************************************************/
1
package org.eclipse.mylar.team;
12
package org.eclipse.mylar.team;
2
13
14
3
import org.eclipse.mylar.context.core.MylarStatusHandler;
15
import org.eclipse.mylar.context.core.MylarStatusHandler;
4
import org.eclipse.mylar.internal.team.ContextChangeSetManager;
16
import org.eclipse.mylar.internal.team.ContextChangeSetManager;
5
import org.eclipse.ui.IStartup;
17
import org.eclipse.ui.IStartup;
Lines 7-79 Link Here
7
import org.eclipse.ui.plugin.AbstractUIPlugin;
19
import org.eclipse.ui.plugin.AbstractUIPlugin;
8
import org.osgi.framework.BundleContext;
20
import org.osgi.framework.BundleContext;
9
21
22
10
/**
23
/**
11
 * The activator class controls the plug-in life cycle
24
 * The activator class controls the plug-in life cycle
12
 */
25
 */
13
public class MylarTeamPlugin extends AbstractUIPlugin implements IStartup {
26
public class MylarTeamPlugin extends AbstractUIPlugin implements IStartup
27
{
14
28
15
	public static final String PLUGIN_ID = "org.eclipse.mylar.team";
29
  public static final String PLUGIN_ID = "org.eclipse.mylar.team";
16
30
17
	private static MylarTeamPlugin INSTANCE;
31
  private static MylarTeamPlugin INSTANCE;
18
32
19
	private ContextChangeSetManager changeSetManager;
33
  private ContextChangeSetManager changeSetManager;
20
34
21
	public static final String CHANGE_SET_MANAGE = "org.eclipse.mylar.team.changesets.manage";
35
  public static final String CHANGE_SET_MANAGE = "org.eclipse.mylar.team.changesets.manage";
22
36
23
	public static final String COMMIT_PREFIX_COMPLETED = "org.eclipse.mylar.team.commit.template.completed";
37
  public static final String COMMIT_TEMPLATE_COMPLETED = "org.eclipse.mylar.team.commit.template.completed";
24
38
25
	public static final String COMMIT_PREFIX_PROGRESS = "org.eclipse.mylar.team.commit.template.progress";
39
  public static final String COMMIT_TEMPLATE_PROGRESS = "org.eclipse.mylar.team.commit.template.progress";
26
40
27
	public static final String DEFAULT_PREFIX_PROGRESS = "Progress on:";
41
  public static final String DEFAULT_TEMPLATE_PROGRESS = "[${task.id}] ${task.summary}";
28
42
29
	public static final String DEFAULT_PREFIX_COMPLETED = "Completed:";
43
  public static final String DEFAULT_TEMPLATE_COMPLETED = "[${task.id}] ${task.summary} (COMPLETED)";
30
44
31
	public MylarTeamPlugin() {
45
  public MylarTeamPlugin()
32
		INSTANCE = this;
46
  {
33
	}
47
    INSTANCE = this;
34
48
  }
35
	public void start(BundleContext context) throws Exception {
49
36
		super.start(context);
50
  public void start(BundleContext context) throws Exception
37
		initPreferenceDefaults();
51
  {
38
52
    super.start(context);
39
		PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
53
    initPreferenceDefaults();
40
			public void run() {
54
41
				try { 
55
    PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable()
42
					changeSetManager = new ContextChangeSetManager();
56
    {
43
					if (getPreferenceStore().getBoolean(CHANGE_SET_MANAGE)) {
57
      public void run()
44
						changeSetManager.enable();
58
      {
45
					}
59
        try
46
				} catch (Exception e) {
60
        {
47
					MylarStatusHandler.fail(e, "Mylar Team start failed",
61
          changeSetManager = new ContextChangeSetManager();
48
							false);
62
          if (getPreferenceStore().getBoolean(CHANGE_SET_MANAGE))
49
				}
63
          {
50
			}
64
            changeSetManager.enable();
51
		});
65
          }
52
	}
66
        }
53
67
        catch (Exception e)
54
	public void earlyStartup() {
68
        {
55
		// all done in start	
69
          MylarStatusHandler.fail(e, "Mylar Team start failed", false);
56
	}
70
        }
57
	
71
      }
58
	public void stop(BundleContext context) throws Exception {
72
    });
59
		INSTANCE = null;
73
  }
60
		super.stop(context);
74
61
		changeSetManager.disable();
75
  public void earlyStartup()
62
	}
76
  {
63
77
    // all done in start	
64
	private void initPreferenceDefaults() {
78
  }
65
		getPreferenceStore().setDefault(CHANGE_SET_MANAGE, true);
79
66
		getPreferenceStore().setDefault(COMMIT_PREFIX_COMPLETED,
80
  public void stop(BundleContext context) throws Exception
67
				DEFAULT_PREFIX_COMPLETED);
81
  {
68
		getPreferenceStore().setDefault(COMMIT_PREFIX_PROGRESS,
82
    INSTANCE = null;
69
				DEFAULT_PREFIX_PROGRESS);
83
    super.stop(context);
70
	}
84
    changeSetManager.disable();
71
85
  }
72
	public static MylarTeamPlugin getDefault() {
86
73
		return INSTANCE;
87
  private void initPreferenceDefaults()
74
	}
88
  {
75
89
    getPreferenceStore().setDefault(CHANGE_SET_MANAGE, true);
76
	public ContextChangeSetManager getChangeSetManager() {
90
    getPreferenceStore().setDefault(COMMIT_TEMPLATE_COMPLETED, DEFAULT_TEMPLATE_COMPLETED);
77
		return changeSetManager;
91
    getPreferenceStore().setDefault(COMMIT_TEMPLATE_PROGRESS, DEFAULT_TEMPLATE_PROGRESS);
78
	}
92
  }
93
94
  public static MylarTeamPlugin getDefault()
95
  {
96
    return INSTANCE;
97
  }
98
99
  public ContextChangeSetManager getChangeSetManager()
100
  {
101
    return changeSetManager;
102
  }
79
}
103
}
(-)src/org/eclipse/mylar/internal/team/ContextChangeSet.java (-240 / +312 lines)
Lines 7-21 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     University Of British Columbia - initial API and implementation
9
 *     University Of British Columbia - initial API and implementation
10
 *     Eike Stepper - template based commit templates
10
 *******************************************************************************/
11
 *******************************************************************************/
11
12
package org.eclipse.mylar.internal.team;
12
package org.eclipse.mylar.internal.team;
13
13
14
import java.util.ArrayList;
15
import java.util.Arrays;
16
import java.util.HashSet;
17
import java.util.List;
18
import java.util.Set;
19
14
20
import org.eclipse.core.resources.IResource;
15
import org.eclipse.core.resources.IResource;
21
import org.eclipse.core.resources.ResourcesPlugin;
16
import org.eclipse.core.resources.ResourcesPlugin;
Lines 25-30 Link Here
25
import org.eclipse.mylar.context.core.InteractionEvent;
20
import org.eclipse.mylar.context.core.InteractionEvent;
26
import org.eclipse.mylar.resources.MylarResourcesPlugin;
21
import org.eclipse.mylar.resources.MylarResourcesPlugin;
27
import org.eclipse.mylar.tasks.core.ITask;
22
import org.eclipse.mylar.tasks.core.ITask;
23
import org.eclipse.mylar.team.ITemplateHandlersManager;
28
import org.eclipse.mylar.team.MylarTeamPlugin;
24
import org.eclipse.mylar.team.MylarTeamPlugin;
29
import org.eclipse.team.core.TeamException;
25
import org.eclipse.team.core.TeamException;
30
import org.eclipse.team.core.diff.IDiff;
26
import org.eclipse.team.core.diff.IDiff;
Lines 35-279 Link Here
35
import org.eclipse.team.internal.core.subscribers.ActiveChangeSetManager;
31
import org.eclipse.team.internal.core.subscribers.ActiveChangeSetManager;
36
import org.osgi.service.prefs.Preferences;
32
import org.osgi.service.prefs.Preferences;
37
33
34
import java.util.ArrayList;
35
import java.util.Arrays;
36
import java.util.HashSet;
37
import java.util.List;
38
import java.util.Set;
39
40
38
/**
41
/**
39
 * @author Mik Kersten
42
 * @author Mik Kersten
40
 */
43
 */
41
public class ContextChangeSet extends CVSActiveChangeSet implements IAdaptable {
44
public class ContextChangeSet extends CVSActiveChangeSet implements IAdaptable
45
{
42
46
43
	private static final String PREFIX_HTTP = "http://";
47
  private static final String PREFIX_HTTP = "http://";
44
48
45
	private static final String PREFIX_HTTPS = "https://";
49
  private static final String PREFIX_HTTPS = "https://";
46
50
47
	private static final String PREFIX_DELIM = ": ";
51
  private static final String PREFIX_DELIM = ": ";
48
52
49
	// HACK: copied from super
53
  // HACK: copied from super
50
	private static final String CTX_TITLE = "title";
54
  private static final String CTX_TITLE = "title";
51
55
52
	public static final String SOURCE_ID = "org.eclipse.mylar.java.context.changeset.add";
56
  public static final String SOURCE_ID = "org.eclipse.mylar.java.context.changeset.add";
53
57
54
	private boolean suppressInterestContribution = false;
58
  private boolean suppressInterestContribution = false;
55
59
56
	private ITask task;
60
  private ITask task;
57
61
58
	public ContextChangeSet(ITask task, ActiveChangeSetManager manager) {
62
  public ContextChangeSet(ITask task, ActiveChangeSetManager manager)
59
		super(manager, task.getDescription());
63
  {
60
		this.task = task;
64
    super(manager, task.getDescription());
61
		initTitle();
65
    this.task = task;
62
	}
66
    initTitle();
63
67
  }
64
	@Override
68
65
	public boolean isUserCreated() {
69
  @Override
66
		return true;
70
  public boolean isUserCreated()
67
	}
71
  {
68
	
72
    return true;
69
	public void initTitle() {
73
  }
70
		super.setName(task.getDescription());
74
71
		super.setTitle(task.getDescription());
75
  public void initTitle()
72
	}
76
  {
73
77
    super.setName(task.getDescription());
74
	/**
78
    super.setTitle(task.getDescription());
75
	 * Encodes the handle in the title, since init won't get called on this
79
  }
76
	 * class.
80
77
	 */
81
  /**
78
	@Override
82
   * Encodes the handle in the title, since init won't get called on this
79
	public void save(Preferences prefs) {
83
   * class.
80
		super.save(prefs);
84
   */
81
		prefs.put(CTX_TITLE, getTitleForPersistance());
85
  @Override
82
	}
86
  public void save(Preferences prefs)
83
87
  {
84
	private String getTitleForPersistance() {
88
    super.save(prefs);
85
		return getTitle() + " (" + task.getHandleIdentifier() + ")";
89
    prefs.put(CTX_TITLE, getTitleForPersistance());
86
	}
90
  }
87
91
88
	public static String getHandleFromPersistedTitle(String title) {
92
  private String getTitleForPersistance()
89
		int delimStart = title.lastIndexOf('(');
93
  {
90
		int delimEnd = title.lastIndexOf(')');
94
    return getTitle() + " (" + task.getHandleIdentifier() + ")";
91
		if (delimStart != -1 && delimEnd != -1) {
95
  }
92
			return title.substring(delimStart + 1, delimEnd);
96
93
		} else {
97
  public static String getHandleFromPersistedTitle(String title)
94
			return null;
98
  {
95
		}
99
    int delimStart = title.lastIndexOf('(');
96
	}
100
    int delimEnd = title.lastIndexOf(')');
97
101
    if (delimStart != -1 && delimEnd != -1)
98
	@Override
102
    {
99
	public String getComment() {
103
      return title.substring(delimStart + 1, delimEnd);
100
		String completedPrefix = MylarTeamPlugin.getDefault().getPreferenceStore().getString(
104
    }
101
				MylarTeamPlugin.COMMIT_PREFIX_COMPLETED);
105
    else
102
		String progressPrefix = MylarTeamPlugin.getDefault().getPreferenceStore().getString(
106
    {
103
				MylarTeamPlugin.COMMIT_PREFIX_PROGRESS);
107
      return null;
104
		String comment = "";
108
    }
105
		comment = generateComment(task, completedPrefix, progressPrefix);
109
  }
106
		return comment;
110
107
	}
111
  @Override
108
112
  public String getComment()
109
	@Override
113
  {
110
	public void remove(IResource resource) {
114
    String completedTemplate = MylarTeamPlugin.getDefault().getPreferenceStore().getString(
111
		super.remove(resource);
115
            MylarTeamPlugin.COMMIT_TEMPLATE_COMPLETED);
112
	}
116
    String progressTemplate = MylarTeamPlugin.getDefault().getPreferenceStore().getString(
113
117
            MylarTeamPlugin.COMMIT_TEMPLATE_PROGRESS);
114
	@Override
118
    return ITemplateHandlersManager.INSTANCE.generateComment(task, completedTemplate,
115
	public void remove(IResource[] newResources) {
119
            progressTemplate);
116
		super.remove(newResources);
120
  }
117
	}
121
118
122
  @Override
119
	@Override
123
  public void remove(IResource resource)
120
	public void add(IDiff diff) {
124
  {
121
		super.add(diff);
125
    super.remove(resource);
122
		IResource resource = getResourceFromDiff(diff);
126
  }
123
		if (!suppressInterestContribution && resource != null) {
127
124
			Set<IResource> resources = new HashSet<IResource>();
128
  @Override
125
			resources.add(resource); 
129
  public void remove(IResource[] newResources)
126
			if (MylarResourcesPlugin.getDefault() != null) {
130
  {
127
				MylarResourcesPlugin.getDefault().getInterestUpdater().addResourceToContext(resources, InteractionEvent.Kind.SELECTION);
131
    super.remove(newResources);
128
			}
132
  }
129
		}
133
130
	}
134
  @Override
131
135
  public void add(IDiff diff)
132
	private IResource getResourceFromDiff(IDiff diff) {
136
  {
133
		if (diff instanceof ResourceDiff) {
137
    super.add(diff);
134
			return ((ResourceDiff)diff).getResource();
138
    IResource resource = getResourceFromDiff(diff);
135
		} else if (diff instanceof ThreeWayDiff) {
139
    if (!suppressInterestContribution && resource != null)
136
			ThreeWayDiff threeWayDiff = (ThreeWayDiff)diff;
140
    {
137
			return ResourcesPlugin.getWorkspace().getRoot().findMember(threeWayDiff.getPath());
141
      Set<IResource> resources = new HashSet<IResource>();
138
		} else {
142
      resources.add(resource);
139
			return null;
143
      if (MylarResourcesPlugin.getDefault() != null)
140
		}
144
      {
141
	} 
145
        MylarResourcesPlugin.getDefault().getInterestUpdater().addResourceToContext(resources,
142
146
                InteractionEvent.Kind.SELECTION);
143
	@Override
147
      }
144
	public void add(IDiff[] diffs) {
148
    }
145
		super.add(diffs);
149
  }
146
	}
150
147
151
  private IResource getResourceFromDiff(IDiff diff)
148
	@Override
152
  {
149
	public void add(IResource[] newResources) throws CoreException {
153
    if (diff instanceof ResourceDiff)
150
		super.add(newResources);
154
    {
151
	}
155
      return ((ResourceDiff)diff).getResource();
152
156
    }
153
	public void restoreResources(IResource[] newResources) throws CoreException {
157
    else if (diff instanceof ThreeWayDiff)
154
		suppressInterestContribution = true;
158
    {
155
		try {
159
      ThreeWayDiff threeWayDiff = (ThreeWayDiff)diff;
156
			super.add(newResources);
160
      return ResourcesPlugin.getWorkspace().getRoot().findMember(threeWayDiff.getPath());
157
			setComment(getComment());
161
    }
158
		} catch (TeamException e) {
162
    else
159
			throw e;
163
    {
160
		} finally {
164
      return null;
161
			suppressInterestContribution = false;
165
    }
162
		}
166
  }
163
	}
167
164
168
  @Override
165
	@Override
169
  public void add(IDiff[] diffs)
166
	public IResource[] getResources() {
170
  {
167
		List<IResource> allResources = getAllResourcesInChangeContext();
171
    super.add(diffs);
168
		return allResources.toArray(new IResource[allResources.size()]);
172
  }
169
	}
173
170
174
  @Override
171
	public List<IResource> getAllResourcesInChangeContext() {
175
  public void add(IResource[] newResources) throws CoreException
172
		Set<IResource> allResources = new HashSet<IResource>();
176
  {
173
		allResources.addAll(Arrays.asList(super.getResources()));
177
    super.add(newResources);
174
		if (MylarResourcesPlugin.getDefault() != null && task.isActive()) {
178
  }
175
			// TODO: if super is always managed correctly should remove following line
179
176
			allResources.addAll(MylarResourcesPlugin.getDefault().getInterestingResources());
180
  public void restoreResources(IResource[] newResources) throws CoreException
177
		}
181
  {
178
		return new ArrayList<IResource>(allResources);
182
    suppressInterestContribution = true;
179
	}
183
    try
180
184
    {
181
	/**
185
      super.add(newResources);
182
	 * TODO: unnessary check context?
186
      setComment(getComment());
183
	 */
187
    }
184
	public boolean contains(IResource local) {
188
    catch (TeamException e)
185
		return getAllResourcesInChangeContext().contains(local);
189
    {
186
	}
190
      throw e;
187
191
    }
188
	public static String generateComment(ITask task, String completedPrefix, String progressPrefix) {
192
    finally
189
		String comment;
193
    {
190
		completedPrefix = fixUpDelimIfPresent(completedPrefix);
194
      suppressInterestContribution = false;
191
		progressPrefix = fixUpDelimIfPresent(progressPrefix);
195
    }
192
		if (task.isCompleted()) {
196
  }
193
			comment = completedPrefix + PREFIX_DELIM;
197
194
		} else {
198
  @Override
195
			comment = progressPrefix + PREFIX_DELIM;
199
  public IResource[] getResources()
196
		}
200
  {
197
		comment += task.getDescription();
201
    List<IResource> allResources = getAllResourcesInChangeContext();
198
		String url = task.getUrl();
202
    return allResources.toArray(new IResource[allResources.size()]);
199
		if (url != null && !url.equals("") && !url.endsWith("//")) {
203
  }
200
			comment += " \n" + url;
204
201
		}
205
  public List<IResource> getAllResourcesInChangeContext()
202
		return comment;
206
  {
203
	}
207
    Set<IResource> allResources = new HashSet<IResource>();
204
208
    allResources.addAll(Arrays.asList(super.getResources()));
205
	private static String fixUpDelimIfPresent(String prefix) {
209
    if (MylarResourcesPlugin.getDefault() != null && task.isActive())
206
		if (prefix.endsWith(":") || prefix.endsWith(PREFIX_DELIM)) {
210
    {
207
			prefix = prefix.substring(0, prefix.lastIndexOf(':'));
211
      // TODO: if super is always managed correctly should remove following line
208
		}
212
      allResources.addAll(MylarResourcesPlugin.getDefault().getInterestingResources());
209
		return prefix;
213
    }
210
	}
214
    return new ArrayList<IResource>(allResources);
211
215
  }
212
	public static String getTaskIdFromCommentOrLabel(String comment) {
216
213
		int firstDelimIndex = comment.indexOf(PREFIX_DELIM);
217
  /**
214
		if (firstDelimIndex != -1) {
218
   * TODO: unnessary check context?
215
			int idStart = firstDelimIndex + PREFIX_DELIM.length();
219
   */
216
			int idEnd = comment.indexOf(PREFIX_DELIM, firstDelimIndex + PREFIX_DELIM.length());// comment.indexOf(PREFIX_DELIM);
220
  public boolean contains(IResource local)
217
			if (idEnd != -1 && idStart < idEnd) {
221
  {
218
				String id = comment.substring(idStart, idEnd);
222
    return getAllResourcesInChangeContext().contains(local);
219
				if (id != null)
223
  }
220
					return id.trim();
224
221
			} else {
225
  /**
222
				// change set label
226
   * @deprecated Use {@link ITemplateHandlersManager#generateComment(ITask, String, String)} instead.
223
				return comment.substring(0, firstDelimIndex);
227
   */
224
			}
228
  public static String generateComment(ITask task, String completedPrefix, String progressPrefix)
225
		}
229
  {
226
		return null;
230
    String comment;
227
	}
231
    completedPrefix = fixUpDelimIfPresent(completedPrefix);
228
232
    progressPrefix = fixUpDelimIfPresent(progressPrefix);
229
	public static String getUrlFromComment(String comment) {
233
    if (task.isCompleted())
230
		int httpIndex = comment.indexOf(PREFIX_HTTP);
234
    {
231
		int httpsIndex = comment.indexOf(PREFIX_HTTPS);
235
      comment = completedPrefix + PREFIX_DELIM;
232
		int idStart = -1;
236
    }
233
		if (httpIndex != -1) {
237
    else
234
			idStart = httpIndex;
238
    {
235
		} else if (httpsIndex != -1) {
239
      comment = progressPrefix + PREFIX_DELIM;
236
			idStart = httpsIndex;
240
    }
237
		}
241
    comment += task.getDescription();
238
		if (idStart != -1) {
242
    String url = task.getUrl();
239
			int idEnd = comment.indexOf(' ', idStart);
243
    if (url != null && !url.equals("") && !url.endsWith("//"))
240
			if (idEnd == -1) {
244
    {
241
				return comment.substring(idStart);
245
      comment += " \n" + url;
242
			} else if (idEnd != -1 && idStart < idEnd) {
246
    }
243
				return comment.substring(idStart, idEnd);
247
    return comment;
244
			}
248
  }
245
		}
249
246
		return null;
250
  private static String fixUpDelimIfPresent(String prefix)
247
	}
251
  {
248
252
    if (prefix.endsWith(":") || prefix.endsWith(PREFIX_DELIM))
249
	@Override
253
    {
250
	public boolean equals(Object object) {
254
      prefix = prefix.substring(0, prefix.lastIndexOf(':'));
251
		if (object instanceof ContextChangeSet && task != null) {
255
    }
252
			ContextChangeSet changeSet = (ContextChangeSet) object;
256
    return prefix;
253
			return task.equals(changeSet.getTask());
257
  }
254
		} else {
258
255
			return super.equals(object);
259
  public static String getTaskIdFromCommentOrLabel(String comment)
256
		}
260
  {
257
	}
261
    int firstDelimIndex = comment.indexOf(PREFIX_DELIM);
258
262
    if (firstDelimIndex != -1)
259
	@Override
263
    {
260
	public int hashCode() {
264
      int idStart = firstDelimIndex + PREFIX_DELIM.length();
261
		if (task != null) {
265
      int idEnd = comment.indexOf(PREFIX_DELIM, firstDelimIndex + PREFIX_DELIM.length());// comment.indexOf(PREFIX_DELIM);
262
			return task.hashCode();
266
      if (idEnd != -1 && idStart < idEnd)
263
		} else {
267
      {
264
			return super.hashCode();
268
        String id = comment.substring(idStart, idEnd);
265
		}
269
        if (id != null) return id.trim();
266
	}
270
      }
267
271
      else
268
	public ITask getTask() {
272
      {
269
		return task;
273
        // change set label
270
	}
274
        return comment.substring(0, firstDelimIndex);
271
275
      }
272
	public Object getAdapter(Class adapter) {
276
    }
273
		if (adapter == ResourceMapping.class) {
277
    return null;
274
			return new ChangeSetResourceMapping(this);
278
  }
275
		} else {
279
276
			return null;
280
  public static String getUrlFromComment(String comment)
277
		}
281
  {
278
	}
282
    int httpIndex = comment.indexOf(PREFIX_HTTP);
283
    int httpsIndex = comment.indexOf(PREFIX_HTTPS);
284
    int idStart = -1;
285
    if (httpIndex != -1)
286
    {
287
      idStart = httpIndex;
288
    }
289
    else if (httpsIndex != -1)
290
    {
291
      idStart = httpsIndex;
292
    }
293
    if (idStart != -1)
294
    {
295
      int idEnd = comment.indexOf(' ', idStart);
296
      if (idEnd == -1)
297
      {
298
        return comment.substring(idStart);
299
      }
300
      else if (idEnd != -1 && idStart < idEnd)
301
      {
302
        return comment.substring(idStart, idEnd);
303
      }
304
    }
305
    return null;
306
  }
307
308
  @Override
309
  public boolean equals(Object object)
310
  {
311
    if (object instanceof ContextChangeSet && task != null)
312
    {
313
      ContextChangeSet changeSet = (ContextChangeSet)object;
314
      return task.equals(changeSet.getTask());
315
    }
316
    else
317
    {
318
      return super.equals(object);
319
    }
320
  }
321
322
  @Override
323
  public int hashCode()
324
  {
325
    if (task != null)
326
    {
327
      return task.hashCode();
328
    }
329
    else
330
    {
331
      return super.hashCode();
332
    }
333
  }
334
335
  public ITask getTask()
336
  {
337
    return task;
338
  }
339
340
  public Object getAdapter(Class adapter)
341
  {
342
    if (adapter == ResourceMapping.class)
343
    {
344
      return new ChangeSetResourceMapping(this);
345
    }
346
    else
347
    {
348
      return null;
349
    }
350
  }
279
}
351
}
(-)plugin.xml (+89 lines)
Lines 3-8 Link Here
3
<?eclipse version="3.0"?>
3
<?eclipse version="3.0"?>
4
<plugin>
4
<plugin>
5
   <extension-point id="providers" name="Mylar Team Providers" schema="schema/providers.exsd"/>
5
   <extension-point id="providers" name="Mylar Team Providers" schema="schema/providers.exsd"/>
6
   <extension-point id="templateHandlers" name="Mylar Template Handlers" schema="schema/templateHandlers.exsd"/>
6
    
7
    
7
   <extension
8
   <extension
8
         point="org.eclipse.mylar.team.providers">
9
         point="org.eclipse.mylar.team.providers">
Lines 152-155 Link Here
152
	   </viewerActionBinding>
153
	   </viewerActionBinding>
153
	</extension>
154
	</extension>
154
	
155
	
156
    <extension
157
          point="org.eclipse.mylar.team.templateHandlers">
158
       <templateHandler
159
             class="org.eclipse.mylar.internal.team.template.TemplateHandler$RepositoryKind"
160
             description="Provides the repository kind of a Mylar task."
161
             recognizedKeyword="repository.kind"/>
162
       <templateHandler
163
             class="org.eclipse.mylar.internal.team.template.TemplateHandler$RepositoryURL"
164
             description="Provides the repository URL of a Mylar task."
165
             recognizedKeyword="repository.url"/>
166
       <templateHandler
167
             class="org.eclipse.mylar.internal.team.template.TemplateHandler$TaskAssignee"
168
             description="Provides the user a Mylar task is assigned to, if available."
169
             recognizedKeyword="task.assignee"/>
170
       <templateHandler
171
             class="org.eclipse.mylar.internal.team.template.TemplateHandler$TaskCC"
172
             description="Provides the comma separated CC list of a Mylar task, if available."
173
             recognizedKeyword="task.cc"/>
174
       <templateHandler
175
             class="org.eclipse.mylar.internal.team.template.TemplateHandler$TaskDescription"
176
             description="Provides the description of a Mylar task."
177
             recognizedKeyword="task.description"/>
178
       <templateHandler
179
             class="org.eclipse.mylar.internal.team.template.TemplateHandler$TaskHandle"
180
             description="Provides the handle of a Mylar task."
181
             recognizedKeyword="task.handle"/>
182
       <templateHandler
183
             class="org.eclipse.mylar.internal.team.template.TemplateHandler$TaskID"
184
             description="Provides the ID of a Mylar task."
185
             recognizedKeyword="task.id"/>
186
       <templateHandler
187
             class="org.eclipse.mylar.internal.team.template.TemplateHandler$TaskKeywords"
188
             description="Provides the comma separated keyword list of a Mylar task, if available."
189
             recognizedKeyword="task.keywords"/>
190
       <templateHandler
191
             class="org.eclipse.mylar.internal.team.template.TemplateHandler$TaskLastModified"
192
             description="Provides the date of last modification of a Mylar task, if available."
193
             recognizedKeyword="task.lastmodified"/>
194
       <templateHandler
195
             class="org.eclipse.mylar.internal.team.template.TemplateHandler$TaskNotes"
196
             description="Provides the notes of a Mylar task."
197
             recognizedKeyword="task.notes"/>
198
       <templateHandler
199
             class="org.eclipse.mylar.internal.team.template.TemplateHandler$TaskPriority"
200
             description="Provides the priority of a Mylar task."
201
             recognizedKeyword="task.priority"/>
202
       <templateHandler
203
             class="org.eclipse.mylar.internal.team.template.TemplateHandler$TaskProduct"
204
             description="Provides the prroduct a Mylar task belongs to, if available."
205
             recognizedKeyword="task.product"/>
206
       <templateHandler
207
             class="org.eclipse.mylar.internal.team.template.TemplateHandler$TaskReporter"
208
             description="Provides the user who reported a Mylar task, if available."
209
             recognizedKeyword="task.reporter"/>
210
       <templateHandler
211
             class="org.eclipse.mylar.internal.team.template.TemplateHandler$TaskResolution"
212
             description="Provides the resolution of a Mylar task, if available."
213
             recognizedKeyword="task.resolution"/>
214
       <templateHandler
215
             class="org.eclipse.mylar.internal.team.template.TemplateHandler$TaskStatus"
216
             description="Provides the status of a Mylar task, if available."
217
             recognizedKeyword="task.status"/>
218
       <templateHandler
219
             class="org.eclipse.mylar.internal.team.template.TemplateHandler$TaskSummary"
220
             description="Provides the summary or description of a Mylar task, whichever is available."
221
             recognizedKeyword="task.summary"/>
222
       <templateHandler
223
             class="org.eclipse.mylar.internal.team.template.TemplateHandler$TaskType"
224
             description="Provides the type of a Mylar task."
225
             recognizedKeyword="task.type"/>
226
       <templateHandler
227
             class="org.eclipse.mylar.internal.team.template.TemplateHandler$TaskURL"
228
             description="Provides the URL of a Mylar task."
229
             recognizedKeyword="task.url"/>
230
       <templateHandler
231
             class="org.eclipse.mylar.internal.team.template.TemplateHandler$Date$TaskCompletion"
232
             description="Provides the completion date of a Mylar task."
233
             recognizedKeyword="task.completiondate"/>
234
       <templateHandler
235
             class="org.eclipse.mylar.internal.team.template.TemplateHandler$Date$TaskCreation"
236
             description="Provides the creation date of a Mylar task."
237
             recognizedKeyword="task.creationdate"/>
238
       <templateHandler
239
             class="org.eclipse.mylar.internal.team.template.TemplateHandler$Date$TaskReminder"
240
             description="Provides the reminder date of a Mylar task."
241
             recognizedKeyword="task.reminderdate"/>
242
    </extension>
243
	
155
</plugin>
244
</plugin>
(-)src/org/eclipse/mylar/internal/team/ui/preferences/MylarTeamPreferencePage.java (-96 / +149 lines)
Lines 7-17 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     University Of British Columbia - initial API and implementation
9
 *     University Of British Columbia - initial API and implementation
10
 *     Eike tepper - commit comment template preferences
10
 *******************************************************************************/
11
 *******************************************************************************/
11
12
12
package org.eclipse.mylar.internal.team.ui.preferences;
13
package org.eclipse.mylar.internal.team.ui.preferences;
13
14
15
16
import org.eclipse.jface.fieldassist.IContentProposalProvider;
17
import org.eclipse.jface.fieldassist.IControlContentAdapter;
18
import org.eclipse.jface.fieldassist.IControlCreator;
19
import org.eclipse.jface.fieldassist.TextContentAdapter;
14
import org.eclipse.jface.preference.PreferencePage;
20
import org.eclipse.jface.preference.PreferencePage;
21
import org.eclipse.mylar.internal.team.template.TemplateHandlerContentProposalProvider;
15
import org.eclipse.mylar.team.MylarTeamPlugin;
22
import org.eclipse.mylar.team.MylarTeamPlugin;
16
import org.eclipse.swt.SWT;
23
import org.eclipse.swt.SWT;
17
import org.eclipse.swt.layout.GridData;
24
import org.eclipse.swt.layout.GridData;
Lines 24-128 Link Here
24
import org.eclipse.swt.widgets.Text;
31
import org.eclipse.swt.widgets.Text;
25
import org.eclipse.ui.IWorkbench;
32
import org.eclipse.ui.IWorkbench;
26
import org.eclipse.ui.IWorkbenchPreferencePage;
33
import org.eclipse.ui.IWorkbenchPreferencePage;
34
import org.eclipse.ui.fieldassist.ContentAssistField;
35
27
36
28
/**
37
/**
29
 * @author Mik Kersten
38
 * @author Mik Kersten
30
 */
39
 */
31
public class MylarTeamPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
40
public class MylarTeamPreferencePage extends PreferencePage implements IWorkbenchPreferencePage
32
41
{
33
	private Button changeSetsManage;
42
  private Button changeSetsManage;
34
43
35
	private Text commitPrefixCompleted = null;
44
  private Text commitTemplateCompleted = null;
36
45
37
	private Text commitPrefixProgress = null;
46
  private Text commitTemplateProgress = null;
47
48
  public MylarTeamPreferencePage()
49
  {
50
    super();
51
    setPreferenceStore(MylarTeamPlugin.getDefault().getPreferenceStore());
52
  }
53
54
  @Override
55
  protected Control createContents(Composite parent)
56
  {
57
    Composite container = new Composite(parent, SWT.NULL);
58
    GridLayout layout = new GridLayout(1, false);
59
    container.setLayout(layout);
60
61
    createChangeSetGroup(container);
62
    createCommitGroup(container);
63
    return container;
64
  }
65
66
  public void init(IWorkbench workbench)
67
  {
68
    // TODO Auto-generated method stub
69
  }
70
71
  @Override
72
  public boolean performOk()
73
  {
74
    getPreferenceStore().setValue(MylarTeamPlugin.COMMIT_TEMPLATE_COMPLETED,
75
            commitTemplateCompleted.getText());
76
    getPreferenceStore().setValue(MylarTeamPlugin.COMMIT_TEMPLATE_PROGRESS,
77
            commitTemplateProgress.getText());
78
    getPreferenceStore().setValue(MylarTeamPlugin.CHANGE_SET_MANAGE,
79
            changeSetsManage.getSelection());
80
81
    if (changeSetsManage.getSelection())
82
    {
83
      MylarTeamPlugin.getDefault().getChangeSetManager().enable();
84
    }
85
    else
86
    {
87
      MylarTeamPlugin.getDefault().getChangeSetManager().disable();
88
    }
89
    return true;
90
  }
91
92
  @Override
93
  public boolean performCancel()
94
  {
95
    return true;
96
  }
97
98
  public void performDefaults()
99
  {
100
    super.performDefaults();
101
    commitTemplateCompleted.setText(getPreferenceStore().getDefaultString(
102
            MylarTeamPlugin.COMMIT_TEMPLATE_COMPLETED));
103
    commitTemplateProgress.setText(getPreferenceStore().getDefaultString(
104
            MylarTeamPlugin.COMMIT_TEMPLATE_PROGRESS));
105
    changeSetsManage.setSelection(getPreferenceStore().getDefaultBoolean(
106
            MylarTeamPlugin.CHANGE_SET_MANAGE));
107
  }
108
109
  private Label createLabel(Composite parent, String text)
110
  {
111
    Label label = new Label(parent, SWT.LEFT);
112
    label.setText(text);
113
    GridData data = new GridData();
114
    data.horizontalSpan = 2;
115
    data.horizontalAlignment = GridData.BEGINNING;
116
    label.setLayoutData(data);
117
    return label;
118
  }
119
120
  private void createChangeSetGroup(Composite parent)
121
  {
122
    Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
123
    group.setText("Change Sets");
124
    group.setLayout(new GridLayout(1, false));
125
    group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
126
127
    changeSetsManage = new Button(group, SWT.CHECK);
128
    changeSetsManage.setText("Automatically create and manage with task context");
129
    changeSetsManage.setSelection(getPreferenceStore()
130
            .getBoolean(MylarTeamPlugin.CHANGE_SET_MANAGE));
131
  }
132
133
  private void createCommitGroup(Composite parent)
134
  {
135
    Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
136
    group.setText("Automatic Commit Messages");
137
    group.setLayout(new GridLayout(2, false));
138
    group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
139
140
    Label completedLabel = createLabel(group, "Completed task template: ");
141
    completedLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
142
143
    String completedTemplate = getPreferenceStore().getString(
144
            MylarTeamPlugin.COMMIT_TEMPLATE_COMPLETED);
145
    commitTemplateCompleted = addTemplateField(group, completedTemplate);
146
147
    Label progressLabel = createLabel(group, "In progress task template: ");
148
    progressLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
149
150
    String progressTemplate = getPreferenceStore().getString(
151
            MylarTeamPlugin.COMMIT_TEMPLATE_PROGRESS);
152
    commitTemplateProgress = addTemplateField(group, progressTemplate);
153
  }
154
155
  private Text addTemplateField(final Composite parent, final String text)
156
  {
157
    IControlContentAdapter adapter = new TextContentAdapter();
158
    IContentProposalProvider provider = new TemplateHandlerContentProposalProvider();
159
    IControlCreator controlCreator = new IControlCreator()
160
    {
161
      public Control createControl(Composite parent, int style)
162
      {
163
        Text control = new Text(parent, style);
164
        control.setText(text);
165
        return control;
166
      }
167
    };
168
169
    ContentAssistField field = new ContentAssistField(parent, SWT.BORDER, controlCreator, adapter,
170
            provider, null, new char[] {'$'});
171
172
    GridData gd = new GridData();
173
    gd.horizontalAlignment = GridData.FILL;
174
    gd.grabExcessHorizontalSpace = true;
175
    gd.verticalAlignment = GridData.CENTER;
176
    gd.grabExcessVerticalSpace = false;
177
    field.getLayoutControl().setLayoutData(gd);
38
178
39
	public MylarTeamPreferencePage() {
179
    return (Text)field.getControl();
40
		super();
180
  }
41
		setPreferenceStore(MylarTeamPlugin.getDefault().getPreferenceStore());
42
	}
43
44
	@Override
45
	protected Control createContents(Composite parent) {
46
		Composite container = new Composite(parent, SWT.NULL);
47
		GridLayout layout = new GridLayout(1, false);
48
		container.setLayout(layout);
49
50
		createChangeSetGroup(container);
51
		createCommitGroup(container);
52
		return container;
53
	}
54
55
	public void init(IWorkbench workbench) {
56
		// TODO Auto-generated method stub
57
	}
58
59
	@Override
60
	public boolean performOk() {
61
		getPreferenceStore().setValue(MylarTeamPlugin.COMMIT_PREFIX_COMPLETED, commitPrefixCompleted.getText());
62
		getPreferenceStore().setValue(MylarTeamPlugin.COMMIT_PREFIX_PROGRESS, commitPrefixProgress.getText());
63
		getPreferenceStore().setValue(MylarTeamPlugin.CHANGE_SET_MANAGE, changeSetsManage.getSelection());
64
65
		if (changeSetsManage.getSelection()) {
66
			MylarTeamPlugin.getDefault().getChangeSetManager().enable();
67
		} else {
68
			MylarTeamPlugin.getDefault().getChangeSetManager().disable();
69
		}
70
		return true;
71
	}
72
73
	@Override
74
	public boolean performCancel() {
75
		return true;
76
	}
77
78
	public void performDefaults() {
79
		super.performDefaults();
80
		commitPrefixCompleted.setText(getPreferenceStore().getDefaultString(MylarTeamPlugin.COMMIT_PREFIX_COMPLETED));
81
		commitPrefixProgress.setText(getPreferenceStore().getDefaultString(MylarTeamPlugin.COMMIT_PREFIX_PROGRESS));
82
		changeSetsManage.setSelection(getPreferenceStore().getDefaultBoolean(MylarTeamPlugin.CHANGE_SET_MANAGE));
83
	}
84
85
	private Label createLabel(Composite parent, String text) {
86
		Label label = new Label(parent, SWT.LEFT);
87
		label.setText(text);
88
		GridData data = new GridData();
89
		data.horizontalSpan = 2;
90
		data.horizontalAlignment = GridData.BEGINNING;
91
		label.setLayoutData(data);
92
		return label;
93
	}
94
95
	private void createChangeSetGroup(Composite parent) {
96
		Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
97
		group.setText("Change Sets");
98
		group.setLayout(new GridLayout(1, false));
99
		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
100
101
		changeSetsManage = new Button(group, SWT.CHECK);
102
		changeSetsManage.setText("Automatically create and manage with task context");
103
		changeSetsManage.setSelection(getPreferenceStore().getBoolean(MylarTeamPlugin.CHANGE_SET_MANAGE));
104
	}
105
106
	private void createCommitGroup(Composite parent) {
107
		Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
108
		group.setText("Automatic Commit Messages");
109
		group.setLayout(new GridLayout(2, false));
110
		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
111
112
		Label completedLabel = createLabel(group, "Completed task prefix: ");
113
		completedLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
114
115
		String completedPrefix = getPreferenceStore().getString(MylarTeamPlugin.COMMIT_PREFIX_COMPLETED);
116
		commitPrefixCompleted = new Text(group, SWT.BORDER);
117
		commitPrefixCompleted.setText(completedPrefix);
118
		commitPrefixCompleted.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
119
120
		Label progressLabel = createLabel(group, "In progress task prefix: ");
121
		progressLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
122
123
		String progressPrefix = getPreferenceStore().getString(MylarTeamPlugin.COMMIT_PREFIX_PROGRESS);
124
		commitPrefixProgress = new Text(group, SWT.BORDER);
125
		commitPrefixProgress.setText(progressPrefix);
126
		commitPrefixProgress.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
127
	}
128
}
181
}
(-)src/org/eclipse/mylar/internal/team/template/TemplateHandlersManager.java (+219 lines)
Added Link Here
1
/***************************************************************************
2
 * Copyright (c) 2004, 2005, 2006 Eike Stepper, Germany.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *    Eike Stepper - initial API and implementation
10
 **************************************************************************/
11
package org.eclipse.mylar.internal.team.template;
12
13
14
import org.eclipse.core.runtime.IConfigurationElement;
15
import org.eclipse.core.runtime.IExtension;
16
import org.eclipse.core.runtime.IExtensionPoint;
17
import org.eclipse.core.runtime.Platform;
18
import org.eclipse.mylar.context.core.MylarStatusHandler;
19
import org.eclipse.mylar.tasks.core.ITask;
20
import org.eclipse.mylar.team.ITemplateHandler;
21
import org.eclipse.mylar.team.ITemplateHandlersManager;
22
import org.eclipse.mylar.team.MylarTeamPlugin;
23
24
import java.text.MessageFormat;
25
import java.util.ArrayList;
26
27
28
/**
29
 * @author Eike Stepper
30
 */
31
public class TemplateHandlersManager implements ITemplateHandlersManager
32
{
33
  private static final String ATTR_CLASS = "class";
34
35
  private static final String ATTR_DESCRIPTION = "description";
36
37
  private static final String ATTR_RECOGNIZED_KEYWORD = "recognizedKeyword";
38
39
  private static final String ELEM_TEMPLATE_HANDLER = "templateHandler";
40
41
  private static final String EXT_POINT_TEMPLATE_HANDLERS = "templateHandlers";
42
43
  public TemplateHandlersManager()
44
  {
45
  }
46
47
  public String[] getRecognizedKeywords()
48
  {
49
    final ArrayList<String> result = new ArrayList<String>();
50
    new ExtensionProcessor()
51
    {
52
      @Override
53
      protected Object processContribution(IConfigurationElement element, String keyword,
54
              String description, String className) throws Exception
55
      {
56
        result.add(keyword);
57
        return null;
58
      }
59
    }.run();
60
61
    return result.toArray(new String[result.size()]);
62
  }
63
64
  public String getHandlerDescription(final String keyword)
65
  {
66
    return (String)new ExtensionProcessor()
67
    {
68
      @Override
69
      protected Object processContribution(IConfigurationElement element, String foundKeyword,
70
              String description, String className) throws Exception
71
      {
72
        return keyword.equals(foundKeyword) ? description : null;
73
      }
74
    }.run();
75
  }
76
77
  public ITemplateHandler createHandler(final String keyword)
78
  {
79
    return (ITemplateHandler)new ExtensionProcessor()
80
    {
81
      @Override
82
      protected Object processContribution(IConfigurationElement element, String foundKeyword,
83
              String description, String className) throws Exception
84
      {
85
        if (keyword.equals(foundKeyword))
86
        {
87
          ITemplateHandler handler = (ITemplateHandler)element
88
                  .createExecutableExtension(ATTR_CLASS);
89
          if (handler instanceof TemplateHandler)
90
          {
91
            ((TemplateHandler)handler).setDescription(description);
92
            ((TemplateHandler)handler).setRecognizedKeyword(foundKeyword);
93
          }
94
          else
95
          {
96
            String recognizedKeyword = handler.getRecognizedKeyword();
97
            if (recognizedKeyword == null || !recognizedKeyword.equals(foundKeyword))
98
            {
99
              throw new IllegalArgumentException(
100
                      "Keyword markup does not match handler implementation");
101
            }
102
          }
103
104
          return handler;
105
        }
106
107
        return null;
108
      }
109
    }.run();
110
  }
111
112
  public String generateComment(ITask task, String completedTemplate, String progressTemplate)
113
  {
114
    String template = task.isCompleted() ? completedTemplate : progressTemplate;
115
    return processKeywords(task, template);
116
  }
117
118
  private String processKeywords(ITask task, String template)
119
  {
120
    String[] segments = template.split("\\$\\{");
121
    StringBuffer buffer = new StringBuffer(segments[0]);
122
123
    for (int i = 1; i < segments.length; i++)
124
    {
125
      String segment = segments[i];
126
      String value = null;
127
      int brace = segment.indexOf('}');
128
      if (brace > 0)
129
      {
130
        String keyword = segment.substring(0, brace);
131
        value = processKeyword(task, keyword);
132
      }
133
134
      if (value != null)
135
      {
136
        buffer.append(value);
137
        buffer.append(segment.substring(brace + 1));
138
      }
139
      else
140
      {
141
        buffer.append("${");
142
        buffer.append(segment);
143
      }
144
    }
145
146
    return buffer.toString();
147
  }
148
149
  private String processKeyword(ITask task, String keyword)
150
  {
151
    try
152
    {
153
      ITemplateHandler handler = createHandler(keyword);
154
      if (handler != null)
155
      {
156
        return handler.getValue(task);
157
      }
158
    }
159
    catch (Exception ex)
160
    {
161
      MylarStatusHandler.log(ex, "Problem while delegating to template handler");
162
    }
163
164
    return null;
165
  }
166
167
  /**
168
   * @author Eike Stepper
169
   */
170
  private static class ExtensionProcessor
171
  {
172
    public Object run()
173
    {
174
      IExtensionPoint extPoint = Platform.getExtensionRegistry().getExtensionPoint(
175
              MylarTeamPlugin.PLUGIN_ID, EXT_POINT_TEMPLATE_HANDLERS);
176
      IExtension[] extensions = extPoint.getExtensions();
177
      for (int i = 0; i < extensions.length; i++)
178
      {
179
        IExtension extension = extensions[i];
180
        IConfigurationElement[] elements = extension.getConfigurationElements();
181
        for (int j = 0; j < elements.length; j++)
182
        {
183
          IConfigurationElement element = elements[j];
184
          if (ELEM_TEMPLATE_HANDLER.equals(element.getName()))
185
          {
186
            try
187
            {
188
              Object result = processContribution(element);
189
              if (result != null) return result;
190
            }
191
            catch (Exception ex)
192
            {
193
              final String msg = MessageFormat.format(
194
                      "Error while processing template handler contribution {0} from plugin {1}.",
195
                      element.getAttribute(ATTR_CLASS), element.getContributor().getName());
196
              MylarStatusHandler.log(ex, msg);
197
            }
198
          }
199
        }
200
      }
201
202
      return null;
203
    }
204
205
    protected Object processContribution(IConfigurationElement element) throws Exception
206
    {
207
      String keyword = element.getAttribute(ATTR_RECOGNIZED_KEYWORD);
208
      String description = element.getAttribute(ATTR_DESCRIPTION);
209
      String className = element.getAttribute(ATTR_CLASS);
210
      return processContribution(element, keyword, description, className);
211
    }
212
213
    protected Object processContribution(IConfigurationElement element, String keyword,
214
            String description, String className) throws Exception
215
    {
216
      return null;
217
    }
218
  }
219
}
(-)src/org/eclipse/mylar/team/ITemplateHandlersManager.java (+31 lines)
Added Link Here
1
/***************************************************************************
2
 * Copyright (c) 2004, 2005, 2006 Eike Stepper, Germany.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *    Eike Stepper - initial API and implementation
10
 **************************************************************************/
11
package org.eclipse.mylar.team;
12
13
14
import org.eclipse.mylar.tasks.core.ITask;
15
16
17
/**
18
 * @author Eike Stepper
19
 */
20
public interface ITemplateHandlersManager
21
{
22
  public static final ITemplateHandlersManager INSTANCE = new org.eclipse.mylar.internal.team.template.TemplateHandlersManager();
23
24
  public String[] getRecognizedKeywords();
25
26
  public String getHandlerDescription(String keyword);
27
28
  public ITemplateHandler createHandler(String keyword);
29
30
  public String generateComment(ITask task, String completedTemplate, String progressTemplate);
31
}
(-)schema/templateHandlers.exsd (+122 lines)
Added Link Here
1
<?xml version='1.0' encoding='UTF-8'?>
2
<!-- Schema file written by PDE -->
3
<schema targetNamespace="org.eclipse.mylar.team">
4
<annotation>
5
      <appInfo>
6
         <meta.schema plugin="org.eclipse.mylar.team" id="templateHandlers" name="Mylar Template Handlers"/>
7
      </appInfo>
8
      <documentation>
9
         [Enter description of this extension point.]
10
      </documentation>
11
   </annotation>
12
13
   <element name="extension">
14
      <complexType>
15
         <sequence>
16
            <element ref="templateHandler" minOccurs="1" maxOccurs="unbounded"/>
17
         </sequence>
18
         <attribute name="point" type="string" use="required">
19
            <annotation>
20
               <documentation>
21
                  
22
               </documentation>
23
            </annotation>
24
         </attribute>
25
         <attribute name="id" type="string">
26
            <annotation>
27
               <documentation>
28
                  
29
               </documentation>
30
            </annotation>
31
         </attribute>
32
         <attribute name="name" type="string">
33
            <annotation>
34
               <documentation>
35
                  
36
               </documentation>
37
               <appInfo>
38
                  <meta.attribute translatable="true"/>
39
               </appInfo>
40
            </annotation>
41
         </attribute>
42
      </complexType>
43
   </element>
44
45
   <element name="templateHandler">
46
      <complexType>
47
         <attribute name="class" type="string" use="required">
48
            <annotation>
49
               <documentation>
50
                  
51
               </documentation>
52
               <appInfo>
53
                  <meta.attribute kind="java" basedOn="org.eclipse.mylar.team.ITemplateHandler"/>
54
               </appInfo>
55
            </annotation>
56
         </attribute>
57
         <attribute name="description" type="string">
58
            <annotation>
59
               <documentation>
60
                  
61
               </documentation>
62
               <appInfo>
63
                  <meta.attribute translatable="true"/>
64
               </appInfo>
65
            </annotation>
66
         </attribute>
67
         <attribute name="recognizedKeyword" type="string" use="required">
68
            <annotation>
69
               <documentation>
70
                  
71
               </documentation>
72
            </annotation>
73
         </attribute>
74
      </complexType>
75
   </element>
76
77
   <annotation>
78
      <appInfo>
79
         <meta.section type="since"/>
80
      </appInfo>
81
      <documentation>
82
         [Enter the first release in which this extension point appears.]
83
      </documentation>
84
   </annotation>
85
86
   <annotation>
87
      <appInfo>
88
         <meta.section type="examples"/>
89
      </appInfo>
90
      <documentation>
91
         [Enter extension point usage example here.]
92
      </documentation>
93
   </annotation>
94
95
   <annotation>
96
      <appInfo>
97
         <meta.section type="apiInfo"/>
98
      </appInfo>
99
      <documentation>
100
         [Enter API information here.]
101
      </documentation>
102
   </annotation>
103
104
   <annotation>
105
      <appInfo>
106
         <meta.section type="implementation"/>
107
      </appInfo>
108
      <documentation>
109
         [Enter information about supplied implementation of this extension point.]
110
      </documentation>
111
   </annotation>
112
113
   <annotation>
114
      <appInfo>
115
         <meta.section type="copyright"/>
116
      </appInfo>
117
      <documentation>
118
         
119
      </documentation>
120
   </annotation>
121
122
</schema>
(-)src/org/eclipse/mylar/team/ITemplateHandler.java (+27 lines)
Added Link Here
1
/***************************************************************************
2
 * Copyright (c) 2004, 2005, 2006 Eike Stepper, Germany.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *    Eike Stepper - initial API and implementation
10
 **************************************************************************/
11
package org.eclipse.mylar.team;
12
13
14
import org.eclipse.mylar.tasks.core.ITask;
15
16
17
/**
18
 * @author Eike Stepper
19
 */
20
public interface ITemplateHandler
21
{
22
  public String getDescription();
23
24
  public String getRecognizedKeyword();
25
26
  public String getValue(ITask task);
27
}
(-)src/org/eclipse/mylar/internal/team/template/TemplateHandler.java (+384 lines)
Added Link Here
1
/***************************************************************************
2
 * Copyright (c) 2004, 2005, 2006 Eike Stepper, Germany.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *    Eike Stepper - initial API and implementation
10
 **************************************************************************/
11
package org.eclipse.mylar.internal.team.template;
12
13
14
import org.eclipse.mylar.tasks.core.AbstractRepositoryTask;
15
import org.eclipse.mylar.tasks.core.ITask;
16
import org.eclipse.mylar.team.ITemplateHandler;
17
18
import java.util.List;
19
20
21
/**
22
 * @author Eike Stepper
23
 */
24
public abstract class TemplateHandler implements ITemplateHandler
25
{
26
  protected String description;
27
28
  protected String recognizedKeyword;
29
30
  protected TemplateHandler()
31
  {
32
  }
33
34
  public String getDescription()
35
  {
36
    return description != null ? description : "Handler for '" + recognizedKeyword + "'";
37
  }
38
39
  public void setDescription(String description)
40
  {
41
    this.description = description;
42
  }
43
44
  public String getRecognizedKeyword()
45
  {
46
    return recognizedKeyword;
47
  }
48
49
  public void setRecognizedKeyword(String recognizedKeyword)
50
  {
51
    if (recognizedKeyword == null)
52
    {
53
      throw new IllegalArgumentException("Keyword to recognize must not be null"); //$NON-NLS-1$
54
    }
55
56
    this.recognizedKeyword = recognizedKeyword;
57
  }
58
59
  public static String implode(List<String> list, String separator)
60
  {
61
    StringBuilder builder = new StringBuilder();
62
    for (String cc : list)
63
    {
64
      if (builder.length() != 0)
65
      {
66
        builder.append(separator);
67
      }
68
69
      builder.append(cc);
70
    }
71
72
    return builder.toString();
73
  }
74
75
  /**
76
   * @author Eike Stepper
77
   */
78
  public static class RepositoryKind extends TemplateHandler
79
  {
80
    public String getValue(ITask task)
81
    {
82
      if (task instanceof AbstractRepositoryTask)
83
      {
84
        return ((AbstractRepositoryTask)task).getRepositoryKind();
85
      }
86
87
      return null;
88
    }
89
  }
90
91
  /**
92
   * @author Eike Stepper
93
   */
94
  public static class RepositoryURL extends TemplateHandler
95
  {
96
    public String getValue(ITask task)
97
    {
98
      if (task instanceof AbstractRepositoryTask)
99
      {
100
        return ((AbstractRepositoryTask)task).getRepositoryUrl();
101
      }
102
103
      return null;
104
    }
105
  }
106
107
  /**
108
   * @author Eike Stepper
109
   */
110
  public static class TaskProduct extends TemplateHandler
111
  {
112
    public String getValue(ITask task)
113
    {
114
      if (task instanceof AbstractRepositoryTask)
115
      {
116
        return ((AbstractRepositoryTask)task).getTaskData().getProduct();
117
      }
118
119
      return null;
120
    }
121
  }
122
123
  /**
124
   * @author Eike Stepper
125
   */
126
  public static class TaskAssignee extends TemplateHandler
127
  {
128
    public String getValue(ITask task)
129
    {
130
      if (task instanceof AbstractRepositoryTask)
131
      {
132
        return ((AbstractRepositoryTask)task).getTaskData().getAssignedTo();
133
      }
134
135
      return null;
136
    }
137
  }
138
139
  /**
140
   * @author Eike Stepper
141
   */
142
  public static class TaskReporter extends TemplateHandler
143
  {
144
    public String getValue(ITask task)
145
    {
146
      if (task instanceof AbstractRepositoryTask)
147
      {
148
        return ((AbstractRepositoryTask)task).getTaskData().getReporter();
149
      }
150
151
      return null;
152
    }
153
  }
154
155
  /**
156
   * @author Eike Stepper
157
   */
158
  public static class TaskResolution extends TemplateHandler
159
  {
160
    public String getValue(ITask task)
161
    {
162
      if (task instanceof AbstractRepositoryTask)
163
      {
164
        return ((AbstractRepositoryTask)task).getTaskData().getResolution();
165
      }
166
167
      return null;
168
    }
169
  }
170
171
  /**
172
   * @author Eike Stepper
173
   */
174
  public static class TaskStatus extends TemplateHandler
175
  {
176
    public String getValue(ITask task)
177
    {
178
      if (task instanceof AbstractRepositoryTask)
179
      {
180
        return ((AbstractRepositoryTask)task).getTaskData().getStatus();
181
      }
182
183
      return null;
184
    }
185
  }
186
187
  /**
188
   * @author Eike Stepper
189
   */
190
  public static class TaskCC extends TemplateHandler
191
  {
192
    public String getValue(ITask task)
193
    {
194
      if (task instanceof AbstractRepositoryTask)
195
      {
196
        List<String> list = ((AbstractRepositoryTask)task).getTaskData().getCC();
197
        return implode(list, ", ");
198
      }
199
200
      return null;
201
    }
202
  }
203
204
  /**
205
   * @author Eike Stepper
206
   */
207
  public static class TaskKeywords extends TemplateHandler
208
  {
209
    public String getValue(ITask task)
210
    {
211
      if (task instanceof AbstractRepositoryTask)
212
      {
213
        List<String> list = ((AbstractRepositoryTask)task).getTaskData().getKeywords();
214
        return implode(list, ", ");
215
      }
216
217
      return null;
218
    }
219
  }
220
221
  /**
222
   * @author Eike Stepper
223
   */
224
  public static class TaskLastModified extends TemplateHandler
225
  {
226
    public String getValue(ITask task)
227
    {
228
      if (task instanceof AbstractRepositoryTask)
229
      {
230
        return ((AbstractRepositoryTask)task).getTaskData().getLastModified();
231
      }
232
233
      return null;
234
    }
235
  }
236
237
  /**
238
   * @author Eike Stepper
239
   */
240
  public static class TaskSummary extends TemplateHandler
241
  {
242
    public String getValue(ITask task)
243
    {
244
      if (task instanceof AbstractRepositoryTask)
245
      {
246
        return ((AbstractRepositoryTask)task).getTaskData().getSummary();
247
      }
248
249
      return task.getDescription();
250
    }
251
  }
252
253
  /**
254
   * @author Eike Stepper
255
   */
256
  public static class TaskDescription extends TemplateHandler
257
  {
258
    public String getValue(ITask task)
259
    {
260
      return task.getDescription();
261
    }
262
  }
263
264
  /**
265
   * @author Eike Stepper
266
   */
267
  public static class TaskHandle extends TemplateHandler
268
  {
269
    public String getValue(ITask task)
270
    {
271
      return task.getHandleIdentifier();
272
    }
273
  }
274
275
  /**
276
   * @author Eike Stepper
277
   */
278
  public static class TaskID extends TemplateHandler
279
  {
280
    public String getValue(ITask task)
281
    {
282
      return AbstractRepositoryTask.getTaskId(task.getHandleIdentifier());
283
    }
284
  }
285
286
  /**
287
   * @author Eike Stepper
288
   */
289
  public static class TaskNotes extends TemplateHandler
290
  {
291
    public String getValue(ITask task)
292
    {
293
      return task.getNotes();
294
    }
295
  }
296
297
  /**
298
   * @author Eike Stepper
299
   */
300
  public static class TaskPriority extends TemplateHandler
301
  {
302
    public String getValue(ITask task)
303
    {
304
      return task.getPriority();
305
    }
306
  }
307
308
  /**
309
   * @author Eike Stepper
310
   */
311
  public static class TaskType extends TemplateHandler
312
  {
313
    public String getValue(ITask task)
314
    {
315
      return task.getTaskType();
316
    }
317
  }
318
319
  /**
320
   * @author Eike Stepper
321
   */
322
  public static class TaskURL extends TemplateHandler
323
  {
324
    public String getValue(ITask task)
325
    {
326
      return task.getUrl();
327
    }
328
  }
329
330
  /**
331
   * @author Eike Stepper
332
   */
333
  protected static abstract class Date extends TemplateHandler
334
  {
335
    public String getValue(ITask task)
336
    {
337
      java.util.Date date = getDate(task);
338
      return formatDate(date);
339
    }
340
341
    protected String formatDate(java.util.Date date)
342
    {
343
      return date.toString();
344
    }
345
346
    protected abstract java.util.Date getDate(ITask task);
347
348
    /**
349
     * @author Eike Stepper
350
     */
351
    public static class TaskCompletion extends Date
352
    {
353
      @Override
354
      protected java.util.Date getDate(ITask task)
355
      {
356
        return task.getCompletionDate();
357
      }
358
    }
359
360
    /**
361
     * @author Eike Stepper
362
     */
363
    public static class TaskCreation extends Date
364
    {
365
      @Override
366
      protected java.util.Date getDate(ITask task)
367
      {
368
        return task.getCreationDate();
369
      }
370
    }
371
372
    /**
373
     * @author Eike Stepper
374
     */
375
    public static class TaskReminder extends Date
376
    {
377
      @Override
378
      protected java.util.Date getDate(ITask task)
379
      {
380
        return task.getReminderDate();
381
      }
382
    }
383
  }
384
}
(-)src/org/eclipse/mylar/internal/team/template/TemplateHandlerContentProposalProvider.java (+158 lines)
Added Link Here
1
/***************************************************************************
2
 * Copyright (c) 2004, 2005, 2006 Eike Stepper, Germany.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *    Eike Stepper - initial API and implementation
10
 **************************************************************************/
11
package org.eclipse.mylar.internal.team.template;
12
13
14
import org.eclipse.jface.fieldassist.IContentProposal;
15
import org.eclipse.jface.fieldassist.IContentProposalProvider;
16
import org.eclipse.mylar.team.ITemplateHandlersManager;
17
18
import java.util.ArrayList;
19
import java.util.List;
20
21
22
/**
23
 * @author Eike Stepper
24
 */
25
public class TemplateHandlerContentProposalProvider implements IContentProposalProvider
26
{
27
  public IContentProposal[] getProposals(String contents, int position)
28
  {
29
    ProposalComputer proposalComputer = new ProposalComputer(contents, position);
30
    return proposalComputer.computeProposals();
31
  }
32
33
  /**
34
   * @author Eike Stepper
35
   */
36
  protected static class ProposalComputer
37
  {
38
    private String contents;
39
40
    private int position;
41
42
    private List<IContentProposal> result = new ArrayList<IContentProposal>();
43
44
    private String[] keywords;
45
46
    private String prefix;
47
48
    public ProposalComputer(String contents, int position)
49
    {
50
      this.contents = contents;
51
      this.position = position;
52
      initKeywords();
53
      initPrefix();
54
    }
55
56
    public IContentProposal[] computeProposals()
57
    {
58
      for (String keyword : keywords)
59
      {
60
        String proposal = getMatch(keyword);
61
        if (proposal != null)
62
        {
63
          addProposal(proposal, keyword);
64
        }
65
      }
66
67
      return result.toArray(new IContentProposal[result.size()]);
68
    }
69
70
    protected ITemplateHandlersManager getTemplateHandlersManager()
71
    {
72
      return ITemplateHandlersManager.INSTANCE;
73
    }
74
75
    private void initKeywords()
76
    {
77
      keywords = getTemplateHandlersManager().getRecognizedKeywords();
78
    }
79
80
    private void initPrefix()
81
    {
82
      prefix = "";
83
      String beforePosition = contents.substring(0, position);
84
      if (beforePosition.endsWith("$"))
85
      {
86
        prefix = "$";
87
      }
88
      else
89
      {
90
        int start = beforePosition.lastIndexOf("${");
91
        if (start >= 0)
92
        {
93
          int end = contents.indexOf('}', start);
94
          if (end >= position)
95
          {
96
            prefix = contents.substring(start, position);
97
          }
98
        }
99
      }
100
    }
101
102
    private String getMatch(String keyword)
103
    {
104
      String wholeProposal = "${" + keyword + "}";
105
      if (wholeProposal.startsWith(prefix))
106
      {
107
        return wholeProposal.substring(prefix.length());
108
      }
109
110
      return null;
111
    }
112
113
    private void addProposal(String proposal, String keyword)
114
    {
115
      String description = getTemplateHandlersManager().getHandlerDescription(keyword);
116
      result.add(new Proposal(proposal, keyword, description));
117
    }
118
119
    /**
120
     * @author Eike Stepper
121
     */
122
    private static final class Proposal implements IContentProposal
123
    {
124
      private final String proposal;
125
126
      private final String keyword;
127
128
      private final String description;
129
130
      private Proposal(String proposal, String keyword, String description)
131
      {
132
        this.proposal = proposal;
133
        this.keyword = keyword;
134
        this.description = description;
135
      }
136
137
      public String getContent()
138
      {
139
        return proposal;
140
      }
141
142
      public int getCursorPosition()
143
      {
144
        return proposal.length();
145
      }
146
147
      public String getDescription()
148
      {
149
        return description;
150
      }
151
152
      public String getLabel()
153
      {
154
        return "${" + keyword + "}";
155
      }
156
    }
157
  }
158
}

Return to bug 117517