blob: 0a40bdae744900dff20161024c4a59ef28202e7b [file] [log] [blame]
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);
}
}
}