diff --git a/pom.xml b/pom.xml index 453fd7a724a91c0e6a807bbfbd95118fbbc97931..83bdc3b4c9543c13697600729fa49a4101f065c9 100644 --- a/pom.xml +++ b/pom.xml @@ -162,6 +162,11 @@ <artifactId>group-api</artifactId> <version>${cytoscape.api.version}</version> </dependency> + <dependency> + <groupId>org.cytoscape</groupId> + <artifactId>command-executor-api</artifactId> + <version>${cytoscape.api.version}</version> + </dependency> </dependencies> <description>A Cytoscape plugin for graph-based clustering that wraps the yoshiko algorithm.</description> diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/CyActivator.java b/src/main/java/de/hhu/ba/yoshikoWrapper/CyActivator.java index 1652fedf579aeec507609e441553917764bda682..a228110a520fbf15eda4e4da8bb87852b7b943a4 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/CyActivator.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/CyActivator.java @@ -26,6 +26,7 @@ import java.util.Properties; import org.cytoscape.application.CyApplicationManager; import org.cytoscape.application.swing.CySwingApplication; import org.cytoscape.application.swing.CytoPanelComponent; +import org.cytoscape.command.CommandExecutorTaskFactory; import org.cytoscape.model.CyNetworkFactory; import org.cytoscape.model.CyNetworkManager; import org.cytoscape.model.subnetwork.CyRootNetworkManager; @@ -94,6 +95,7 @@ public class CyActivator extends AbstractCyActivator { //TODO: Not sure how to correctly infer arguments here CyCore.renderingEngineFactory = getService(context,RenderingEngineFactory.class); CyCore.cloneNetworkTaskFactory = getService(context,CloneNetworkTaskFactory.class); + CyCore.commandExecutorTaskFactory = getService(context,CommandExecutorTaskFactory.class); //Store a reference to the Version for easier access YoshUtil.version = context.getBundle().getVersion(); diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/core/CyCore.java b/src/main/java/de/hhu/ba/yoshikoWrapper/core/CyCore.java index e51449e2435f1bf8899a0b74e4b9bb89c888203d..0707782327a120d99aae7875d0a09ae0ea03c4e8 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/CyCore.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/CyCore.java @@ -25,6 +25,7 @@ import java.util.concurrent.CountDownLatch; import org.cytoscape.application.CyApplicationManager; import org.cytoscape.application.swing.CySwingApplication; +import org.cytoscape.command.CommandExecutorTaskFactory; import org.cytoscape.model.CyNetwork; import org.cytoscape.model.CyNetworkFactory; import org.cytoscape.model.CyNetworkManager; @@ -68,6 +69,7 @@ public class CyCore { public static CyRootNetworkManager rootNetworkManager; public static RenderingEngineFactory<CyNetwork> renderingEngineFactory; public static CloneNetworkTaskFactory cloneNetworkTaskFactory; + public static CommandExecutorTaskFactory commandExecutorTaskFactory; // //Convenience diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/core/NetworkParser.java b/src/main/java/de/hhu/ba/yoshikoWrapper/core/NetworkParser.java index eed69b62659ecd024ea1dc4bb32de447650fb4ec..64d16b7924508984994bac10bcbe746078cb8839 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/NetworkParser.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/NetworkParser.java @@ -1,16 +1,16 @@ /******************************************************************************* * Copyright (C) 2017 Philipp Spohr - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -34,18 +34,18 @@ import de.hhu.ba.yoshikoWrapper.logging.YoshikoLogger; import de.hhu.ba.yoshikoWrapper.swig.LibraryInput; public class NetworkParser { - + //Symbolic Links private static Logger logger = YoshikoLogger.getInstance().getLogger(); - public static LibraryInput parseNetwork( + public static LibraryInput parseNetwork ( CyNetwork net, NodeMap nodeMap, CyColumn weightColumn, CyColumn permanentColumn, CyColumn forbiddenColumn, double deletionCostDefault - ) + ) throws NetworkParsingException { //Create an empty instance / fetch C++ object pointer LibraryInput generatedInput = new LibraryInput(); @@ -54,18 +54,16 @@ public class NetworkParser { generatedInput.setSize(net.getNodeCount()); //Fetch edges List<CyEdge> edges = net.getEdgeList(); - - //Loop over edges for (CyEdge e : edges) { - + //Parse editing costs double weight = deletionCostDefault; - + //Fetch entry and check if it exists CyRow edgeEntry = net.getRow(e); - + //Check if there is a weight column defined, else skip if (weightColumn != null){ //Check if the column contains an entry for the respective edge @@ -83,7 +81,7 @@ public class NetworkParser { //Parse Forbidden/Permanent markers boolean forbidden = false; boolean permanent = false; - + if (permanentColumn != null) { //Additional check as it is not required to have a value in every row if (edgeEntry.get(permanentColumn.getName(), Boolean.class) != null) { @@ -97,8 +95,13 @@ public class NetworkParser { } } + //Check for edges that are forbidden AND permanent -> Throw exception + if (forbidden && permanent) { + throw new NetworkParsingException(LocalizationManager.get("dualInfinityError")); + } + logger.debug("Found Edge: "+edgeEntry.get("name", String.class)+ " with weight:"+weight); - + generatedInput.addEdge( nodeMap.get(e.getSource()), nodeMap.get(e.getTarget()), @@ -106,7 +109,7 @@ public class NetworkParser { permanent, forbidden ); - + } } return generatedInput; diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/core/NetworkParsingException.java b/src/main/java/de/hhu/ba/yoshikoWrapper/core/NetworkParsingException.java new file mode 100644 index 0000000000000000000000000000000000000000..65b9c43f636b55db41004897497493859df510aa --- /dev/null +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/NetworkParsingException.java @@ -0,0 +1,17 @@ +package de.hhu.ba.yoshikoWrapper.core; + +@SuppressWarnings("serial") +public class NetworkParsingException extends Exception { + + private String msg; + + public NetworkParsingException(String msg) { + this.msg = msg; + } + + @Override + public String getMessage() { + return LocalizationManager.get("networkParsingException")+" "+msg; + } + +} diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/core/YoshUtil.java b/src/main/java/de/hhu/ba/yoshikoWrapper/core/YoshUtil.java index b85271e2678b27b813e1517ad1980646d9635149..9580bd570bd9236e71f08aced0b19b57cc941141 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/YoshUtil.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/YoshUtil.java @@ -5,4 +5,6 @@ import org.osgi.framework.Version; public class YoshUtil { public static Version version; + + public static final String ABOUT_LINK = "https://spqrph.github.io/cytoscape-tutorials/presentations/yoshiko/yoshiko.html#/title"; } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/cytoUtil/CommandExecutor.java b/src/main/java/de/hhu/ba/yoshikoWrapper/cytoUtil/CommandExecutor.java new file mode 100644 index 0000000000000000000000000000000000000000..382678f48f22b7c532b6946286679ea8b435c799 --- /dev/null +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/cytoUtil/CommandExecutor.java @@ -0,0 +1,20 @@ +package de.hhu.ba.yoshikoWrapper.cytoUtil; + +import java.util.Map; + +import org.cytoscape.work.TaskObserver; + +import de.hhu.ba.yoshikoWrapper.core.CyCore; + +public class CommandExecutor{ + + public static void executeCommand(String namespace, String command, + Map<String, Object> args, TaskObserver observer) { + ; + CyCore.dialogTaskManager.execute( + CyCore.commandExecutorTaskFactory.createTaskIterator(namespace, command, args, observer) + ); + + } + +} diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/help/HelpLinks.java b/src/main/java/de/hhu/ba/yoshikoWrapper/help/HelpLinks.java index 3c77e1c6ed3b106244588407cd430f9bdcaede43..597eca449ea4b4e2d14892793aaa8c7025e4521c 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/help/HelpLinks.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/help/HelpLinks.java @@ -21,75 +21,13 @@ ******************************************************************************/ package de.hhu.ba.yoshikoWrapper.help; -import java.awt.Container; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.WeakHashMap; +import java.util.HashMap; -import org.slf4j.Logger; - -import de.hhu.ba.yoshikoWrapper.logging.YoshikoLogger; -import de.hhu.ba.yoshikoWrapper.swing.components.EditCostPanel; - -/** - * Helper class that provides URIs to access the Bachelor Thesis paper sections that can be used as a manual - * - */ public final class HelpLinks { - //SYMBOLIC LINKS - - /** - * Convenience function for better code readability - */ - private static final Logger logger = YoshikoLogger.getInstance().getLogger(); - - // - - /** - * The base location of the bachelor thesis paper - */ - //TODO: Add final location when published - private static final String docLocation = "https://gitlab.cs.uni-duesseldorf.de/spohr/YoshikoWrapper/tree/master"; - - /** - * A HashMap linking Classes to a link, pointing to a specific subsection of the BachelorThesis paper that is relevant for understanding the Class - */ - private static final WeakHashMap <Class<? extends Container>,URI> helpLinks; - - /** - * Initialization for the HashMap - */ + public static final HashMap<String,Object> mainInfo = new HashMap<String,Object>(); static { - helpLinks = new WeakHashMap<Class<? extends Container>,URI>(); - try { - helpLinks.put(EditCostPanel.class, (buildURI("subsubsection.2.2.1"))); - } catch (URISyntaxException e) { - logger.error("Error initializing URI for help file:\n"+e.getMessage()); - } - } - - - /** - * Returns the URI that leads to the relevant help section for the class provided - * @param c The Container class for which the help link should be fetched - * @return The help link as URI - */ - public static URI getHelpLink(Class<? extends Container> c) { - if (helpLinks.containsKey(c)) { - return helpLinks.get(c); - } - return null; - } - - /** - * Internal helper function that builds a valid URI from the base address and the fragment denoting the relevant section - * @param fragment The fragment naming the nameddest in the pdf file - * @return The compound URI made from base address and fragment - * @throws URISyntaxException If invalid -> Should never be called during runtime in a stable version - */ - private static URI buildURI(String fragment) throws URISyntaxException { - return new URI(null,docLocation,"nameddest="+fragment); + mainInfo.put("url", "https://spqrph.github.io/cytoscape-tutorials/presentations/yoshiko/yoshiko.html#/title"); } } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/AboutDialogFactory.java b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/AboutDialogFactory.java deleted file mode 100644 index 915093c4f50779a988c24cf7c5060e97cec784af..0000000000000000000000000000000000000000 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/AboutDialogFactory.java +++ /dev/null @@ -1,57 +0,0 @@ -package de.hhu.ba.yoshikoWrapper.swing; - -import javax.swing.GroupLayout; -import javax.swing.GroupLayout.Alignment; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; - -import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; -import de.hhu.ba.yoshikoWrapper.core.YoshUtil; -import de.hhu.ba.yoshikoWrapper.swing.components.YoshikoHeader; - -/**Factory for a simple About-Dialog that provides some basic info about the software - * - */ -public class AboutDialogFactory{ - - private static JPanel getDialogPanel() { - - JPanel ret = new JPanel(); - - final YoshikoHeader header; - final JLabel version; - final JLabel text; - - header = new YoshikoHeader(); - version = new JLabel(LocalizationManager.get("wrapperVersion")+": "+YoshUtil.version); - text = new JLabel(LocalizationManager.get("about")); - - SwingUtil.addAll(ret, header,version,text); - - GroupLayout layout = new GroupLayout(ret); - layout.setAutoCreateGaps(true); - layout.setHorizontalGroup(layout.createParallelGroup(Alignment.CENTER) - .addComponent(header) - .addComponent(version) - .addComponent(text) - ); - layout.setVerticalGroup(layout.createSequentialGroup() - .addComponent(header) - .addComponent(version) - .addComponent(text) - ); - - ret.setLayout(layout); - - return ret; - } - - public static void showDialog() { - JOptionPane.showMessageDialog( - null, - getDialogPanel(), - LocalizationManager.get("aboutTitle"), - JOptionPane.PLAIN_MESSAGE); - } -} diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/HelpButton.java b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/HelpButton.java index f4bdbc1e279534261b418b8352705f3d61b88eb1..bb7a004b480438f9f90e1bc0884b469d0ec2e844 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/HelpButton.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/HelpButton.java @@ -6,13 +6,17 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.io.IOException; import java.net.URI; +import java.util.HashMap; import javax.swing.BorderFactory; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JOptionPane; +import org.cytoscape.command.CommandExecutorTaskFactory; + import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; +import de.hhu.ba.yoshikoWrapper.cytoUtil.CommandExecutor; import de.hhu.ba.yoshikoWrapper.help.HelpLinks; import de.hhu.ba.yoshikoWrapper.swing.GraphicsLoader; @@ -28,31 +32,33 @@ public class HelpButton extends JButton{ * The default icon for the help button that should be shown if the button is not highlighted */ private static final ImageIcon defaultIcon = GraphicsLoader.getInfoIcon(SIZE); + /** - * The icon tor the help button that should be shown if the button is highlighted + * The icon for the help button that should be shown if the button is highlighted */ private static final ImageIcon hlIcon = GraphicsLoader.getInfoIconHL(SIZE); + + public HelpButton() { + super(defaultIcon); + + //Design/Style setToolTipText(LocalizationManager.get("tooltip_helpButton")); setBorder(BorderFactory.createEmptyBorder()); + + //Add main functionality addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - URI uri = HelpLinks.getHelpLink(getParent().getClass()); - if (uri != null) { - try { - java.awt.Desktop.getDesktop().browse(uri); - } catch (IOException ex) { - JOptionPane.showMessageDialog(null, "DEBUG: Thesis is currently not online! Works only on my pc!"); - ex.printStackTrace(); - } - } + + CommandExecutor.executeCommand("cybrowser", "show",HelpLinks.mainInfo , null); } } ); + //Add mouse listener (cosmetic only) addMouseListener(new MouseListener() { @Override diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/MainPanel.java b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/MainPanel.java index 0b60b3c9ad36fa03a442b9c2ea5cd1a5d60020c8..5c521c5319b22c3e908887d83e34784ede30649f 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/MainPanel.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/MainPanel.java @@ -59,7 +59,6 @@ import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; import de.hhu.ba.yoshikoWrapper.core.ParameterSet; import de.hhu.ba.yoshikoWrapper.core.YoshikoLoader; import de.hhu.ba.yoshikoWrapper.cytoUtil.GraphAnalyzer; -import de.hhu.ba.yoshikoWrapper.swing.AboutDialogFactory; import de.hhu.ba.yoshikoWrapper.swing.GraphicsLoader; import de.hhu.ba.yoshikoWrapper.swing.LibraryPanelFactory; import de.hhu.ba.yoshikoWrapper.swing.SwingUtil; @@ -118,7 +117,7 @@ public class MainPanel extends JPanel implements CytoPanelComponent { @Override public void actionPerformed(ActionEvent e) { - AboutDialogFactory.showDialog(); + //CommandExecutorTaskFactory fac; } }); diff --git a/src/main/resources/YoshikoStrings.properties b/src/main/resources/YoshikoStrings.properties index 085bc84fa8523db2b86a9d2d671d6cb8563005cf..69c2d91bf4b04128faea4709f51fafbe40b7c513 100644 --- a/src/main/resources/YoshikoStrings.properties +++ b/src/main/resources/YoshikoStrings.properties @@ -34,12 +34,15 @@ cost = Editing Cost: createMetaGraph = Create Meta-Graph createClusterView = Create Cluster Views currentGap = [ILP] Current Instance Gap + defaultDeletion = Default deletion cost: defaultInsertion = Default insertion cost: deleteSolution = Do you really want to delete this solution? directedGraphWarning = This algorithm works on undirected graphs. Directed edges are \n treated as undirected edges. disableMultiThreading = Disable Multithreading discardSolution = Discard +dualInfinityError = An edge was marked as forbidden and permanent. + editingCostPanel = Editing Costs exportSelectedClusters = Export selected clusters firstStart = Thanks for using the Yoshiko Clustering Tool!\nIt appears, that this is your first time using this tool.\nIf you want an in-depth explanation of the algorithm please refer to: [INSERT COOL LINK HERE] @@ -57,11 +60,14 @@ metaGraph = Meta Graph metaGraph_edges = Fetching edges and calculating edge strengths multFactor = Multiplicative Factor for SNR: multiGraphWarning = This graph is a multigraph. This algorithms behavior on multigraphs is not yet researched. + +networkParsingException: An error occured while parsing the network: noFeasible = No feasible solution found! noLibMessage = There is no Yoshiko Library currently loaded! You might have to specify its location. noLibTitle = Library not loaded! noMappingHint = You haven't mapped the cost value to a column in your edge table.\nYoshiko runs significantly faster and generates better solutions if you map values. nodes = Nodes + optionpane_title = Yoshiko Info noClustersSelected = You have not selected any clusters notOptimal = Optimality not guaranteed