Java tutorial
/* * Copyright (c) 2011-2012, Marc Rttig. * Copyright (c) 2012, Bjrn Kahlert. * Copyright (c) 2012, Stephan Aiche. * * This file is part of GenericKnimeNodes. * * GenericKnimeNodes 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 3 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, see <http://www.gnu.org/licenses/>. */ package org.ballproject.knime.nodegeneration; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.logging.Logger; import org.apache.commons.io.FileUtils; import org.ballproject.knime.base.config.INodeConfiguration; import org.ballproject.knime.base.util.Helper; import org.ballproject.knime.nodegeneration.exceptions.DuplicateNodeNameException; import org.ballproject.knime.nodegeneration.exceptions.InvalidNodeNameException; import org.ballproject.knime.nodegeneration.exceptions.UnknownMimeTypeException; import org.ballproject.knime.nodegeneration.model.KNIMEPluginMeta; import org.ballproject.knime.nodegeneration.model.directories.NodesBuildDirectory; import org.ballproject.knime.nodegeneration.model.directories.NodesSourceDirectory; import org.ballproject.knime.nodegeneration.model.directories.build.NodesBuildIconsDirectory; import org.ballproject.knime.nodegeneration.model.directories.build.NodesBuildKnimeNodesDirectory; import org.ballproject.knime.nodegeneration.model.directories.source.DescriptorsDirectory; import org.ballproject.knime.nodegeneration.model.directories.source.IconsDirectory; import org.ballproject.knime.nodegeneration.model.files.CTDFile; import org.ballproject.knime.nodegeneration.templates.BinaryResourcesTemplate; import org.ballproject.knime.nodegeneration.templates.BuildPropertiesTemplate; import org.ballproject.knime.nodegeneration.templates.ManifestMFTemplate; import org.ballproject.knime.nodegeneration.templates.MimeFileCellFactoryTemplate; import org.ballproject.knime.nodegeneration.templates.NodeDialogTemplate; import org.ballproject.knime.nodegeneration.templates.NodeFactoryTemplate; import org.ballproject.knime.nodegeneration.templates.NodeFactoryXMLTemplate; import org.ballproject.knime.nodegeneration.templates.NodeModelTemplate; import org.ballproject.knime.nodegeneration.templates.NodeViewTemplate; import org.ballproject.knime.nodegeneration.templates.PluginActivatorTemplate; import org.ballproject.knime.nodegeneration.templates.PluginXMLTemplate; import org.ballproject.knime.nodegeneration.util.NodeDescriptionUtils; import org.ballproject.knime.nodegeneration.util.Utils; import org.ballproject.knime.nodegeneration.writer.DatWriter; import org.ballproject.knime.nodegeneration.writer.PropertiesWriter; import org.dom4j.DocumentException; import org.eclipse.core.commands.ExecutionException; import org.knime.core.node.NodeFactory; public class NodeGenerator { private static final Logger LOGGER = Logger.getLogger(NodeGenerator.class.getCanonicalName()); private NodesSourceDirectory srcDir; private KNIMEPluginMeta meta; private NodesBuildDirectory buildDir; @SuppressWarnings("serial") public NodeGenerator(File pluginDir, File buildDir2) throws IOException, DocumentException, InvalidNodeNameException, DuplicateNodeNameException, ExecutionException, UnknownMimeTypeException { this.srcDir = new NodesSourceDirectory(pluginDir); this.meta = new KNIMEPluginMeta(srcDir.getProperties()); if (buildDir2 != null) { this.buildDir = new NodesBuildDirectory(buildDir2, meta.getPackageRoot()); } else { this.buildDir = new NodesBuildDirectory(meta.getPackageRoot()); } LOGGER.info("Creating KNIME plugin sources\n\tFrom: " + this.srcDir + "\n\tTo: " + this.buildDir); boolean dynamicCTDs = NodeDescriptionUtils.createCTDsIfNecessary(srcDir); DescriptorsDirectory descriptorsDirectory = (dynamicCTDs) ? new DescriptorsDirectory(srcDir.getExecutablesDirectory()) : srcDir.getDescriptorsDirectory(); if (dynamicCTDs) LOGGER.info("Using dynamically created ctd files"); else LOGGER.info("Using static ctd files"); // build.properties - only useful if you re-import the generated node in // Eclipse new BuildPropertiesTemplate().write(buildDir.getBuildProperties()); // META-INF/MANIFEST.MF new ManifestMFTemplate(meta).write(buildDir.getManifestMf()); // src/[PACKAGE]/knime/PluginActivator.java new PluginActivatorTemplate(meta.getPackageRoot()) .write(new File(this.buildDir.getKnimeDirectory(), "PluginActivator.java")); // src/[PACKAGE]/knime/plugin.properties new PropertiesWriter(new File(this.buildDir.getKnimeDirectory(), "plugin.properties")) .write(new HashMap<String, String>() { { put("use_ini", srcDir.getProperty("use_ini", "true")); put("ini_switch", srcDir.getProperty("ini_switch", "-ini")); } }); // src/[PACKAGE]/knime/InternalTools.dat new DatWriter(new File(this.buildDir.getKnimeDirectory(), "InternalTools.dat")) .write(descriptorsDirectory.getInternalCtdFiles()); // src/[PACKAGE]/knime/ExternalTools.dat new DatWriter(new File(this.buildDir.getKnimeDirectory(), "ExternalTools.dat")) .write(descriptorsDirectory.getExternalCtdFiles()); // src/[PACKAGE]/knime/nodes/mimetypes/MimeFileCellFactory.java new MimeFileCellFactoryTemplate(meta.getPackageRoot(), srcDir.getMimeTypes()).write(new File( buildDir.getKnimeNodesDirectory(), "mimetypes" + File.separator + "MimeFileCellFactory.java")); PluginXMLTemplate pluginXML = new PluginXMLTemplate(); // src/[PACKAGE]/knime/nodes/*/* for (CTDFile ctdFile : descriptorsDirectory.getCTDFiles()) { LOGGER.info("Start processing ctd file: " + ctdFile.getName()); String factoryClass = copyNodeSources(ctdFile, srcDir.getIconsDirectory(), buildDir.getKnimeNodesDirectory(), meta); String absoluteCategory = "/" + meta.getNodeRepositoryRoot() + "/" + meta.getName() + "/" + ctdFile.getNodeConfiguration().getCategory(); pluginXML.registerNode(factoryClass, absoluteCategory); } // icons/* copyFolderIcon(srcDir.getIconsDirectory(), buildDir.getIconsDirectory()); registerSplashIcon(meta, pluginXML, srcDir.getIconsDirectory(), buildDir.getIconsDirectory()); // plugin.xml pluginXML.saveTo(buildDir.getPluginXml()); // src/[PACKAGE]/knime/nodes/binres/BinaryResources.java new BinaryResourcesTemplate(meta.getPackageRoot()) .write(new File(this.buildDir.getBinaryResourcesDirectory(), "BinaryResources.java")); // src/[PACKAGE]/knime/nodes/binres/*.ini *.zip if (srcDir.getPayloadDirectory() != null) srcDir.getPayloadDirectory().copyPayloadTo(buildDir.getBinaryResourcesDirectory()); LOGGER.info("KNIME plugin sources successfully created in:\n\t" + this.buildDir); } public File getSourceDirectory() { return this.srcDir; } public File getBuildDirectory() { return this.buildDir; } public String getPluginName() { return meta.getName(); } public String getPluginVersion() { return meta.getVersion(); } public static void copyFolderIcon(IconsDirectory iconsSrc, NodesBuildIconsDirectory iconsDest) throws IOException { File categoryIcon = iconsSrc.getCategoryIcon(); if (categoryIcon != null && categoryIcon.canRead()) { // TODO: only set icon file in plugin.xml for categories if this // method was called Helper.copyFile(categoryIcon, new File(iconsDest, "category.png")); } } public static void registerSplashIcon(KNIMEPluginMeta meta, PluginXMLTemplate pluginXML, IconsDirectory iconsSrc, NodesBuildIconsDirectory iconsDest) throws IOException { File splashIcon = iconsSrc.getSplashIcon(); if (splashIcon != null && splashIcon.canRead()) { Helper.copyFile(splashIcon, new File(iconsDest, "splash.png")); pluginXML.registerSplashIcon(meta, new File("icons/splash.png")); } } /** * Copies the java sources needed to invoke a tool (described by a * {@link CTDFile}) to the specified {@link NodesBuildKnimeNodesDirectory}. * * @param ctdFile * which described the wrapped tool * @param iconsDir * location where node icons reside * @param nodesDir * location where to create a sub directory containing the * generated sources * @param pluginMeta * meta information used to adapt the java files * @return the fully qualified name of the {@link NodeFactory} class able to * build instances of the node. * @throws IOException * @throws UnknownMimeTypeException */ public static String copyNodeSources(CTDFile ctdFile, IconsDirectory iconsDir, NodesBuildKnimeNodesDirectory nodesDir, KNIMEPluginMeta pluginMeta) throws IOException, UnknownMimeTypeException { INodeConfiguration nodeConfiguration = ctdFile.getNodeConfiguration(); String nodeName = Utils.fixKNIMENodeName(nodeConfiguration.getName()); File nodeSourceDir = new File(nodesDir, nodeName); nodeSourceDir.mkdirs(); File nodeIcon = iconsDir.getNodeIcon(nodeConfiguration); if (nodeIcon != null) FileUtils.copyFileToDirectory(nodeIcon, nodeSourceDir); /* * all files placed into src/[PACKAGE]/knime/nodes/[NODE_NAME] */ new NodeDialogTemplate(pluginMeta.getPackageRoot(), nodeName) .write(new File(nodeSourceDir, nodeName + "NodeDialog.java")); new NodeViewTemplate(pluginMeta.getPackageRoot(), nodeName) .write(new File(nodeSourceDir, nodeName + "NodeView.java")); new NodeModelTemplate(pluginMeta.getPackageRoot(), nodeName, nodeConfiguration) .write(new File(nodeSourceDir, nodeName + "NodeModel.java")); new NodeFactoryXMLTemplate(nodeName, nodeConfiguration, (nodeIcon != null) ? nodeIcon.getName() : "./default.png") .write(new File(nodeSourceDir, nodeName + "NodeFactory.xml")); new NodeFactoryTemplate(pluginMeta.getPackageRoot(), nodeName) .write(new File(nodeSourceDir, nodeName + "NodeFactory.java")); File nodeConfigDir = new File(nodeSourceDir, "config"); nodeConfigDir.mkdirs(); /* * all files placed into src/[PACKAGE]/knime/nodes/[NODE_NAME]/config */ Helper.copyFile(ctdFile, new File(nodeConfigDir, "config.xml")); return pluginMeta.getPackageRoot() + ".knime.nodes." + nodeName + "." + nodeName + "NodeFactory"; } }