Skip to content

Commit

Permalink
Merge pull request #183 from genericworkflownodes/feature/VersionedDy…
Browse files Browse the repository at this point in the history
…namicNodes

[Feature] Versioned dynamic nodes
  • Loading branch information
jpfeuffer authored Nov 15, 2017
2 parents 667e0d0 + eac9895 commit 93b2e1f
Show file tree
Hide file tree
Showing 12 changed files with 500 additions and 57 deletions.
8 changes: 8 additions & 0 deletions com.genericworkflownodes.knime/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<extension-point id="com.genericworkflownodes.knime.mime.demangler.Demangler" name="Demangler" schema="schema/com.genericworkflownodes.knime.mime.demangler.Demangler.exsd"/>
<extension-point id="com.genericworkflownodes.knime.execution.CommandGenerator" name="CommandGenerator" schema="schema/com.genericworkflownodes.knime.execution.CommandGenerator.exsd"/>
<extension-point id="com.genericworkflownodes.knime.execution.Executor" name="Executor" schema="schema/com.genericworkflownodes.knime.execution.Executor.exsd"/>
<extension-point id="com.genericworkflownodes.knime.dynamic.VersionedNodeSetFactory" name="VersionedNodeSetFactory" schema="schema/com.genericworkflownodes.knime.dynamic.VersionedNodeSetFactory.exsd"/>

<extension point="org.knime.workbench.repository.categories">
<category description="/community/GenericKnimeNodes" icon="icons/category.png" level-id="GenericKnimeNodes" name="GenericKnimeNodes" path="/community"/>
Expand Down Expand Up @@ -142,4 +143,11 @@
</serializer>
</DataType>
</extension>
<extension
point="org.knime.workbench.repository.nodesets">
<nodeset
deprecated="false"
factory-class="com.genericworkflownodes.knime.dynamic.VersionedNodeSetFactoryManager">
</nodeset>
</extension>
</plugin>
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Schema file written by PDE -->
<schema targetNamespace="com.genericworkflownodes.knime" xmlns="http://www.w3.org/2001/XMLSchema">
<annotation>
<appinfo>
<meta.schema plugin="com.genericworkflownodes.knime" id="com.genericworkflownodes.knime.dynamic.VersionedNodeSetFactory" name="VersionedNodeSetFactory"/>
</appinfo>
<documentation>
[Enter description of this extension point.]
</documentation>
</annotation>

<element name="extension">
<annotation>
<appinfo>
<meta.element />
</appinfo>
</annotation>
<complexType>
<choice minOccurs="1" maxOccurs="unbounded">
<element ref="versionednodesetfactory"/>
</choice>
<attribute name="point" type="string" use="required">
<annotation>
<documentation>

</documentation>
</annotation>
</attribute>
<attribute name="id" type="string">
<annotation>
<documentation>

</documentation>
</annotation>
</attribute>
<attribute name="name" type="string">
<annotation>
<documentation>

</documentation>
<appinfo>
<meta.attribute translatable="true"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>

<element name="versionednodesetfactory">
<complexType>
<attribute name="class" type="string" use="required">
<annotation>
<documentation>

</documentation>
<appinfo>
<meta.attribute kind="java" basedOn=":com.genericworkflownodes.knime.dynamic.GenericNodeSetFactory"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>

<annotation>
<appinfo>
<meta.section type="since"/>
</appinfo>
<documentation>
[Enter the first release in which this extension point appears.]
</documentation>
</annotation>

<annotation>
<appinfo>
<meta.section type="examples"/>
</appinfo>
<documentation>
[Enter extension point usage example here.]
</documentation>
</annotation>

<annotation>
<appinfo>
<meta.section type="apiinfo"/>
</appinfo>
<documentation>
[Enter API information here.]
</documentation>
</annotation>

<annotation>
<appinfo>
<meta.section type="implementation"/>
</appinfo>
<documentation>
[Enter information about supplied implementation of this extension point.]
</documentation>
</annotation>


</schema>
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
Expand All @@ -47,7 +53,12 @@ public final class BinaryManager {
/**
* Path inside the bundle where the binaries should be located.
*/
private static final String BUNDLE_PATH = "payload";
private static final String BUNDLE_PATH = "payload";

/**
* Path inside the bundle where the descriptors should be located.
*/
private static final String DESCRIPTORS_PATH = BUNDLE_PATH + File.separator + "descriptors";

/**
* File that should be present to identify the correct path.
Expand Down Expand Up @@ -162,6 +173,16 @@ private File findShippedBinary(final String executableName) {
return null;
}
}

public File resolveToolDescriptorPath(final String relToolPath) {
Bundle bundle = FrameworkUtil.getBundle(classInBundle);
try {
return new File(FileLocator.toFileURL(bundle.getResource(DESCRIPTORS_PATH + File.separator + relToolPath)).getFile());
} catch (IOException e) {
// TODO Auto-generated catch block
return null;
}
}

/**
* Search the bundle for the given file name.
Expand All @@ -188,4 +209,31 @@ private File findFileInBundle(final String fileName) {
}
}
}

/**
* Search the bundle for CTDs and list them in a List of Files.
*
* @return List of CTD Files in the bundle
* @throws URISyntaxException
*/
public Iterable<String> listTools() {
Bundle bundle = FrameworkUtil.getBundle(classInBundle);
Enumeration<URL> e = bundle.findEntries(DESCRIPTORS_PATH, "*.ctd", true);
ArrayList<String> files = new ArrayList<>();
Path p;
try {
p = Paths.get(FileLocator.toFileURL(bundle.getResource(DESCRIPTORS_PATH)).toString());
} catch (Exception ex) {
return Collections.emptyList();
}
while (e.hasMoreElements()){
try {
Path el = Paths.get(FileLocator.toFileURL(e.nextElement()).toString());
files.add(p.relativize(el).toString());
} catch (IOException e1) {
e1.printStackTrace();
}
}
return files;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,11 @@ public interface IPluginConfiguration {
* @return
*/
String getDockerMachine();

/**
* The version of the plugin
*
* @return
*/
String getPluginVersion();
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
import java.util.Map;
import java.util.Properties;

import org.eclipse.osgi.service.resolver.BundleDescription;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;

import com.genericworkflownodes.knime.custom.config.BinaryManager;
import com.genericworkflownodes.knime.custom.config.IPluginConfiguration;

Expand Down Expand Up @@ -68,6 +72,11 @@ public class PluginConfiguration implements IPluginConfiguration {
*/
private final String m_dockerMachine;

/**
* The version
*/
private final String m_version;

/**
* C'tor for {@link PluginConfiguration}.
*
Expand All @@ -87,22 +96,24 @@ public PluginConfiguration(final String pluginId, final String pluginName,
m_pluginId = pluginId;
m_pluginName = pluginName;
m_props = props;
Bundle bundle = FrameworkUtil.getBundle(classFromPlugin);
m_version = bundle.getVersion().toString();
m_binaryManager = new BinaryManager(classFromPlugin);
Properties p = new Properties();
Map<String,Properties> toolMap = new Hashtable<String,Properties>();
for(String key: m_props.stringPropertyNames()){
if(key.startsWith("tool.")){
for (String key: m_props.stringPropertyNames()) {
if (key.startsWith("tool.")) {
String value = m_props.getProperty(key);
p.put(key, value);
String[] keyElements = key.split("\\.");
if(keyElements.length > 2){
if (keyElements.length > 2) {
String tool_key = "";
for(int i=2;i<keyElements.length;i++){
for (int i=2; i<keyElements.length; i++) {
tool_key+=keyElements[i];
}
if(toolMap.containsKey(keyElements[1])){
if (toolMap.containsKey(keyElements[1])) {
toolMap.get(keyElements[1]).put(tool_key, value);
}else{
} else {
Properties p_tool = new Properties();
p_tool.put(tool_key, value);
toolMap.put(keyElements[1], p_tool);
Expand All @@ -114,6 +125,15 @@ public PluginConfiguration(final String pluginId, final String pluginName,
m_specifcToolProps = toolMap;
m_dockerMachine = props.getProperty("dockerMachine","default");
}

/**
* {@inheritDoc}
*/
@Override
public final String getPluginVersion() {
return m_version;
}


/**
* {@inheritDoc}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,28 +41,26 @@
*
* @author Fillbrunn, Alexander
*/
public abstract class DynamicGenericNodeFactory
extends DynamicNodeFactory<DynamicGenericNodeModel> {
public abstract class DynamicGenericNodeFactory extends GenericNodeFactory {

/**
* The configuration key for the ctd file.
*/
public static final String CTD_FILE_CFG_KEY = "ctdFile";

public static final String ID_CFG_KEY = "id";

public static final String NSFID_CFG_KEY = "nsfid";

public static final String DEPRECATION_CFG_KEY = "deprecated";

private static final NodeLogger logger = NodeLogger.getLogger(DynamicGenericNodeFactory.class);

private String m_nsfid;
private String m_id;
private String m_ctdFile;
private INodeConfiguration m_config;

/**
* Implement this method and return the configuration of the plugin
* the nodes are hosted in.
* @return the plugin configuration.
*/
protected abstract IPluginConfiguration getPluginConfig();
private boolean m_deprecated;

protected String getIconPath() {
return "";
Expand Down Expand Up @@ -129,7 +127,6 @@ public NodeView<DynamicGenericNodeModel> createNodeView(final int viewIndex,
public boolean hasDialog() {
return true;
}

/**
* {@inheritDoc}
*/
Expand All @@ -148,13 +145,22 @@ public void loadAdditionalFactorySettings(ConfigRO config)
throws InvalidSettingsException {
m_ctdFile = config.getString(CTD_FILE_CFG_KEY);
m_id = config.getString(ID_CFG_KEY);
m_nsfid = config.getString(NSFID_CFG_KEY);
try {
m_deprecated = VersionedNodeSetFactoryManager.isFactoryDeprecated(m_nsfid);
} catch (InterruptedException e) {
// This means that loading the nodes was interrupted.
// We simply leave the node non-deprecated.
logger.error(e);
}
super.loadAdditionalFactorySettings(config);
}

@Override
public void saveAdditionalFactorySettings(ConfigWO config) {
config.addString(CTD_FILE_CFG_KEY, m_ctdFile);
config.addString(ID_CFG_KEY, m_id);
config.addString(NSFID_CFG_KEY, m_nsfid);
super.saveAdditionalFactorySettings(config);
}

Expand All @@ -167,7 +173,8 @@ protected NodeDescription createNodeDescription() {

// Node
KnimeNode node = doc.addNewKnimeNode();
node.setName(cfg.getExecutableName());
node.setDeprecated(m_deprecated);
node.setName(cfg.getName());
node.setIcon(getIconPath());
node.setType(KnimeNode.Type.MANIPULATOR);

Expand Down Expand Up @@ -224,7 +231,7 @@ private INodeConfiguration getNodeConfiguration()
}

private InputStream getConfigAsStream() throws FileNotFoundException {
return new FileInputStream(DynamicGenericNodeSetFactory.resolveSourceFile(getClass(), m_ctdFile));
return new FileInputStream(getPluginConfig().getBinaryManager().resolveToolDescriptorPath(m_ctdFile));
}

private String mimetypes2String(List<String> mt) {
Expand All @@ -238,5 +245,4 @@ private String mimetypes2String(List<String> mt) {
mimetypes.append("]");
return mimetypes.toString();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ protected PortObjectSpec[] configure(PortObjectSpec[] inSpecs)
URIPortObjectSpec spec = (URIPortObjectSpec) inSpecs[i];

// get MIMEType from incoming port
// TODO: we should check all file extensions, if its more then one
// TODO: we should check all file extensions, if its more than one
String mt = MIMEMap.getMIMEType(spec.getFileExtensions().get(0));

// check whether input MIMEType is in list of allowed MIMETypes
Expand Down
Loading

0 comments on commit 93b2e1f

Please sign in to comment.