Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorspingel2011-05-29 14:46:11 +0000
committerspingel2011-05-29 14:46:11 +0000
commit3845075581138bb690843b570f0723ef240f18a3 (patch)
treed808823a40f2833468081c30e6c0050b5a3878e9
parent293e1f6cf4284f2c5465175460e765826637d1c8 (diff)
downloadorg.eclipse.mylyn.tasks-3845075581138bb690843b570f0723ef240f18a3.tar.gz
org.eclipse.mylyn.tasks-3845075581138bb690843b570f0723ef240f18a3.tar.xz
org.eclipse.mylyn.tasks-3845075581138bb690843b570f0723ef240f18a3.zip
NEW - bug 339467: [discovery] inform users when new versions or connectors are available
https://bugs.eclipse.org/bugs/show_bug.cgi?id=339467
-rw-r--r--org.eclipse.mylyn.tasks.core/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/Environment.java171
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/FeedEntry.java107
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/FeedReader.java65
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/ServiceMessage.java39
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/ServiceMessageManager.java88
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/ServiceMessageXmlHandler.java3
-rw-r--r--org.eclipse.mylyn.tasks.tests/META-INF/MANIFEST.MF2
-rw-r--r--org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/EnvironmentTest.java142
-rw-r--r--org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/FeedReaderTest.java66
-rw-r--r--org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/ui/TaskListServiceMessageControlTest.java31
-rw-r--r--org.eclipse.mylyn.tasks.tests/testdata/FeedReaderTest/update1.xml41
-rw-r--r--org.eclipse.mylyn.tasks.ui/META-INF/MANIFEST.MF3
-rw-r--r--org.eclipse.mylyn.tasks.ui/plugin.xml24
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/TasksUiPlugin.java25
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/ShowTasksConnectorDiscoveryWizardCommandHandler.java76
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/notifications/TaskListServiceMessageControl.java108
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/preferences/TasksUiPreferencePage.java27
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TasksUiInternal.java2
19 files changed, 909 insertions, 116 deletions
diff --git a/org.eclipse.mylyn.tasks.core/META-INF/MANIFEST.MF b/org.eclipse.mylyn.tasks.core/META-INF/MANIFEST.MF
index 604613462..335a58a51 100644
--- a/org.eclipse.mylyn.tasks.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.mylyn.tasks.core/META-INF/MANIFEST.MF
@@ -19,4 +19,9 @@ Export-Package: org.eclipse.mylyn.internal.provisional.tasks.core;x-internal:=tr
org.eclipse.mylyn.tasks.core,
org.eclipse.mylyn.tasks.core.data,
org.eclipse.mylyn.tasks.core.sync
+Import-Package: com.sun.syndication.feed;version="0.9.0";resolution:=optional,
+ com.sun.syndication.feed.module;version="0.9.0";resolution:=optional,
+ com.sun.syndication.feed.synd;version="0.9.0";resolution:=optional,
+ com.sun.syndication.io;version="0.9.0";resolution:=optional,
+ org.jdom;version="1.0.0";resolution:=optional
Bundle-Localization: plugin
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/Environment.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/Environment.java
new file mode 100644
index 000000000..aced0f558
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/Environment.java
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.core.notifications;
+
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.Version;
+
+/**
+ * @author Steffen Pingel
+ */
+public class Environment {
+
+ private final Dictionary<Object, Object> environment;
+
+ public Environment() {
+ environment = new Hashtable<Object, Object>(System.getProperties());
+ }
+
+ public Version getFrameworkVersion() {
+ Bundle bundle = Platform.getBundle("org.eclipse.mylyn"); //$NON-NLS-1$
+ if (bundle != null) {
+ return bundle.getVersion();
+ } else {
+ return Version.emptyVersion;
+ }
+ }
+
+ public Version getPlatformVersion() {
+ Bundle bundle = Platform.getBundle("org.eclipse.platform"); //$NON-NLS-1$
+ if (bundle == null) {
+ bundle = Platform.getBundle(Platform.PI_RUNTIME);
+ }
+ if (bundle != null) {
+ String versionString = bundle.getHeaders().get(org.osgi.framework.Constants.BUNDLE_VERSION);
+ try {
+ return new Version(versionString);
+ } catch (IllegalArgumentException e) {
+ // should never happen
+ }
+ }
+ return Version.emptyVersion;
+ }
+
+ public Version getRuntimeVersion() {
+ Version result = parseRuntimeVersion(System.getProperty("java.runtime.version")); //$NON-NLS-1$
+ if (result == Version.emptyVersion) {
+ result = parseRuntimeVersion(System.getProperty("java.version")); //$NON-NLS-1$
+ }
+ return result;
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public boolean matches(FeedEntry entry, IProgressMonitor monitor) {
+ if (!matchesVersion(entry.getFilter("frameworkVersion"), getFrameworkVersion())) { //$NON-NLS-1$
+ return false;
+ }
+ if (!matchesVersion(entry.getFilter("platformVersion"), getPlatformVersion())) { //$NON-NLS-1$
+ return false;
+ }
+ if (!matchesVersion(entry.getFilter("runtimeVersion"), getRuntimeVersion())) { //$NON-NLS-1$
+ return false;
+ }
+ List<String> filterExpressions = entry.getFilters("filter"); //$NON-NLS-1$
+ for (String filterExpression : filterExpressions) {
+ try {
+ Filter filter = FrameworkUtil.createFilter(filterExpression);
+ if (!filter.match((Dictionary) environment)) {
+ return false;
+ }
+ } catch (InvalidSyntaxException e) {
+ // ignore that filter
+ }
+ }
+ List<String> requiredFeatures = entry.getFilters("requires"); //$NON-NLS-1$
+ for (String requiredFeature : requiredFeatures) {
+ if (!getInstalledFeatures(monitor).contains(parseFeature(requiredFeature))) {
+ return false;
+ }
+ }
+ List<String> conflictedFeatures = entry.getFilters("conflicts"); //$NON-NLS-1$
+ for (String conflictedFeature : conflictedFeatures) {
+ if (getInstalledFeatures(monitor).contains(parseFeature(conflictedFeature))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private int findLastNumberIndex(String versionString, int secondSeparator) {
+ int lastDigit = secondSeparator;
+ for (int i = secondSeparator + 1; i < versionString.length(); i++) {
+ if (Character.isDigit(versionString.charAt(i))) {
+ lastDigit++;
+ } else {
+ break;
+ }
+ }
+ if (lastDigit == secondSeparator) {
+ return secondSeparator - 1;
+ }
+ return lastDigit;
+ }
+
+ public Set<String> getInstalledFeatures(IProgressMonitor monitor) {
+ return Collections.emptySet();
+ }
+
+ private boolean matchesVersion(String expectedVersionRangeExpression, Version actualVersion) {
+ if (expectedVersionRangeExpression != null) {
+ try {
+ VersionRange versionRange = new VersionRange(expectedVersionRangeExpression);
+ if (!versionRange.isIncluded(actualVersion)) {
+ return false;
+ }
+ } catch (IllegalArgumentException e) {
+ // ignore
+ }
+ }
+ return true;
+ }
+
+ private String parseFeature(String requiredFeature) {
+ int i = requiredFeature.indexOf(";"); //$NON-NLS-1$
+ if (i != -1) {
+ return requiredFeature.substring(0, i);
+ }
+ return requiredFeature;
+ }
+
+ private Version parseRuntimeVersion(String versionString) {
+ if (versionString != null) {
+ int firstSeparator = versionString.indexOf('.');
+ if (firstSeparator != -1) {
+ try {
+ int secondSeparator = versionString.indexOf('.', firstSeparator + 1);
+ if (secondSeparator != -1) {
+ return new Version(versionString.substring(0,
+ findLastNumberIndex(versionString, secondSeparator) + 1));
+ }
+ return new Version(versionString.substring(0,
+ findLastNumberIndex(versionString, firstSeparator) + 1));
+ } catch (IllegalArgumentException e) {
+ // ignore
+ }
+ }
+ }
+ return Version.emptyVersion;
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/FeedEntry.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/FeedEntry.java
new file mode 100644
index 000000000..4098c4c88
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/FeedEntry.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.core.notifications;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+
+import com.sun.syndication.feed.module.DCModule;
+import com.sun.syndication.feed.module.DCSubject;
+import com.sun.syndication.feed.synd.SyndEntry;
+
+/**
+ * @author Steffen Pingel
+ */
+public class FeedEntry extends ServiceMessage {
+
+ private final SyndEntry source;
+
+ public FeedEntry(SyndEntry source) {
+ this.source = source;
+ setId(source.getUri());
+ setTitle(source.getTitle());
+ if (source.getDescription() != null) {
+ setDescription(source.getDescription().getValue());
+ }
+ setUrl(source.getLink());
+ setImage("dialog_messasge_info_image"); //$NON-NLS-1$
+ }
+
+ public FeedEntry() {
+ this.source = null;
+ }
+
+ public SyndEntry getSource() {
+ return source;
+ }
+
+ public List<String> getFilters(String key) {
+ Assert.isNotNull(key);
+ List<String> result = new ArrayList<String>();
+ DCModule module = (DCModule) source.getModule(DCModule.URI);
+ if (module != null && module.getSubjects() != null) {
+ for (Iterator<?> it = module.getSubjects().iterator(); it.hasNext();) {
+ DCSubject category = (DCSubject) it.next();
+ String value = parseFilter(key, category.getValue());
+ if (value != null) {
+ result.add(value);
+ }
+ }
+ }
+// for (Iterator<?> it = source.getCategories().iterator(); it.hasNext();) {
+// SyndCategory category = (SyndCategory) it.next();
+// String value = parseFilter(key, category.getName());
+// if (value != null) {
+// result.add(value);
+// }
+// }
+ return result;
+ }
+
+ public String getFilter(String key) {
+ Assert.isNotNull(key);
+ DCModule module = (DCModule) source.getModule(DCModule.URI);
+ if (module != null && module.getSubjects() != null) {
+ for (Iterator<?> it = module.getSubjects().iterator(); it.hasNext();) {
+ DCSubject category = (DCSubject) it.next();
+ String value = parseFilter(key, category.getValue());
+ if (value != null) {
+ return value;
+ }
+ }
+ }
+// for (Iterator<?> it = source.getCategories().iterator(); it.hasNext();) {
+// SyndCategory category = (SyndCategory) it.next();
+// String value = parseCategory(key, category.getName());
+// if (value != null) {
+// return value;
+// }
+// }
+ return null;
+ }
+
+ private String parseFilter(String key, String category) {
+ if (category != null) {
+ int i = category.indexOf("="); //$NON-NLS-1$
+ if (i != -1) {
+ if (category.substring(0, i).trim().equals(key)) {
+ return category.substring(i + 1).trim();
+ }
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/FeedReader.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/FeedReader.java
new file mode 100644
index 000000000..bba4dfc1e
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/FeedReader.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.core.notifications;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
+
+import com.sun.syndication.feed.synd.SyndEntry;
+import com.sun.syndication.feed.synd.SyndFeed;
+import com.sun.syndication.io.SyndFeedInput;
+import com.sun.syndication.io.XmlReader;
+
+/**
+ * @author Steffen Pingel
+ */
+public class FeedReader {
+
+ private final Environment environment;
+
+ private final List<FeedEntry> entries;
+
+ public FeedReader(Environment environment) {
+ this.environment = environment;
+ this.entries = new ArrayList<FeedEntry>();
+ }
+
+ public IStatus parse(InputStream in, IProgressMonitor monitor) {
+ SyndFeedInput input = new SyndFeedInput();
+ try {
+ SyndFeed feed = input.build(new XmlReader(in));
+ for (Iterator<?> it = feed.getEntries().iterator(); it.hasNext();) {
+ SyndEntry syndEntry = (SyndEntry) it.next();
+ FeedEntry entry = new FeedEntry(syndEntry);
+ if (environment.matches(entry, monitor)) {
+ entries.add(entry);
+ }
+ }
+ return Status.OK_STATUS;
+ } catch (Exception e) {
+ return new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, IStatus.ERROR,
+ "Failed to parse RSS feed", e); //$NON-NLS-1$
+ }
+ }
+
+ public List<FeedEntry> getEntries() {
+ return entries;
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/ServiceMessage.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/ServiceMessage.java
index 4b96603bd..144e82d7a 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/ServiceMessage.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/ServiceMessage.java
@@ -14,10 +14,10 @@ package org.eclipse.mylyn.internal.tasks.core.notifications;
/**
* @author Robert Elves
*/
-public class ServiceMessage {
+public class ServiceMessage implements Comparable<ServiceMessage> {
public enum Element {
- ID, TITLE, DESCRIPTION, URL, IMAGE, VERSION
+ ID, TITLE, DESCRIPTION, URL, IMAGE
};
private String id;
@@ -30,8 +30,6 @@ public class ServiceMessage {
private String image;
- private String version;
-
private String eTag;
private String lastModified;
@@ -72,10 +70,6 @@ public class ServiceMessage {
return lastModified;
}
- public String getVersion() {
- return version;
- }
-
public void setId(String id) {
this.id = id;
}
@@ -96,12 +90,33 @@ public class ServiceMessage {
this.image = image;
}
- public void setVersion(String version) {
- this.version = version;
- }
-
public boolean isValid() {
return id != null && title != null && description != null && image != null;
}
+ public int compareTo(ServiceMessage o) {
+ return -getId().compareTo(o.getId());
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("ServiceMessage [id="); //$NON-NLS-1$
+ builder.append(id);
+ builder.append(", title="); //$NON-NLS-1$
+ builder.append(title);
+ builder.append(", description="); //$NON-NLS-1$
+ builder.append(description);
+ builder.append(", url="); //$NON-NLS-1$
+ builder.append(url);
+ builder.append(", image="); //$NON-NLS-1$
+ builder.append(image);
+ builder.append(", eTag="); //$NON-NLS-1$
+ builder.append(eTag);
+ builder.append(", lastModified="); //$NON-NLS-1$
+ builder.append(lastModified);
+ builder.append("]"); //$NON-NLS-1$
+ return builder.toString();
+ }
+
}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/ServiceMessageManager.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/ServiceMessageManager.java
index adc0a381d..8c19a2ef5 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/ServiceMessageManager.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/ServiceMessageManager.java
@@ -8,16 +8,13 @@
package org.eclipse.mylyn.internal.tasks.core.notifications;
+import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Date;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
@@ -45,11 +42,11 @@ public class ServiceMessageManager {
protected static final long START_DELAY = 30 * 1000;
- protected static final long RECHECK_DELAY = 24 * 60 * 60 * 1000;
+ protected static final long RECHECK_DELAY = 14 * 24 * 60 * 60 * 1000;
private String serviceMessageUrl;
- private volatile List<ServiceMessage> messages = Collections.emptyList();
+ private volatile List<? extends ServiceMessage> messages = Collections.emptyList();
private Job messageCheckJob;
@@ -63,11 +60,19 @@ public class ServiceMessageManager {
private final long checktime;
- public ServiceMessageManager(String serviceMessageUrl, String lastModified, String eTag, long checktime) {
+ private final Environment environment;
+
+ public ServiceMessageManager(String serviceMessageUrl, String lastModified, String eTag, long checktime,
+ Environment environment) {
this.serviceMessageUrl = serviceMessageUrl;
this.lastModified = lastModified;
this.checktime = checktime;
this.eTag = eTag;
+ this.environment = environment;
+ }
+
+ public ServiceMessageManager(String serviceMessageUrl, String lastModified, String eTag, long checktime) {
+ this(serviceMessageUrl, lastModified, eTag, checktime, new Environment());
}
public void start() {
@@ -75,8 +80,13 @@ public class ServiceMessageManager {
messageCheckJob = new Job("Checking for new service message") { //$NON-NLS-1$
@Override
protected IStatus run(IProgressMonitor monitor) {
- updateServiceMessage(monitor);
- return Status.OK_STATUS;
+ try {
+ updateServiceMessage(monitor);
+ return Status.OK_STATUS;
+ } catch (Throwable t) {
+ // fail silently
+ return Status.CANCEL_STATUS;
+ }
}
};
@@ -95,18 +105,17 @@ public class ServiceMessageManager {
messageCheckJob.schedule(START_DELAY);
} else {
long nextCheckTime = checktime + RECHECK_DELAY;
- long now = new Date().getTime();
+ long now = System.currentTimeMillis();
if (nextCheckTime < now) {
messageCheckJob.schedule(START_DELAY);
} else if (nextCheckTime > now) {
- if ((nextCheckTime - now) < START_DELAY) {
+ if (nextCheckTime - now < START_DELAY) {
messageCheckJob.schedule(START_DELAY);
} else {
messageCheckJob.schedule(nextCheckTime - now);
}
}
}
-
}
public void stop() {
@@ -143,16 +152,17 @@ public class ServiceMessageManager {
listeners.remove(listener);
}
- private void notifyListeners(List<ServiceMessage> messages) {
+ private void notifyListeners(List<? extends ServiceMessage> messages) {
this.messages = messages;
for (final ServiceMessage message : messages) {
message.setETag(eTag);
message.setLastModified(lastModified);
}
+ ArrayList<ServiceMessage> sortedMessages = new ArrayList<ServiceMessage>(messages);
+ Collections.sort(messages);
final ServiceMessageEvent event = new ServiceMessageEvent(this, ServiceMessageEvent.EVENT_KIND.MESSAGE_UPDATE,
- messages);
-
+ sortedMessages);
for (final IServiceMessageListener listener : listeners) {
SafeRunner.run(new ISafeRunnable() {
public void run() throws Exception {
@@ -176,7 +186,7 @@ public class ServiceMessageManager {
*/
public int updateServiceMessage(IProgressMonitor monitor) {
int status = -1;
- List<ServiceMessage> messages = null;
+ List<? extends ServiceMessage> messages = null;
try {
HttpClient httpClient = new HttpClient(WebUtil.getConnectionManager());
WebUtil.configureHttpClient(httpClient, null);
@@ -203,13 +213,7 @@ public class ServiceMessageManager {
InputStream in = WebUtil.getResponseBodyAsStream(method, monitor);
try {
- SAXParserFactory factory = SAXParserFactory.newInstance();
- factory.setValidating(false);
- SAXParser parser = factory.newSAXParser();
-
- ServiceMessageXmlHandler handler = new ServiceMessageXmlHandler();
- parser.parse(in, handler);
- messages = handler.getMessages();
+ messages = readMessages(in, monitor);
} finally {
in.close();
}
@@ -218,21 +222,15 @@ public class ServiceMessageManager {
} else if (status == HttpStatus.SC_NOT_MODIFIED) {
// no new messages
} else {
- if (!statusLogged) {
- statusLogged = true;
- StatusHandler.log(new Status(IStatus.WARNING, ITasksCoreConstants.ID_PLUGIN,
- "Http error retrieving service message: " + HttpStatus.getStatusText(status))); //$NON-NLS-1$
- }
+ logStatus(new Status(IStatus.WARNING, ITasksCoreConstants.ID_PLUGIN,
+ "Http error retrieving service message: " + HttpStatus.getStatusText(status))); //$NON-NLS-1$
}
} finally {
WebUtil.releaseConnection(method, monitor);
}
} catch (Exception e) {
- if (!statusLogged) {
- statusLogged = true;
- StatusHandler.log(new Status(IStatus.WARNING, ITasksCoreConstants.ID_PLUGIN,
- "Http error retrieving service message.", e)); //$NON-NLS-1$
- }
+ logStatus(new Status(IStatus.WARNING, ITasksCoreConstants.ID_PLUGIN,
+ "Http error retrieving service message.", e)); //$NON-NLS-1$
}
if (messages != null && messages.size() > 0) {
@@ -241,4 +239,28 @@ public class ServiceMessageManager {
return status;
}
+ private void logStatus(IStatus status) {
+ if (!statusLogged) {
+ statusLogged = true;
+ //StatusHandler.log(status);
+ }
+ }
+
+// private List<ServiceMessage> readMessages(InputStream in) throws ParserConfigurationException, SAXException,
+// IOException {
+// SAXParserFactory factory = SAXParserFactory.newInstance();
+// factory.setValidating(false);
+// SAXParser parser = factory.newSAXParser();
+//
+// ServiceMessageXmlHandler handler = new ServiceMessageXmlHandler();
+// parser.parse(in, handler);
+// return handler.getMessages();
+// }
+
+ private List<? extends ServiceMessage> readMessages(InputStream in, IProgressMonitor monitor) throws IOException {
+ FeedReader reader = new FeedReader(environment);
+ reader.parse(in, monitor);
+ return reader.getEntries();
+ }
+
}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/ServiceMessageXmlHandler.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/ServiceMessageXmlHandler.java
index 3ba14985c..27b5fa6fe 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/ServiceMessageXmlHandler.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/notifications/ServiceMessageXmlHandler.java
@@ -75,9 +75,6 @@ public class ServiceMessageXmlHandler extends DefaultHandler {
case IMAGE:
message.setImage(parsedText);
break;
- case VERSION:
- message.setVersion(parsedText);
- break;
}
} catch (IllegalArgumentException e) {
// ignore unrecognized elements
diff --git a/org.eclipse.mylyn.tasks.tests/META-INF/MANIFEST.MF b/org.eclipse.mylyn.tasks.tests/META-INF/MANIFEST.MF
index bc0ef9598..7cea214a0 100644
--- a/org.eclipse.mylyn.tasks.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.mylyn.tasks.tests/META-INF/MANIFEST.MF
@@ -33,10 +33,12 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.equinox.security,
org.eclipse.mylyn.tests.util,
org.eclipse.mylyn.tasks.search
+Import-Package: com.sun.syndication.feed.synd;version="0.9.0";resolution:=optional
Export-Package: org.eclipse.mylyn.tasks.tests;x-internal:=true,
org.eclipse.mylyn.tasks.tests.connector;x-internal:=true,
org.eclipse.mylyn.tasks.tests.core;x-internal:=true,
org.eclipse.mylyn.tasks.tests.data;x-internal:=true,
+ org.eclipse.mylyn.tasks.tests.support;x-internal:=true,
org.eclipse.mylyn.tasks.tests.ui;x-internal:=true,
org.eclipse.mylyn.tasks.tests.ui.editor;x-internal:=true,
org.eclipse.mylyn.tasks.tests.util;x-internal:=true
diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/EnvironmentTest.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/EnvironmentTest.java
new file mode 100644
index 000000000..bc90e9034
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/EnvironmentTest.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Tasktop Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.tasks.tests.core;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.mylyn.internal.tasks.core.notifications.Environment;
+import org.eclipse.mylyn.internal.tasks.core.notifications.FeedEntry;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+/**
+ * @author Steffen Pingel
+ */
+public class EnvironmentTest extends TestCase {
+
+ private class StubEntry extends FeedEntry {
+
+ private final Map<String, String> map;
+
+ public StubEntry(Map<String, String> map) {
+ this.map = map;
+ }
+
+ @Override
+ public List<String> getFilters(String key) {
+ String value = getFilter(key);
+ if (value != null) {
+ return Collections.singletonList(value);
+ }
+ return Collections.emptyList();
+ }
+
+ @Override
+ public String getFilter(String key) {
+ return map.get(key);
+ }
+
+ }
+
+ private Environment environment;
+
+ Set<String> installedFeatures;
+
+ @Override
+ protected void setUp() throws Exception {
+ installedFeatures = new HashSet<String>();
+ environment = new Environment() {
+ @Override
+ public Set<String> getInstalledFeatures(IProgressMonitor monitor) {
+ return installedFeatures;
+ }
+ };
+ }
+
+ public void testGetRuntimeVersion() {
+ Version runtimeVersion = environment.getRuntimeVersion();
+ assertTrue("Expected value between 1.5-1.8, got " + runtimeVersion,
+ new VersionRange("[1.5.0,1.8.0)").isIncluded(runtimeVersion));
+ }
+
+ public void testGetPlatformVersion() {
+ Version platformVersion = environment.getPlatformVersion();
+ if (Platform.isRunning()) {
+ assertTrue("Expected value between 3.4-5.0, got " + platformVersion,
+ new VersionRange("[3.4.0,5.0.0)").isIncluded(platformVersion));
+ } else {
+ assertEquals(Version.emptyVersion, platformVersion);
+ }
+ }
+
+ public void testGetFrameworkVersion() {
+ Version frameworkVersion = environment.getFrameworkVersion();
+ if (Platform.isRunning()) {
+ assertTrue("Expected value > 3.6, got " + frameworkVersion,
+ new VersionRange("3.6.0").isIncluded(frameworkVersion));
+ } else {
+ assertEquals(Version.emptyVersion, frameworkVersion);
+ }
+ }
+
+ public void testMatchesFrameworkVersion() {
+ Map<String, String> values = new HashMap<String, String>();
+ assertTrue(environment.matches(new StubEntry(values), null));
+
+ values.put("frameworkVersion", "[1.0.0,2.0.0)");
+ assertFalse(environment.matches(new StubEntry(values), null));
+
+ values.put("frameworkVersion", "[0.0.0,10.0.0)");
+ assertTrue(environment.matches(new StubEntry(values), null));
+ }
+
+ public void testMatchesRequires() {
+ Map<String, String> values = new HashMap<String, String>();
+ values.put("requires", "org.eclipse.mylyn");
+ assertFalse(environment.matches(new StubEntry(values), null));
+
+ installedFeatures.add("org.eclipse.mylyn");
+ assertTrue(environment.matches(new StubEntry(values), null));
+ }
+
+ public void testMatchesConflicts() {
+ Map<String, String> values = new HashMap<String, String>();
+ values.put("conflicts", "org.eclipse.mylyn");
+ assertTrue(environment.matches(new StubEntry(values), null));
+
+ installedFeatures.add("org.eclipse.mylyn");
+ assertFalse(environment.matches(new StubEntry(values), null));
+ }
+
+ public void testMatchesRequiresConflicts() {
+ Map<String, String> values = new HashMap<String, String>();
+ values.put("requires", "org.eclipse.mylyn");
+ values.put("conflicts", "org.eclipse.cdt");
+ assertFalse(environment.matches(new StubEntry(values), null));
+
+ installedFeatures.add("org.eclipse.mylyn");
+ assertTrue(environment.matches(new StubEntry(values), null));
+
+ installedFeatures.add("org.eclipse.cdt");
+ assertFalse(environment.matches(new StubEntry(values), null));
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/FeedReaderTest.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/FeedReaderTest.java
new file mode 100644
index 000000000..a42345a89
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/FeedReaderTest.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Tasktop Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.tasks.tests.core;
+
+import java.util.Collections;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.mylyn.commons.tests.support.CommonTestUtil;
+import org.eclipse.mylyn.internal.tasks.core.notifications.Environment;
+import org.eclipse.mylyn.internal.tasks.core.notifications.FeedEntry;
+import org.eclipse.mylyn.internal.tasks.core.notifications.FeedReader;
+
+/**
+ * @author Steffen Pingel
+ */
+public class FeedReaderTest extends TestCase {
+
+ private FeedReader reader;
+
+ private Environment environment;
+
+ @Override
+ protected void setUp() throws Exception {
+ environment = new Environment() {
+ @Override
+ public Set<String> getInstalledFeatures(IProgressMonitor monitor) {
+ return Collections.singleton("org.eclipse.mylyn");
+ }
+ };
+ reader = new FeedReader(environment);
+ }
+
+ public void testParse() throws Exception {
+ assertEquals(Status.OK_STATUS, reader.parse(
+ CommonTestUtil.getResource(FeedReaderTest.class, "testdata/FeedReaderTest/update1.xml"), null));
+ assertEquals(2, reader.getEntries().size());
+ Collections.sort(reader.getEntries());
+
+ FeedEntry entry = reader.getEntries().get(0);
+ assertEquals("New Connectors", entry.getTitle());
+ assertEquals("[0.0.0,3.7.0)", entry.getFilter("frameworkVersion"));
+ assertEquals("New connectors are now available. <a href=\"#discovery\">Show connectors</a>.",
+ entry.getDescription());
+
+ entry = reader.getEntries().get(1);
+ assertEquals("Mylyn 3.6 is now available", entry.getTitle());
+ assertEquals("1.5.0", entry.getFilter("runtimeVersion"));
+ assertEquals(
+ "Mylyn 3.7 is now available. <a href=\"http://eclipse.org/mylyn/new/\">See New and Noteworthy</a> for details.",
+ entry.getDescription());
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/ui/TaskListServiceMessageControlTest.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/ui/TaskListServiceMessageControlTest.java
new file mode 100644
index 000000000..b8edda030
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/ui/TaskListServiceMessageControlTest.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Tasktop Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.tasks.tests.ui;
+
+import junit.framework.TestCase;
+
+import org.eclipse.mylyn.internal.tasks.ui.notifications.TaskListServiceMessageControl;
+
+/**
+ * @author Steffen Pingel
+ */
+public class TaskListServiceMessageControlTest extends TestCase {
+
+ public void testGetAction() {
+ assertEquals("abc", TaskListServiceMessageControl.getAction("ABC"));
+ assertEquals("abc", TaskListServiceMessageControl.getAction("abc"));
+ assertEquals("def", TaskListServiceMessageControl.getAction("http://eclipse.org?action=DEF"));
+ assertEquals("defg", TaskListServiceMessageControl.getAction("http://eclipse.org?action=defg&foo=bar"));
+ assertEquals(null, TaskListServiceMessageControl.getAction("http://eclipse.org?foo=bar&action=defg"));
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.tests/testdata/FeedReaderTest/update1.xml b/org.eclipse.mylyn.tasks.tests/testdata/FeedReaderTest/update1.xml
new file mode 100644
index 000000000..47fbb4af3
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.tests/testdata/FeedReaderTest/update1.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<rss version="2.0"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ >
+<channel>
+<title>Mylyn Updates</title>
+<link>http://eclipse.org/mylyn</link>
+<description>Mylyn Updates</description>
+<lastBuildDate>Fri, 27 May 2011 17:33:37 +0000</lastBuildDate>
+<language>en</language>
+<item>
+<title>Mylyn 3.6 is now available</title>
+<link>http://eclipse.org/mylyn/new/</link>
+<pubDate>Thu, 24 Mar 2011 14:00:07 +0000</pubDate>
+<dc:creator>Steffen Pingel</dc:creator>
+<dc:subject>runtimeVersion=1.5.0</dc:subject>
+<dc:subject>requires=org.eclipse.mylyn</dc:subject>
+<category>Mylyn</category>
+<guid isPermaLink="false">20110527-0000</guid>
+<description>Mylyn 3.7 is now available. &lt;a href="http://eclipse.org/mylyn/new/"&gt;See New and Noteworthy&lt;/a&gt; for details.</description>
+</item>
+<item>
+<title>New Connectors</title>
+<link>http://eclipse.org/mylyn/new/</link>
+<pubDate>Fri, 27 May 2011 12:00:00 +0000</pubDate>
+<dc:creator>Steffen Pingel</dc:creator>
+<dc:subject>frameworkVersion=[0.0.0,3.7.0)</dc:subject>
+<guid isPermaLink="false">20110527-0001</guid>
+<description>New connectors are now available. &lt;a href="#discovery"&gt;Show connectors&lt;/a&gt;.</description>
+</item>
+<item>
+<title>Filtered Item</title>
+<link>http://eclipse.org/mylyn/new/</link>
+<pubDate>Fri, 27 May 2011 12:00:00 +0000</pubDate>
+<dc:creator>Steffen Pingel</dc:creator>
+<dc:subject>frameworkVersion=[1.0.0,2.0.0)</dc:subject>
+<guid isPermaLink="false">20110527-0002</guid>
+<description>Specifies an unsatisfiable framework version.</description>
+</item>
+</channel>
+</rss>
diff --git a/org.eclipse.mylyn.tasks.ui/META-INF/MANIFEST.MF b/org.eclipse.mylyn.tasks.ui/META-INF/MANIFEST.MF
index e032f10f7..6a1ef30b2 100644
--- a/org.eclipse.mylyn.tasks.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.mylyn.tasks.ui/META-INF/MANIFEST.MF
@@ -26,7 +26,8 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.mylyn.commons.net;bundle-version="[3.0.0,4.0.0)",
org.eclipse.mylyn.commons.ui;bundle-version="[3.0.0,4.0.0)",
org.eclipse.mylyn.monitor.core;bundle-version="[3.0.0,4.0.0)",
- org.eclipse.mylyn.commons.repositories;bundle-version="0.1.0"
+ org.eclipse.mylyn.commons.repositories;bundle-version="0.1.0",
+ org.eclipse.mylyn.discovery.ui;bundle-version="3.6.0";resolution:=optional
Bundle-ActivationPolicy: lazy
Bundle-Vendor: %Bundle-Vendor
Export-Package: org.eclipse.mylyn.internal.provisional.tasks.ui.wizards;x-internal:=true,
diff --git a/org.eclipse.mylyn.tasks.ui/plugin.xml b/org.eclipse.mylyn.tasks.ui/plugin.xml
index b683f884e..c9316d897 100644
--- a/org.eclipse.mylyn.tasks.ui/plugin.xml
+++ b/org.eclipse.mylyn.tasks.ui/plugin.xml
@@ -2105,5 +2105,27 @@
</toolbar>
</menuContribution>
</extension>
-
+ <extension
+ point="org.eclipse.ui.commands">
+ <command
+ description="%command.description"
+ id="org.eclipse.mylyn.tasks.ui.discoveryWizardCommand"
+ name="%command.name">
+ </command>
+ </extension>
+ <extension
+ point="org.eclipse.ui.handlers">
+ <handler
+ class="org.eclipse.mylyn.internal.tasks.ui.commands.ShowTasksConnectorDiscoveryWizardCommandHandler"
+ commandId="org.eclipse.mylyn.tasks.ui.discoveryWizardCommand">
+ <enabledWhen>
+ <and>
+ <test
+ property="org.eclipse.core.runtime.isBundleInstalled" args="org.eclipse.mylyn.discovery.ui"/>
+ <test
+ property="org.eclipse.core.runtime.isBundleInstalled" args="org.eclipse.equinox.p2.repository"/>
+ </and>
+ </enabledWhen>
+ </handler>
+ </extension>
</plugin>
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/TasksUiPlugin.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/TasksUiPlugin.java
index 71ae0d530..fc0893f22 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/TasksUiPlugin.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/TasksUiPlugin.java
@@ -58,6 +58,7 @@ import org.eclipse.mylyn.internal.commons.identity.IdentityModel;
import org.eclipse.mylyn.internal.commons.identity.gravatar.GravatarConnector;
import org.eclipse.mylyn.internal.commons.ui.TaskBarManager;
import org.eclipse.mylyn.internal.context.core.ContextCorePlugin;
+import org.eclipse.mylyn.internal.discovery.ui.DiscoveryUi;
import org.eclipse.mylyn.internal.monitor.ui.MonitorUiPlugin;
import org.eclipse.mylyn.internal.provisional.commons.ui.AbstractNotification;
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonColors;
@@ -83,6 +84,7 @@ import org.eclipse.mylyn.internal.tasks.core.externalization.ExternalizationMana
import org.eclipse.mylyn.internal.tasks.core.externalization.IExternalizationParticipant;
import org.eclipse.mylyn.internal.tasks.core.externalization.TaskListExternalizationParticipant;
import org.eclipse.mylyn.internal.tasks.core.externalization.TaskListExternalizer;
+import org.eclipse.mylyn.internal.tasks.core.notifications.Environment;
import org.eclipse.mylyn.internal.tasks.core.notifications.ServiceMessageManager;
import org.eclipse.mylyn.internal.tasks.ui.actions.ActivateTaskDialogAction;
import org.eclipse.mylyn.internal.tasks.ui.actions.NewTaskAction;
@@ -666,12 +668,23 @@ public class TasksUiPlugin extends AbstractUIPlugin {
Long checktime = getPreferenceStore().getLong(ITasksUiPreferenceConstants.LAST_SERVICE_MESSAGE_CHECKTIME);
- serviceMessageManager = new ServiceMessageManager(serviceMessageUrl, lastMod, etag, checktime);
+ serviceMessageManager = new ServiceMessageManager(serviceMessageUrl, lastMod, etag, checktime,
+ new Environment() {
+ private Set<String> installedFeatures;
+
+ @Override
+ public Set<String> getInstalledFeatures(IProgressMonitor monitor) {
+ if (installedFeatures == null) {
+ installedFeatures = DiscoveryUi.createInstallJob().getInstalledFeatures(monitor);
+ }
+ return installedFeatures;
+ }
+ });
// Disabled for initial 3.4 release as per bug#263528
-// if (getPreferenceStore().getBoolean(ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED)) {
-// serviceMessageManager.start();
-// }
+ if (getPreferenceStore().getBoolean(ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED)) {
+ serviceMessageManager.start();
+ }
// trigger lazy initialization
new TasksUiInitializationJob().schedule();
@@ -943,7 +956,7 @@ public class TasksUiPlugin extends AbstractUIPlugin {
store.setDefault(ITasksUiPreferenceConstants.PREF_DATA_DIR, getDefaultDataDirectory());
store.setDefault(ITasksUiPreferenceConstants.GROUP_SUBTASKS, true);
store.setDefault(ITasksUiPreferenceConstants.NOTIFICATIONS_ENABLED, true);
- store.setDefault(ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED, true);
+ store.setDefault(ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED, false);
store.setDefault(ITasksUiPreferenceConstants.FILTER_PRIORITY, PriorityLevel.P5.toString());
store.setDefault(ITasksUiPreferenceConstants.EDITOR_TASKS_RICH, true);
store.setDefault(ITasksUiPreferenceConstants.EDITOR_CURRENT_LINE_HIGHLIGHT, false);
@@ -972,7 +985,7 @@ public class TasksUiPlugin extends AbstractUIPlugin {
store.setDefault(ITasksUiPreferenceConstants.AUTO_EXPAND_TASK_LIST, true);
store.setDefault(ITasksUiPreferenceConstants.TASK_LIST_TOOL_TIPS_ENABLED, true);
- store.setDefault(ITasksUiPreferenceConstants.SERVICE_MESSAGE_URL, "http://eclipse.org/mylyn/message.xml"); //$NON-NLS-1$
+ store.setDefault(ITasksUiPreferenceConstants.SERVICE_MESSAGE_URL, "http://eclipse.org/mylyn/updates.xml"); //$NON-NLS-1$
}
public static TaskActivityManager getTaskActivityManager() {
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/ShowTasksConnectorDiscoveryWizardCommandHandler.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/ShowTasksConnectorDiscoveryWizardCommandHandler.java
new file mode 100644
index 000000000..970b0b553
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/ShowTasksConnectorDiscoveryWizardCommandHandler.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.internal.tasks.ui.commands;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.mylyn.internal.discovery.ui.wizards.ConnectorDiscoveryWizard;
+import org.eclipse.mylyn.internal.provisional.commons.ui.WorkbenchUtil;
+import org.eclipse.mylyn.internal.tasks.ui.ITasksUiPreferenceConstants;
+import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A command that causes the {@link ConnectorDiscoveryWizard} to appear in a dialog.
+ *
+ * @author David Green
+ * @author Steffen Pingel
+ */
+public class ShowTasksConnectorDiscoveryWizardCommandHandler extends AbstractHandler {
+
+ private static final String ID_P2_INSTALL_UI = "org.eclipse.equinox.p2.ui.sdk/org.eclipse.equinox.p2.ui.sdk.install"; //$NON-NLS-1$
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+
+ // check to make sure that the p2 install ui is enabled
+ if (WorkbenchUtil.allowUseOf(ID_P2_INSTALL_UI)) {
+ ConnectorDiscoveryWizard wizard = new ConnectorDiscoveryWizard();
+ WizardDialog dialog = new WizardDialog(WorkbenchUtil.getShell(), wizard) {
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ super.createButtonsForButtonBar(parent);
+ ((GridLayout) parent.getLayout()).numColumns++;
+ final Button button = new Button(parent, SWT.CHECK);
+ button.setSelection(TasksUiPlugin.getDefault()
+ .getPreferenceStore()
+ .getBoolean(ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED));
+ button.setText("Notify when new connectors are available");
+ button.setFont(JFaceResources.getDialogFont());
+ button.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent event) {
+ TasksUiPlugin.getDefault()
+ .getPreferenceStore()
+ .setValue(ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED,
+ button.getSelection());
+ }
+ });
+ button.moveAbove(null);
+ }
+ };
+ dialog.open();
+ } else {
+ MessageDialog.openWarning(WorkbenchUtil.getShell(), "Install Connectors",
+ "Unable to launch connector install since the required platform support is not available.");
+ }
+
+ return null;
+ }
+}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/notifications/TaskListServiceMessageControl.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/notifications/TaskListServiceMessageControl.java
index 6c6ce2a0d..d4c3f996a 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/notifications/TaskListServiceMessageControl.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/notifications/TaskListServiceMessageControl.java
@@ -12,6 +12,8 @@
package org.eclipse.mylyn.internal.tasks.ui.notifications;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.util.Collections;
import java.util.Date;
@@ -29,10 +31,10 @@ import org.eclipse.mylyn.internal.tasks.core.notifications.ServiceMessageEvent;
import org.eclipse.mylyn.internal.tasks.ui.ITasksUiPreferenceConstants;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.internal.tasks.ui.actions.AddRepositoryAction;
+import org.eclipse.mylyn.internal.tasks.ui.preferences.TasksUiPreferencePage;
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
import org.eclipse.mylyn.internal.tasks.ui.wizards.Messages;
import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
-import org.eclipse.osgi.service.resolver.VersionRange;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
@@ -41,7 +43,6 @@ import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.IHandlerService;
-import org.osgi.framework.Version;
/**
* @author Robert Elves
@@ -54,6 +55,7 @@ public class TaskListServiceMessageControl extends ServiceMessageControl impleme
public TaskListServiceMessageControl(Composite parent) {
super(parent);
+ setPreferencesPageId(TasksUiPreferencePage.ID);
}
static ExecutionEvent createExecutionEvent(Command command, IHandlerService handlerService) {
@@ -83,12 +85,15 @@ public class TaskListServiceMessageControl extends ServiceMessageControl impleme
continue;
}
- if (!lastMessageId.equals(message.getId()) && isForCurrentVersion(message)) {
+ if (message.getId().compareTo(lastMessageId) > 0) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
setMessage(message);
+ // event id is not used but must be set to make configure link visible
+ setEventId(""); //$NON-NLS-1$
}
});
+ break;
}
}
break;
@@ -98,21 +103,6 @@ public class TaskListServiceMessageControl extends ServiceMessageControl impleme
}
}
- private boolean isForCurrentVersion(ServiceMessage message) {
- if (message.getVersion() == null) {
- return true;
- }
-
- try {
- VersionRange version = new VersionRange(message.getVersion());
- String versionString = (String) TasksUiPlugin.getDefault().getBundle().getHeaders().get("Bundle-Version"); //$NON-NLS-1$
- return version.isIncluded(new Version(versionString));
- } catch (IllegalArgumentException e) {
- // invalid version range
- return false;
- }
- }
-
public void setMessage(ServiceMessage message) {
if (message != null) {
ensureControl();
@@ -126,8 +116,8 @@ public class TaskListServiceMessageControl extends ServiceMessageControl impleme
this.currentMessage = message;
setTitle(message.getTitle());
- setDescription(message.getDescription());
setTitleImage(Dialog.getImage(message.getImage()));
+ setDescription(message.getDescription());
}
}
@@ -136,35 +126,67 @@ public class TaskListServiceMessageControl extends ServiceMessageControl impleme
return new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
- if (e.text != null) {
- String action = e.text.toLowerCase();
- if ("create-local-task".equals(action)) { //$NON-NLS-1$
- closeMessage();
- LocalTask task = TasksUiInternal.createNewLocalTask(null);
- TasksUiUtil.openTask(task);
- } else if ("connect".equals(action)) { //$NON-NLS-1$
- closeMessage();
- new AddRepositoryAction().run();
- } else if ("discovery".equals(action)) { //$NON-NLS-1$
- closeMessage();
- final Command discoveryWizardCommand = TasksUiInternal.getConfiguredDiscoveryWizardCommand();
- if (discoveryWizardCommand != null && discoveryWizardCommand.isEnabled()) {
- IHandlerService handlerService = (IHandlerService) PlatformUI.getWorkbench().getService(
- IHandlerService.class);
- try {
- handlerService.executeCommand(discoveryWizardCommand.getId(), null);
- } catch (Exception e1) {
- IStatus status = new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, NLS.bind(
- Messages.SelectRepositoryConnectorPage_discoveryProblemMessage,
- new Object[] { e1.getMessage() }), e1);
- TasksUiInternal.logAndDisplayStatus(
- Messages.SelectRepositoryConnectorPage_discoveryProblemTitle, status);
- }
+ if (e.text == null) {
+ return;
+ }
+
+ String action = getAction(e.text);
+ if ("create-local-task".equals(action)) { //$NON-NLS-1$
+ closeMessage();
+ LocalTask task = TasksUiInternal.createNewLocalTask(null);
+ TasksUiUtil.openTask(task);
+ } else if ("connect".equals(action)) { //$NON-NLS-1$
+ closeMessage();
+ new AddRepositoryAction().run();
+ } else if ("discovery".equals(action)) { //$NON-NLS-1$
+ closeMessage();
+ final Command discoveryWizardCommand = TasksUiInternal.getConfiguredDiscoveryWizardCommand();
+ if (discoveryWizardCommand != null && discoveryWizardCommand.isEnabled()) {
+ IHandlerService handlerService = (IHandlerService) PlatformUI.getWorkbench().getService(
+ IHandlerService.class);
+ try {
+ handlerService.executeCommand(discoveryWizardCommand.getId(), null);
+ } catch (Exception e1) {
+ IStatus status = new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, NLS.bind(
+ Messages.SelectRepositoryConnectorPage_discoveryProblemMessage,
+ new Object[] { e1.getMessage() }), e1);
+ TasksUiInternal.logAndDisplayStatus(
+ Messages.SelectRepositoryConnectorPage_discoveryProblemTitle, status);
}
}
+ } else if (TasksUiInternal.isValidUrl(e.text)) {
+ TasksUiUtil.openUrl(e.text);
}
}
+
};
}
+ /**
+ * Extracts action from query part or a URL if applicable.
+ */
+ public static String getAction(String action) {
+ if (action.startsWith("http")) { //$NON-NLS-1$
+ URL url;
+ try {
+ url = new URL(action);
+ String query = url.getQuery();
+ if (query != null && query.startsWith("action=")) { //$NON-NLS-1$
+ int i = query.indexOf("&"); //$NON-NLS-1$
+ if (i != -1) {
+ action = query.substring(7, i);
+ } else {
+ action = query.substring(7);
+ }
+ } else {
+ return null;
+ }
+ } catch (MalformedURLException e1) {
+ // ignore
+ return null;
+ }
+ }
+ return action.toLowerCase();
+ }
+
}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/preferences/TasksUiPreferencePage.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/preferences/TasksUiPreferencePage.java
index 9dfa3266e..5fac8ff7f 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/preferences/TasksUiPreferencePage.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/preferences/TasksUiPreferencePage.java
@@ -111,8 +111,7 @@ public class TasksUiPreferencePage extends PreferencePage implements IWorkbenchP
private Button showTaskTrimButton;
- // Disabled for initial 3.4 release as per bug#263528
-// private Button taskListServiceMessageEnabledButton;
+ private Button taskListServiceMessageEnabledButton;
public TasksUiPreferencePage() {
super();
@@ -213,9 +212,8 @@ public class TasksUiPreferencePage extends PreferencePage implements IWorkbenchP
getPreferenceStore().setValue(ITasksUiPreferenceConstants.TASK_LIST_TOOL_TIPS_ENABLED,
taskListTooltipEnabledButton.getSelection());
- // Disabled for initial 3.4 release as per bug#263528
-// getPreferenceStore().setValue(ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED,
-// taskListServiceMessageEnabledButton.getSelection());
+ getPreferenceStore().setValue(ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED,
+ taskListServiceMessageEnabledButton.getSelection());
getPreferenceStore().setValue(ITasksUiPreferenceConstants.SHOW_TRIM, showTaskTrimButton.getSelection());
getPreferenceStore().setValue(ITasksUiPreferenceConstants.WEEK_START_DAY, getWeekStartValue());
@@ -288,9 +286,8 @@ public class TasksUiPreferencePage extends PreferencePage implements IWorkbenchP
taskListTooltipEnabledButton.setSelection(getPreferenceStore().getBoolean(
ITasksUiPreferenceConstants.TASK_LIST_TOOL_TIPS_ENABLED));
- // Disabled for initial 3.4 release as per bug#263528
-// taskListServiceMessageEnabledButton.setSelection(getPreferenceStore().getBoolean(
-// ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED));
+ taskListServiceMessageEnabledButton.setSelection(getPreferenceStore().getBoolean(
+ ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED));
showTaskTrimButton.setSelection(getPreferenceStore().getBoolean(ITasksUiPreferenceConstants.SHOW_TRIM));
weekStartCombo.select(getPreferenceStore().getInt(ITasksUiPreferenceConstants.WEEK_START_DAY) - 1);
@@ -328,9 +325,8 @@ public class TasksUiPreferencePage extends PreferencePage implements IWorkbenchP
taskListTooltipEnabledButton.setSelection(getPreferenceStore().getDefaultBoolean(
ITasksUiPreferenceConstants.TASK_LIST_TOOL_TIPS_ENABLED));
- // Disabled for initial 3.4 release as per bug#263528
-// taskListServiceMessageEnabledButton.setSelection(getPreferenceStore().getDefaultBoolean(
-// ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED));
+ taskListServiceMessageEnabledButton.setSelection(getPreferenceStore().getDefaultBoolean(
+ ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED));
showTaskTrimButton.setSelection(getPreferenceStore().getDefaultBoolean(ITasksUiPreferenceConstants.SHOW_TRIM));
// synchQueries.setSelection(getPreferenceStore().getDefaultBoolean(
@@ -519,11 +515,10 @@ public class TasksUiPreferencePage extends PreferencePage implements IWorkbenchP
taskListTooltipEnabledButton.setSelection(getPreferenceStore().getBoolean(
ITasksUiPreferenceConstants.TASK_LIST_TOOL_TIPS_ENABLED));
- // Disabled for initial 3.4 release as per bug#263528
-// taskListServiceMessageEnabledButton = new Button(group, SWT.CHECK);
-// taskListServiceMessageEnabledButton.setText(Messages.TasksUiPreferencePage_show_service_messages);
-// taskListServiceMessageEnabledButton.setSelection(getPreferenceStore().getBoolean(
-// ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED));
+ taskListServiceMessageEnabledButton = new Button(group, SWT.CHECK);
+ taskListServiceMessageEnabledButton.setText("Display notification when new connectors are available"); //$NON-NLS-1$
+ taskListServiceMessageEnabledButton.setSelection(getPreferenceStore().getBoolean(
+ ITasksUiPreferenceConstants.SERVICE_MESSAGES_ENABLED));
}
private void createTaskActivityGroup(Composite container) {
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TasksUiInternal.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TasksUiInternal.java
index 3954cfd76..3e1e9a401 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TasksUiInternal.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TasksUiInternal.java
@@ -165,7 +165,7 @@ public class TasksUiInternal {
*/
public static Command getConfiguredDiscoveryWizardCommand() {
ICommandService service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);
- final Command discoveryWizardCommand = service.getCommand("org.eclipse.mylyn.discovery.ui.discoveryWizardCommand"); //$NON-NLS-1$
+ final Command discoveryWizardCommand = service.getCommand("org.eclipse.mylyn.tasks.ui.discoveryWizardCommand"); //$NON-NLS-1$
if (discoveryWizardCommand != null) {
IHandlerService handlerService = (IHandlerService) PlatformUI.getWorkbench().getService(
IHandlerService.class);

Back to the top