/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.core.component.model.api;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Map;
import org.apache.commons.logging.LogFactory;
import de.rcenvironment.core.communication.common.LogicalNodeId;
import de.rcenvironment.core.communication.common.NodeIdentifierUtils;
import de.rcenvironment.core.component.api.ComponentConstants;
import de.rcenvironment.core.component.api.ComponentUtils;
import de.rcenvironment.core.component.execution.api.Component;
import de.rcenvironment.core.component.model.configuration.api.ConfigurationDescription;
import de.rcenvironment.core.component.model.endpoint.api.EndpointDefinitionsProvider;
import de.rcenvironment.core.component.model.endpoint.api.EndpointDescriptionsManager;
import de.rcenvironment.core.datamodel.api.EndpointType;
/**
* Class holding information about an installed {@link Component}.
*
* @author Roland Gude
* @author Jens Ruehmkorf
* @author Doreen Seider
* @author Robert Mischke
* @author Christian Weiss
* @author Sascha Zur
* @author David Scholz
*/
public class ComponentDescription implements Serializable, Cloneable, Comparable<ComponentDescription> {
/**
* Prefix for {@link java.beans.PropertyChangeEvent}s concerning properties.
*/
public static final String PROPERTIES_PREFIX = "properties.";
/** Key of default configuration map. */
public static final String DEFAULT_CONFIG_ID = "de.rcenvironment.rce.component.configuration.default";
private static final long serialVersionUID = -7551319972711119245L;
private ComponentInstallation componentInstallation;
private ComponentRevision componentRevision;
private ComponentInterface componentInterface;
private final EndpointDescriptionsManager inputDescriptionsManager;
private final EndpointDescriptionsManager outputDescriptionsManager;
private ConfigurationDescription configurationDescription;
private boolean isNodeIdTransient = false;
public ComponentDescription(ComponentInstallation componentInstallation) {
this.componentInstallation = componentInstallation;
this.componentRevision = componentInstallation.getComponentRevision();
this.componentInterface = componentRevision.getComponentInterface();
inputDescriptionsManager = new EndpointDescriptionsManager(componentInterface.getInputDefinitionsProvider(),
EndpointType.INPUT);
outputDescriptionsManager = new EndpointDescriptionsManager(componentInterface.getOutputDefinitionsProvider(),
EndpointType.OUTPUT);
configurationDescription = new ConfigurationDescription(componentInterface.getConfigurationDefinition(),
componentInterface.getConfigurationExtensionDefinitions());
}
/**
* Initializes the component with default initial values such as endpoints.
* May only be called for newly created components.
*/
public void initializeWithDefaults() {
inputDescriptionsManager.addInitialDynamicEndpointDescriptions();
outputDescriptionsManager.addInitialDynamicEndpointDescriptions();
configurationDescription.setConfigurationValue(ComponentConstants.CONFIG_KEY_STORE_DATA_ITEM,
String.valueOf(true));
}
public String getIdentifier() {
return componentInterface.getIdentifier();
}
/**
* @return name of implementing class
*/
public String getClassName() {
return componentRevision.getClassName();
}
public String getName() {
return componentInterface.getDisplayName();
}
public String getGroup() {
return componentInterface.getGroupName();
}
public String getVersion() {
return componentInterface.getVersion();
}
public ComponentSize getSize() {
return componentInterface.getSize();
}
public boolean getIsNodeIdTransient() {
return isNodeIdTransient;
}
public void setIsNodeIdTransient(boolean isNodeTransient) {
this.isNodeIdTransient = isNodeTransient;
}
public EndpointDescriptionsManager getInputDescriptionsManager() {
return inputDescriptionsManager;
}
public EndpointDescriptionsManager getOutputDescriptionsManager() {
return outputDescriptionsManager;
}
public EndpointDefinitionsProvider getDeclarativeInputDescriptionsProvider() {
return componentInterface.getInputDefinitionsProvider();
}
public EndpointDefinitionsProvider getDeclarativeOutputDescriptionsProvider() {
return componentInterface.getOutputDefinitionsProvider();
}
public ConfigurationDescription getConfigurationDescription() {
return configurationDescription;
}
/**
* @return <code>true</code> if the component can technically only be
* executed locally, otherwise <code>false</code>
*/
public boolean canOnlyBeExecutedLocally() {
return componentInterface.getLocalExecutionOnly();
}
/**
* @return <code>true</code> if the component should be disposed workflow
* disposal, <code>false</code> if immediately when the component
* had finished (default behavior)
*/
public boolean performLazyDisposal() {
return componentInterface.getPerformLazyDisposal();
}
public byte[] getIcon16() {
return componentInterface.getIcon16();
}
public byte[] getIcon24() {
return componentInterface.getIcon24();
}
public byte[] getIcon32() {
return componentInterface.getIcon32();
}
/**
* @return node to run on
*/
public LogicalNodeId getNode() {
if (componentInstallation.getNodeId() != null) {
return NodeIdentifierUtils.parseArbitraryIdStringToLogicalNodeIdWithExceptionWrapping(componentInstallation.getNodeId());
}
return null;
}
/**
* @param installation
* new {@link ComponentInstallation} to set
*/
public void setComponentInstallationAndUpdateConfiguration(ComponentInstallation installation) {
setComponentInstallation(installation);
Map<String, String> config = configurationDescription.getConfiguration();
Map<String, String> placeholders = configurationDescription.getPlaceholders();
configurationDescription = new ConfigurationDescription(
installation.getComponentRevision().getComponentInterface().getConfigurationDefinition(),
installation.getComponentRevision().getComponentInterface().getConfigurationExtensionDefinitions());
configurationDescription.setConfiguration(config);
configurationDescription.setPlaceholders(placeholders);
}
public ComponentInstallation getComponentInstallation() {
return componentInstallation;
}
/**
* Copies the execution information of the given component description.
*
* @param installation
* component installation with execution information to copy
*/
public void setComponentInstallation(ComponentInstallation installation) {
String interfaceId = componentInterface.getIdentifier();
String newInterfaceId = installation.getComponentRevision().getComponentInterface().getIdentifier();
if (!newInterfaceId.equals(interfaceId) && !(newInterfaceId.startsWith(ComponentUtils.MISSING_COMPONENT_PREFIX))
&& newInterfaceId.endsWith(interfaceId)
&& !(interfaceId.startsWith(ComponentUtils.MISSING_COMPONENT_PREFIX))
&& interfaceId.endsWith(newInterfaceId)) {
throw new IllegalArgumentException(
"Component installation doesn't refer to the interface: " + componentInterface.getIdentifier());
}
this.componentInstallation = installation;
this.componentRevision = componentInstallation.getComponentRevision();
this.componentInterface = componentRevision.getComponentInterface();
}
@Override
public String toString() {
return getNode() + ":" + componentInterface.getIdentifier();
}
@Override
public ComponentDescription clone() {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
oos.flush();
ByteArrayInputStream bin = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bin);
ComponentDescription cd = (ComponentDescription) ois.readObject();
ois.close();
bin.close();
oos.close();
bos.close();
return cd;
} catch (IOException e) {
LogFactory.getLog(ComponentDescription.class).error("cloning component description failed", e);
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
LogFactory.getLog(ComponentDescription.class).error("cloning component description failed", e);
throw new RuntimeException(e);
}
}
@Override
public int compareTo(ComponentDescription o) {
return this.getName().compareTo(o.getName());
}
public ComponentInterface getComponentInterface() {
return componentInterface;
}
}