Commit 147092ef authored by Philipp Spohr's avatar Philipp Spohr
Browse files

-Hotfix: Prevented using forbidden and permanent for the same edge

-Work on CyRest support
parent 80a9cd87
......@@ -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>
......
......@@ -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();
......
......@@ -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
......
/*******************************************************************************
* 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;
......
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;
}
}
......@@ -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";
}
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)
);
}
}
......@@ -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");
}
}
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);
}
}
......@@ -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
......
......@@ -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;
}
});
......
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment