You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by st...@apache.org on 2015/02/17 12:45:39 UTC
[15/52] [abbrv] incubator-taverna-workbench git commit:
taverna-ui-impl/
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionDeserializer.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionDeserializer.java b/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionDeserializer.java
new file mode 100644
index 0000000..0a40bda
--- /dev/null
+++ b/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionDeserializer.java
@@ -0,0 +1,167 @@
+package net.sf.taverna.t2.servicedescriptions.impl;
+
+import static net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.CONFIGURATION;
+import static net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.IGNORED;
+import static net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.PROVIDERS;
+import static net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.PROVIDER_ID;
+import static net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.TYPE;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import uk.org.taverna.scufl2.api.configurations.Configuration;
+import net.sf.taverna.t2.servicedescriptions.ConfigurableServiceProvider;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+class ServiceDescriptionDeserializer {
+ private List<ServiceDescriptionProvider> serviceDescriptionProviders;
+
+ ServiceDescriptionDeserializer(
+ List<ServiceDescriptionProvider> serviceDescriptionProviders) {
+ this.serviceDescriptionProviders = serviceDescriptionProviders;
+ }
+
+ public void deserialize(ServiceDescriptionRegistry registry,
+ File serviceDescriptionsFile) throws DeserializationException {
+ try (FileInputStream serviceDescriptionFileStream = new FileInputStream(
+ serviceDescriptionsFile)) {
+ deserialize(registry, serviceDescriptionFileStream);
+ } catch (FileNotFoundException ex) {
+ throw new DeserializationException("Could not locate file "
+ + serviceDescriptionsFile.getAbsolutePath()
+ + " containing service descriptions.");
+ } catch (IOException ex) {
+ throw new DeserializationException(
+ "Could not read stream containing service descriptions from "
+ + serviceDescriptionsFile.getAbsolutePath(), ex);
+ }
+ }
+
+ public void deserialize(ServiceDescriptionRegistry registry,
+ URL serviceDescriptionsURL) throws DeserializationException {
+ try (InputStream serviceDescriptionInputStream = serviceDescriptionsURL
+ .openStream()) {
+ deserialize(registry, serviceDescriptionInputStream);
+ } catch (FileNotFoundException ex) {
+ throw new DeserializationException("Could not open URL "
+ + serviceDescriptionsURL
+ + " containing service descriptions.");
+ } catch (IOException ex) {
+ throw new DeserializationException(
+ "Could not read stream containing service descriptions from "
+ + serviceDescriptionsURL, ex);
+ }
+ }
+
+ private static final JsonFactory factory = new JsonFactory();
+
+ private void deserialize(ServiceDescriptionRegistry registry,
+ InputStream serviceDescriptionsInputStream) throws IOException,
+ DeserializationException {
+ ObjectNode node = (ObjectNode) new ObjectMapper(factory)
+ .readTree(serviceDescriptionsInputStream);
+ List<ServiceDescriptionProvider> providers = deserializeProviders(node,
+ true);
+ for (ServiceDescriptionProvider provider : providers)
+ registry.addServiceDescriptionProvider(provider);
+ }
+
+ public Collection<? extends ServiceDescriptionProvider> deserializeDefaults(
+ ServiceDescriptionRegistry registry,
+ File defaultConfigurableServiceProvidersFile)
+ throws DeserializationException {
+ ObjectNode node;
+ try (FileInputStream serviceDescriptionStream = new FileInputStream(
+ defaultConfigurableServiceProvidersFile)) {
+ node = (ObjectNode) new ObjectMapper(factory)
+ .readTree(serviceDescriptionStream);
+ } catch (IOException e) {
+ throw new DeserializationException("Can't read "
+ + defaultConfigurableServiceProvidersFile);
+ }
+ return deserializeProviders(node, false);
+ }
+
+ private List<ServiceDescriptionProvider> deserializeProviders(
+ ObjectNode rootNode, boolean obeyIgnored)
+ throws DeserializationException {
+ List<ServiceDescriptionProvider> providers = new ArrayList<>();
+
+ ArrayNode providersNode = (ArrayNode) rootNode.get(PROVIDERS);
+ if (providersNode != null)
+ for (JsonNode provider : providersNode)
+ providers.add(deserializeProvider((ObjectNode) provider));
+
+ if (obeyIgnored) {
+ ArrayNode ignoredNode = (ArrayNode) rootNode.get(IGNORED);
+ if (ignoredNode != null)
+ for (JsonNode provider : ignoredNode)
+ providers
+ .remove(deserializeProvider((ObjectNode) provider));
+ }
+
+ return providers;
+ }
+
+ private ServiceDescriptionProvider deserializeProvider(
+ ObjectNode providerNode) throws DeserializationException {
+ String providerId = providerNode.get(PROVIDER_ID).asText().trim();
+ ServiceDescriptionProvider provider = null;
+ for (ServiceDescriptionProvider serviceProvider : serviceDescriptionProviders)
+ if (serviceProvider.getId().equals(providerId)) {
+ provider = serviceProvider;
+ break;
+ }
+ if (provider == null)
+ throw new DeserializationException(
+ "Could not find provider with id " + providerId);
+
+ /*
+ * So we know the service provider now, but we need a separate instance
+ * of that provider for each providerElem. E.g. we can have 2 or more
+ * WSDL provider elements and need to return a separate provider
+ * instance for each as they will have different configurations.
+ */
+ ServiceDescriptionProvider instance = provider.newInstance();
+
+ if (instance instanceof ConfigurableServiceProvider)
+ try {
+ Configuration config = new Configuration();
+ config.setType(URI.create(providerNode.get(TYPE).textValue()));
+ config.setJson(providerNode.get(CONFIGURATION));
+ if (config != null)
+ ((ConfigurableServiceProvider) instance).configure(config);
+ } catch (Exception e) {
+ throw new DeserializationException(
+ "Could not configure provider " + providerId
+ + " using bean " + providerNode, e);
+ }
+ return instance;
+ }
+
+ @SuppressWarnings("serial")
+ static class DeserializationException extends Exception {
+ public DeserializationException(String string) {
+ super(string);
+ }
+
+ public DeserializationException(String string, Exception ex) {
+ super(string, ex);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionRegistryImpl.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionRegistryImpl.java b/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionRegistryImpl.java
new file mode 100644
index 0000000..9dc3f00
--- /dev/null
+++ b/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionRegistryImpl.java
@@ -0,0 +1,652 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.servicedescriptions.impl;
+
+import static java.lang.System.currentTimeMillis;
+import static java.lang.Thread.MIN_PRIORITY;
+import static java.lang.Thread.currentThread;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import net.sf.taverna.t2.lang.observer.MultiCaster;
+import net.sf.taverna.t2.lang.observer.Observer;
+import net.sf.taverna.t2.servicedescriptions.ConfigurableServiceProvider;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescription;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionsConfiguration;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider.FindServiceDescriptionsCallBack;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
+import net.sf.taverna.t2.servicedescriptions.events.AddedProviderEvent;
+import net.sf.taverna.t2.servicedescriptions.events.PartialServiceDescriptionsNotification;
+import net.sf.taverna.t2.servicedescriptions.events.ProviderErrorNotification;
+import net.sf.taverna.t2.servicedescriptions.events.ProviderStatusNotification;
+import net.sf.taverna.t2.servicedescriptions.events.ProviderUpdatingNotification;
+import net.sf.taverna.t2.servicedescriptions.events.ProviderWarningNotification;
+import net.sf.taverna.t2.servicedescriptions.events.RemovedProviderEvent;
+import net.sf.taverna.t2.servicedescriptions.events.ServiceDescriptionProvidedEvent;
+import net.sf.taverna.t2.servicedescriptions.events.ServiceDescriptionRegistryEvent;
+import net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionDeserializer.DeserializationException;
+
+import org.apache.commons.beanutils.BeanUtils;
+import org.apache.log4j.Logger;
+
+import uk.org.taverna.configuration.app.ApplicationConfiguration;
+
+public class ServiceDescriptionRegistryImpl implements ServiceDescriptionRegistry {
+ /**
+ * If a writable property of this name on a provider exists (ie. the provider has a method
+ * setServiceDescriptionRegistry(ServiceDescriptionRegistry registry) - then this property will
+ * be set to the current registry.
+ */
+ public static final String SERVICE_DESCRIPTION_REGISTRY = "serviceDescriptionRegistry";
+ public static Logger logger = Logger.getLogger(ServiceDescriptionRegistryImpl.class);
+ public static final ThreadGroup threadGroup = new ThreadGroup("Service description providers");
+ /**
+ * Total maximum timeout while waiting for description threads to finish
+ */
+ private static final long DESCRIPTION_THREAD_TIMEOUT_MS = 3000;
+ protected static final String CONF_DIR = "conf";
+ protected static final String SERVICE_PROVIDERS_FILENAME = "service_providers.xml";
+ private static final String DEFAULT_CONFIGURABLE_SERVICE_PROVIDERS_FILENAME = "default_service_providers.xml";
+
+ private ServiceDescriptionsConfiguration serviceDescriptionsConfig;
+ private ApplicationConfiguration applicationConfiguration;
+ /**
+ * <code>false</code> until first call to {@link #loadServiceProviders()} - which is done by
+ * first call to {@link #getServiceDescriptionProviders()}.
+ */
+ private boolean hasLoadedProviders = false;
+ /**
+ * <code>true</code> while {@link #loadServiceProviders(File)},
+ * {@link #loadServiceProviders(URL)} or {@link #loadServiceProviders()} is in progress, avoids
+ * triggering {@link #saveServiceDescriptions()} on
+ * {@link #addServiceDescriptionProvider(ServiceDescriptionProvider)} calls.
+ */
+ private boolean loading = false;
+ private MultiCaster<ServiceDescriptionRegistryEvent> observers = new MultiCaster<>(this);
+ private List<ServiceDescriptionProvider> serviceDescriptionProviders;
+ private Set<ServiceDescriptionProvider> allServiceProviders;
+ private Map<ServiceDescriptionProvider, Set<ServiceDescription>> providerDescriptions = new HashMap<>();
+ private Map<ServiceDescriptionProvider, Thread> serviceDescriptionThreads = new HashMap<>();
+ /**
+ * Service providers added by the user, should be saved
+ */
+ private Set<ServiceDescriptionProvider> userAddedProviders = new HashSet<>();
+ private Set<ServiceDescriptionProvider> userRemovedProviders = new HashSet<>();
+ private Set<ServiceDescriptionProvider> defaultServiceDescriptionProviders;
+ /**
+ * File containing a list of configured ConfigurableServiceProviders which is used to get the
+ * default set of service descriptions together with those provided by AbstractTemplateServiceS.
+ * This file is located in the conf directory of the Taverna startup directory.
+ */
+ private File defaultConfigurableServiceProvidersFile;
+ private boolean defaultSystemConfigurableProvidersLoaded = false;
+
+ static {
+ threadGroup.setMaxPriority(MIN_PRIORITY);
+ }
+
+ public ServiceDescriptionRegistryImpl(
+ ApplicationConfiguration applicationConfiguration) {
+ this.applicationConfiguration = applicationConfiguration;
+ defaultConfigurableServiceProvidersFile = new File(
+ getTavernaStartupConfigurationDirectory(),
+ DEFAULT_CONFIGURABLE_SERVICE_PROVIDERS_FILENAME);
+ }
+
+ /**
+ * Get the Taverna distribution (startup) configuration directory.
+ */
+ private File getTavernaStartupConfigurationDirectory() {
+ File distroHome = null;
+ File configDirectory = null;
+ distroHome = applicationConfiguration.getStartupDir();
+ configDirectory = new File(distroHome, "conf");
+ if (!configDirectory.exists())
+ configDirectory.mkdir();
+ return configDirectory;
+ }
+
+ private static void joinThreads(Collection<? extends Thread> threads,
+ long descriptionThreadTimeoutMs) {
+ long finishJoinBy = currentTimeMillis() + descriptionThreadTimeoutMs;
+ for (Thread thread : threads) {
+ // No shorter timeout than 1 ms (thread.join(0) waits forever!)
+ long timeout = Math.max(1, finishJoinBy - currentTimeMillis());
+ try {
+ thread.join(timeout);
+ } catch (InterruptedException e) {
+ currentThread().interrupt();
+ return;
+ }
+ if (thread.isAlive())
+ logger.debug("Thread did not finish " + thread);
+ }
+ }
+
+
+ @Override
+ public void addObserver(Observer<ServiceDescriptionRegistryEvent> observer) {
+ observers.addObserver(observer);
+ }
+
+ @Override
+ public void addServiceDescriptionProvider(ServiceDescriptionProvider provider) {
+ synchronized (this) {
+ userRemovedProviders.remove(provider);
+ if (!getDefaultServiceDescriptionProviders().contains(provider))
+ userAddedProviders.add(provider);
+ allServiceProviders.add(provider);
+ }
+
+ // Spring-like auto-config
+ try {
+ // BeanUtils should ignore this if provider does not have that property
+ BeanUtils.setProperty(provider, SERVICE_DESCRIPTION_REGISTRY, this);
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ logger.warn("Could not set serviceDescriptionRegistry on "
+ + provider, e);
+ }
+
+ if (!loading)
+ saveServiceDescriptions();
+ observers.notify(new AddedProviderEvent(provider));
+ updateServiceDescriptions(false, false);
+ }
+
+ private File findServiceDescriptionsFile() {
+ File confDir = new File(
+ applicationConfiguration.getApplicationHomeDir(), CONF_DIR);
+ confDir.mkdirs();
+ if (!confDir.isDirectory())
+ throw new RuntimeException("Invalid directory: " + confDir);
+ File serviceDescriptionsFile = new File(confDir,
+ SERVICE_PROVIDERS_FILENAME);
+ return serviceDescriptionsFile;
+ }
+
+ @Override
+ public List<Observer<ServiceDescriptionRegistryEvent>> getObservers() {
+ return observers.getObservers();
+ }
+
+ // Fallback to this method that uses hardcoded default services if you cannot read them from
+ // the file.
+// @SuppressWarnings("unchecked")
+// public synchronized Set<ServiceDescriptionProvider> getDefaultServiceDescriptionProvidersFallback() {
+// /*if (defaultServiceDescriptionProviders != null) {
+// return defaultServiceDescriptionProviders;
+// }
+// defaultServiceDescriptionProviders = new HashSet<ServiceDescriptionProvider>();
+// */
+// for (ServiceDescriptionProvider provider : serviceDescriptionProviders) {
+//
+// /* We do not need these - already loaded them from getDefaultServiceDescriptionProviders()
+// if (!(provider instanceof ConfigurableServiceProvider)) {
+// defaultServiceDescriptionProviders.add(provider);
+// continue;
+// }*/
+//
+// // Just load the hard coded default configurable service providers
+// if (provider instanceof ConfigurableServiceProvider){
+// ConfigurableServiceProvider<Object> template = ((ConfigurableServiceProvider<Object>)
+// provider);
+// // Get configurations
+// List<Object> configurables = template.getDefaultConfigurations();
+// for (Object config : configurables) {
+// // Make a copy that we can configure
+// ConfigurableServiceProvider<Object> configurableProvider = template.clone();
+// try {
+// configurableProvider.configure(config);
+// } catch (ConfigurationException e) {
+// logger.warn("Can't configure provider "
+// + configurableProvider + " with " + config);
+// continue;
+// }
+// defaultServiceDescriptionProviders.add(configurableProvider);
+// }
+// }
+// }
+// return defaultServiceDescriptionProviders;
+// }
+
+ // Get the default services.
+ @Override
+ public synchronized Set<ServiceDescriptionProvider> getDefaultServiceDescriptionProviders() {
+ if (defaultServiceDescriptionProviders != null)
+ return defaultServiceDescriptionProviders;
+ defaultServiceDescriptionProviders = new HashSet<>();
+
+ /*
+ * Add default configurable service description providers from the
+ * default_service_providers.xml file
+ */
+ if (defaultConfigurableServiceProvidersFile.exists()) {
+ try {
+ ServiceDescriptionDeserializer deserializer = new ServiceDescriptionDeserializer(
+ serviceDescriptionProviders);
+ defaultServiceDescriptionProviders.addAll(deserializer
+ .deserializeDefaults(this,
+ defaultConfigurableServiceProvidersFile));
+ /*
+ * We have successfully loaded the defaults for system
+ * configurable providers. Note that there are still defaults
+ * for third party configurable providers, which will be loaded
+ * below using getDefaultConfigurations().
+ */
+ defaultSystemConfigurableProvidersLoaded = true;
+ } catch (Exception e) {
+ logger.error("Could not load default service providers from "
+ + defaultConfigurableServiceProvidersFile.getAbsolutePath(), e);
+
+ /*
+ * Fallback on the old hardcoded method of loading default
+ * system configurable service providers using
+ * getDefaultConfigurations().
+ */
+ defaultSystemConfigurableProvidersLoaded = false;
+ }
+ } else {
+ logger.warn("Could not find the file "
+ + defaultConfigurableServiceProvidersFile.getAbsolutePath()
+ + " containing default system service providers. "
+ + "Using the hardcoded list of default system providers.");
+
+ /*
+ * Fallback on the old hardcoded method of loading default system
+ * configurable service providers using getDefaultConfigurations().
+ */
+ defaultSystemConfigurableProvidersLoaded = false;
+ }
+
+ /*
+ * Load other default service description providers - template, local
+ * workers and third party configurable service providers
+ */
+ for (ServiceDescriptionProvider provider : serviceDescriptionProviders) {
+ /*
+ * Template service providers (beanshell, string constant, etc. )
+ * and providers of local workers.
+ */
+ if (!(provider instanceof ConfigurableServiceProvider)) {
+ defaultServiceDescriptionProviders.add(provider);
+ continue;
+ }
+
+ /*
+ * Default system or third party configurable service description
+ * provider. System ones are read from the
+ * default_service_providers.xml file so getDefaultConfigurations()
+ * on them will not have much effect here unless
+ * defaultSystemConfigurableProvidersLoaded is set to false.
+ */
+ //FIXME needs to be designed to work using Configuration instances
+ //FIXME needs to get configurations via OSGi discovery
+ /*
+ ConfigurableServiceProvider template = (ConfigurableServiceProvider) provider;
+ // Get configurations
+ for (ObjectNode config : template.getDefaultConfigurations()) {
+ // Make a copy that we can configure
+ ConfigurableServiceProvider configurableProvider = template.clone();
+ try {
+ configurableProvider.configure(config);
+ } catch (ConfigurationException e) {
+ logger.warn("Can't configure provider "
+ + configurableProvider + " with " + config);
+ continue;
+ }
+ defaultServiceDescriptionProviders.add(configurableProvider);
+ }
+ */
+ }
+
+ return defaultServiceDescriptionProviders;
+ }
+
+ @Override
+ public synchronized Set<ServiceDescriptionProvider> getServiceDescriptionProviders() {
+ if (allServiceProviders != null)
+ return new HashSet<>(allServiceProviders);
+ allServiceProviders = new HashSet<>(userAddedProviders);
+ synchronized (this) {
+ if (!hasLoadedProviders)
+ try {
+ loadServiceProviders();
+ } catch (Exception e) {
+ logger.error("Could not load service providers", e);
+ } finally {
+ hasLoadedProviders = true;
+ }
+ }
+ for (ServiceDescriptionProvider provider : getDefaultServiceDescriptionProviders()) {
+ if (userRemovedProviders.contains(provider))
+ continue;
+ if (provider instanceof ConfigurableServiceProvider
+ && !serviceDescriptionsConfig.isIncludeDefaults())
+ // We'll skip the default configurable service provders
+ continue;
+ allServiceProviders.add(provider);
+ }
+ return new HashSet<>(allServiceProviders);
+ }
+
+ @Override
+ public Set<ServiceDescriptionProvider> getServiceDescriptionProviders(
+ ServiceDescription sd) {
+ Set<ServiceDescriptionProvider> result = new HashSet<>();
+ for (ServiceDescriptionProvider sdp : providerDescriptions.keySet())
+ if (providerDescriptions.get(sdp).contains(sd))
+ result.add(sdp);
+ return result;
+ }
+
+ @Override
+ public Set<ServiceDescription> getServiceDescriptions() {
+ updateServiceDescriptions(false, true);
+ Set<ServiceDescription> serviceDescriptions = new HashSet<>();
+ synchronized (providerDescriptions) {
+ for (Set<ServiceDescription> providerDesc : providerDescriptions
+ .values())
+ serviceDescriptions.addAll(providerDesc);
+ }
+ return serviceDescriptions;
+ }
+
+ @Override
+ public ServiceDescription getServiceDescription(URI serviceType) {
+ for (ServiceDescription serviceDescription : getServiceDescriptions())
+ if (serviceDescription.getActivityType().equals(serviceType))
+ return serviceDescription;
+ return null;
+ }
+
+ @Override
+ public List<ConfigurableServiceProvider> getUnconfiguredServiceProviders() {
+ List<ConfigurableServiceProvider> providers = new ArrayList<>();
+ for (ServiceDescriptionProvider provider : serviceDescriptionProviders)
+ if (provider instanceof ConfigurableServiceProvider)
+ providers.add((ConfigurableServiceProvider) provider);
+ return providers;
+ }
+
+ @Override
+ public Set<ServiceDescriptionProvider> getUserAddedServiceProviders() {
+ return new HashSet<>(userAddedProviders);
+ }
+
+ @Override
+ public Set<ServiceDescriptionProvider> getUserRemovedServiceProviders() {
+ return new HashSet<>(userRemovedProviders);
+ }
+
+ @Override
+ public void loadServiceProviders() {
+ File serviceProviderFile = findServiceDescriptionsFile();
+ if (serviceProviderFile.isFile())
+ loadServiceProviders(serviceProviderFile);
+ hasLoadedProviders = true;
+ }
+
+ @Override
+ public void loadServiceProviders(File serviceProvidersFile) {
+ ServiceDescriptionDeserializer deserializer = new ServiceDescriptionDeserializer(
+ serviceDescriptionProviders);
+ loading = true;
+ try {
+ deserializer.deserialize(this, serviceProvidersFile);
+ } catch (DeserializationException e) {
+ logger.error("failed to deserialize configuration", e);
+ }
+ loading = false;
+ }
+
+ @Override
+ public void loadServiceProviders(URL serviceProvidersURL) {
+ ServiceDescriptionDeserializer deserializer = new ServiceDescriptionDeserializer(
+ serviceDescriptionProviders);
+ loading = true;
+ try {
+ deserializer.deserialize(this, serviceProvidersURL);
+ } catch (DeserializationException e) {
+ logger.error("failed to deserialize configuration", e);
+ }
+ loading = false;
+ }
+
+ @Override
+ public void refresh() {
+ updateServiceDescriptions(true, false);
+ }
+
+ @Override
+ public void removeObserver(Observer<ServiceDescriptionRegistryEvent> observer) {
+ observers.removeObserver(observer);
+ }
+
+ @Override
+ public synchronized void removeServiceDescriptionProvider(
+ ServiceDescriptionProvider provider) {
+ if (!userAddedProviders.remove(provider))
+ // Not previously added - must be a default one.. but should we remove it?
+ if (loading || serviceDescriptionsConfig.isRemovePermanently()
+ && serviceDescriptionsConfig.isIncludeDefaults())
+ userRemovedProviders.add(provider);
+ if (allServiceProviders.remove(provider)) {
+ synchronized (providerDescriptions) {
+ Thread thread = serviceDescriptionThreads.remove(provider);
+ if (thread != null)
+ thread.interrupt();
+ providerDescriptions.remove(provider);
+ }
+ observers.notify(new RemovedProviderEvent(provider));
+ }
+ if (!loading)
+ saveServiceDescriptions();
+ }
+
+ @Override
+ public void saveServiceDescriptions() {
+ File serviceDescriptionsFile = findServiceDescriptionsFile();
+ saveServiceDescriptions(serviceDescriptionsFile);
+ }
+
+ @Override
+ public void saveServiceDescriptions(File serviceDescriptionsFile) {
+ ServiceDescriptionSerializer serializer = new ServiceDescriptionSerializer();
+ try {
+ serializer.serializeRegistry(this, serviceDescriptionsFile);
+ } catch (IOException e) {
+ throw new RuntimeException("Can't save service descriptions to "
+ + serviceDescriptionsFile);
+ }
+ }
+
+ /**
+ * Exports all configurable service providers (that give service
+ * descriptions) currently found in the Service Registry (apart from service
+ * templates and local services) regardless of who added them (user or
+ * default system providers).
+ * <p>
+ * Unlike {@link #saveServiceDescriptions}, this export does not have the
+ * "ignored providers" section as this is just a plain export of everything
+ * in the Service Registry.
+ *
+ * @param serviceDescriptionsFile
+ */
+ @Override
+ public void exportCurrentServiceDescriptions(File serviceDescriptionsFile) {
+ ServiceDescriptionSerializer serializer = new ServiceDescriptionSerializer();
+ try {
+ serializer.serializeFullRegistry(this, serviceDescriptionsFile);
+ } catch (IOException e) {
+ throw new RuntimeException("Could not save service descriptions to "
+ + serviceDescriptionsFile);
+ }
+ }
+
+ public void setServiceDescriptionProvidersList(
+ List<ServiceDescriptionProvider> serviceDescriptionProviders) {
+ this.serviceDescriptionProviders = serviceDescriptionProviders;
+ }
+
+ private void updateServiceDescriptions(boolean refreshAll, boolean waitFor) {
+ List<Thread> threads = new ArrayList<>();
+ for (ServiceDescriptionProvider provider : getServiceDescriptionProviders()) {
+ synchronized (providerDescriptions) {
+ if (providerDescriptions.containsKey(provider) && !refreshAll)
+ // We'll used the cached values
+ continue;
+ Thread oldThread = serviceDescriptionThreads.get(provider);
+ if (oldThread != null && oldThread.isAlive()) {
+ if (refreshAll)
+ // New thread will override the old thread
+ oldThread.interrupt();
+ else {
+ // observers.notify(new ProviderStatusNotification(provider, "Waiting for provider"));
+ continue;
+ }
+ }
+ // Not run yet - we'll start a new tread
+ Thread thread = new FindServiceDescriptionsThread(provider);
+ threads.add(thread);
+ serviceDescriptionThreads.put(provider, thread);
+ thread.start();
+ }
+ }
+ if (waitFor)
+ joinThreads(threads, DESCRIPTION_THREAD_TIMEOUT_MS);
+ }
+
+ @Override
+ public boolean isDefaultSystemConfigurableProvidersLoaded() {
+ return defaultSystemConfigurableProvidersLoaded;
+ }
+
+ /**
+ * Sets the serviceDescriptionsConfig.
+ *
+ * @param serviceDescriptionsConfig
+ * the new value of serviceDescriptionsConfig
+ */
+ public void setServiceDescriptionsConfig(
+ ServiceDescriptionsConfiguration serviceDescriptionsConfig) {
+ this.serviceDescriptionsConfig = serviceDescriptionsConfig;
+ }
+
+ class FindServiceDescriptionsThread extends Thread implements
+ UncaughtExceptionHandler, FindServiceDescriptionsCallBack {
+ private final ServiceDescriptionProvider provider;
+ private boolean aborting = false;
+ private final Set<ServiceDescription> providerDescs = new HashSet<>();
+
+ FindServiceDescriptionsThread(ServiceDescriptionProvider provider) {
+ super(threadGroup, "Find service descriptions from " + provider);
+ this.provider = provider;
+ setUncaughtExceptionHandler(this);
+ setDaemon(true);
+ }
+
+ @Override
+ public void fail(String message, Throwable ex) {
+ logger.warn("Provider " + getProvider() + ": " + message, ex);
+ if (aborting)
+ return;
+ observers.notify(new ProviderErrorNotification(getProvider(),
+ message, ex));
+ }
+
+ @Override
+ public void finished() {
+ if (aborting)
+ return;
+ synchronized (providerDescriptions) {
+ providerDescriptions.put(getProvider(), providerDescs);
+ }
+ observers.notify(new ServiceDescriptionProvidedEvent(getProvider(),
+ providerDescs));
+ }
+
+ @Override
+ public void partialResults(
+ Collection<? extends ServiceDescription> serviceDescriptions) {
+ if (aborting)
+ return;
+ providerDescs.addAll(serviceDescriptions);
+ synchronized (providerDescriptions) {
+ providerDescriptions.put(getProvider(), providerDescs);
+ }
+ observers.notify(new PartialServiceDescriptionsNotification(
+ getProvider(), serviceDescriptions));
+ }
+
+ @Override
+ public void status(String message) {
+ logger.debug("Provider " + getProvider() + ": " + message);
+ if (aborting)
+ return;
+ observers.notify(new ProviderStatusNotification(getProvider(),
+ message));
+ }
+
+ @Override
+ public void warning(String message) {
+ logger.warn("Provider " + getProvider() + ": " + message);
+ if (aborting)
+ return;
+ observers.notify(new ProviderWarningNotification(getProvider(),
+ message));
+ }
+
+ public ServiceDescriptionProvider getProvider() {
+ return provider;
+ }
+
+ @Override
+ public void interrupt() {
+ aborting = true;
+ super.interrupt();
+ }
+
+ @Override
+ public void run() {
+ observers.notify(new ProviderUpdatingNotification(provider));
+ getProvider().findServiceDescriptionsAsync(this);
+ }
+
+ @Override
+ public void uncaughtException(Thread t, Throwable ex) {
+ logger.error("Uncaught exception in " + t, ex);
+ fail("Uncaught exception", ex);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionSerializer.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionSerializer.java b/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionSerializer.java
new file mode 100644
index 0000000..8a047a3
--- /dev/null
+++ b/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionSerializer.java
@@ -0,0 +1,102 @@
+package net.sf.taverna.t2.servicedescriptions.impl;
+
+import static net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.CONFIGURATION;
+import static net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.IGNORED;
+import static net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.PROVIDERS;
+import static net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.PROVIDER_ID;
+import static net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.SERVICE_PANEL_CONFIGURATION;
+import static net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionConstants.TYPE;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Set;
+
+import net.sf.taverna.t2.servicedescriptions.ConfigurableServiceProvider;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
+
+import org.apache.log4j.Logger;
+import org.jdom.JDOMException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+class ServiceDescriptionSerializer {
+ private static Logger logger = Logger
+ .getLogger(ServiceDescriptionSerializer.class);
+
+ public void serializeRegistry(ServiceDescriptionRegistry registry, File file)
+ throws IOException {
+ Set<ServiceDescriptionProvider> ignoreProviders = registry
+ .getUserRemovedServiceProviders();
+ JsonNode registryElement = serializeRegistry(registry, ignoreProviders);
+ try (BufferedOutputStream bufferedOutStream = new BufferedOutputStream(
+ new FileOutputStream(file))) {
+ bufferedOutStream.write(registryElement.toString()
+ .getBytes("UTF-8"));
+ }
+ }
+
+ /**
+ * Export the whole service registry to an xml file, regardless of who added
+ * the service provider (user or system default). In this case there will be
+ * no "ignored providers" in the saved file.
+ */
+ public void serializeFullRegistry(ServiceDescriptionRegistry registry,
+ File file) throws IOException {
+ JsonNode registryElement = serializeRegistry(registry, ALL_PROVIDERS);
+ try (BufferedOutputStream bufferedOutStream = new BufferedOutputStream(
+ new FileOutputStream(file))) {
+ bufferedOutStream.write(registryElement.toString()
+ .getBytes("UTF-8"));
+ }
+ }
+
+ private static final JsonNodeFactory factory = JsonNodeFactory.instance;
+ private static final Set<ServiceDescriptionProvider> ALL_PROVIDERS = null;
+
+ private JsonNode serializeRegistry(ServiceDescriptionRegistry registry,
+ Set<ServiceDescriptionProvider> ignoreProviders) {
+ ObjectNode overallConfiguration = factory.objectNode();
+ overallConfiguration.put(SERVICE_PANEL_CONFIGURATION,
+ ignoreProviders != ALL_PROVIDERS ? "full" : "defaults only");
+ ArrayNode providers = overallConfiguration.putArray(PROVIDERS);
+
+ for (ServiceDescriptionProvider provider : registry
+ .getUserAddedServiceProviders())
+ try {
+ providers.add(serializeProvider(provider));
+ } catch (JDOMException | IOException e) {
+ logger.warn("Could not serialize " + provider, e);
+ }
+
+ if (ignoreProviders != ALL_PROVIDERS) {
+ ArrayNode ignored = overallConfiguration.putArray(IGNORED);
+ for (ServiceDescriptionProvider provider : ignoreProviders)
+ try {
+ ignored.add(serializeProvider(provider));
+ } catch (JDOMException | IOException e) {
+ logger.warn("Could not serialize " + provider, e);
+ }
+ }
+
+ return overallConfiguration;
+ }
+
+ private JsonNode serializeProvider(ServiceDescriptionProvider provider)
+ throws JDOMException, IOException {
+ ObjectNode node = factory.objectNode();
+ node.put(PROVIDER_ID, provider.getId());
+
+ if (provider instanceof ConfigurableServiceProvider) {
+ ConfigurableServiceProvider configurable = (ConfigurableServiceProvider) provider;
+ node.put(TYPE, configurable.getConfiguration().getType().toString());
+ node.put(CONFIGURATION, configurable.getConfiguration().getJson());
+ }
+ return node;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionXMLConstants.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionXMLConstants.java b/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionXMLConstants.java
new file mode 100644
index 0000000..ee180a7
--- /dev/null
+++ b/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionXMLConstants.java
@@ -0,0 +1,15 @@
+package net.sf.taverna.t2.servicedescriptions.impl;
+
+import org.jdom.Namespace;
+
+public interface ServiceDescriptionXMLConstants {
+
+ public static final Namespace SERVICE_DESCRIPTION_NS = Namespace
+ .getNamespace("http://taverna.sf.net/2009/xml/servicedescription");
+ public static final String PROVIDER = "provider";
+ public static final String PROVIDERS = "providers";
+ public static final String SERVICE_DESCRIPTIONS = "serviceDescriptions";
+ public static final String IGNORED_PROVIDERS = "ignoredProviders";
+ public static final String PROVIDER_IDENTIFIER = "providerId";
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionsConfigurationImpl.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionsConfigurationImpl.java b/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionsConfigurationImpl.java
new file mode 100644
index 0000000..ef0295c
--- /dev/null
+++ b/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/servicedescriptions/impl/ServiceDescriptionsConfigurationImpl.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.servicedescriptions.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionsConfiguration;
+
+import uk.org.taverna.configuration.AbstractConfigurable;
+import uk.org.taverna.configuration.ConfigurationManager;
+
+public class ServiceDescriptionsConfigurationImpl extends AbstractConfigurable
+ implements ServiceDescriptionsConfiguration {
+ private static final String INCLUDE_DEFAULTS = "includeDefaults";
+ private static final String SERVICE_PALETTE = "Service providers";
+ private static final String SERVICE_PALETTE_PREFIX = "ServiceProviders";
+ private static final String CATEGORY = "Services";
+ private static final String UUID = "f0d1ef24-9337-412f-b2c3-220a01e2efd0";
+ private static final String REMOVE_PERMANENTLY = "removePermanently";
+
+ public ServiceDescriptionsConfigurationImpl(
+ ConfigurationManager configurationManager) {
+ super(configurationManager);
+ }
+
+ @Override
+ public String getCategory() {
+ return CATEGORY;
+ }
+
+ @Override
+ public Map<String, String> getDefaultPropertyMap() {
+ Map<String, String> defaults = new HashMap<String, String>();
+ defaults.put(INCLUDE_DEFAULTS, "true");
+ defaults.put(REMOVE_PERMANENTLY, "true");
+ return defaults;
+ }
+
+ @Override
+ public String getDisplayName() {
+ return SERVICE_PALETTE;
+ }
+
+ @Override
+ public String getFilePrefix() {
+ return SERVICE_PALETTE_PREFIX;
+ }
+
+ @Override
+ public String getUUID() {
+ return UUID;
+ }
+
+ @Override
+ public boolean isIncludeDefaults() {
+ return Boolean.parseBoolean(getProperty(INCLUDE_DEFAULTS));
+ }
+
+ @Override
+ public void setIncludeDefaults(boolean includeDefaults) {
+ setProperty(INCLUDE_DEFAULTS, Boolean.toString(includeDefaults));
+ }
+
+ @Override
+ public boolean isRemovePermanently() {
+ return Boolean.parseBoolean(getProperty(REMOVE_PERMANENTLY));
+ }
+
+ @Override
+ public void setRemovePermanently(boolean removePermanently) {
+ setProperty(REMOVE_PERMANENTLY, Boolean.toString(removePermanently));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfiguration.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfiguration.java b/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfiguration.java
new file mode 100644
index 0000000..46f82c4
--- /dev/null
+++ b/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfiguration.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.activitypalette;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import uk.org.taverna.configuration.AbstractConfigurable;
+import uk.org.taverna.configuration.ConfigurationManager;
+
+public class ActivityPaletteConfiguration extends AbstractConfigurable {
+ private Map<String,String> defaultPropertyMap;
+
+ public ActivityPaletteConfiguration(ConfigurationManager configurationManager) {
+ super(configurationManager);
+ }
+
+ @Override
+ public String getCategory() {
+ return "Services";
+ }
+
+ @Override
+ public Map<String, String> getDefaultPropertyMap() {
+ if (defaultPropertyMap == null) {
+ defaultPropertyMap = new HashMap<>();
+
+ // //wsdl
+ //defaultPropertyMap.put("taverna.defaultwsdl", "http://www.ebi.ac.uk/xembl/XEMBL.wsdl,"+
+ // "http://soap.genome.jp/KEGG.wsdl,"+
+ // "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/soap/eutils.wsdl,"+
+ // "http://soap.bind.ca/wsdl/bind.wsdl,"+
+ // "http://www.ebi.ac.uk/ws/services/urn:Dbfetch?wsdl");
+
+ // //soaplab
+ //defaultPropertyMap.put("taverna.defaultsoaplab", "http://www.ebi.ac.uk/soaplab/services/");
+
+ // //biomart
+ //defaultPropertyMap.put("taverna.defaultmartregistry","http://www.biomart.org/biomart");
+
+ //add property names
+ //defaultPropertyMap.put("name.taverna.defaultwsdl", "WSDL");
+ //defaultPropertyMap.put("name.taverna.defaultsoaplab","Soaplab");
+ //defaultPropertyMap.put("name.taverna.defaultmartregistry", "Biomart");
+ }
+ return defaultPropertyMap;
+ }
+
+ @Override
+ public String getDisplayName() {
+ return "Activity Palette";
+ }
+
+ @Override
+ public String getFilePrefix() {
+ return "ActivityPalette";
+ }
+
+ @Override
+ public String getUUID() {
+ return "ad9f3a60-5967-11dd-ae16-0800200c9a66";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfigurationPanel.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfigurationPanel.java b/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfigurationPanel.java
new file mode 100644
index 0000000..6166e60
--- /dev/null
+++ b/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfigurationPanel.java
@@ -0,0 +1,284 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.activitypalette;
+
+import static java.awt.BorderLayout.CENTER;
+import static java.awt.BorderLayout.EAST;
+import static java.awt.BorderLayout.NORTH;
+import static java.awt.BorderLayout.SOUTH;
+import static java.awt.FlowLayout.LEFT;
+import static java.awt.FlowLayout.RIGHT;
+import static javax.swing.BoxLayout.Y_AXIS;
+import static javax.swing.JOptionPane.INFORMATION_MESSAGE;
+import static javax.swing.JOptionPane.WARNING_MESSAGE;
+import static javax.swing.JOptionPane.YES_NO_OPTION;
+import static javax.swing.JOptionPane.YES_OPTION;
+import static javax.swing.JOptionPane.showConfirmDialog;
+import static javax.swing.JOptionPane.showInputDialog;
+import static javax.swing.border.BevelBorder.LOWERED;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.BoxLayout;
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.DefaultListCellRenderer;
+import javax.swing.DefaultListModel;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.border.BevelBorder;
+
+import org.apache.log4j.Logger;
+
+@SuppressWarnings("serial")
+public class ActivityPaletteConfigurationPanel extends JPanel {
+ private static Logger logger = Logger
+ .getLogger(ActivityPaletteConfigurationPanel.class);
+
+ private Map<String,List<String>> values = new HashMap<>();
+ private Map<String,String> names = new HashMap<>();
+ private DefaultComboBoxModel<String> model;
+ private DefaultListModel<String> listModel;
+ private JList<String> propertyListItems;
+ private String selectedKey;
+ private JButton deleteTypeButton;
+ private final ActivityPaletteConfiguration config;
+
+ public ActivityPaletteConfigurationPanel(ActivityPaletteConfiguration config) {
+ super(new BorderLayout());
+ this.config = config;
+
+ model = new DefaultComboBoxModel<>();
+ for (String key : config.getInternalPropertyMap().keySet()) {
+ if (key.startsWith("taverna.")
+ && config.getPropertyStringList(key) != null) {
+ model.addElement(key);
+ values.put(key,
+ new ArrayList<>(config.getPropertyStringList(key)));
+ }
+ if (key.startsWith("name.taverna."))
+ names.put(key, config.getProperty(key).toString());
+ }
+ deleteTypeButton = new JButton("Delete");
+
+ final JButton addTypeButton = new JButton("Add");
+ final JComboBox<String> comboBox = new JComboBox<>(model);
+ comboBox.setRenderer(new DefaultListCellRenderer() {
+ @Override
+ public Component getListCellRendererComponent(JList<?> list,
+ Object value, int index, boolean isSelected,
+ boolean cellHasFocus) {
+ if (value != null && value instanceof String) {
+ String name = names.get("name." + value);
+ if (name != null)
+ value = name;
+ }
+ return super.getListCellRendererComponent(list, value, index,
+ isSelected, cellHasFocus);
+ }
+ });
+
+ deleteTypeButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ String displayText = names.get("name." + selectedKey);
+ if (displayText == null)
+ displayText = selectedKey;
+ if (confirm("Confirm removal",
+ "Are you sure you wish to remove the type "
+ + displayText + "?")) {
+ names.remove("name." + selectedKey);
+ values.remove(selectedKey);
+ model.removeElement(selectedKey);
+ comboBox.setSelectedIndex(0);
+ }
+ }
+ });
+
+ addTypeButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ String key = input("New key", "Provide the new key.");
+ if (key == null)
+ return;
+ String name = input("Name for the key",
+ "Provide the name for the key: " + key);
+ if (name == null)
+ return;
+
+ values.put(key, new ArrayList<String>());
+ names.put("name." + key, name);
+ model.addElement(key);
+ comboBox.setSelectedItem(key);
+ }
+ });
+
+ comboBox.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (comboBox.getSelectedItem() != null
+ && comboBox.getSelectedItem() instanceof String) {
+ selectedKey = (String) comboBox.getSelectedItem();
+ List<String> selectedList = values.get(selectedKey);
+ populateList(selectedList);
+ deleteTypeButton.setEnabled(selectedList.size() == 0);
+ }
+ }
+ });
+
+ JPanel propertySelectionPanel = new JPanel(new FlowLayout(LEFT));
+ propertySelectionPanel.add(new JLabel("Activity type:"));
+ propertySelectionPanel.add(comboBox);
+ propertySelectionPanel.add(addTypeButton);
+ propertySelectionPanel.add(deleteTypeButton);
+ add(propertySelectionPanel, NORTH);
+
+ JPanel listPanel = new JPanel(new BorderLayout());
+ listModel = new DefaultListModel<>();
+ propertyListItems = new JList<>(listModel);
+ propertyListItems.setBorder(new BevelBorder(LOWERED));
+
+ listPanel.add(propertyListItems, CENTER);
+ listPanel.add(listButtons(), EAST);
+
+ add(listPanel, CENTER);
+
+ add(applyButtonPanel(), SOUTH);
+
+ if (model.getSize() > 0)
+ comboBox.setSelectedItem(model.getElementAt(0));
+ }
+
+ private void populateList(List<String> selectedList) {
+ listModel.removeAllElements();
+ for (String item : selectedList)
+ listModel.addElement(item);
+ }
+
+ private JPanel applyButtonPanel() {
+ JPanel applyPanel = new JPanel(new FlowLayout(RIGHT));
+ JButton applyButton = new JButton("Apply");
+
+ applyButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ config.getInternalPropertyMap().clear();
+ for (String key : values.keySet()) {
+ List<String> properties = values.get(key);
+ config.setPropertyStringList(key, new ArrayList<>(
+ properties));
+ }
+ for (String key : names.keySet())
+ config.setProperty(key, names.get(key));
+ store();
+ }
+ });
+
+ applyPanel.add(applyButton);
+ return applyPanel;
+ }
+
+ private void store() {
+ try {
+ //FIXME
+ //ConfigurationManager.getInstance().store(config);
+ } catch (Exception e1) {
+ logger.error("There was an error storing the configuration:"
+ + config.getFilePrefix() + " (UUID=" + config.getUUID()
+ + ")", e1);
+ }
+ }
+
+ private JPanel listButtons() {
+ JPanel panel = new JPanel();
+ panel.setLayout(new BoxLayout(panel, Y_AXIS));
+ JButton addButton = new JButton("+");
+ addButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ String value = input("New property", "Provide new value for: "
+ + selectedKey);
+ if (value != null) {
+ listModel.addElement(value);
+ values.get(selectedKey).add(value);
+ deleteTypeButton.setEnabled(false);
+ }
+ }
+ });
+
+ JButton deleteButton = new JButton("-");
+ deleteButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ Object value = propertyListItems.getSelectedValue();
+ if (confirm("Confirm removal",
+ "Are you sure you wish to remove " + value + "?")) {
+ listModel.removeElement(value);
+ values.get(selectedKey).remove(value);
+ if (values.get(selectedKey).size() == 0)
+ deleteTypeButton.setEnabled(true);
+ }
+ }
+ });
+
+ panel.add(addButton);
+ panel.add(deleteButton);
+
+ return panel;
+ }
+
+ private boolean confirm(String title, String message) {
+ return showConfirmDialog(this, message, title, YES_NO_OPTION,
+ WARNING_MESSAGE) == YES_OPTION;
+ }
+
+ private String input(String title, String message) {
+ return showInputDialog(this, message, title, INFORMATION_MESSAGE);
+ }
+
+/* private JButton getAddTypeButton() {
+ JButton result = new JButton("Add");
+ result.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ String val = input("New property value","New property value");
+ if (val!=null) {
+ if (values.get(val) == null) {
+ model.addElement(val);
+ values.put(val, new ArrayList<String>());
+ } else
+ showMessageDialog(ActivityPaletteConfigurationPanel.this, "This property already exists");
+ }
+ }
+ });
+ return result;
+ }
+*/
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfigurationUIFactory.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfigurationUIFactory.java b/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfigurationUIFactory.java
new file mode 100644
index 0000000..39c4a5a
--- /dev/null
+++ b/taverna-workbench-activity-palette-impl/src/main/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfigurationUIFactory.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.activitypalette;
+
+import javax.swing.JPanel;
+
+import uk.org.taverna.configuration.Configurable;
+import uk.org.taverna.configuration.ConfigurationUIFactory;
+
+public class ActivityPaletteConfigurationUIFactory implements
+ ConfigurationUIFactory {
+ private ActivityPaletteConfiguration activityPaletteConfiguration;
+
+ @Override
+ public boolean canHandle(String uuid) {
+ return uuid != null && uuid.equals(getConfigurable().getUUID());
+ }
+
+ @Override
+ public Configurable getConfigurable() {
+ return activityPaletteConfiguration;
+ }
+
+ @Override
+ public JPanel getConfigurationPanel() {
+ return new ActivityPaletteConfigurationPanel(
+ activityPaletteConfiguration);
+ }
+
+ public void setActivityPaletteConfiguration(
+ ActivityPaletteConfiguration activityPaletteConfiguration) {
+ this.activityPaletteConfiguration = activityPaletteConfiguration;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-activity-palette-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.configuration.ConfigurationUIFactory
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.configuration.ConfigurationUIFactory b/taverna-workbench-activity-palette-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.configuration.ConfigurationUIFactory
new file mode 100644
index 0000000..6c9fed9
--- /dev/null
+++ b/taverna-workbench-activity-palette-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.configuration.ConfigurationUIFactory
@@ -0,0 +1 @@
+#net.sf.taverna.t2.workbench.ui.activitypalette.ActivityPaletteConfigurationUIFactory
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-activity-palette-impl/src/main/resources/META-INF/spring/activity-palette-impl-context-osgi.xml
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-impl/src/main/resources/META-INF/spring/activity-palette-impl-context-osgi.xml b/taverna-workbench-activity-palette-impl/src/main/resources/META-INF/spring/activity-palette-impl-context-osgi.xml
new file mode 100644
index 0000000..34921f5
--- /dev/null
+++ b/taverna-workbench-activity-palette-impl/src/main/resources/META-INF/spring/activity-palette-impl-context-osgi.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans:beans xmlns="http://www.springframework.org/schema/osgi" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:beans="http://www.springframework.org/schema/beans"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/osgi
+ http://www.springframework.org/schema/osgi/spring-osgi.xsd">
+
+ <service ref="ServiceDescriptionRegistryImpl" interface="net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry"/>
+ <service ref="ServiceDescriptionsConfigurationImpl" interface="net.sf.taverna.t2.servicedescriptions.ServiceDescriptionsConfiguration"/>
+
+ <reference id="configurationManager" interface="uk.org.taverna.configuration.ConfigurationManager" />
+ <reference id="applicationConfiguration" interface="uk.org.taverna.configuration.app.ApplicationConfiguration" />
+
+ <list id="serviceDescriptionProviders" interface="net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider" cardinality="0..N" greedy-proxying="true"/>
+
+</beans:beans>
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-activity-palette-impl/src/main/resources/META-INF/spring/activity-palette-impl-context.xml
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-impl/src/main/resources/META-INF/spring/activity-palette-impl-context.xml b/taverna-workbench-activity-palette-impl/src/main/resources/META-INF/spring/activity-palette-impl-context.xml
new file mode 100644
index 0000000..9f7110f
--- /dev/null
+++ b/taverna-workbench-activity-palette-impl/src/main/resources/META-INF/spring/activity-palette-impl-context.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <bean name="ServiceDescriptionRegistryImpl" class="net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionRegistryImpl">
+ <constructor-arg name="applicationConfiguration" ref="applicationConfiguration" />
+ <property name="serviceDescriptionProvidersList" ref="serviceDescriptionProviders" />
+ <property name="serviceDescriptionsConfig">
+ <ref local="ServiceDescriptionsConfigurationImpl"/>
+ </property>
+ </bean>
+
+ <bean id="ServiceDescriptionsConfigurationImpl" class="net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionsConfigurationImpl">
+ <constructor-arg ref="configurationManager"/>
+ </bean>
+
+ <!-- Don't think ActivityPalette is still used -->
+ <!-- <bean id="ActivityPaletteConfiguration" class="net.sf.taverna.t2.workbench.ui.activitypalette.ActivityPaletteConfiguration">
+ <constructor-arg ref="configurationManager"/>
+ </bean> -->
+
+</beans>
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-activity-palette-impl/src/test/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfigurationTest.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-impl/src/test/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfigurationTest.java b/taverna-workbench-activity-palette-impl/src/test/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfigurationTest.java
new file mode 100644
index 0000000..081a9af
--- /dev/null
+++ b/taverna-workbench-activity-palette-impl/src/test/java/net/sf/taverna/t2/workbench/ui/activitypalette/ActivityPaletteConfigurationTest.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.activitypalette;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import uk.org.taverna.configuration.app.impl.ApplicationConfigurationImpl;
+import uk.org.taverna.configuration.impl.ConfigurationManagerImpl;
+
+public class ActivityPaletteConfigurationTest {
+
+ private ActivityPaletteConfiguration conf;
+ private ConfigurationManagerImpl manager;
+
+ @Before
+ public void setup() {
+ File f = new File(System.getProperty("java.io.tmpdir"));
+ final File d = new File(f,UUID.randomUUID().toString());
+ d.mkdir();
+ manager = new ConfigurationManagerImpl(new ApplicationConfigurationImpl() {
+ @Override
+ public File getApplicationHomeDir() {
+ return d;
+ }
+ });
+ conf=new ActivityPaletteConfiguration(manager);
+ conf.restoreDefaults();
+ }
+
+ @Test
+ public void testEmptyList() throws Exception {
+ conf.setPropertyStringList("list", new ArrayList<String>());
+ assertTrue("Result was not a list but was:"+conf.getProperty("list"),conf.getPropertyStringList("list") instanceof List);
+ assertTrue("Result was not a list but was:"+conf.getPropertyStringList("list"),conf.getPropertyStringList("list") instanceof List);
+ List<String> list = conf.getPropertyStringList("list");
+ assertEquals("There should be 0 elements",0,list.size());
+ }
+
+ @Test
+ public void testSingleItem() throws Exception {
+ List<String> list = new ArrayList<>();
+ list.add("fred");
+ conf.setPropertyStringList("single", list);
+
+ assertTrue("should be an ArrayList",conf.getPropertyStringList("single") instanceof List);
+ List<String> l = conf.getPropertyStringList("single");
+ assertEquals("There should be 1 element",1,l.size());
+ assertEquals("Its value should be fred","fred",l.get(0));
+ }
+
+ @Test
+ public void testList() throws Exception {
+ List<String> list = new ArrayList<>();
+ list.add("fred");
+ list.add("bloggs");
+ conf.setPropertyStringList("list", list);
+
+ assertTrue("should be an ArrayList",conf.getPropertyStringList("list") instanceof List);
+ List<String> l = conf.getPropertyStringList("list");
+ assertEquals("There should be 1 element",2,l.size());
+ assertEquals("Its value should be fred","fred",l.get(0));
+ assertEquals("Its value should be bloggs","bloggs",l.get(1));
+ }
+
+ @Test
+ public void testNull() throws Exception {
+ assertNull("Should return null",conf.getProperty("blah blah blah"));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-activity-palette-impl/src/test/resources/META-INF/services/net.sf.taverna.t2.partition.PartitionAlgorithmSetSPI
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-impl/src/test/resources/META-INF/services/net.sf.taverna.t2.partition.PartitionAlgorithmSetSPI b/taverna-workbench-activity-palette-impl/src/test/resources/META-INF/services/net.sf.taverna.t2.partition.PartitionAlgorithmSetSPI
new file mode 100644
index 0000000..9f3c02d
--- /dev/null
+++ b/taverna-workbench-activity-palette-impl/src/test/resources/META-INF/services/net.sf.taverna.t2.partition.PartitionAlgorithmSetSPI
@@ -0,0 +1 @@
+net.sf.taverna.t2.partition.DummyPartitionAlgorithmSet
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-activity-palette-impl/src/test/resources/META-INF/services/net.sf.taverna.t2.partition.PropertyExtractorSPI
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-impl/src/test/resources/META-INF/services/net.sf.taverna.t2.partition.PropertyExtractorSPI b/taverna-workbench-activity-palette-impl/src/test/resources/META-INF/services/net.sf.taverna.t2.partition.PropertyExtractorSPI
new file mode 100644
index 0000000..f5e7226
--- /dev/null
+++ b/taverna-workbench-activity-palette-impl/src/test/resources/META-INF/services/net.sf.taverna.t2.partition.PropertyExtractorSPI
@@ -0,0 +1,3 @@
+net.sf.taverna.t2.partition.DummyExtractor1
+net.sf.taverna.t2.partition.DummyExtractor2
+net.sf.taverna.t2.partition.DummyExtractor3
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-activity-palette-impl/src/test/resources/META-INF/services/net.sf.taverna.t2.partition.QueryFactory
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-impl/src/test/resources/META-INF/services/net.sf.taverna.t2.partition.QueryFactory b/taverna-workbench-activity-palette-impl/src/test/resources/META-INF/services/net.sf.taverna.t2.partition.QueryFactory
new file mode 100644
index 0000000..2d26d31a
--- /dev/null
+++ b/taverna-workbench-activity-palette-impl/src/test/resources/META-INF/services/net.sf.taverna.t2.partition.QueryFactory
@@ -0,0 +1,2 @@
+net.sf.taverna.t2.partition.DummyActivityQueryFactory
+net.sf.taverna.t2.partition.DummyQueryFactory
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-configuration-impl/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-workbench-configuration-impl/pom.xml b/taverna-workbench-configuration-impl/pom.xml
new file mode 100644
index 0000000..19356bb
--- /dev/null
+++ b/taverna-workbench-configuration-impl/pom.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>net.sf.taverna.t2</groupId>
+ <artifactId>ui-impl</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ </parent>
+ <groupId>net.sf.taverna.t2.ui-impl</groupId>
+ <artifactId>configuration-impl</artifactId>
+ <packaging>bundle</packaging>
+ <name>Configuration Management Implementations</name>
+ <description>General configuration management</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>net.sf.taverna.t2.ui-api</groupId>
+ <artifactId>menu-api</artifactId>
+ <version>${t2.ui.api.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>net.sf.taverna.t2.ui-api</groupId>
+ <artifactId>helper-api</artifactId>
+ <version>${t2.ui.api.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>net.sf.taverna.t2.ui-api</groupId>
+ <artifactId>configuration-api</artifactId>
+ <version>${t2.ui.api.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>uk.org.taverna.configuration</groupId>
+ <artifactId>taverna-configuration-api</artifactId>
+ <version>${taverna.configuration.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>uk.org.taverna.configuration</groupId>
+ <artifactId>taverna-app-configuration-api</artifactId>
+ <version>${taverna.configuration.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>uk.org.taverna.configuration</groupId>
+ <artifactId>taverna-configuration-impl</artifactId>
+ <version>0.1.1-SNAPSHOT</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>uk.org.taverna.configuration</groupId>
+ <artifactId>taverna-app-configuration-impl</artifactId>
+ <version>0.1.1-SNAPSHOT</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/WorkbenchConfigurationImpl.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/WorkbenchConfigurationImpl.java b/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/WorkbenchConfigurationImpl.java
new file mode 100644
index 0000000..0e63a4a
--- /dev/null
+++ b/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/WorkbenchConfigurationImpl.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.impl.configuration;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sf.taverna.t2.workbench.configuration.workbench.WorkbenchConfiguration;
+
+import org.apache.log4j.Logger;
+
+import uk.org.taverna.configuration.AbstractConfigurable;
+import uk.org.taverna.configuration.ConfigurationManager;
+import uk.org.taverna.configuration.app.ApplicationConfiguration;
+
+/**
+ * An implementation of Configurable for general Workbench configuration
+ * properties
+ *
+ * @author Stuart Owen
+ * @author Stian Soiland-Reyes
+ */
+public class WorkbenchConfigurationImpl extends AbstractConfigurable implements
+ WorkbenchConfiguration {
+ private static Logger logger = Logger
+ .getLogger(WorkbenchConfiguration.class);
+ private static final int DEFAULT_MAX_MENU_ITEMS = 20;
+ public static final String TAVERNA_DOTLOCATION = "taverna.dotlocation";
+ public static final String MAX_MENU_ITEMS = "taverna.maxmenuitems";
+ public static final String WARN_INTERNAL_ERRORS = "taverna.warninternal";
+ public static final String CAPTURE_CONSOLE = "taverna.captureconsole";
+ private static final String BIN = "bin";
+ private static final String BUNDLE_CONTENTS = "Contents";
+ private static final String BUNDLE_MAC_OS = "MacOS";
+ private static final String DOT_EXE = "dot.exe";
+ private static final String DOT_FALLBACK = "dot";
+ public static String uuid = "c14856f0-5967-11dd-ae16-0800200c9a66";
+ private static final String MAC_OS_X = "Mac OS X";
+ private static final String WIN32I386 = "win32i386";
+ private static final String WINDOWS = "Windows";
+
+ private ApplicationConfiguration applicationConfiguration;
+
+ /**
+ * Constructs a new <code>WorkbenchConfigurationImpl</code>.
+ *
+ * @param configurationManager
+ */
+ public WorkbenchConfigurationImpl(ConfigurationManager configurationManager) {
+ super(configurationManager);
+ }
+
+ Map<String, String> defaultWorkbenchProperties = null;
+ Map<String, String> workbenchProperties = new HashMap<String, String>();
+
+ @Override
+ public String getCategory() {
+ return "general";
+ }
+
+ @Override
+ public Map<String, String> getDefaultPropertyMap() {
+ if (defaultWorkbenchProperties == null) {
+ defaultWorkbenchProperties = new HashMap<>();
+ String dotLocation = System.getProperty(TAVERNA_DOTLOCATION) != null ? System
+ .getProperty(TAVERNA_DOTLOCATION) : getDefaultDotLocation();
+ if (dotLocation != null)
+ defaultWorkbenchProperties
+ .put(TAVERNA_DOTLOCATION, dotLocation);
+ defaultWorkbenchProperties.put(MAX_MENU_ITEMS,
+ Integer.toString(DEFAULT_MAX_MENU_ITEMS));
+ defaultWorkbenchProperties.put(WARN_INTERNAL_ERRORS,
+ Boolean.FALSE.toString());
+ defaultWorkbenchProperties.put(CAPTURE_CONSOLE,
+ Boolean.TRUE.toString());
+ }
+ return defaultWorkbenchProperties;
+ }
+
+ @Override
+ public String getDisplayName() {
+ return "Workbench";
+ }
+
+ @Override
+ public String getFilePrefix() {
+ return "Workbench";
+ }
+
+ @Override
+ public String getUUID() {
+ return uuid;
+ }
+
+ @Override
+ public boolean getWarnInternalErrors() {
+ String property = getProperty(WARN_INTERNAL_ERRORS);
+ return Boolean.parseBoolean(property);
+ }
+
+ @Override
+ public boolean getCaptureConsole() {
+ String property = getProperty(CAPTURE_CONSOLE);
+ return Boolean.parseBoolean(property);
+ }
+
+ @Override
+ public void setWarnInternalErrors(boolean warnInternalErrors) {
+ setProperty(WARN_INTERNAL_ERRORS, Boolean.toString(warnInternalErrors));
+ }
+
+ @Override
+ public void setCaptureConsole(boolean captureConsole) {
+ setProperty(CAPTURE_CONSOLE, Boolean.toString(captureConsole));
+ }
+
+ @Override
+ public void setMaxMenuItems(int maxMenuItems) {
+ if (maxMenuItems < 2)
+ throw new IllegalArgumentException(
+ "Maximum menu items must be at least 2");
+ setProperty(MAX_MENU_ITEMS, Integer.toString(maxMenuItems));
+ }
+
+ @Override
+ public int getMaxMenuItems() {
+ String property = getProperty(MAX_MENU_ITEMS);
+ try {
+ int maxMenuItems = Integer.parseInt(property);
+ if (maxMenuItems >= 2)
+ return maxMenuItems;
+ logger.warn(MAX_MENU_ITEMS + " can't be less than 2");
+ } catch (NumberFormatException ex) {
+ logger.warn("Invalid number for " + MAX_MENU_ITEMS + ": "
+ + property);
+ }
+ // We'll return the default instead
+ return DEFAULT_MAX_MENU_ITEMS;
+ }
+
+ @Override
+ public String getDotLocation() {
+ return getProperty(TAVERNA_DOTLOCATION);
+ }
+
+ @Override
+ public void setDotLocation(String dotLocation) {
+ setProperty(TAVERNA_DOTLOCATION, dotLocation);
+ }
+
+ private String getDefaultDotLocation() {
+ if (applicationConfiguration == null)
+ return null;
+ File startupDir = applicationConfiguration.getStartupDir();
+ if (startupDir == null)
+ return DOT_FALLBACK;
+
+ String os = System.getProperty("os.name");
+ if (os.equals(MAC_OS_X))
+ if (startupDir.getParentFile() != null) {
+ File contentsDir = startupDir.getParentFile().getParentFile();
+ if (contentsDir != null
+ && contentsDir.getName().equalsIgnoreCase(
+ BUNDLE_CONTENTS)) {
+ File dot = new File(new File(contentsDir, BUNDLE_MAC_OS),
+ DOT_FALLBACK);
+ if (dot.exists())
+ return dot.getAbsolutePath();
+ }
+ } else if (os.startsWith(WINDOWS)) {
+ File binWin386Dir = new File(new File(startupDir, BIN),
+ WIN32I386);
+ File dot = new File(binWin386Dir, DOT_EXE);
+ if (dot.exists())
+ return dot.getAbsolutePath();
+ }
+ return DOT_FALLBACK;
+ }
+
+ /**
+ * Sets the applicationConfiguration.
+ *
+ * @param applicationConfiguration
+ * the new value of applicationConfiguration
+ */
+ public void setApplicationConfiguration(
+ ApplicationConfiguration applicationConfiguration) {
+ this.applicationConfiguration = applicationConfiguration;
+ defaultWorkbenchProperties = null;
+ }
+}