diff --git a/.travis.yml b/.travis.yml index 6716365c..16f3581b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,11 @@ language: java install: true jdk: oraclejdk8 +cache: + directories: + - $HOME/.m2 + - $HOME/.gradle + env: matrix: - TERM=dumb diff --git a/LICENSE.txt b/LICENSE.txt index 18915849..ae63204b 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: diff --git a/VWorkflows-Core/gradle.properties b/VWorkflows-Core/gradle.properties index ea7ad798..67c5c240 100644 --- a/VWorkflows-Core/gradle.properties +++ b/VWorkflows-Core/gradle.properties @@ -1 +1 @@ -publishJars = true +publishJars=true diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ClickEvent.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ClickEvent.java index 624f7324..fbab8570 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ClickEvent.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ClickEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -41,7 +41,6 @@ import javafx.event.EventType; /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ public class ClickEvent extends Event { @@ -80,6 +79,5 @@ public Object getEvent() { return event; } - } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/CompatibilityResult.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/CompatibilityResult.java index c6a30bca..ebaa25c4 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/CompatibilityResult.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/CompatibilityResult.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -35,10 +35,13 @@ /** * This interface describes whether two connectors are compatible for a connection. + * * @author Michael Hoffer <info@michaelhoffer.de> */ public interface CompatibilityResult { boolean isCompatible(); + String getMessage(); + String getStatus(); } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Connection.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Connection.java index b5cfe177..b2cd1ed2 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Connection.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Connection.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -35,27 +35,33 @@ /** * This interface defines a connection between two connectors. + * * @author Michael Hoffer <info@michaelhoffer.de> */ -public interface Connection extends Model{ -// public String getSenderId(); -// public void setSenderId(String id); -// public String getReceiverId(); -// public void setReceiverId(String id); - public void setSender(Connector s); - public void setReceiver(Connector r); - public Connector getReceiver(); - public Connector getSender(); - - public String getId(); - public void setId(String id); - - public String getType(); - - public Connections getConnections(); +public interface Connection extends Model { + // String getSenderId(); + // void setSenderId(String id); + // String getReceiverId(); + // void setReceiverId(String id); + void setSender(Connector s); + + void setReceiver(Connector r); + + Connector getReceiver(); + + Connector getSender(); + + String getId(); + + void setId(String id); + + String getType(); + + Connections getConnections(); @Override - public void setVisualizationRequest(VisualizationRequest vReq); + void setVisualizationRequest(VisualizationRequest vReq); + @Override - public VisualizationRequest getVisualizationRequest(); + VisualizationRequest getVisualizationRequest(); } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectionEvent.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectionEvent.java index f1b64de4..8b54282b 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectionEvent.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectionEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -43,6 +43,7 @@ /** * This class defines a connection event. A connection event is fired when a * connection is made between two connectors. + * * @author Michael Hoffer <info@michaelhoffer.de> */ public class ConnectionEvent extends Event { @@ -76,7 +77,6 @@ public Connector getReceiverConnector() { } /** - * * @return the connection */ public Connection getConnection() { diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectionResult.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectionResult.java index ed2354db..590cfd40 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectionResult.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectionResult.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -35,20 +35,23 @@ /** * This interface defines the result of an attempt to connect two {@code Connector}s + * * @author Michael Hoffer <info@michaelhoffer.de> */ public interface ConnectionResult { /** * Get the connection object for the connection being attempted + * * @return the connection */ Connection getConnection(); - -// List getPath(); + + // List getPath(); /** - * Get the status of the connection. + * Get the status of the connection. + * * @return the status of the connection */ CompatibilityResult getStatus(); diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Connections.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Connections.java index 1076d254..81211682 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Connections.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Connections.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -49,63 +49,67 @@ public interface Connections extends Model { * * @param c the connection to add */ - public void add(Connection c); + void add(Connection c); /** * Adds the connection defined by the specified connectors. * * @param s sender connector * @param r receiver connector + * * @return connection that has been added */ - public Connection add(Connector s, Connector r); + Connection add(Connector s, Connector r); /** * Adds the connection defined by the specified connectors. * - * @param id the id of the connection that shall be added - * @param s the sender connector - * @param r the receiver connector + * @param id the id of the connection that shall be added + * @param s the sender connector + * @param r the receiver connector * @param vReq the visualization request of the connection + * * @return connection that has been added */ - public Connection add(String id, Connector s, Connector r, VisualizationRequest vReq); + Connection add(String id, Connector s, Connector r, VisualizationRequest vReq); /** * Removes the specified connection from this collection * * @param c connection to remove */ - public void remove(Connection c); + void remove(Connection c); /** * Returns the specified connection. * * @param id id of the connection to be returned - * @param s sender connector - * @param r receiver connector + * @param s sender connector + * @param r receiver connector + * * @return the requested connection or null if no such * connection exists */ - public Connection get(String id, Connector s, Connector r); + Connection get(String id, Connector s, Connector r); /** * Returns all connections betwenn the specified connectors. * * @param s sender connector * @param r receiver connector + * * @return all connections betwenn the specified connectors */ - public Collection getAll(Connector s, Connector r); + Collection getAll(Connector s, Connector r); /** * Removes the specified connection from this collection. * * @param id connection id - * @param s sender connector - * @param r receiver connector + * @param s sender connector + * @param r receiver connector */ - public void remove(String id, Connector s, Connector r); + void remove(String id, Connector s, Connector r); /** * Removes all connections between the specified connectors from this @@ -114,72 +118,63 @@ public interface Connections extends Model { * @param s sender connector * @param r receiver connector */ - public void removeAll(Connector s, Connector r); - - /** - * Defines the connection implementation class that shall be used. - * - * @param cls connection implementation class - */ - public void setConnectionClass(Class cls); - - /** - * Returns the connection implementation class. - * - * @return the connection implementation class - */ - public Class getConnectionClass(); + void removeAll(Connector s, Connector r); /** * Returns the connections defined by this collection. * * @return the connections defined by this collection */ - public ObservableList getConnections(); + ObservableList getConnections(); /** * Returns all connections that are connected to the specified connector. * * @param c connector + * * @return all connections that are connected to the specified connector */ - public Collection getAllWith(Connector c); + Collection getAllWith(Connector c); /** * Returns all connections that are connected to the specified node. * * @param n node + * * @return all connections that are connected to the specified node */ - public Collection getAllWithNode(VNode n); + Collection getAllWithNode(VNode n); /** * Determines whether the specified input connector is connected. * * @param id connector id + * * @return true if the specified input connector is connected; * false otherwise */ - public boolean isInputConnected(Connector id); + boolean isInputConnected(Connector id); /** * Determines whether the specified output connector is connected. * * @param id connector id + * * @return true if the specified output connector is connected; * false otherwise */ - public boolean isOutputConnected(Connector id); + boolean isOutputConnected(Connector id); /** * Determines if a connection exists between the specified connectors. * * @param s sender connector * @param r receiver connector + * * @return true if a connection between the specified * connectors exists; false otherwise */ - public boolean contains(Connector s, Connector r); + boolean contains(Connector s, Connector r); /** * Returns the connection type of this collection. @@ -187,5 +182,5 @@ public interface Connections extends Model { * @return connection type (e.g. "control" or * "data") */ - public String getType(); + String getType(); } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Connector.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Connector.java index 7ceba0ff..6bb76f13 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Connector.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Connector.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -36,6 +36,8 @@ import javafx.beans.property.ObjectProperty; import javafx.event.EventHandler; +import java.util.List; + /** * This interface describes a connector. A connector is used to link nodes * together. It serves as the input or output for the node. Methods allow you to @@ -52,7 +54,7 @@ public interface Connector extends Model { * @return connection type (e.g. "control" or * "data") */ - public String getType(); + String getType(); /** * Determines whether this connector is an input connector. @@ -60,7 +62,7 @@ public interface Connector extends Model { * @return true if this connector is an input connector; * false otherwise */ - public boolean isInput(); + boolean isInput(); /** * Determines whether this connector is an output connector. @@ -68,42 +70,42 @@ public interface Connector extends Model { * @return true if this connector is an output connector; * false otherwise */ - public boolean isOutput(); + boolean isOutput(); /** * Returns the global id of this connector. * * @return global connector id */ - public String getId(); + String getId(); /** * Returns the local id of this connector. * * @return local connector id */ - public String getLocalId(); + String getLocalId(); /** * Defines the local id of this connector. * * @param id the id to set */ - public void setLocalId(String id); + void setLocalId(String id); /** * Returns the parent node of this connector. * * @return parent node of this connector */ - public VNode getNode(); + VNode getNode(); /** * Defines the value object of this connector. * * @param obj value object to set */ - public void setValueObject(ValueObject obj); + void setValueObject(ValueObject obj); /** * Returns the value object of this connector. @@ -111,61 +113,71 @@ public interface Connector extends Model { * @return value object or null if no value object has been * defined */ - public ValueObject getValueObject(); + ValueObject getValueObject(); /** * Returns the value object property (can be used to get notified if the value object changes). + * * @return value object property */ - public ObjectProperty valueObjectProperty(); + ObjectProperty valueObjectProperty(); /** * Adds the specified connection-event listener to this connector. - * + * * @param handler the listener to add */ - public void addConnectionEventListener(EventHandler handler); + void addConnectionEventListener(EventHandler handler); /** * Removes the specified connection-event listener from this connector. + * * @param handler the listener to remove */ - public void removeConnectionEventListener(EventHandler handler); + void removeConnectionEventListener(EventHandler handler); /** * Adds the specified click-event listener to this connector. + * * @param handler the listener to add */ - public void addClickEventListener(EventHandler handler); + void addClickEventListener(EventHandler handler); /** * Removes the specified click-event listener from this connector. + * * @param handler the listener to remove */ - public void removeClickEventListener(EventHandler handler); + void removeClickEventListener(EventHandler handler); /** * Perform a mouse click on this connector. - * @param btn the click button + * + * @param btn the click button * @param event the event (e.g. javafx mouse-event) */ - public void click(MouseButton btn, Object event); - + void click(MouseButton btn, Object event); + /** * Defines the maximum allowed number of connections. + * * @param numConnections maximum allowed number of connections ({@code [0,MAX_INT]}) */ - public void setMaxNumberOfConnections(int numConnections); - + void setMaxNumberOfConnections(int numConnections); + /** - * Returns the maximum allowed number of connections. + * Returns the maximum allowed number of connections. + * * @return maximum allowed number of connections ({@code [0,MAX_INT]}) */ - public int getMaxNumberOfConnections(); - + int getMaxNumberOfConnections(); + /** - * Returns the property of the maximum allowed number of connections. + * Returns the property of the maximum allowed number of connections. + * * @return maximum allowed number of connections ({@code [0,MAX_INT]}) */ - public ObjectProperty maxNumberOfConnectionsProperty(); + ObjectProperty maxNumberOfConnectionsProperty(); + + List> getConnectionEventHandlers(); } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/NodeFactory.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectorValueObject.java similarity index 82% rename from VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/NodeFactory.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectorValueObject.java index 8d105352..f8440234 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/NodeFactory.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectorValueObject.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -33,19 +33,9 @@ */ package eu.mihosoft.vrl.workflow; -import eu.mihosoft.vrl.workflow.skin.Skin; - /** - * Node factory. - * @author Michael Hoffer <info@michaelhoffer.de> - * @param node type - * @param skin type + * @author Andres Almiray */ -public interface NodeFactory> { - - /** - * Creates a new node. - * @return new node - */ - public T newNode(); +public interface ConnectorValueObject extends ValueObject { + Connector getConnector(); } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/DefaultConnectorValueObject.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/DefaultConnectorValueObject.java deleted file mode 100644 index cf2f5b11..00000000 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/DefaultConnectorValueObject.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * Please cite the following publication(s): - * - * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - - * A Framework for Declarative GUI Programming on the Java Platform. - * Computing and Visualization in Science, 2011, in press. - * - * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of Michael Hoffer . - */ -package eu.mihosoft.vrl.workflow; - -import javafx.beans.property.ObjectProperty; -import javafx.beans.property.SimpleObjectProperty; - -/** - * This class defines a default connector value object. ValueObjects are used to - * store data in connectors. It is a placeholder for a value object as it's - * get/setValue methods are not implemented. - * - * @author Michael Hoffer <info@michaelhoffer.de> - */ -public class DefaultConnectorValueObject implements ValueObject { - - private transient VNode parent; - private transient Connector c; - private VisualizationRequest vReq; - private final ObjectProperty valueProperty = new SimpleObjectProperty<>(); - - private String errorMessage; - - public DefaultConnectorValueObject() { - } - - public DefaultConnectorValueObject(Connector c) { - this.c = c; - this.parent = c.getNode(); - } - - @Override - public VNode getParent() { - return parent; - } - - public Connector getConnector() { - return c; - } - - @Override - public Object getValue() { - return valueProperty().get(); - } - - @Override - public void setValue(Object o) { - valueProperty().set(o); - } - - @Override - public ObjectProperty valueProperty() { - return this.valueProperty; - } - - @Override - public CompatibilityResult compatible(final ValueObject sender, final String flowType) { - - return new CompatibilityResult() { - - private boolean compatible; - - { - compatible = computeCompatibility(); - } - - private boolean computeCompatibility() { - // System.out.println(" -> isCompatible: "); - boolean differentObjects = sender != DefaultConnectorValueObject.this; - - boolean compatibleType = false; - - int numConnectionsOfReceiver = getParent().getFlow(). - getConnections(flowType).getAllWith(c).size(); - - boolean lessThanMaxNumberOfConnections = true; - - int maxNumConnections = c.getMaxNumberOfConnections(); - - if (sender instanceof DefaultConnectorValueObject) { - - DefaultConnectorValueObject senderConnectorVObj = - (DefaultConnectorValueObject) sender; - compatibleType = getConnector().getType(). - equals(senderConnectorVObj.getConnector().getType()) - && getConnector().isInput() && senderConnectorVObj. - getConnector().isOutput(); - - int numConnectionsOfSender = senderConnectorVObj.parent. - getFlow().getConnections(flowType). - getAllWith(senderConnectorVObj.c).size(); - - maxNumConnections = Math.min(c.getMaxNumberOfConnections(), - senderConnectorVObj.c.getMaxNumberOfConnections()); - - lessThanMaxNumberOfConnections - = numConnectionsOfReceiver < maxNumConnections - && numConnectionsOfSender < maxNumConnections; - - } - - if (!differentObjects) { - errorMessage = "Connections can only established between different nodes." - + " Sender node cannot be equal to receiver node."; - } else if (!compatibleType) { - errorMessage = "Connections can only established between" - + " connectors of the same connection/flow type."; - } else if (!lessThanMaxNumberOfConnections) { - errorMessage = "Trying to creating more than " + maxNumConnections - + " number of connections is not allowed."; - } - - return differentObjects && compatibleType && lessThanMaxNumberOfConnections; - } - - @Override - public boolean isCompatible() { - return compatible; - } - - @Override - public String getMessage() { - - String senderId = sender.getParent() + ":undefined"; - - if (sender instanceof DefaultConnectorValueObject) { - senderId = ((DefaultConnectorValueObject) sender).getConnector().getId(); - } - - return "incompatible: " + senderId + " -> " + getConnector().getId() + ", reason: " + errorMessage; - } - - @Override - public String getStatus() { - throw new UnsupportedOperationException("Not supported yet."); - } - }; // end CompatibilityResult - } - - @Override - public VisualizationRequest getVisualizationRequest() { - return vReq; - } - - @Override - public void setVisualizationRequest(VisualizationRequest vReq) { - this.vReq = vReq; - } - - /** - * @param parent the parent to set - */ - @Override - public void setParent(VNode parent) { - this.parent = parent; - } -} diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/FlowModel.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/FlowModel.java index 39077ddb..4b931b43 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/FlowModel.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/FlowModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -41,32 +41,34 @@ * * @author Michael Hoffer <info@michaelhoffer.de> */ -interface FlowModel extends Model, VisibleState { +public interface FlowModel extends Model, VisibleState { /** * Attempts to create the specified connection. This method never creates an * actual connection. It only checks whether the requested connection is * valid. * - * @param s sender node (uses main output connector of this node if - * specified) - * @param r receiver node (uses main input connector of this node if - * specified) + * @param s sender node (uses main output connector of this node if + * specified) + * @param r receiver node (uses main input connector of this node if + * specified) * @param flowType connection type + * * @return connection result */ - public ConnectionResult tryConnect(VNode s, VNode r, String flowType); + ConnectionResult tryConnect(VNode s, VNode r, String flowType); /** * Requests the specified connection. If the specified connection can be * established it will be created. * - * @param s sender node - * @param r receiver node + * @param s sender node + * @param r receiver node * @param flowType connection type + * * @return connection result */ - public ConnectionResult connect(VNode s, VNode r, String flowType); + ConnectionResult connect(VNode s, VNode r, String flowType); /** * Attempts to create the specified connection. This method never creates an @@ -75,9 +77,10 @@ interface FlowModel extends Model, VisibleState { * * @param s sender connector * @param r receiver connector + * * @return connection result */ - public ConnectionResult tryConnect(Connector s, Connector r); + ConnectionResult tryConnect(Connector s, Connector r); /** * Requests the specified connection. If the specified connection can be @@ -85,102 +88,103 @@ interface FlowModel extends Model, VisibleState { * * @param s sender node * @param r receiver node + * * @return connection result */ - public ConnectionResult connect(Connector s, Connector r); + ConnectionResult connect(Connector s, Connector r); /** * Removes the specified node from this flow. * * @param n the node to remove + * * @return the removed node or null if no node has been removed */ - public VNode remove(VNode n); + VNode remove(VNode n); /** * Clears this flow, i.e., removes all nodes and connections. */ - public void clear(); + void clear(); /** * Returns the nodes of this flow. * * @return nodes of this flow */ - public ObservableList getNodes(); + ObservableList getNodes(); /** * Returns the sender of the specified connection. * * @param c connection + * * @return the sender of the specified connection or null if * the node does not exist */ - public VNode getSender(Connection c); + VNode getSender(Connection c); /** * Returns the receiver of the specified connection. * * @param c connection + * * @return the receiver of the specified connection or null if * the node does not exist */ - public VNode getReceiver(Connection c); + VNode getReceiver(Connection c); /** * Adds the specified connections to this flow. + * * @param connections connections to add - * @param flowType connection type + * @param flowType connection type */ - public void addConnections(Connections connections, String flowType); + void addConnections(Connections connections, String flowType); /** * Returns the all connections of the specified flow/connection type + * * @param flowType connection type + * * @return all connections of the specified flow/connection type */ - public Connections getConnections(String flowType); + Connections getConnections(String flowType); /** * Returns all connections of this flow. + * * @return all connections of this flow */ - public ObservableMap getAllConnections(); - - /** - * Defines the flow node implementation class used by this flow model. - * @param cls flow node implementation class - */ - public void setFlowNodeClass(Class cls); - - /** - * Returns the flow node implementation class used by this flow. - * @return the flow node implementation class used by this flow - */ - public Class getFlowNodeClass(); + ObservableMap getAllConnections(); /** * Defines the id generator that shall be used by this flow. + * * @param generator id generator */ - public void setIdGenerator(IdGenerator generator); + void setIdGenerator(IdGenerator generator); /** * Returns the id generator used by this flow. + * * @return id generator */ - public IdGenerator getIdGenerator(); + IdGenerator getIdGenerator(); /** * Defines the node lookup that shall be used by this flow. + * * @param nodeLookup node lookup */ - public void setNodeLookup(NodeLookup nodeLookup); + void setNodeLookup(NodeLookup nodeLookup); /** * Returns the node lookup that is used by this flow. + * * @return node lookup */ - public NodeLookup getNodeLookup(); + NodeLookup getNodeLookup(); + VNode registerNode(VNode result, ValueObject obj, String parentId); } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/IdGenerator.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/IdGenerator.java index b4027246..7acd8f8e 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/IdGenerator.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/IdGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -50,40 +50,43 @@ public interface IdGenerator { * * @param id id to add */ - public void addId(String id); + void addId(String id); /** * Adds all ids from the specified id generator. * * @param generator id generator that contains the ids that shall be added */ - public void addIds(IdGenerator generator); + void addIds(IdGenerator generator); /** * Generates a new id and adds it to this id generator. * * @return the generated id */ - public String newId(); + String newId(); /** * Generates a new id with the specified prefix and adds it to rhis id * generator. * * @param prefix id prefix + * * @return the generated id */ - public String newId(String prefix); + String newId(String prefix); /** * Returns the ids created/managed by this id generator - * @return + * + * @return */ - public Set getIds(); + Set getIds(); /** * Returns a new child id generator. + * * @return child id generator */ - public IdGenerator newChild(); + IdGenerator newChild(); } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Lookup.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Lookup.java index 3fe94167..0916d5e5 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Lookup.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Lookup.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -45,8 +45,9 @@ public interface Lookup { * Returns the element with the specified id. * * @param id id of the requested element + * * @return the requested element or null if the requested * element does not exist */ - public T getById(String id); + T getById(String id); } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Model.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Model.java index 8fb1e72e..ed93a6a9 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Model.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Model.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/MouseButton.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/MouseButton.java index 80c05c4d..a1f1d4e1 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/MouseButton.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/MouseButton.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -40,8 +40,9 @@ /** * This enum encapsulates the different mouse buttons that can be detected. - * @see ClickEvent + * * @author Michael Hoffer <info@michaelhoffer.de> + * @see ClickEvent */ public enum MouseButton { /** diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/NodeLookup.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/NodeLookup.java index 6e9324a7..6f705937 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/NodeLookup.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/NodeLookup.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -44,8 +44,9 @@ public interface NodeLookup extends Lookup { * Returns the connector with the specified id. * * @param id global connector id + * * @return connector with the specified global id or null if no * such connector exists */ - public Connector getConnectorById(String id); + Connector getConnectorById(String id); } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/PropertyStorage.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/PropertyStorage.java index 15af345a..7b3ebdca 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/PropertyStorage.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/PropertyStorage.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -39,13 +39,12 @@ package eu.mihosoft.vrl.workflow; -import java.util.Collection; import javafx.collections.MapChangeListener; +import java.util.Collection; import java.util.Optional; /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ public interface PropertyStorage { @@ -54,6 +53,7 @@ public interface PropertyStorage { * Indicates whether this storage contains the requested property. * * @param key key + * * @return {@code true} if this storage contains the requested property; * {@code false} */ @@ -71,6 +71,7 @@ public interface PropertyStorage { * * @param property type * @param key key + * * @return the property; an empty {@link java.util.Optional} will be * returned if the property does not exist or the type does not match */ @@ -79,27 +80,29 @@ public interface PropertyStorage { /** * Sets a property. Existing properties are overwritten. * - * @param key key + * @param key key * @param property property */ void set(String key, T property); - /** - * Adds the specified listener to the property map. + /** + * Adds the specified listener to the property storage. + * * @param l change listener */ - public void addListener(MapChangeListener l); - + void addListener(MapChangeListener l); + /** - * Removes the specified listener from the property map. + * Removes the specified listener from the property storage. + * * @param l change listener */ - public void removeListener(MapChangeListener l); - + void removeListener(MapChangeListener l); + /** * Returns the keys that are currently used by the property storage. + * * @return keys used by the property storage */ - public Collection getKeys(); - + Collection getKeys(); } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Selectable.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Selectable.java index d77978ca..c47da6e4 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Selectable.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/Selectable.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -66,6 +66,7 @@ public interface Selectable { * Requests (de-)selection of this object. * * @param b selection state (true or false) + * * @return true if this object has been selected; * false otherwise */ diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ThruConnector.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ThruConnector.java index 10635849..a28deb9d 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ThruConnector.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ThruConnector.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -36,18 +36,21 @@ /** * A passthru connector. Passthru connectors are used to establish connections * between nodes in different hierarchy levels. + * * @author Michael Hoffer <info@michaelhoffer.de> */ -public interface ThruConnector extends Connector{ - +public interface ThruConnector extends Connector { + /** * Returns the inner connector node. + * * @return inner connector node */ VNode getInnerNode(); - + /** * Returns the inner connector. + * * @return inner connector */ Connector getInnerConnector(); diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VFlow.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VFlow.java index ccdf7230..0853095f 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VFlow.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VFlow.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -45,6 +45,7 @@ import java.util.Collection; import java.util.List; +import java.util.Map; /** * The {@code VFlow} interface describes a workflow controller. A workflow is a @@ -60,35 +61,35 @@ public interface VFlow { * * @param flow flow model */ - public void setModel(VFlowModel flow); + void setModel(VFlowModel flow); /** * Defines the node lookup that shall be used by this flow controller. * * @param nodeLookup */ - public void setNodeLookup(NodeLookup nodeLookup); + void setNodeLookup(NodeLookup nodeLookup); /** * Returns the node lookup that is used by this flow controller. * * @return */ - public NodeLookup getNodeLookup(); + NodeLookup getNodeLookup(); /** * Returns the model that is used by this flow controller. * * @return the model that is used by this flow controller */ - public VFlowModel getModel(); + VFlowModel getModel(); /** * Returns the property of the model that is used by this flow controller. * * @return the property of the model that is used by this flow controller */ - public ObjectProperty modelProperty(); + ObjectProperty modelProperty(); /** * Attempts to create the specified connection. This method never creates an @@ -97,9 +98,10 @@ public interface VFlow { * * @param s sender connector * @param r receiver connector + * * @return connection result */ - public ConnectionResult tryConnect(Connector s, Connector r); + ConnectionResult tryConnect(Connector s, Connector r); /** * Requests the specified connection. If the specified connection can be @@ -107,151 +109,146 @@ public interface VFlow { * * @param s sender node * @param r receiver node + * * @return connection result */ - public ConnectionResult connect(Connector s, Connector r); + ConnectionResult connect(Connector s, Connector r); /** * Attempts to create the specified connection. This method never creates an * actual connection. It only checks whether the requested connection is * valid. * - * @param s sender node (uses main output connector of this node if - * specified) - * @param r receiver node (uses main input connector of this node if - * specified) + * @param s sender node (uses main output connector of this node if + * specified) + * @param r receiver node (uses main input connector of this node if + * specified) * @param flowType connection type + * * @return connection result */ - public ConnectionResult tryConnect(VNode s, VNode r, String flowType); + ConnectionResult tryConnect(VNode s, VNode r, String flowType); /** * Requests the specified connection. If the specified connection can be * established it will be created. * - * @param s sender node - * @param r receiver node + * @param s sender node + * @param r receiver node * @param flowType connection type + * * @return connection result */ - public ConnectionResult connect(VNode s, VNode r, String flowType); + ConnectionResult connect(VNode s, VNode r, String flowType); - public ConnectionResult tryConnect(VFlow s, VNode r, String flowType); + ConnectionResult tryConnect(VFlow s, VNode r, String flowType); - public ConnectionResult tryConnect(VNode s, VFlow r, String flowType); + ConnectionResult tryConnect(VNode s, VFlow r, String flowType); - public ConnectionResult tryConnect(VFlow s, VFlow r, String flowType); + ConnectionResult tryConnect(VFlow s, VFlow r, String flowType); - public ConnectionResult connect(VFlow s, VNode r, String flowType); + ConnectionResult connect(VFlow s, VNode r, String flowType); - public ConnectionResult connect(VNode s, VFlow r, String flowType); + ConnectionResult connect(VNode s, VFlow r, String flowType); - public ConnectionResult connect(VFlow s, VFlow r, String flowType); + ConnectionResult connect(VFlow s, VFlow r, String flowType); /** * Removes the specified node from this flow. * * @param n the node to remove + * * @return the removed node or null if no node has been removed */ - public VNode remove(VNode n); + VNode remove(VNode n); /** * Returns the nodes of this flow. * * @return nodes of this flow */ - public ObservableList getNodes(); + ObservableList getNodes(); /** * Clears this flow, i.e., removes all nodes and connections. */ - public void clear(); + void clear(); /** * Returns the sender of the specified connection. * * @param c connection + * * @return the sender of the specified connection or null if * the node does not exist */ - public VNode getSender(Connection c); + VNode getSender(Connection c); /** * Returns the receiver of the specified connection. * * @param c connection + * * @return the receiver of the specified connection or null if * the node does not exist */ - public VNode getReceiver(Connection c); + VNode getReceiver(Connection c); /** * Adds the specified connections to this flow controller. * * @param connections connections to add - * @param flowType connection type + * @param flowType connection type */ - public void addConnections(Connections connections, String flowType); + void addConnections(Connections connections, String flowType); /** * Returns the all connections of the specified flow/connection type * * @param flowType connection type + * * @return all connections of the specified flow/connection type */ - public Connections getConnections(String flowType); + Connections getConnections(String flowType); /** * Returns all connections of this flow controller. * * @return all connections of this flow controller */ - public ObservableMap getAllConnections(); - - /** - * Defines the flow node implementation class used by this flow controller. - * - * @param cls flow node implementation class - */ - public void setFlowNodeClass(Class cls); - - /** - * Returns the flow node implementation class used by this flow controller. - * - * @return the flow node implementation class used by this flow controller - */ - public Class getFlowNodeClass(); + ObservableMap getAllConnections(); /** * Adds a new node to this flow. * * @param obj value object that shall be used for the requested node + * * @return new node */ - public VNode newNode(ValueObject obj); + VNode newNode(ValueObject obj); /** * Adds a new node to this flow. * * @return new node */ - public VNode newNode(); + VNode newNode(); /** * Adds a new subflow to this flow. * * @param obj value object that shall be used for the requested subflow + * * @return new subflow */ - public VFlow newSubFlow(ValueObject obj); + VFlow newSubFlow(ValueObject obj); /** * Adds a new subflow to this flow. * * @return new subflow */ - public VFlow newSubFlow(); + VFlow newSubFlow(); /** * Returns all direct subcontrollers of this flow controller. Subcontrollers @@ -260,97 +257,95 @@ public interface VFlow { * * @return all direct subcontrollers of this flow controller */ - public Collection getSubControllers(); + Collection getSubControllers(); /** * Defines the skin factories for this flow controller. * * @param skinFactories skin factories that shall be used by this flow - * controller - * - * Doesn't use Generics because generic arrays are not supported. GENERICS - * ARE CRAPPY! - * {@link http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6227971} - * + * controller + *

+ * Doesn't use Generics because generic arrays are not supported. GENERICS + * ARE CRAPPY! + * {@link http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6227971} */ - public void setSkinFactories(SkinFactory... skinFactories); + void setSkinFactories(SkinFactory... skinFactories); /** * Defines the skin factories for this flow controller. * * @param skinFactories skin factories that shall be used by this flow - * controller + * controller */ - public void setSkinFactories(Collection> skinFactories); + void setSkinFactories(Collection> skinFactories); /** * Returns the skin factories that are used by this flow controller. * * @return the skin factories that are used by this flow controller */ - public Collection> getSkinFactories(); + Collection> getSkinFactories(); /** * Adds the specified skin factories to this flow controller. * * @param skinFactories skin factories that shall be added to this flow - * controller - * - * Doesn't use Generics because generic arrays are not supported. GENERICS - * ARE CRAPPY! - * {@link http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6227971} - * + * controller + *

+ * Doesn't use Generics because generic arrays are not supported. GENERICS + * ARE CRAPPY! + * {@link http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6227971} */ - public void addSkinFactories(SkinFactory... skinFactories); + void addSkinFactories(SkinFactory... skinFactories); /** * Adds the specified skin factories to this flow controller. * * @param skinFactories skin factories that shall be added to this flow - * controller + * controller */ - public void addSkinFactories(Collection> skinFactories); + void addSkinFactories(Collection> skinFactories); /** * Removes the specified skin factories from this flow controller. * * @param skinFactories skin factories to be removed */ - public void removeSkinFactories(SkinFactory... skinFactories); + void removeSkinFactories(SkinFactory... skinFactories); /** * Removes the specified skin factories from this flow controller. * * @param skinFactories skin factories to be removed */ - public void removeSkinFactories(Collection> skinFactories); + void removeSkinFactories(Collection> skinFactories); /** * Defines the id generator that shall be used by this flow controller. * * @param generator id generator */ - public void setIdGenerator(IdGenerator generator); + void setIdGenerator(IdGenerator generator); /** * Returns the id generator used by this flow controller. * * @return id generator */ - public IdGenerator getIdGenerator(); + IdGenerator getIdGenerator(); - public List getNodeSkinsById(String id); + List getNodeSkinsById(String id); - public FlowNodeSkinLookup getNodeSkinLookup(); + FlowNodeSkinLookup getNodeSkinLookup(); - public void setNodeSkinLookup(FlowNodeSkinLookup skinLookup); + void setNodeSkinLookup(FlowNodeSkinLookup skinLookup); - public void setVisible(boolean state); + void setVisible(boolean state); - public boolean isVisible(); + boolean isVisible(); - public BooleanProperty visibleState(); + BooleanProperty visibleState(); Connector addInput(String type); @@ -360,10 +355,11 @@ public interface VFlow { * Returns child flow by id. * * @param id the id that specifies the requested flow + * * @return the requested child flow or null if no such flow * exists */ - public VFlow getFlowById(String id); + VFlow getFlowById(String id); VFlow getParent(); @@ -371,11 +367,13 @@ public interface VFlow { VFlow getRootFlow(); - public ThruConnector addThruInput(String type); + ThruConnector addThruInput(String type); + + ThruConnector addThruOutput(String type); - public ThruConnector addThruOutput(String type); + ObservableList getThruInputs(); - public ObservableList getThruInputs(); + ObservableList getThruOutputs(); - public ObservableList getThruOutputs(); + Map getConnectionSkinMap(SkinFactory skinFactory); } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VFlowModel.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VFlowModel.java index ba781f54..be2cd653 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VFlowModel.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VFlowModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -36,24 +36,24 @@ import javafx.collections.ObservableList; /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ public interface VFlowModel extends FlowModel, VNode { - public VFlowModel newFlowNode(ValueObject obj); + VFlowModel newFlowNode(ValueObject obj); + + VFlowModel newFlowNode(); + + VNode newNode(ValueObject obj); - public VFlowModel newFlowNode(); + VNode newNode(); - public VNode newNode(ValueObject obj); + ThruConnector addThruInput(String type); - public VNode newNode(); + ThruConnector addThruOutput(String type); - public ThruConnector addThruInput(String type); + ObservableList getThruInputs(); - public ThruConnector addThruOutput(String type); - - public ObservableList getThruInputs(); - public ObservableList getThruOutputs(); + ObservableList getThruOutputs(); } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VNode.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VNode.java index 067bcd34..064419cf 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VNode.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VNode.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -42,126 +42,135 @@ import java.util.Collection; /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ public interface VNode extends Model, Selectable { - public StringProperty titleProperty(); + StringProperty titleProperty(); - public void setTitle(String title); + void setTitle(String title); - public String getTitle(); + String getTitle(); - public StringProperty idProperty(); + StringProperty idProperty(); /** * Defines the local id of this node. * * @param id id to set */ - public void setId(String id); + void setId(String id); /** * Returns the local id of this node. * * @return */ - public String getId(); + String getId(); /** * Returns the global id of this node * * @return global id of this node */ -// public String getGlobalId(); - public DoubleProperty xProperty(); + // String getGlobalId(); + DoubleProperty xProperty(); + + DoubleProperty yProperty(); + + void setX(double x); - public DoubleProperty yProperty(); + void setY(double x); - public void setX(double x); + double getX(); - public void setY(double x); + double getY(); - public double getX(); + DoubleProperty widthProperty(); - public double getY(); + DoubleProperty heightProperty(); - public DoubleProperty widthProperty(); + void setWidth(double w); - public DoubleProperty heightProperty(); + void setHeight(double h); - public void setWidth(double w); + double getWidth(); - public void setHeight(double h); + double getHeight(); - public double getWidth(); + // ObservableList getChildren(); + // ObservableList> getInputs(); + // ObservableList> getOutputs(); + void setValueObject(ValueObject obj); - public double getHeight(); + ValueObject getValueObject(); -// public ObservableList getChildren(); -// public ObservableList> getInputs(); -// public ObservableList> getOutputs(); - public void setValueObject(ValueObject obj); + ObjectProperty valueObjectProperty(); - public ValueObject getValueObject(); + VFlowModel getFlow(); - public ObjectProperty valueObjectProperty(); + // boolean isInputOfType(String type); + // + // boolean isOutputOfType(String type); + // boolean isInput(); + // + // boolean isOutput(); + // void setInput(boolean state, String type); + // void setOutput(boolean state, String type); + Connector addInput(String type); - public VFlowModel getFlow(); + Connector addOutput(String type); -// boolean isInputOfType(String type); -// -// boolean isOutputOfType(String type); -// boolean isInput(); -// -// boolean isOutput(); -// void setInput(boolean state, String type); -// void setOutput(boolean state, String type); - public Connector addInput(String type); + Connector addConnector(Connector c); - public Connector addOutput(String type); + boolean removeConnector(Connector c); - public Connector addConnector(Connector c); - - public boolean removeConnector(Connector c); + // ObservableList getInputTypes(); + // + // ObservableList getOutputTypes(); + Collection getMainInputTypes(); -// ObservableList getInputTypes(); -// -// ObservableList getOutputTypes(); - public Collection getMainInputTypes(); + Collection getMainOutputTypes(); - public Collection getMainOutputTypes(); + Connector getMainInput(String type); - public Connector getMainInput(String type); + Connector getMainOutput(String type); - public Connector getMainOutput(String type); + Connector setMainInput(Connector connector); - public Connector setMainInput(Connector connector); + Connector setMainOutput(Connector connector); - public Connector setMainOutput(Connector connector); + Connector getConnector(String localId); - public Connector getConnector(String localId); + ObservableList getConnectors(); - public ObservableList getConnectors(); + ObservableList getInputs(); - public ObservableList getInputs(); + ObservableList getOutputs(); + + BooleanProperty selectableProperty(); + + boolean isSelectable(); - public ObservableList getOutputs(); - - public BooleanProperty selectableProperty(); - public boolean isSelectable(); - - /** * Returns the distance to the root element. */ - public int getDepth(); - + int getDepth(); + /** * Returns the root element of this flow. + * * @return root element */ - public FlowModel getRoot(); - + FlowModel getRoot(); + + Connector addInput(VNode node, String type); + + Connector addOutput(VNode node, String type); + + ThruConnector addThruInput(VNode node, String type, VNode innerNode, Connector innerConnector); + + ThruConnector addThruOutput(VNode node, String type, VNode innerNode, Connector innerConnector); + + Connector addConnector(VNode node, Connector c); } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VNodeImpl.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VNodeImpl.java deleted file mode 100644 index 1b3541e4..00000000 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VNodeImpl.java +++ /dev/null @@ -1,604 +0,0 @@ -/* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * Please cite the following publication(s): - * - * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - - * A Framework for Declarative GUI Programming on the Java Platform. - * Computing and Visualization in Science, 2011, in press. - * - * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of Michael Hoffer . - */ -package eu.mihosoft.vrl.workflow; - -import javafx.beans.property.BooleanProperty; -import javafx.beans.property.DoubleProperty; -import javafx.beans.property.ObjectProperty; -import javafx.beans.property.ReadOnlyBooleanProperty; -import javafx.beans.property.ReadOnlyProperty; -import javafx.beans.property.SimpleBooleanProperty; -import javafx.beans.property.SimpleDoubleProperty; -import javafx.beans.property.SimpleObjectProperty; -import javafx.beans.property.SimpleStringProperty; -import javafx.beans.property.StringProperty; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; -import javafx.collections.FXCollections; -import javafx.collections.ListChangeListener; -import javafx.collections.ObservableList; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -/** - * - * @author Michael Hoffer <info@michaelhoffer.de> - */ -class VNodeImpl implements VNode { - - private final ObservableList connectors - = FXCollections.observableArrayList(); - private ObservableList inputs - = FXCollections.observableArrayList(); - private ObservableList outputs - = FXCollections.observableArrayList(); - private final ObservableList unmodifiableInputs - = FXCollections.unmodifiableObservableList(inputs); - private final ObservableList unmodifiableOutputs - = FXCollections.unmodifiableObservableList(outputs); - private final StringProperty idProperty = new SimpleStringProperty(); - private final StringProperty titleProperty = new SimpleStringProperty(); - private final DoubleProperty xProperty = new SimpleDoubleProperty(); - private final DoubleProperty yProperty = new SimpleDoubleProperty(); - private final DoubleProperty widthProperty = new SimpleDoubleProperty(); - private final DoubleProperty heightProperty = new SimpleDoubleProperty(); - - private final BooleanProperty selectedProperty = new SimpleBooleanProperty(false); - private final BooleanProperty selectableProperty = new SimpleBooleanProperty(true); - - private final ObjectProperty valueObjectProperty - = new SimpleObjectProperty<>(); - private VFlowModel flow; - - private IdGenerator connectorIdGenerator = new IdGeneratorImpl(); - private final Map mainInputs = new HashMap<>(); - private final Map mainOutputs = new HashMap<>(); - private ObjectProperty vReqProperty; - - public VNodeImpl(VFlowModel flow) { - - this.flow = flow; - - setWidth(200); - setHeight(150); - - setTitle("Node"); - - setValueObject(new DefaultValueObject(this)); - - valueObjectProperty.addListener(new ChangeListener() { - @Override - public void changed(ObservableValue ov, ValueObject t, ValueObject t1) { - if (t1 != null) { - t1.setParent(VNodeImpl.this); - } - } - }); - - connectors.addListener(new ListChangeListener() { - @Override - public void onChanged(Change change) { - while (change.next()) { - if (change.wasPermutated()) { - for (int i = change.getFrom(); i < change.getTo(); ++i) { - //permutate - String action = "permutate"; // TODO: implement - } - } -// else if (change.wasUpdated()) { -// //TODO: update item -// -// } - else if (change.wasRemoved()) { - for (Connector connector : change.getRemoved()) { - if (connector.isInput()) { - inputs.remove(connector); - - } - - if (connector.isOutput()) { - outputs.remove(connector); - } - - Connections connections = getFlow().getConnections(connector.getType()); - connections.getConnections().removeAll(connections.getAllWith(connector)); - - connectorIdGenerator.getIds().remove(connector.getId()); - } - } else if (change.wasAdded()) { - for (Connector connector : change.getAddedSubList()) { - if (connector.isInput()) { - inputs.add(connector); -// System.out.println("added input:" + unmodifiableInputs.size()); - } - - if (connector.isOutput()) { - outputs.add(connector); -// System.out.println("added output:" + unmodifiableOutputs.size()); - } - - if (connector instanceof ThruConnector) { - connector.setLocalId(connectorIdGenerator.newId("thru")); - } else { - connector.setLocalId(connectorIdGenerator.newId()); - } - } - } - } - } - }); - -// -// outputs.addListener(new ListChangeListener>() { -// @Override -// public void onChanged(Change> change) { -// throw new UnsupportedOperationException("Not supported yet."); -// } -// }); - } - -// @Override -// public ObservableList> getInputs() { -// return inputs; -// } -// -// @Override -// public ObservableList> getOutputs() { -// return outputs; -// } - @Override - public StringProperty titleProperty() { - return titleProperty; - } - - @Override - public final void setTitle(String title) { - titleProperty.set(title); - } - - @Override - public String getTitle() { - return titleProperty.get(); - } - - @Override - public StringProperty idProperty() { - return idProperty; - } - - @Override - public void setId(String id) { - idProperty.set(id); - } - - @Override - public String getId() { - return idProperty.get(); - } - - @Override - public DoubleProperty xProperty() { - return xProperty; - } - - @Override - public DoubleProperty yProperty() { - return yProperty; - } - - @Override - public void setX(double x) { - xProperty.set(x); - } - - @Override - public void setY(double y) { - yProperty.set(y); - } - - @Override - public double getX() { - return xProperty.get(); - } - - @Override - public double getY() { - return yProperty.get(); - } - - @Override - public DoubleProperty widthProperty() { - return widthProperty; - } - - @Override - public DoubleProperty heightProperty() { - return heightProperty; - } - - @Override - public final void setWidth(double w) { - widthProperty.set(w); - } - - @Override - public final void setHeight(double h) { - heightProperty.set(h); - } - - @Override - public double getWidth() { - return widthProperty.get(); - } - - @Override - public double getHeight() { - return heightProperty.get(); - } - -// @Override -// public ObservableList getChildren() { -// return children; -// } - @Override - public ValueObject getValueObject() { - return valueObjectProperty.get(); - } - - @Override - public final void setValueObject(ValueObject o) { - valueObjectProperty.set(o); - } - - @Override - public ObjectProperty valueObjectProperty() { - return valueObjectProperty; - } - - /** - * @return the vReq - */ - @Override - public VisualizationRequest getVisualizationRequest() { - return visualizationRequestProperty().getValue(); - } - - /** - * @param vReq the vReq to set - */ - @Override - public void setVisualizationRequest(VisualizationRequest vReq) { - _visualizationRequestProperty().set(vReq); - } - - private ObjectProperty _visualizationRequestProperty() { - if (vReqProperty == null) { - vReqProperty = new SimpleObjectProperty<>(); - vReqProperty.set(new VisualizationRequestImpl()); - } - - if (vReqProperty.get() == null) { - vReqProperty.set(new VisualizationRequestImpl()); - } - - return vReqProperty; - } - - @Override - public ReadOnlyProperty visualizationRequestProperty() { - return _visualizationRequestProperty(); - } - -// @Override -// public void setSkin(Skin skin) { -// skinProperty.set(skin); -// } -// -// @Override -// public Skin getSkin() { -// return skinProperty.get(); -// } -// -// @Override -// public ObjectProperty skinProperty() { -// return skinProperty; -// } - /** - * @return the flow - */ - @Override - public VFlowModel getFlow() { - return flow; - } - -// @Override -// public void setOutput(boolean state, String type) { -// if (state && !outputTypes.contains(type)) { -// outputTypes.add(type); -// } else if (!state) { -// outputTypes.remove(type); -// } -// } -// -// @Override -// public void setInput(boolean state, String type) { -// if (state && !inputTypes.contains(type)) { -// inputTypes.add(type); -// } else if (!state) { -// inputTypes.remove(type); -// } -// } - @Override - public Connector addInput(String type) { - return addInput(this, type); - } - - @Override - public Connector addOutput(String type) { - return this.addOutput(this, type); - } - - @Override - public Connector addConnector(Connector c) { - return addConnector(this, c); - } - - Connector addInput(VNode node, String type) { - Connector c = new ConnectorImpl( - node, type, null, true); - connectors.add(c); - return c; - } - - Connector addOutput(VNode node, String type) { - Connector c = new ConnectorImpl( - node, type, null, false); - connectors.add(c); - return c; - } - - ThruConnector addThruInput(VNode node, String type, VNode innerNode, Connector innerConnector) { - ThruConnector c = new ThruConnectorImpl( - node, type, null, true, innerNode, innerConnector); - connectors.add(c); - return c; - } - - ThruConnector addThruOutput(VNode node, String type, VNode innerNode, Connector innerConnector) { - ThruConnector c = new ThruConnectorImpl( - node, type, null, false, innerNode, innerConnector); - connectors.add(c); - return c; - } - - Connector addConnector(VNode node, Connector c) { - String localId = c.getLocalId(); - - if (connectorIdGenerator.getIds().contains(localId)) { - throw new IllegalArgumentException( - "Cannot add connector: id \"" + localId + "\" already in use"); - } - - Connector result = new ConnectorImpl(node, c); - connectors.add(result); - - connectorIdGenerator.addId(localId); - - return result; - } - -// @Override -// public boolean isInputOfType(String type) { -// return inputTypes.contains(type); -// } -// -// @Override -// public boolean isOutputOfType(String type) { -// return outputTypes.contains(type); -// } -// -// @Override -// public boolean isOutput() { -// return !outputTypes.isEmpty(); -// } -// -// @Override -// public boolean isInput() { -// return !inputTypes.isEmpty(); -// } -// @Override -// public String getGlobalId() { -// String id = getId(); -// -// if (getFlow() ==null) { -// return id; -// } -// -// FlowNode parent = getFlow(); -// -// while (parent.getFlow()!=null) { -// id = parent.getGlobalId() + ":" + id; -// parent = parent.getFlow(); -// } -// -// return id; -// } -// @Override -// public ObservableList getInputTypes() { -// return inputTypes; -// } -// -// @Override -// public ObservableList getOutputTypes() { -// return outputTypes; -// } - @Override - public Connector getMainInput(String type) { - return mainInputs.get(type); - } - - @Override - public Connector getMainOutput(String type) { - return mainOutputs.get(type); - } - - @Override - public Collection getMainInputTypes() { - return mainInputs.keySet(); - } - - @Override - public Collection getMainOutputTypes() { - return mainOutputs.keySet(); - } - - @Override - public Connector setMainInput(Connector connector) { - mainInputs.put(connector.getType(), connector); - return connector; - } - - @Override - public Connector setMainOutput(Connector connector) { - mainOutputs.put(connector.getType(), connector); - return connector; - } - - @Override - public Connector getConnector(String localId) { - for (Connector c : connectors) { - if (c.getLocalId().equals(localId)) { - return c; - } - } - - return null; - } - - @Override - public ObservableList getConnectors() { - return this.connectors; - } - - @Override - public ObservableList getInputs() { - return this.unmodifiableInputs; - } - - @Override - public ObservableList getOutputs() { - return this.unmodifiableOutputs; - } - - @Override - public final boolean isSelected() { - return selectedProperty().get(); - } - - @Override - public final boolean requestSelection(boolean select) { - - if (!select) { - selectedProperty.set(false); - } - - if (isSelectable()) { - selectedProperty.set(select); - return true; - } else { - return false; - } - } - - @Override - public final ReadOnlyBooleanProperty selectedProperty() { - return this.selectedProperty; - } - - @Override - public final BooleanProperty selectableProperty() { - return selectableProperty; - } - - @Override - public final boolean isSelectable() { - return selectableProperty().get(); - } - - public final void setSelectable(boolean b) { - selectableProperty().set(b); - } - - @Override - public boolean isVisualizationRequestInitialized() { - return vReqProperty != null; - } - - @Override - public boolean removeConnector(Connector c) { - return this.connectors.remove(c); - } - - @Override - public int getDepth() { - VFlowModel parent = this.getFlow(); - - int depth = 0; - - while (parent != null) { - parent = parent.getFlow(); - depth++; - } - - return depth; - } - - @Override - public FlowModel getRoot() { - - VFlowModel root = null; - VFlowModel parent = this.getFlow(); - - while (parent != null) { - root = parent; - parent = parent.getFlow(); - } - - return root; - - } - -} diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ValueObject.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ValueObject.java index 96c313ac..aa14f1c3 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ValueObject.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ValueObject.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -36,17 +36,23 @@ import javafx.beans.property.ObjectProperty; /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ public interface ValueObject { - public VNode getParent(); - public void setParent(VNode p); - public Object getValue(); - public void setValue(Object o); - public ObjectProperty valueProperty(); + VNode getParent(); + + void setParent(VNode p); + + Object getValue(); + + void setValue(Object o); + + ObjectProperty valueProperty(); + // assumes we are receiver - public CompatibilityResult compatible(ValueObject sender, String flowTpe); - public VisualizationRequest getVisualizationRequest(); - public void setVisualizationRequest(VisualizationRequest vReq); + CompatibilityResult compatible(ValueObject sender, String flowTpe); + + VisualizationRequest getVisualizationRequest(); + + void setVisualizationRequest(VisualizationRequest vReq); } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VisibleState.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VisibleState.java index d03cca1e..3f27e662 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VisibleState.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VisibleState.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -36,14 +36,13 @@ import javafx.beans.property.BooleanProperty; /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ public interface VisibleState { - public BooleanProperty visibleProperty(); + BooleanProperty visibleProperty(); - public boolean isVisible(); + boolean isVisible(); - public void setVisible(boolean b); + void setVisible(boolean b); } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VisualizationRequest.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VisualizationRequest.java index e2d1f896..28514deb 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VisualizationRequest.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VisualizationRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -34,34 +34,34 @@ package eu.mihosoft.vrl.workflow; /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ -public interface VisualizationRequest extends PropertyStorage{ - - static final String KEY_STYLE = "visualization-request:style"; +public interface VisualizationRequest extends PropertyStorage { + + String KEY_STYLE = "visualization-request:style"; /** * Defines the maximum connector size. */ - static final String KEY_MAX_CONNECTOR_SIZE = "visualization-request:connector:max-size"; + String KEY_MAX_CONNECTOR_SIZE = "visualization-request:connector:max-size"; /** * Defines whether connectors can change their layout position (switch edges). */ - static final String KEY_CONNECTOR_AUTO_LAYOUT = "visualization-request:connector:auto-layout"; + String KEY_CONNECTOR_AUTO_LAYOUT = "visualization-request:connector:auto-layout"; /** * Defines whether to disable editing, i.e., changes to nodes and connections. */ - static final String KEY_DISABLE_EDITING = "visualization-request:skin:disable-editing"; + String KEY_DISABLE_EDITING = "visualization-request:skin:disable-editing"; /** * Defines whether nodes can be removed. */ - static final String KEY_NODE_NOT_REMOVABLE = "visualization-request:skin:node-not-removable"; - + String KEY_NODE_NOT_REMOVABLE = "visualization-request:skin:node-not-removable"; + /** * Defines whether connector prefers top-down layout. */ - static final String KEY_CONNECTOR_PREFER_TOP_DOWN = "visualization-request:connector:prefer-top-down"; - - public void setStyle(String style); - public String getStyle(); + String KEY_CONNECTOR_PREFER_TOP_DOWN = "visualization-request:connector:prefer-top-down"; + + void setStyle(String style); + + String getStyle(); } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectionsImpl.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractConnections.java similarity index 65% rename from VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectionsImpl.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractConnections.java index 1cb6e35a..dbdfeae5 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectionsImpl.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractConnections.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -31,22 +31,26 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of Michael Hoffer . */ -package eu.mihosoft.vrl.workflow; - +package eu.mihosoft.vrl.workflow.base; + +import eu.mihosoft.vrl.workflow.Connection; +import eu.mihosoft.vrl.workflow.Connections; +import eu.mihosoft.vrl.workflow.Connector; +import eu.mihosoft.vrl.workflow.VNode; +import eu.mihosoft.vrl.workflow.VisualizationRequest; +import eu.mihosoft.vrl.workflow.impl.DefaultVisualizationRequest; import javafx.beans.property.ObjectProperty; import javafx.beans.property.ReadOnlyProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; + +import static eu.mihosoft.vrl.workflow.util.ConnectionUtils.connectionId; /** * This class provides a default implementation of the {@code Connections} @@ -54,42 +58,33 @@ * * @author Michael Hoffer <info@michaelhoffer.de> */ -class ConnectionsImpl implements Connections { - - private String type; - private Map connections = new HashMap<>(); - private Class connectionClass = ConnectionBase.class; -// Map senders = new HashMap<>(); -// Map receivers = new HashMap<>(); - private ObservableList observableConnections - = FXCollections.observableArrayList(); - private ObjectProperty vReqProperty; - - // private ObjectProperty skinProperty = new SimpleObjectProperty<>(); - public ConnectionsImpl(String type) { - this.type = type; - } +public abstract class AbstractConnections implements Connections { + protected final String type; + protected final Map connections = new HashMap<>(); + protected final ObservableList observableConnections = FXCollections.observableArrayList(); - private static String connectionId(String id, String s, String r) { - return "id=" + id + ";[" + s + "]->[" + r + "]"; - } + protected ObjectProperty visualizationRequest; - private static String connectionId(Connection c) { - return connectionId(c.getId(), c.getSender().getId(), c.getReceiver().getId()); + public AbstractConnections(String type) { + this.type = type; } @Override public void add(Connection c) { - checkUniqueness(c); connections.put(connectionId(c), c); observableConnections.add(c); } + protected void checkUniqueness(Connection c) { + if (connections.containsKey(connectionId(c))) { + throw new IllegalStateException("Cannot add connection: a connection with equal id already added!"); + } + } + @Override public Connection add(Connector s, Connector r) { - // search id: String id = "0"; int count = 0; @@ -117,11 +112,7 @@ public Connection add(String id, Connector s, Connector r, VisualizationRequest @Override public void remove(Connection c) { connections.remove(connectionId(c)); - observableConnections.remove(c); - -// decSenderCounter(c.getSenderId()); -// decReceiverCounter(c.getReceiverId()); } @Override @@ -131,59 +122,24 @@ public Connection get(String id, Connector s, Connector r) { @Override public void remove(String id, Connector s, Connector r) { - observableConnections.remove(get(id, s, r)); - connections.remove(connectionId(id, s.getId(), r.getId())); - -// decSenderCounter(s); -// decReceiverCounter(r); - } - - @Override - public void setConnectionClass(Class cls) { - try { - Constructor constructor = cls.getConstructor(Connections.class, String.class, Connector.class, Connector.class, String.class); - - } catch (NoSuchMethodException | SecurityException ex) { - Logger.getLogger(ConnectionsImpl.class.getName()).log(Level.SEVERE, null, ex); - throw new IllegalArgumentException("constructor missing: (Connections, String, Connector, Connector, String)"); - } - - this.connectionClass = cls; - } - - @Override - public Class getConnectionClass() { - return connectionClass; } - private Connection createConnection(String id, Connector s, Connector r) { - + protected Connection createConnection(String id, Connector s, Connector r) { if (s == null) { throw new IllegalArgumentException("Sender must not be null."); } - + if (r == null) { throw new IllegalArgumentException("Receiver must not be null."); } - Connection result = null; - - try { - Constructor constructor = getConnectionClass().getConstructor(Connections.class, String.class, Connector.class, Connector.class, String.class); - try { - result = (Connection) constructor.newInstance(this, id, s, r, type); - } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { - Logger.getLogger(ConnectionsImpl.class.getName()).log(Level.SEVERE, null, ex); - } - } catch (NoSuchMethodException | SecurityException ex) { - Logger.getLogger(ConnectionsImpl.class.getName()).log(Level.SEVERE, null, ex); - } - - return result; + return instantiateConnection(id, s, r); } + protected abstract Connection instantiateConnection(String id, Connector sender, Connector receiver); + @Override public ObservableList getConnections() { return observableConnections; @@ -196,7 +152,7 @@ public Collection getAllWith(Connector c) { for (Connection conn : getConnections()) { if (conn.getSender().getId().equals(c.getId()) - || conn.getReceiver().getId().equals(c.getId())) { + || conn.getReceiver().getId().equals(c.getId())) { result.add(conn); } } @@ -206,7 +162,6 @@ public Collection getAllWith(Connector c) { @Override public Collection getAllWithNode(VNode n) { - Collection result = new ArrayList<>(); for (Connection conn : getConnections()) { @@ -219,23 +174,13 @@ public Collection getAllWithNode(VNode n) { return result; } - private void checkUniqueness(Connection c) { - - if (connections.containsKey(connectionId(c))) { - throw new IllegalStateException( - "Cannot add connection: a connection with equal id already added!"); - } - } - - @Override public Collection getAll(Connector s, Connector r) { - Collection result = new ArrayList<>(); for (Connection c : connections.values()) { if (c.getSender().getId().equals(s.getId()) - && c.getReceiver().getId().equals(r.getId())) { + && c.getReceiver().getId().equals(r.getId())) { result.add(c); } } @@ -245,12 +190,11 @@ public Collection getAll(Connector s, Connector r) { @Override public void removeAll(Connector s, Connector r) { - Collection delList = new ArrayList<>(); for (Connection c : connections.values()) { if (c.getSender().getId().equals(s.getId()) - && c.getReceiver().getId().equals(r.getId())) { + && c.getReceiver().getId().equals(r.getId())) { delList.add(c); } } @@ -260,34 +204,27 @@ public void removeAll(Connector s, Connector r) { } } - /** - * @return the vReq - */ @Override public VisualizationRequest getVisualizationRequest() { return visualizationRequestProperty().getValue(); } - /** - * @param vReq the vReq to set - */ @Override - public void setVisualizationRequest(VisualizationRequest vReq) { - _visualizationRequestProperty().set(vReq); + public void setVisualizationRequest(VisualizationRequest visualizationRequest) { + writableVisualizationRequestProperty().set(visualizationRequest); } - private ObjectProperty _visualizationRequestProperty() { - if (vReqProperty == null) { - vReqProperty = new SimpleObjectProperty<>(); - setVisualizationRequest(new VisualizationRequestImpl()); + protected ObjectProperty writableVisualizationRequestProperty() { + if (visualizationRequest == null) { + visualizationRequest = new SimpleObjectProperty<>(this, "visualizationRequest", new DefaultVisualizationRequest()); } - return vReqProperty; + return visualizationRequest; } @Override public ReadOnlyProperty visualizationRequestProperty() { - return _visualizationRequestProperty(); + return writableVisualizationRequestProperty(); } @Override @@ -321,9 +258,6 @@ public boolean contains(Connector s, Connector r) { return getAll(s, r).iterator().hasNext(); } - /** - * @return the type - */ @Override public String getType() { return type; @@ -331,7 +265,6 @@ public String getType() { @Override public String toString() { - StringBuilder result = new StringBuilder(); result.append("[ type: ").append(getType()).append('\n'); @@ -347,6 +280,6 @@ public String toString() { @Override public boolean isVisualizationRequestInitialized() { - return vReqProperty != null; + return visualizationRequest != null; } } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectorImpl.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractConnector.java similarity index 70% rename from VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectorImpl.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractConnector.java index 90e6cf1a..70b04689 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectorImpl.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractConnector.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -31,8 +31,17 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of Michael Hoffer . */ -package eu.mihosoft.vrl.workflow; - +package eu.mihosoft.vrl.workflow.base; + +import eu.mihosoft.vrl.workflow.ClickEvent; +import eu.mihosoft.vrl.workflow.ConnectionEvent; +import eu.mihosoft.vrl.workflow.Connector; +import eu.mihosoft.vrl.workflow.ConnectorValueObject; +import eu.mihosoft.vrl.workflow.MouseButton; +import eu.mihosoft.vrl.workflow.VNode; +import eu.mihosoft.vrl.workflow.ValueObject; +import eu.mihosoft.vrl.workflow.VisualizationRequest; +import eu.mihosoft.vrl.workflow.impl.DefaultVisualizationRequest; import javafx.beans.property.ObjectProperty; import javafx.beans.property.ReadOnlyProperty; import javafx.beans.property.SimpleObjectProperty; @@ -47,34 +56,34 @@ * * @author Michael Hoffer <info@michaelhoffer.de> */ -class ConnectorImpl implements Connector { - - private VNode node; - private String type; - private String localId; - private ObjectProperty vReqProperty; - private boolean input; - private boolean output; - private final ObjectProperty valueObjectProperty = - new SimpleObjectProperty<>(); - private transient List> connectionEventHandlers; - private transient List> clickEventHandlers; - - private final int maxNumberOfConnectionsDefault = Integer.MAX_VALUE; - private ObjectProperty maxNumberOfConnectionsProperty; - - public ConnectorImpl(VNode node, String type, String localId, boolean input) { +public abstract class AbstractConnector implements Connector { + protected static final int DEFAULT_MAX_NUMBER_OF_CONNECTIONS = Integer.MAX_VALUE; + + protected final VNode node; + protected final String type; + protected final boolean input; + + protected ObjectProperty visualizationRequest; + protected ObjectProperty maxNumberOfConnections; + protected final ObjectProperty valueObject = new SimpleObjectProperty<>(this, "valueObject"); + + protected String localId; + protected transient List> connectionEventHandlers; + protected transient List> clickEventHandlers; + + public AbstractConnector(VNode node, Connector connector) { + this(node, connector.getType(), connector.getLocalId(), connector.isInput()); + } + + public AbstractConnector(VNode node, String type, String localId, boolean input) { this.type = type; this.localId = localId; this.node = node; this.input = input; - this.output = !input; - setValueObject(new DefaultConnectorValueObject(this)); + setValueObject(instantiateConnectorValueObject()); } - public ConnectorImpl(VNode node, Connector c) { - this(node, c.getType(), c.getLocalId(), c.isInput()); - } + protected abstract ConnectorValueObject instantiateConnectorValueObject(); @Override public String getType() { @@ -114,21 +123,21 @@ public VisualizationRequest getVisualizationRequest() { */ @Override public void setVisualizationRequest(VisualizationRequest vReq) { - _visualizationRequestProperty().set(vReq); + writableVisualizationRequestProperty().set(vReq); } - private ObjectProperty _visualizationRequestProperty() { - if (vReqProperty == null) { - vReqProperty = new SimpleObjectProperty<>(); - setVisualizationRequest(new VisualizationRequestImpl()); + protected ObjectProperty writableVisualizationRequestProperty() { + if (visualizationRequest == null) { + visualizationRequest = new SimpleObjectProperty<>(this, "visualizationRequest"); + setVisualizationRequest(new DefaultVisualizationRequest()); } - return vReqProperty; + return visualizationRequest; } @Override public ReadOnlyProperty visualizationRequestProperty() { - return _visualizationRequestProperty(); + return writableVisualizationRequestProperty(); } /** @@ -144,7 +153,7 @@ public boolean isInput() { */ @Override public boolean isOutput() { - return output; + return !input; } @Override @@ -159,10 +168,10 @@ public ValueObject getValueObject() { @Override public ObjectProperty valueObjectProperty() { - return this.valueObjectProperty; + return this.valueObject; } - private List> getEventHandlers() { + protected List> getEventHandlers() { if (this.getConnectionEventHandlers() == null) { this.connectionEventHandlers = new ArrayList<>(); } @@ -186,9 +195,6 @@ public void removeConnectionEventListener(EventHandler handler) } } - /** - * @return the connectionEventHandlers - */ public List> getConnectionEventHandlers() { return connectionEventHandlers; } @@ -221,7 +227,6 @@ public List> getClickEventHandlers() { @Override public void click(MouseButton btn, Object event) { - if (clickEventHandlers == null) { return; } @@ -235,7 +240,7 @@ public void click(MouseButton btn, Object event) { @Override public boolean isVisualizationRequestInitialized() { - return vReqProperty != null; + return visualizationRequest != null; } @Override @@ -245,8 +250,8 @@ public void setMaxNumberOfConnections(int numConnections) { @Override public int getMaxNumberOfConnections() { - if (maxNumberOfConnectionsProperty==null) { - return maxNumberOfConnectionsDefault; + if (maxNumberOfConnections == null) { + return DEFAULT_MAX_NUMBER_OF_CONNECTIONS; } else { return maxNumberOfConnectionsProperty().get(); } @@ -254,11 +259,10 @@ public int getMaxNumberOfConnections() { @Override public ObjectProperty maxNumberOfConnectionsProperty() { - if (maxNumberOfConnectionsProperty == null) { - maxNumberOfConnectionsProperty = new SimpleObjectProperty<>( - maxNumberOfConnectionsDefault); + if (maxNumberOfConnections == null) { + maxNumberOfConnections = new SimpleObjectProperty<>(this, "maxNumberOfConnections", DEFAULT_MAX_NUMBER_OF_CONNECTIONS); } - - return maxNumberOfConnectionsProperty; + + return maxNumberOfConnections; } } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractConnectorValueObject.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractConnectorValueObject.java new file mode 100644 index 00000000..8c3fa22c --- /dev/null +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractConnectorValueObject.java @@ -0,0 +1,101 @@ +/* + * Copyright 2012-2017 Michael Hoffer . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Please cite the following publication(s): + * + * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - + * A Framework for Declarative GUI Programming on the Java Platform. + * Computing and Visualization in Science, 2011, in press. + * + * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of Michael Hoffer . + */ +package eu.mihosoft.vrl.workflow.base; + +import eu.mihosoft.vrl.workflow.Connector; +import eu.mihosoft.vrl.workflow.ConnectorValueObject; +import eu.mihosoft.vrl.workflow.VNode; +import eu.mihosoft.vrl.workflow.VisualizationRequest; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; + +/** + * This class defines a default connector value object. ValueObjects are used to + * store data in connectors. It is a placeholder for a value object as it's + * get/setValue methods are not implemented. + * + * @author Michael Hoffer <info@michaelhoffer.de> + */ +public abstract class AbstractConnectorValueObject implements ConnectorValueObject { + protected final ObjectProperty value = new SimpleObjectProperty<>(this, "value"); + protected final Connector connector; + + protected VNode parent; + protected VisualizationRequest visualizationRequest; + + public AbstractConnectorValueObject(Connector connector) { + this.connector = connector; + this.parent = connector.getNode(); + } + + @Override + public VNode getParent() { + return parent; + } + + @Override + public Connector getConnector() { + return connector; + } + + @Override + public Object getValue() { + return value.get(); + } + + @Override + public void setValue(Object value) { + this.value.set(value); + } + + @Override + public ObjectProperty valueProperty() { + return this.value; + } + + @Override + public VisualizationRequest getVisualizationRequest() { + return visualizationRequest; + } + + @Override + public void setVisualizationRequest(VisualizationRequest vReq) { + this.visualizationRequest = vReq; + } + + @Override + public void setParent(VNode parent) { + this.parent = parent; + } +} diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/FlowModelImpl.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractFlowModel.java similarity index 63% rename from VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/FlowModelImpl.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractFlowModel.java index 85f1182c..81c1d955 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/FlowModelImpl.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractFlowModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -31,8 +31,21 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of Michael Hoffer . */ -package eu.mihosoft.vrl.workflow; - +package eu.mihosoft.vrl.workflow.base; + +import eu.mihosoft.vrl.workflow.CompatibilityResult; +import eu.mihosoft.vrl.workflow.Connection; +import eu.mihosoft.vrl.workflow.ConnectionResult; +import eu.mihosoft.vrl.workflow.Connections; +import eu.mihosoft.vrl.workflow.Connector; +import eu.mihosoft.vrl.workflow.FlowModel; +import eu.mihosoft.vrl.workflow.IdGenerator; +import eu.mihosoft.vrl.workflow.NodeLookup; +import eu.mihosoft.vrl.workflow.VNode; +import eu.mihosoft.vrl.workflow.ValueObject; +import eu.mihosoft.vrl.workflow.VisualizationRequest; +import eu.mihosoft.vrl.workflow.impl.NoDefaultConnectorValueObject; +import eu.mihosoft.vrl.workflow.util.VConnections; import javafx.beans.property.BooleanProperty; import javafx.beans.property.ReadOnlyProperty; import javafx.beans.property.SimpleBooleanProperty; @@ -40,14 +53,9 @@ import javafx.collections.ObservableList; import javafx.collections.ObservableMap; -import java.lang.reflect.Constructor; import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; -import java.util.List; import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; /** * This class implements the flow model. The flow model manages the connections @@ -55,21 +63,16 @@ * * @author Michael Hoffer <info@michaelhoffer.de> */ -public class FlowModelImpl implements FlowModel { - - private final ObservableMap connections - = FXCollections.observableHashMap(); - private final ObservableMap readOnlyObservableConnections - = FXCollections.unmodifiableObservableMap(connections); - private final ObservableList observableNodes - = FXCollections.observableArrayList(); - private final ObservableList readOnlyObservableNodes - = FXCollections.unmodifiableObservableList(observableNodes); - private final Map nodes = new HashMap<>(); - private Class flowNodeClass = VNodeImpl.class; - private final BooleanProperty visibleProperty = new SimpleBooleanProperty(); - private IdGenerator idGenerator; - private NodeLookup nodeLookup; +public abstract class AbstractFlowModel implements FlowModel { + protected final ObservableMap connections = FXCollections.observableHashMap(); + protected final ObservableMap readOnlyObservableConnections = FXCollections.unmodifiableObservableMap(connections); + protected final ObservableList observableNodes = FXCollections.observableArrayList(); + protected final ObservableList readOnlyObservableNodes = FXCollections.unmodifiableObservableList(observableNodes); + protected final Map nodes = new HashMap<>(); + protected final BooleanProperty visibleProperty = new SimpleBooleanProperty(this, "visible"); + + protected IdGenerator idGenerator; + protected NodeLookup nodeLookup; @Override public BooleanProperty visibleProperty() { @@ -86,19 +89,8 @@ public boolean isVisible() { return visibleProperty.get(); } - // TODO duplicated code - private static String connectionId(String id, String s, String r) { - return "id=" + id + ";[" + s + "]->[" + r + "]"; - } - - // TODO duplicated code - private static String connectionId(Connection c) { - return connectionId(c.getId(), c.getSender().getId(), c.getReceiver().getId()); - } - @Override public ConnectionResult tryConnect(VNode s, VNode r, String type) { - ValueObject senderValObj = new NoDefaultConnectorValueObject(s); ValueObject receiverValObj = new NoDefaultConnectorValueObject(r); @@ -110,15 +102,11 @@ public ConnectionResult tryConnect(VNode s, VNode r, String type) { receiverValObj = r.getMainInput(type).getValueObject(); } - CompatibilityResult result = receiverValObj. - compatible(senderValObj, type); - - return new ConnectionResultImpl(result, null); + return instantiateConnectionResult(receiverValObj.compatible(senderValObj, type), null); } @Override public ConnectionResult connect(VNode s, VNode r, String type) { - ConnectionResult result = tryConnect(s, r, type); if (!result.getStatus().isCompatible()) { @@ -136,36 +124,28 @@ public ConnectionResult connect(VNode s, VNode r, String type) { receiver = r.getMainInput(type); } -// System.out.println("ADD: " + sender + ", " + receiver); - Connection connection = getConnections(type).add(sender, receiver); - - - - return new ConnectionResultImpl(result.getStatus(), connection); + return instantiateConnectionResult(result.getStatus(), getConnections(type).add(sender, receiver)); } @Override public ConnectionResult tryConnect(Connector s, Connector r) { - CompatibilityResult result = r.getValueObject(). - compatible(s.getValueObject(), s.getType()); - - return new ConnectionResultImpl(result, null); + CompatibilityResult result = r.getValueObject().compatible(s.getValueObject(), s.getType()); + return instantiateConnectionResult(result, null); } @Override public ConnectionResult connect(Connector s, Connector r) { - ConnectionResult result = tryConnect(s, r); if (!result.getStatus().isCompatible()) { return result; } - Connection connection = getConnections(s.getType()).add(s, r); - - return new ConnectionResultImpl(result.getStatus(), connection); + return instantiateConnectionResult(result.getStatus(), getConnections(s.getType()).add(s, r)); } + protected abstract ConnectionResult instantiateConnectionResult(CompatibilityResult compatibilityResult, Connection connection); + @Override public ObservableList getNodes() { return readOnlyObservableNodes; @@ -173,31 +153,19 @@ public ObservableList getNodes() { @Override public void clear() { - List delList = new ArrayList<>(observableNodes); - - for (VNode n : delList) { + for (VNode n : new ArrayList<>(observableNodes)) { remove(n); } } @Override public VNode remove(VNode n) { - -// if (n instanceof FlowModel) { -// ((FlowModel)n).clear(); -// } VNode result = nodes.remove(n.getId()); observableNodes.remove(n); -// removeNodeSkin(n); for (Connections cns : getAllConnections().values()) { - - Collection connectionsToRemove - = cns.getAllWithNode(n); - - for (Connection c : connectionsToRemove) { + for (Connection c : cns.getAllWithNode(n)) { cns.remove(c); -// removeConnectionSkin(c); } } @@ -233,38 +201,21 @@ public VNode getReceiver(Connection c) { } @Override - public void setFlowNodeClass(Class cls) { - try { - Constructor constructor = cls.getConstructor(FlowModel.class); - throw new IllegalArgumentException("constructor missing: (String, String)"); - } catch (NoSuchMethodException | SecurityException ex) { - Logger.getLogger(ConnectionsImpl.class.getName()).log(Level.SEVERE, null, ex); - } - - this.flowNodeClass = cls; - } - - @Override - public Class getFlowNodeClass() { - return flowNodeClass; - } - - VNode newNode(VNode result, ValueObject obj, String parentId) { - - result.setValueObject(obj); + public VNode registerNode(VNode node, ValueObject obj, String parentId) { + node.setValueObject(obj); if (getIdGenerator() == null) { throw new IllegalStateException("Please define an idgenerator before creating nodes!"); } - String id = getIdGenerator().newId(parentId+":"); - - result.setId(id); + String id = getIdGenerator().newId(parentId + ":"); - nodes.put(id, result); - observableNodes.add(result); + node.setId(id); + nodes.put(id, node); + // should check if node is not inside observableNodes? + observableNodes.add(node); - return result; + return node; } @Override @@ -274,41 +225,29 @@ public void addConnections(Connections connections, String flowType) { @Override public VisualizationRequest getVisualizationRequest() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + throw new UnsupportedOperationException("Not supported yet."); } @Override public void setVisualizationRequest(VisualizationRequest vReq) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + throw new UnsupportedOperationException("Not supported yet."); } - /** - * @return the idGenerator - */ @Override public IdGenerator getIdGenerator() { return idGenerator; } - /** - * @param idGenerator the idGenerator to set - */ @Override public void setIdGenerator(IdGenerator idGenerator) { this.idGenerator = idGenerator; } - /** - * @return the nodeLookup - */ @Override public NodeLookup getNodeLookup() { return nodeLookup; } - /** - * @param nodeLookup the nodeLookup to set - */ @Override public void setNodeLookup(NodeLookup nodeLookup) { this.nodeLookup = nodeLookup; diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VFlowImpl.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractVFlow.java similarity index 58% rename from VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VFlowImpl.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractVFlow.java index deafddad..c432dc76 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VFlowImpl.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractVFlow.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -31,18 +31,31 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of Michael Hoffer . */ -package eu.mihosoft.vrl.workflow; - +package eu.mihosoft.vrl.workflow.base; + +import eu.mihosoft.vrl.workflow.Connection; +import eu.mihosoft.vrl.workflow.ConnectionEvent; +import eu.mihosoft.vrl.workflow.ConnectionResult; +import eu.mihosoft.vrl.workflow.Connections; +import eu.mihosoft.vrl.workflow.Connector; +import eu.mihosoft.vrl.workflow.FlowModel; +import eu.mihosoft.vrl.workflow.IdGenerator; +import eu.mihosoft.vrl.workflow.NodeLookup; +import eu.mihosoft.vrl.workflow.ThruConnector; +import eu.mihosoft.vrl.workflow.VFlow; +import eu.mihosoft.vrl.workflow.VFlowModel; +import eu.mihosoft.vrl.workflow.VNode; +import eu.mihosoft.vrl.workflow.ValueObject; import eu.mihosoft.vrl.workflow.skin.ConnectionSkin; import eu.mihosoft.vrl.workflow.skin.FlowNodeSkinLookup; import eu.mihosoft.vrl.workflow.skin.SkinFactory; import eu.mihosoft.vrl.workflow.skin.VNodeSkin; +import eu.mihosoft.vrl.workflow.util.VConnections; import javafx.beans.property.BooleanProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.ReadOnlyObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.collections.ListChangeListener; import javafx.collections.MapChangeListener; @@ -61,29 +74,35 @@ import java.util.logging.Level; import java.util.logging.Logger; +import static eu.mihosoft.vrl.workflow.util.ConnectionUtils.connectionId; + /** * An implementation of the {@code VFlow} interface. This class manages the * workflow * * @author Michael Hoffer <info@michaelhoffer.de> */ -class VFlowImpl implements VFlow { - - final ObjectProperty modelProperty = new SimpleObjectProperty<>(); - private ListChangeListener nodesListener; - private ListChangeListener connectionsListener; - private final ObservableList> skinFactories = FXCollections.observableArrayList(); - private final Map> nodeSkins = new WeakHashMap<>(); - private final Map> connectionSkins = new WeakHashMap<>(); - private final ObservableMap subControllers = FXCollections.observableHashMap(); - private ChangeListener visibilityListener; - private IdGenerator idGenerator; - private NodeLookup nodeLookup; - private FlowNodeSkinLookup nodeSkinLookup; - private final ObjectProperty parentProperty = new SimpleObjectProperty<>(); - - public VFlowImpl(VFlow parent, VFlowModel model, SkinFactory... skinFactories) { +public abstract class AbstractVFlow implements VFlow { + protected final ObjectProperty model = new SimpleObjectProperty<>(); + protected final ObjectProperty parent = new SimpleObjectProperty<>(this, "parent"); + + protected final Map> nodeSkins = new WeakHashMap<>(); + protected final Map> connectionSkins = new WeakHashMap<>(); + protected final ObservableMap subControllers = FXCollections.observableHashMap(); + protected final ObservableList> skinFactories = FXCollections.observableArrayList(); + protected ChangeListener visibilityListener; + protected IdGenerator idGenerator; + protected ListChangeListener nodesListener; + protected ListChangeListener connectionsListener; + protected NodeLookup nodeLookup; + protected FlowNodeSkinLookup nodeSkinLookup; + + public AbstractVFlow(VFlowModel model, SkinFactory... skinFactories) { + this(null, model, skinFactories); + } + + public AbstractVFlow(VFlow parent, VFlowModel model, SkinFactory... skinFactories) { init(); if (model.getIdGenerator() != null) { @@ -94,25 +113,45 @@ public VFlowImpl(VFlow parent, VFlowModel model, SkinFactory> skinFactories) { + this(null, model, skinFactories); + } + + public AbstractVFlow(VFlow parent, VFlowModel model, Collection> skinFactories) { + init(); + + if (model.getIdGenerator() != null) { + setIdGenerator(model.getIdGenerator()); + } + + if (model.getNodeLookup() != null) { + setNodeLookup(model.getNodeLookup()); + } + + this.parent.set(parent); + setModel(model); + setSkinFactories(skinFactories); } @Override public ReadOnlyObjectProperty parentProperty() { - return parentProperty; + return parent; } @Override public VFlow getParent() { - return parentProperty().get(); + return parent.get(); } @Override public VFlow getRootFlow() { VFlow root = this; - VFlow parent = this.getParent(); + VFlow parent = getParent(); while (parent != null) { root = parent; @@ -122,275 +161,254 @@ public VFlow getRootFlow() { return root; } - public VFlowImpl(VFlow parent, VFlowModel model, Collection> skinFactories) { - init(); + protected void init() { + setIdGenerator(instantiateIdGenerator()); + setNodeSkinLookup(instantiateSkinLookup()); - if (model.getIdGenerator() != null) { - setIdGenerator(model.getIdGenerator()); - } + nodesListener = createsNodeListener(); + connectionsListener = createConnectionsListener(); + visibilityListener = createVisibilityListener(); + model.addListener(createModelListener()); + } - if (model.getNodeLookup() != null) { - setNodeLookup(model.getNodeLookup()); - } + protected abstract IdGenerator instantiateIdGenerator(); - setModel(model); - setSkinFactories(skinFactories); + protected abstract FlowNodeSkinLookup instantiateSkinLookup(); - } + protected ChangeListener createModelListener() { + return (value, oldValue, newValue) -> { + // removeUIFromAllSkinFactories(); + Collection> tmpFactories = new ArrayList<>(); + tmpFactories.addAll(getSkinFactories()); + removeSkinFactories(getSkinFactories()); + setSkinFactories(tmpFactories); - private void init() { + if (oldValue != null) { - setIdGenerator(new IdGeneratorImpl()); - setNodeSkinLookup(new FlowNodeSkinLookupImpl(this)); + if (nodesListener != null) { + oldValue.getNodes().removeListener(nodesListener); + } - nodesListener = new ListChangeListener() { - @Override - public void onChanged(ListChangeListener.Change change) { - while (change.next()) { - if (change.wasPermutated()) { - for (int i = change.getFrom(); i < change.getTo(); ++i) { - //permutate - String action = "permutate"; // TODO: implement - } - } else if (change.wasUpdated()) { - //update item - String action = "update"; // TODO: implement - } else if (change.wasRemoved()) { - // removed - for (VNode n : change.getRemoved()) { -// if (nodeSkins.containsKey(n.getId())) { - if (!getNodeSkinsById(n.getId()).isEmpty()) { - - removeNodeSkinFromAllSkinFactories(n); - - for (Connector connector : n.getConnectors()) { - -// System.out.println("conn: " + connector); - Collection connections - = getConnections(connector.getType()). - getAllWith(connector); - - for (Connection connection : connections) { - VFlowImpl.this.getConnections(connector.getType()). - remove(connection); - } - } + if (connectionsListener != null) { + for (Connections conn : oldValue.getAllConnections().values()) { + System.out.println("listener for conn-type removed: " + conn.getType()); + conn.getConnections().removeListener(connectionsListener); + } + } -// System.out.println("remove node: " + n.getId()); - } + if (visibilityListener != null) { + oldValue.visibleProperty().removeListener(visibilityListener); + } + } - if (n instanceof FlowModel) { - subControllers.remove(n.getId()); - } + if (newValue != null) { + _updateIdGenerator(); + _updateNodeLookup(); + + if (nodesListener != null) { + newValue.getNodes().addListener(nodesListener); + } + for (Connections conn : newValue.getAllConnections().values()) { + conn.getConnections().addListener(connectionsListener); + } + + newValue.getAllConnections().addListener(new MapChangeListener() { + @Override + public void onChanged(Change change) { + if (change.wasAdded()) { + change.getValueAdded().getConnections().addListener(connectionsListener); } - } else if (change.wasAdded()) { - // added - for (VNode n : change.getAddedSubList()) { -// if (!nodeSkins.containsKey(n.getId())) { - if (getNodeSkinsById(n.getId()).isEmpty()) { - createNodeSkins(n, skinFactories); -// System.out.println("add node: " + n.getId() + ", title: " + n.getTitle()); - } else { - String action = "handle error"; // TODO: implement -// System.out.println("can't add node: " + n.getId() + ", title: " + n.getTitle()); - } + + if (change.wasRemoved()) { + change.getValueRemoved().getConnections().removeListener(connectionsListener); } } + }); - } // end while change.next() + getModel().visibleProperty().addListener(visibilityListener); } }; + } - connectionsListener = new ListChangeListener() { - @Override - public void onChanged(ListChangeListener.Change change) { - - while (change.next()) { - if (change.wasPermutated()) { - for (int i = change.getFrom(); i < change.getTo(); ++i) { - //permutate - String action = "permutate"; // TODO: implement - } - } else if (change.wasUpdated()) { - //update item - String action = "update"; // TODO: implement - } else if (change.wasRemoved()) { - // removed - for (Connection c : change.getRemoved()) { - - // fire events - // 07.09.2013 - // TODO add connector references to connections - // reason: lookup is too expensive -// Connector s = getNodeLookup().getConnectorById(c.getSenderId()); -// Connector r = getNodeLookup().getConnectorById(c.getReceiverId()); - Connector s = c.getSender(); - Connector r = c.getReceiver(); - - ConnectionEvent evt = new ConnectionEvent(ConnectionEvent.REMOVE, s, r, c); - - if (s != null) { - - Collection> eventHandlersS - = ((ConnectorImpl) s).getConnectionEventHandlers(); - - if (eventHandlersS != null) { - for (EventHandler evtHandler : eventHandlersS) { - try { - evtHandler.handle(evt); - } catch (Throwable tr) { - Logger.getLogger(VFlowImpl.class.getName()).log(Level.SEVERE, null, tr); - } - } - } - } - - if (r != null) { - - Collection> eventHandlersR - = ((ConnectorImpl) r).getConnectionEventHandlers(); + protected ChangeListener createVisibilityListener() { + return (value, oldValue, newValue) -> { + if (newValue) { + setSkinFactories(getSkinFactories()); + } else { + removeUIFromAllSkinFactories(); + } + }; + } - if (eventHandlersR != null) { - for (EventHandler evtHandler : eventHandlersR) { - try { - evtHandler.handle(evt); - } catch (Throwable tr) { - Logger.getLogger(VFlowImpl.class.getName()).log(Level.SEVERE, null, tr); - } - } - } - } + protected ListChangeListener createConnectionsListener() { + return change -> { + while (change.next()) { + if (change.wasPermutated()) { + for (int i = change.getFrom(); i < change.getTo(); ++i) { + //permutate + String action = "permutate"; // TODO: implement + } + } else if (change.wasUpdated()) { + //update item + String action = "update"; // TODO: implement + } else if (change.wasRemoved()) { + // removed + for (Connection c : change.getRemoved()) { - // fire events - // remove skins for each connection - // that have been removed - removeConnectionSkinFromAllSkinFactories(c); -// System.out.println("remove skin: " + c); - } - } else if (change.wasAdded()) { - // added - for (Connection c : change.getAddedSubList()) { + // fire events + // 07.09.2013 + // TODO add connector references to connections + // reason: lookup is too expensive + // Connector s = getNodeLookup().getConnectorById(c.getSenderId()); + // Connector r = getNodeLookup().getConnectorById(c.getReceiverId()); + Connector s = c.getSender(); + Connector r = c.getReceiver(); - // fire events - // 07.09.2013 - // TODO add connector references to connections - // reason: lookup is too expensive -// Connector s = getNodeLookup().getConnectorById(c.getSenderId()); -// Connector r = getNodeLookup().getConnectorById(c.getReceiverId()); - Connector s = c.getSender(); - Connector r = c.getReceiver(); + ConnectionEvent evt = new ConnectionEvent(ConnectionEvent.REMOVE, s, r, c); - ConnectionEvent evt = new ConnectionEvent(ConnectionEvent.ADD, s, r, c); + if (s != null) { - Collection> eventHandlersS - = ((ConnectorImpl) s).getConnectionEventHandlers(); + Collection> eventHandlersS = s.getConnectionEventHandlers(); if (eventHandlersS != null) { for (EventHandler evtHandler : eventHandlersS) { try { evtHandler.handle(evt); } catch (Throwable tr) { - Logger.getLogger(VFlowImpl.class.getName()).log(Level.SEVERE, null, tr); + Logger.getLogger(AbstractVFlow.class.getName()).log(Level.SEVERE, null, tr); } } } + } - Collection> eventHandlersR - = ((ConnectorImpl) r).getConnectionEventHandlers(); + if (r != null) { + + Collection> eventHandlersR = r.getConnectionEventHandlers(); if (eventHandlersR != null) { for (EventHandler evtHandler : eventHandlersR) { try { evtHandler.handle(evt); } catch (Throwable tr) { - Logger.getLogger(VFlowImpl.class.getName()).log(Level.SEVERE, null, tr); + Logger.getLogger(AbstractVFlow.class.getName()).log(Level.SEVERE, null, tr); } } } - - // fire events - // create skins for added connections - createConnectionSkins(c, c.getType(), getSkinFactories()); -// System.out.println("add skin: " + c); } + + // fire events + // remove skins for each connection + // that have been removed + removeConnectionSkinFromAllSkinFactories(c); + // System.out.println("remove skin: " + c); } - } + } else if (change.wasAdded()) { + // added + for (Connection c : change.getAddedSubList()) { + + // fire events + // 07.09.2013 + // TODO add connector references to connections + // reason: lookup is too expensive + // Connector s = getNodeLookup().getConnectorById(c.getSenderId()); + // Connector r = getNodeLookup().getConnectorById(c.getReceiverId()); + Connector s = c.getSender(); + Connector r = c.getReceiver(); + + ConnectionEvent evt = new ConnectionEvent(ConnectionEvent.ADD, s, r, c); + + Collection> eventHandlersS = s.getConnectionEventHandlers(); + + if (eventHandlersS != null) { + for (EventHandler evtHandler : eventHandlersS) { + try { + evtHandler.handle(evt); + } catch (Throwable tr) { + Logger.getLogger(AbstractVFlow.class.getName()).log(Level.SEVERE, null, tr); + } + } + } - } - }; + Collection> eventHandlersR = r.getConnectionEventHandlers(); - visibilityListener = new ChangeListener() { - @Override - public void changed(ObservableValue ov, Boolean t, Boolean t1) { + if (eventHandlersR != null) { + for (EventHandler evtHandler : eventHandlersR) { + try { + evtHandler.handle(evt); + } catch (Throwable tr) { + Logger.getLogger(AbstractVFlow.class.getName()).log(Level.SEVERE, null, tr); + } + } + } -// System.out.println("visible: " + t1 + " : " + getModel().isVisible() + " : " + getModel().getId()); - if (t1) { - setSkinFactories(getSkinFactories()); - } else { - removeUIFromAllSkinFactories(); + // fire events + // create skins for added connections + createConnectionSkins(c, c.getType(), getSkinFactories()); + // System.out.println("add skin: " + c); + } } } - }; - - modelProperty.addListener(new ChangeListener() { - @Override - public void changed(ObservableValue ov, FlowModel t, FlowModel t1) { - -// removeUIFromAllSkinFactories(); - Collection> tmpFactories = new ArrayList<>(); - tmpFactories.addAll(getSkinFactories()); - removeSkinFactories(getSkinFactories()); - setSkinFactories(tmpFactories); - if (t != null) { + }; + } - if (nodesListener != null) { - t.getNodes().removeListener(nodesListener); + protected ListChangeListener createsNodeListener() { + return change -> { + while (change.next()) { + if (change.wasPermutated()) { + for (int i = change.getFrom(); i < change.getTo(); ++i) { + //permutate + String action = "permutate"; // TODO: implement } + } else if (change.wasUpdated()) { + //update item + String action = "update"; // TODO: implement + } else if (change.wasRemoved()) { + // removed + for (VNode n : change.getRemoved()) { + // if (nodeSkins.containsKey(n.getId())) { + if (!getNodeSkinsById(n.getId()).isEmpty()) { + + removeNodeSkinFromAllSkinFactories(n); + + for (Connector connector : n.getConnectors()) { + + // System.out.println("conn: " + connector); + Collection connections + = getConnections(connector.getType()). + getAllWith(connector); + + for (Connection connection : connections) { + AbstractVFlow.this.getConnections(connector.getType()). + remove(connection); + } + } - if (connectionsListener != null) { - for (Connections conn : t.getAllConnections().values()) { - System.out.println("listener for conn-type removed: " + conn.getType()); - conn.getConnections().removeListener(connectionsListener); + // System.out.println("remove node: " + n.getId()); } - } - if (visibilityListener != null) { - t.visibleProperty().removeListener(visibilityListener); - } - } - - if (t1 != null) { - - _updateIdGenerator(); - _updateNodeLookup(); - - if (nodesListener != null) { - t1.getNodes().addListener(nodesListener); - } + if (n instanceof FlowModel) { + subControllers.remove(n.getId()); + } - for (Connections conn : t1.getAllConnections().values()) { - conn.getConnections().addListener(connectionsListener); } - - t1.getAllConnections().addListener(new MapChangeListener() { - @Override - public void onChanged(MapChangeListener.Change change) { - if (change.wasAdded()) { - change.getValueAdded().getConnections().addListener(connectionsListener); - } - - if (change.wasRemoved()) { - change.getValueRemoved().getConnections().removeListener(connectionsListener); - } + } else if (change.wasAdded()) { + // added + for (VNode n : change.getAddedSubList()) { + // if (!nodeSkins.containsKey(n.getId())) { + if (getNodeSkinsById(n.getId()).isEmpty()) { + createNodeSkins(n, skinFactories); + // System.out.println("add node: " + n.getId() + ", title: " + n.getTitle()); + } else { + String action = "handle error"; // TODO: implement + // System.out.println("can't add node: " + n.getId() + ", title: " + n.getTitle()); } - }); - - getModel().visibleProperty().addListener(visibilityListener); + } } - } - }); + + } // end while change.next() + }; } private void _updateIdGenerator() { @@ -399,21 +417,13 @@ private void _updateIdGenerator() { private void _updateNodeLookup() { if (nodeLookup == null) { - setNodeLookup(new NodeLookupImpl(getModel())); + setNodeLookup(instantiateNodeLookup(getModel())); } getModel().setNodeLookup(getNodeLookup()); } - // TODO duplicated code - public static String connectionId(String id, String s, String r) { - return "id=" + id + ";[" + s + "]->[" + r + "]"; - } - - // TODO duplicated code - public static String connectionId(Connection c) { - return connectionId(c.getId(), c.getSender().getId(), c.getReceiver().getId()); - } + protected abstract NodeLookup instantiateNodeLookup(VFlowModel model); @Override public ConnectionResult tryConnect(Connector s, Connector r) { @@ -495,19 +505,8 @@ public VNode getReceiver(Connection c) { return getModel().getReceiver(c); } - @Override - public void setFlowNodeClass(Class cls) { - getModel().setFlowNodeClass(cls); - } - - @Override - public Class getFlowNodeClass() { - return getModel().getFlowNodeClass(); - } - @Override public VNode newNode(ValueObject obj) { - return getModel().newNode(obj); } @@ -516,20 +515,19 @@ public VNode newNode() { return getModel().newNode(); } - private List> createNodeSkins(VNode n, List> skinFactories) { + protected List> createNodeSkins(VNode n, List> skinFactories) { return createNodeSkins(n, skinFactories.toArray(new SkinFactory[skinFactories.size()])); } - private List> createNodeSkins(VNode n, SkinFactory... skinFactories) { - + protected List> createNodeSkins(VNode n, SkinFactory... skinFactories) { if (getModel() != null && !getModel().isVisible()) { return null; } -// System.out.println(">> creating skins for node: " + n.getId()); + // System.out.println(">> creating skins for node: " + n.getId()); List> skins = new ArrayList<>(); -// System.out.println(" --> #skinFactories: " + skinFactories.length); + // System.out.println(" --> #skinFactories: " + skinFactories.length); for (SkinFactory skinFactory : skinFactories) { if (skinFactory == null) { @@ -537,34 +535,33 @@ private List> createNodeSkins(VNode n, SkinFactory adding to skinfsctory: " + skinFactory); + // System.out.println(" --> adding to skinfsctory: " + skinFactory); VNodeSkin skin = skinFactory.createSkin(n, this); -// nodeSkins.put(n.getId(), skin); + // nodeSkins.put(n.getId(), skin); putNodeSkin(skinFactory, skin); skin.add(); skins.add(skin); - } return skins; } - private void putNodeSkin(SkinFactory skinFactory, VNodeSkin skin) { + protected void putNodeSkin(SkinFactory skinFactory, VNodeSkin skin) { Map nodeSkinMap = getNodeSkinMap(skinFactory); -// System.out.println("put skin " + skin + "for: " + skin.getModel().getId() + ", factory: " + skinFactory); + // System.out.println("put skin " + skin + "for: " + skin.getModel().getId() + ", factory: " + skinFactory); nodeSkinMap.put(skin.getModel().getId(), skin); } - private VNodeSkin getNodeSkin(SkinFactory skinFactory, String id) { + protected VNodeSkin getNodeSkin(SkinFactory skinFactory, String id) { Map nodeSkinMap = getNodeSkinMap(skinFactory); VNodeSkin nodeSkin = nodeSkinMap.get(id); -// System.out.println("skin for " + id + " = " + nodeSkin + ", factory: " + skinFactory + ", controller: " + getModel().getId()); + // System.out.println("skin for " + id + " = " + nodeSkin + ", factory: " + skinFactory + ", controller: " + getModel().getId()); return nodeSkin; } @@ -578,7 +575,7 @@ public List getAllNodeSkins() { return result; } - private VNodeSkin removeNodeSkinFromFactory(SkinFactory skinFactory, String id) { + protected VNodeSkin removeNodeSkinFromFactory(SkinFactory skinFactory, String id) { Map nodeSkinMap = getNodeSkinMap(skinFactory); VNodeSkin skin = nodeSkinMap.remove(id); @@ -611,7 +608,7 @@ private VNodeSkin removeNodeSkinFromFactory(SkinFactory skinFactory, Stri return skin; } - private void putConnectionSkin(SkinFactory skinFactory, ConnectionSkin skin) { + protected void putConnectionSkin(SkinFactory skinFactory, ConnectionSkin skin) { Map connectionSkinMap = getConnectionSkinMap(skinFactory); connectionSkinMap.put(connectionId(skin.getModel()), skin); @@ -627,7 +624,7 @@ public List getAllConnectionSkins() { return result; } - private ConnectionSkin removeConnectionSkinFromFactory(SkinFactory skinFactory, Connection c) { + protected ConnectionSkin removeConnectionSkinFromFactory(SkinFactory skinFactory, Connection c) { Map connectionSkinsMap = getConnectionSkinMap(skinFactory); ConnectionSkin skin = connectionSkinsMap.remove(connectionId(c)); @@ -639,8 +636,7 @@ private ConnectionSkin removeConnectionSkinFromFactory(SkinFactory s return skin; } - private List createConnectionSkins(Connection c, String type, List> skinFactories) { - + protected List createConnectionSkins(Connection c, String type, List> skinFactories) { SkinFactory[] skinFactoryArray = new SkinFactory[skinFactories.size()]; for (int i = 0; i < skinFactories.size(); i++) { @@ -650,8 +646,7 @@ private List createConnectionSkins(Connection c, String type, Li return createConnectionSkins(c, type, skinFactoryArray); } - private List createConnectionSkins(Connection c, String type, SkinFactory... skinFactories) { - + protected List createConnectionSkins(Connection c, String type, SkinFactory... skinFactories) { List skins = new ArrayList<>(); if (getModel() != null && !getModel().isVisible()) { @@ -666,7 +661,7 @@ private List createConnectionSkins(Connection c, String type, Sk ConnectionSkin skin = skinFactory.createSkin(c, this, type); -// connectionSkins.put(connectionId(c), skin); + // connectionSkins.put(connectionId(c), skin); putConnectionSkin(skinFactory, skin); skin.add(); @@ -676,8 +671,7 @@ private List createConnectionSkins(Connection c, String type, Sk return skins; } - private void removeNodeSkinFromAllSkinFactories(VNode n) { - + protected void removeNodeSkinFromAllSkinFactories(VNode n) { for (SkinFactory skinFactory : getSkinFactories()) { if (skinFactory == null) { @@ -686,26 +680,21 @@ private void removeNodeSkinFromAllSkinFactories(VNode n) { removeNodeSkinFromFactory(skinFactory, n.getId()); } - } - private void removeConnectionSkinFromAllSkinFactories(Connection c) { - + protected void removeConnectionSkinFromAllSkinFactories(Connection c) { for (SkinFactory skinFactory : this.getSkinFactories()) { removeConnectionSkinFromFactory(skinFactory, c); } } - private void removeUIFromAllSkinFactories() { - + protected void removeUIFromAllSkinFactories() { for (SkinFactory skinFactory : getSkinFactories()) { removeUI(skinFactory); } - } - private void removeUI(SkinFactory skinFactory) { - + protected void removeUI(SkinFactory skinFactory) { Collection nodeDelList = getNodeSkinMap(skinFactory).values(); Collection nodeDelListCopy = new ArrayList<>(); nodeDelListCopy.addAll(nodeDelList); @@ -719,7 +708,7 @@ private void removeUI(SkinFactory Collection connectionDelListCopy = new ArrayList<>(); connectionDelListCopy.addAll(connectionDelList); - for (ConnectionSkin cS : connectionDelListCopy) { + for (ConnectionSkin cS : connectionDelListCopy) { cS.remove(); removeConnectionSkinFromFactory(skinFactory, cS.getModel()); } @@ -732,7 +721,6 @@ public final void setSkinFactories(Collection> tmpList = new ArrayList<>(); for (SkinFactory sF : skinFactories) { @@ -760,7 +744,6 @@ public final void addSkinFactories(SkinFactory... skinFactories) { this.getSkinFactories().addAll(tmpList); if (skinFactories.length > 0) { - for (VNode n : getNodes()) { createNodeSkins(n, skinFactories); @@ -778,7 +761,6 @@ public final void addSkinFactories(SkinFactory... skinFactories) { } for (VFlow fC : subControllers.values()) { - Collection> childSkinFactories = new ArrayList<>(); for (SkinFactory sF : skinFactories) { @@ -787,7 +769,7 @@ public final void addSkinFactories(SkinFactory... skinFactories) { if (sF != null) { childNodeSkinFactory = sF.createChild( - getNodeSkin(sF, fC.getModel().getId())); + getNodeSkin(sF, fC.getModel().getId())); } childSkinFactories.add(childNodeSkinFactory); @@ -799,12 +781,7 @@ public final void addSkinFactories(SkinFactory... skinFactories) { @Override public void removeSkinFactories(SkinFactory... skinFactories) { -// if (getModel() != null) { -// System.out.println(">> remove skinfactories from " + getModel().getId() + ", #sf: " + getSkinFactories().size()); -// } - for (SkinFactory skinFactory : skinFactories) { - removeUI(skinFactory); this.skinFactories.remove(skinFactory); @@ -818,10 +795,7 @@ public void removeSkinFactories(SkinFactory #skinFactories: " + getSkinFactories().size()); } @Override @@ -846,37 +820,31 @@ public void addConnections(Connections connections, String flowType) { @Override public final void setModel(VFlowModel flow) { - modelProperty.set(flow); + model.set(flow); for (VNode n : flow.getNodes()) { if (n instanceof VFlowModel) { newSubFlow((VFlowModel) n); } } - } @Override public VFlowModel getModel() { - return modelProperty.get(); + return model.get(); } @Override public ObjectProperty modelProperty() { - return modelProperty; + return model; } - private VFlow newSubFlow(VFlowModel flowNode) { - + protected VFlow newSubFlow(VFlowModel flowNode) { Collection> childFactories = new ArrayList<>(); if (isVisible()) { - for (SkinFactory skinFactory : getSkinFactories()) { - - VNodeSkin skin = getNodeSkin(skinFactory, flowNode.getId());//nodeSkins.get(flowNode.getId()); - -// System.out.println("skin: " + skin + ", node: " + flowNode.getId()); + VNodeSkin skin = getNodeSkin(skinFactory, flowNode.getId()); SkinFactory childFactory = null; if (skinFactory != null) { @@ -886,7 +854,7 @@ private VFlow newSubFlow(VFlowModel flowNode) { } } - VFlow controller = new VFlowImpl(this, flowNode, childFactories); + VFlow controller = instantiateVFlow(flowNode, childFactories); controller.setIdGenerator(getIdGenerator()); controller.setNodeLookup(getNodeLookup()); @@ -895,8 +863,8 @@ private VFlow newSubFlow(VFlowModel flowNode) { for (String connectionType : getAllConnections().keySet()) { if (flowNode.getConnections(connectionType) == null) { controller.addConnections( - VConnections.newConnections(connectionType), - connectionType); + VConnections.newConnections(connectionType), + connectionType); } } @@ -905,6 +873,8 @@ private VFlow newSubFlow(VFlowModel flowNode) { return controller; } + protected abstract VFlow instantiateVFlow(VFlowModel flowNode, Collection> childFactories); + @Override public VFlow newSubFlow(ValueObject obj) { return newSubFlow(getModel().newFlowNode(obj)); @@ -932,17 +902,11 @@ public IdGenerator getIdGenerator() { return idGenerator; } - /** - * @return the nodeLookup - */ @Override public NodeLookup getNodeLookup() { return nodeLookup; } - /** - * @param nodeLookup the nodeLookup to set - */ @Override public final void setNodeLookup(NodeLookup nodeLookup) { this.nodeLookup = nodeLookup; @@ -950,7 +914,6 @@ public final void setNodeLookup(NodeLookup nodeLookup) { @Override public List getNodeSkinsById(String id) { - List result = new ArrayList<>(); for (SkinFactory sF : this.getSkinFactories()) { @@ -979,37 +942,6 @@ public BooleanProperty visibleState() { return getModel().visibleProperty(); } -// @Override -// public boolean isInputOfType(String type) { -// return getModel().isInputOfType(type); -// } -// -// @Override -// public boolean isOutputOfType(String type) { -// return getModel().isOutputOfType(type); -// } -// -// @Override -// public boolean isInput() { -// return getModel().isInput(); -// } -// -// @Override -// public boolean isOutput() { -// return getModel().isOutput(); -// } -// -// -// -// @Override -// public ObservableList getInputTypes() { -// return getModel().getInputTypes(); -// } -// -// @Override -// public ObservableList getOutputTypes() { -// return getModel().getOutputTypes(); -// } public synchronized Map getNodeSkinMap(SkinFactory skinFactory) { Map nodeSkinMap = nodeSkins.get(skinFactory); if (nodeSkinMap == null) { @@ -1019,6 +951,7 @@ public synchronized Map getNodeSkinMap(SkinFactory skinFactor return nodeSkinMap; } + @Override public synchronized Map getConnectionSkinMap(SkinFactory skinFactory) { Map connectionSkinMap = connectionSkins.get(skinFactory); if (connectionSkinMap == null) { @@ -1028,9 +961,6 @@ public synchronized Map getConnectionSkinMap(SkinFactory return connectionSkinMap; } - /** - * @return the skinFactories - */ @Override public ObservableList> getSkinFactories() { return skinFactories; @@ -1056,7 +986,7 @@ public VFlow getFlowById(String id) { return getFlowById(this, id); } - private VFlow getFlowById(VFlow parent, String id) { + protected VFlow getFlowById(VFlow parent, String id) { if (getModel().getId().equals(id)) { return this; diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VFlowModelImpl.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractVFlowModel.java similarity index 74% rename from VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VFlowModelImpl.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractVFlowModel.java index 032d037a..23a8c8c0 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VFlowModelImpl.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractVFlowModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -31,8 +31,21 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of Michael Hoffer . */ -package eu.mihosoft.vrl.workflow; - +package eu.mihosoft.vrl.workflow.base; + +import eu.mihosoft.vrl.workflow.Connection; +import eu.mihosoft.vrl.workflow.ConnectionResult; +import eu.mihosoft.vrl.workflow.Connections; +import eu.mihosoft.vrl.workflow.Connector; +import eu.mihosoft.vrl.workflow.FlowModel; +import eu.mihosoft.vrl.workflow.IdGenerator; +import eu.mihosoft.vrl.workflow.NodeLookup; +import eu.mihosoft.vrl.workflow.ThruConnector; +import eu.mihosoft.vrl.workflow.VFlowModel; +import eu.mihosoft.vrl.workflow.VNode; +import eu.mihosoft.vrl.workflow.ValueObject; +import eu.mihosoft.vrl.workflow.VisualizationRequest; +import eu.mihosoft.vrl.workflow.impl.DefaultValueObject; import javafx.beans.property.BooleanProperty; import javafx.beans.property.DoubleProperty; import javafx.beans.property.ObjectProperty; @@ -44,29 +57,19 @@ import javafx.collections.ObservableList; import javafx.collections.ObservableMap; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; import java.util.Collection; -import java.util.logging.Level; -import java.util.logging.Logger; /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ -class VFlowModelImpl implements VFlowModel { - - private final VNodeImpl node; - private final FlowModelImpl flow; +public abstract class AbstractVFlowModel implements VFlowModel { + protected final VNode node; + protected final FlowModel flow; - private ObservableList thruInputs - = FXCollections.observableArrayList(); - private ObservableList thruOutputs - = FXCollections.observableArrayList(); - private final ObservableList unmodifiableThruInputs - = FXCollections.unmodifiableObservableList(thruInputs); - private final ObservableList unmodifiableThruOutputs - = FXCollections.unmodifiableObservableList(thruOutputs); + protected final ObservableList thruInputs = FXCollections.observableArrayList(); + protected final ObservableList thruOutputs = FXCollections.observableArrayList(); + private final ObservableList unmodifiableThruInputs = FXCollections.unmodifiableObservableList(thruInputs); + private final ObservableList unmodifiableThruOutputs = FXCollections.unmodifiableObservableList(thruOutputs); @Override public BooleanProperty visibleProperty() { @@ -83,9 +86,8 @@ public boolean isVisible() { return flow.isVisible(); } - public VFlowModelImpl(FlowModel parentFlow) { - - flow = new FlowModelImpl(); + public AbstractVFlowModel(FlowModel parentFlow) { + flow = instantiateFlowModel(); VFlowModel pFlow = null; @@ -102,32 +104,33 @@ public VFlowModelImpl(FlowModel parentFlow) { setIdGenerator(parentFlow.getIdGenerator().newChild()); } - node = new VNodeImpl(pFlow); + node = instantiateVNode(pFlow); setTitle("Node"); node.getConnectors().addListener( - (ListChangeListener.Change c) -> { - while (c.next()) { - for (Connector connector : c.getRemoved()) { - if (connector instanceof ThruConnector) { - - ThruConnector tC = (ThruConnector) connector; - - if (tC.isInput()) { - thruInputs.remove(tC); - } else if (tC.isOutput()) { - thruOutputs.remove(tC); - } - - flow.remove(tC.getInnerNode()); + (ListChangeListener.Change c) -> { + while (c.next()) { + for (Connector connector : c.getRemoved()) { + if (connector instanceof ThruConnector) { + ThruConnector tC = (ThruConnector) connector; + + if (tC.isInput()) { + thruInputs.remove(tC); + } else if (tC.isOutput()) { + thruOutputs.remove(tC); } - } + flow.remove(tC.getInnerNode()); + } } - }); - + } + }); } + protected abstract FlowModel instantiateFlowModel(); + + protected abstract VNode instantiateVNode(VFlowModel parentFlow); + @Override public ConnectionResult tryConnect(VNode s, VNode r, String flowType) { return flow.tryConnect(s, r, flowType); @@ -188,16 +191,6 @@ public ObservableMap getAllConnections() { return flow.getAllConnections(); } - @Override - public void setFlowNodeClass(Class cls) { - flow.setFlowNodeClass(cls); - } - - @Override - public Class getFlowNodeClass() { - return flow.getFlowNodeClass(); - } - @Override public VisualizationRequest getVisualizationRequest() { return node.getVisualizationRequest(); @@ -323,73 +316,49 @@ public VFlowModel getFlow() { return node.getFlow(); } -// @Override -// public boolean isInput() { -// return node.isInput(); -// } -// -// @Override -// public boolean isOutput() { -// return node.isOutput(); -// } @Override public VFlowModel newFlowNode(ValueObject obj) { - VFlowModel flowNode = new VFlowModelImpl(this); - - return (VFlowModel) flow.newNode(flowNode, obj, getId()); + VFlowModel flowNode = instantiateVFlowModel(this); + return (VFlowModel) flow.registerNode(flowNode, obj, getId()); } @Override public VFlowModel newFlowNode() { - VFlowModel flowNode = new VFlowModelImpl(this); + VFlowModel flowNode = instantiateVFlowModel(this); flowNode.setNodeLookup(getNodeLookup()); - DefaultValueObject valObj = new DefaultValueObject(); + ValueObject valObj = createValueObject(); - VFlowModel result = (VFlowModel) flow.newNode(flowNode, valObj, getId()); // end newNode() + VFlowModel result = (VFlowModel) flow.registerNode(flowNode, valObj, getId()); valObj.setParent(result); return result; + } + + protected abstract VFlowModel instantiateVFlowModel(FlowModel parent); + protected DefaultValueObject createValueObject() { + return new DefaultValueObject(); } @Override public VNode newNode(ValueObject obj) { - - VNode result = null; - - try { - Constructor constructor = getFlowNodeClass().getConstructor(VFlowModel.class); - try { - result = (VNode) constructor.newInstance(this); - result.setValueObject(obj); - - result = flow.newNode(result, obj, getId()); - - } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { - Logger.getLogger(ConnectionsImpl.class.getName()).log(Level.SEVERE, null, ex); - } - } catch (NoSuchMethodException | SecurityException ex) { - Logger.getLogger(ConnectionsImpl.class.getName()).log(Level.SEVERE, null, ex); - } - + VNode result = instantiateVNode(this); + result.setValueObject(obj); + result = flow.registerNode(result, obj, getId()); return result; } @Override public VNode newNode() { - DefaultValueObject valObj = new DefaultValueObject(); + ValueObject valObj = createValueObject(); VNode result = newNode(valObj); valObj.setParent(result); return result; } -// @Override -// public String getGlobalId() { -// return node.getGlobalId(); -// } @Override public final void setIdGenerator(IdGenerator generator) { flow.setIdGenerator(generator); @@ -410,25 +379,6 @@ public NodeLookup getNodeLookup() { return flow.getNodeLookup(); } -// @Override -// public ObservableList getInputTypes() { -// return node.getInputTypes(); -// } -// -// @Override -// public ObservableList getOutputTypes() { -// return node.getOutputTypes(); -// } -// -// @Override -// public boolean isInputOfType(String type) { -// return node.isInputOfType(type); -// } -// -// @Override -// public boolean isOutputOfType(String type) { -// return node.isOutputOfType(type); -// } @Override public Connector getMainInput(String type) { return this.node.getMainInput(type); @@ -528,17 +478,16 @@ public boolean isVisualizationRequestInitialized() { @Override public ThruConnector addThruInput(String type) { - VNode innerNode = newNode(); innerNode.getVisualizationRequest(). - set(VisualizationRequest.KEY_NODE_NOT_REMOVABLE, true); + set(VisualizationRequest.KEY_NODE_NOT_REMOVABLE, true); Connector innerConnector = innerNode. - setMainOutput(innerNode.addOutput(type)); + setMainOutput(innerNode.addOutput(type)); ThruConnector tC = node.addThruInput( - node, type, innerNode, innerConnector); + node, type, innerNode, innerConnector); thruInputs.add(tC); @@ -547,17 +496,16 @@ public ThruConnector addThruInput(String type) { @Override public ThruConnector addThruOutput(String type) { - VNode innerNode = newNode(); innerNode.getVisualizationRequest(). - set(VisualizationRequest.KEY_NODE_NOT_REMOVABLE, true); + set(VisualizationRequest.KEY_NODE_NOT_REMOVABLE, true); Connector innerConnector = innerNode. - setMainInput(innerNode.addInput(type)); + setMainInput(innerNode.addInput(type)); ThruConnector tC = node.addThruOutput( - node, type, innerNode, innerConnector); + node, type, innerNode, innerConnector); thruOutputs.add(tC); @@ -594,4 +542,34 @@ public FlowModel getRoot() { return root; } + + @Override + public Connector addInput(VNode node, String type) { + return this.node.addInput(node, type); + } + + @Override + public Connector addOutput(VNode node, String type) { + return this.node.addOutput(node, type); + } + + @Override + public ThruConnector addThruInput(VNode node, String type, VNode innerNode, Connector innerConnector) { + return this.node.addThruInput(node, type, innerNode, innerConnector); + } + + @Override + public ThruConnector addThruOutput(VNode node, String type, VNode innerNode, Connector innerConnector) { + return this.node.addThruOutput(node, type, innerNode, innerConnector); + } + + @Override + public Connector addConnector(VNode node, Connector c) { + return this.node.addConnector(node, c); + } + + @Override + public VNode registerNode(VNode result, ValueObject obj, String parentId) { + return this.flow.registerNode(result, obj, parentId); + } } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractVNode.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractVNode.java new file mode 100644 index 00000000..3fb3efc6 --- /dev/null +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractVNode.java @@ -0,0 +1,490 @@ +/* + * Copyright 2012-2017 Michael Hoffer . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Please cite the following publication(s): + * + * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - + * A Framework for Declarative GUI Programming on the Java Platform. + * Computing and Visualization in Science, 2011, in press. + * + * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of Michael Hoffer . + */ +package eu.mihosoft.vrl.workflow.base; + +import eu.mihosoft.vrl.workflow.Connections; +import eu.mihosoft.vrl.workflow.Connector; +import eu.mihosoft.vrl.workflow.FlowModel; +import eu.mihosoft.vrl.workflow.IdGenerator; +import eu.mihosoft.vrl.workflow.ThruConnector; +import eu.mihosoft.vrl.workflow.VFlowModel; +import eu.mihosoft.vrl.workflow.VNode; +import eu.mihosoft.vrl.workflow.ValueObject; +import eu.mihosoft.vrl.workflow.VisualizationRequest; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.DoubleProperty; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.ReadOnlyBooleanProperty; +import javafx.beans.property.ReadOnlyProperty; +import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleDoubleProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import javafx.collections.FXCollections; +import javafx.collections.ListChangeListener; +import javafx.collections.ObservableList; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +/** + * @author Michael Hoffer <info@michaelhoffer.de> + */ +public abstract class AbstractVNode implements VNode { + protected final ObservableList inputs = FXCollections.observableArrayList(); + protected final ObservableList outputs = FXCollections.observableArrayList(); + protected final ObservableList connectors = FXCollections.observableArrayList(); + protected final ObservableList unmodifiableOutputs = FXCollections.unmodifiableObservableList(outputs); + protected final ObservableList unmodifiableInputs = FXCollections.unmodifiableObservableList(inputs); + protected final StringProperty idProperty = new SimpleStringProperty(); + + protected final StringProperty titleProperty = new SimpleStringProperty(this, "title"); + protected final DoubleProperty xProperty = new SimpleDoubleProperty(this, "x"); + protected final DoubleProperty yProperty = new SimpleDoubleProperty(this, "y"); + protected final DoubleProperty widthProperty = new SimpleDoubleProperty(this, "width"); + protected final DoubleProperty heightProperty = new SimpleDoubleProperty(this, "height"); + + protected final BooleanProperty selectedProperty = new SimpleBooleanProperty(false, "selected"); + protected final BooleanProperty selectableProperty = new SimpleBooleanProperty(true, "selectable"); + + protected final ObjectProperty valueObjectProperty = new SimpleObjectProperty<>(this, "valueObject"); + protected final Map mainInputs = new HashMap<>(); + protected final Map mainOutputs = new HashMap<>(); + + protected VFlowModel flow; + protected IdGenerator connectorIdGenerator; + protected ObjectProperty visualizationRequestProperty; + + public AbstractVNode(VFlowModel flow) { + this.flow = flow; + connectorIdGenerator = instantiateIdGenerator(); + + setWidth(200); + setHeight(150); + + setTitle("Node"); + + setValueObject(instantiateValueObject()); + + valueObjectProperty.addListener((value, oldValue, newValue) -> { + if (newValue != null) { + newValue.setParent(AbstractVNode.this); + } + }); + + connectors.addListener(createConnectorsListener()); + } + + protected abstract IdGenerator instantiateIdGenerator(); + + protected abstract ValueObject instantiateValueObject(); + + protected ListChangeListener createConnectorsListener() { + return change -> { + while (change.next()) { + if (change.wasRemoved()) { + for (Connector connector : change.getRemoved()) { + if (connector.isInput()) { + inputs.remove(connector); + + } + + if (connector.isOutput()) { + outputs.remove(connector); + } + + Connections connections = getFlow().getConnections(connector.getType()); + connections.getConnections().removeAll(connections.getAllWith(connector)); + + connectorIdGenerator.getIds().remove(connector.getId()); + } + } else if (change.wasAdded()) { + for (Connector connector : change.getAddedSubList()) { + if (connector.isInput()) { + inputs.add(connector); + } + + if (connector.isOutput()) { + outputs.add(connector); + } + + if (connector instanceof ThruConnector) { + connector.setLocalId(connectorIdGenerator.newId("thru")); + } else { + connector.setLocalId(connectorIdGenerator.newId()); + } + } + } + } + }; + } + + @Override + public StringProperty titleProperty() { + return titleProperty; + } + + @Override + public final void setTitle(String title) { + titleProperty.set(title); + } + + @Override + public String getTitle() { + return titleProperty.get(); + } + + @Override + public StringProperty idProperty() { + return idProperty; + } + + @Override + public void setId(String id) { + idProperty.set(id); + } + + @Override + public String getId() { + return idProperty.get(); + } + + @Override + public DoubleProperty xProperty() { + return xProperty; + } + + @Override + public DoubleProperty yProperty() { + return yProperty; + } + + @Override + public void setX(double x) { + xProperty.set(x); + } + + @Override + public void setY(double y) { + yProperty.set(y); + } + + @Override + public double getX() { + return xProperty.get(); + } + + @Override + public double getY() { + return yProperty.get(); + } + + @Override + public DoubleProperty widthProperty() { + return widthProperty; + } + + @Override + public DoubleProperty heightProperty() { + return heightProperty; + } + + @Override + public final void setWidth(double w) { + widthProperty.set(w); + } + + @Override + public final void setHeight(double h) { + heightProperty.set(h); + } + + @Override + public double getWidth() { + return widthProperty.get(); + } + + @Override + public double getHeight() { + return heightProperty.get(); + } + + @Override + public ValueObject getValueObject() { + return valueObjectProperty.get(); + } + + @Override + public final void setValueObject(ValueObject o) { + valueObjectProperty.set(o); + } + + @Override + public ObjectProperty valueObjectProperty() { + return valueObjectProperty; + } + + @Override + public VisualizationRequest getVisualizationRequest() { + return visualizationRequestProperty().getValue(); + } + + @Override + public void setVisualizationRequest(VisualizationRequest vReq) { + writableVisualizationRequestProperty().set(vReq); + } + + protected ObjectProperty writableVisualizationRequestProperty() { + if (visualizationRequestProperty == null) { + visualizationRequestProperty = new SimpleObjectProperty<>(this, "visualizationRequest"); + visualizationRequestProperty.set(instantiateVisualizationRequest()); + } + + if (visualizationRequestProperty.get() == null) { + visualizationRequestProperty.set(instantiateVisualizationRequest()); + } + + return visualizationRequestProperty; + } + + protected abstract VisualizationRequest instantiateVisualizationRequest(); + + @Override + public ReadOnlyProperty visualizationRequestProperty() { + return writableVisualizationRequestProperty(); + } + + @Override + public VFlowModel getFlow() { + return flow; + } + + @Override + public Connector addInput(String type) { + return addInput(this, type); + } + + @Override + public Connector addOutput(String type) { + return this.addOutput(this, type); + } + + @Override + public Connector addConnector(Connector c) { + return addConnector(this, c); + } + + public Connector addInput(VNode node, String type) { + Connector c = instantiateConnector(node, type, null, true); + connectors.add(c); + return c; + } + + public Connector addOutput(VNode node, String type) { + Connector c = instantiateConnector(node, type, null, false); + connectors.add(c); + return c; + } + + protected abstract Connector instantiateConnector(VNode node, String type, String localId, boolean input); + + public ThruConnector addThruInput(VNode node, String type, VNode innerNode, Connector innerConnector) { + ThruConnector c = instantiateThruConnector(node, type, null, true, innerNode, innerConnector); + connectors.add(c); + return c; + } + + public ThruConnector addThruOutput(VNode node, String type, VNode innerNode, Connector innerConnector) { + ThruConnector c = instantiateThruConnector(node, type, null, false, innerNode, innerConnector); + connectors.add(c); + return c; + } + + protected abstract ThruConnector instantiateThruConnector(VNode node, String type, String localId, boolean input, VNode innerNode, Connector innerConnector); + + public Connector addConnector(VNode node, Connector c) { + String localId = c.getLocalId(); + + if (connectorIdGenerator.getIds().contains(localId)) { + throw new IllegalArgumentException( + "Cannot add connector: id \"" + localId + "\" already in use"); + } + + Connector result = instantiateConnector(node, c); + connectors.add(result); + + connectorIdGenerator.addId(localId); + + return result; + } + + protected abstract Connector instantiateConnector(VNode node, Connector connector); + + @Override + public Connector getMainInput(String type) { + return mainInputs.get(type); + } + + @Override + public Connector getMainOutput(String type) { + return mainOutputs.get(type); + } + + @Override + public Collection getMainInputTypes() { + return mainInputs.keySet(); + } + + @Override + public Collection getMainOutputTypes() { + return mainOutputs.keySet(); + } + + @Override + public Connector setMainInput(Connector connector) { + mainInputs.put(connector.getType(), connector); + return connector; + } + + @Override + public Connector setMainOutput(Connector connector) { + mainOutputs.put(connector.getType(), connector); + return connector; + } + + @Override + public Connector getConnector(String localId) { + for (Connector c : connectors) { + if (c.getLocalId().equals(localId)) { + return c; + } + } + + return null; + } + + @Override + public ObservableList getConnectors() { + return this.connectors; + } + + @Override + public ObservableList getInputs() { + return this.unmodifiableInputs; + } + + @Override + public ObservableList getOutputs() { + return this.unmodifiableOutputs; + } + + @Override + public final boolean isSelected() { + return selectedProperty().get(); + } + + @Override + public final boolean requestSelection(boolean select) { + + if (!select) { + selectedProperty.set(false); + } + + if (isSelectable()) { + selectedProperty.set(select); + return true; + } else { + return false; + } + } + + @Override + public final ReadOnlyBooleanProperty selectedProperty() { + return this.selectedProperty; + } + + @Override + public final BooleanProperty selectableProperty() { + return selectableProperty; + } + + @Override + public final boolean isSelectable() { + return selectableProperty().get(); + } + + public final void setSelectable(boolean b) { + selectableProperty().set(b); + } + + @Override + public boolean isVisualizationRequestInitialized() { + return visualizationRequestProperty != null; + } + + @Override + public boolean removeConnector(Connector c) { + return this.connectors.remove(c); + } + + @Override + public int getDepth() { + VFlowModel parent = this.getFlow(); + + int depth = 0; + + while (parent != null) { + parent = parent.getFlow(); + depth++; + } + + return depth; + } + + @Override + public FlowModel getRoot() { + + VFlowModel root = null; + VFlowModel parent = this.getFlow(); + + while (parent != null) { + root = parent; + parent = parent.getFlow(); + } + + return root; + } +} diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/DefaultValueObject.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractValueObject.java similarity index 62% rename from VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/DefaultValueObject.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractValueObject.java index 2c5d71de..d0852e67 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/DefaultValueObject.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/base/AbstractValueObject.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -31,25 +31,29 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of Michael Hoffer . */ -package eu.mihosoft.vrl.workflow; +package eu.mihosoft.vrl.workflow.base; +import eu.mihosoft.vrl.workflow.VNode; +import eu.mihosoft.vrl.workflow.ValueObject; +import eu.mihosoft.vrl.workflow.VisualizationRequest; +import eu.mihosoft.vrl.workflow.impl.DefaultVisualizationRequest; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; /** - * This class defines a value object you can assign a value. + * This class defines a value object you can assign a value. + * * @author Michael Hoffer <info@michaelhoffer.de> */ -public class DefaultValueObject implements ValueObject { - - private VNode parent; - private final ObjectProperty valueProperty = new SimpleObjectProperty(); - private VisualizationRequest vReq = null; +public abstract class AbstractValueObject implements ValueObject { + protected VNode parent; + protected final ObjectProperty value = new SimpleObjectProperty(this, "value"); + protected VisualizationRequest visualizationRequest; - public DefaultValueObject() { + public AbstractValueObject() { } - public DefaultValueObject(VNode parent) { + public AbstractValueObject(VNode parent) { this.parent = parent; } @@ -70,46 +74,21 @@ public void setValue(Object o) { @Override public ObjectProperty valueProperty() { - return valueProperty; - } - - @Override - public CompatibilityResult compatible(final ValueObject sender, final String flowType) { - return new CompatibilityResult() { - @Override - public boolean isCompatible() { - boolean differentObjects = sender != DefaultValueObject.this; -// boolean compatibleType = getParent().isInputOfType(flowType) -// && sender.getParent().isOutputOfType(flowType); - - return differentObjects /*&& compatibleType*/; - } - - @Override - public String getMessage() { - return "incompatible: " + sender.getParent().getId() + " -> " + getParent().getId(); - } - - @Override - public String getStatus() { - throw new UnsupportedOperationException("Not supported yet."); - } - }; + return value; } @Override public VisualizationRequest getVisualizationRequest() { - - if (vReq == null) { - vReq = new VisualizationRequestImpl(); + if (visualizationRequest == null) { + visualizationRequest = new DefaultVisualizationRequest(); } - - return vReq; + + return visualizationRequest; } - + @Override - public void setVisualizationRequest(VisualizationRequest vReq) { - this.vReq = vReq; + public void setVisualizationRequest(VisualizationRequest visualizationRequest) { + this.visualizationRequest = visualizationRequest; } /** diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectionBase.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/ConnectionBase.java similarity index 63% rename from VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectionBase.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/ConnectionBase.java index b31f8d37..d81ca992 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectionBase.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/ConnectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -31,8 +31,12 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of Michael Hoffer . */ -package eu.mihosoft.vrl.workflow; +package eu.mihosoft.vrl.workflow.impl; +import eu.mihosoft.vrl.workflow.Connection; +import eu.mihosoft.vrl.workflow.Connections; +import eu.mihosoft.vrl.workflow.Connector; +import eu.mihosoft.vrl.workflow.VisualizationRequest; import javafx.beans.property.ObjectProperty; import javafx.beans.property.ReadOnlyProperty; import javafx.beans.property.SimpleObjectProperty; @@ -44,49 +48,24 @@ * * @author Michael Hoffer <info@michaelhoffer.de> */ -class ConnectionBase implements Connection { - - private String senderId; - private String receiverId; - private String id; - private String type; - private ObjectProperty vReqProperty; - private Connections connections; - private Connector sender; - private Connector receiver; - -// private ObjectProperty skinProperty = new SimpleObjectProperty<>(); - public ConnectionBase() { - } - -// public ConnectionBase(Connections connections, String id, String senderId, String receiverId, String type) { -// this.connections = connections; -// this.id = id; -// this.senderId = senderId; -// this.receiverId = receiverId; -// this.type = type; -// } +public class ConnectionBase implements Connection { + protected String id; + protected String type; + protected ObjectProperty visualizationRequest; + protected Connections connections; + protected Connector sender; + protected Connector receiver; + public ConnectionBase(Connections connections, String id, Connector sender, Connector receiver, String type) { this.connections = connections; this.id = id; - setSender(sender); - setReceiver(receiver); + this.sender = sender; + this.receiver = receiver; this.type = type; - } - -// @Override -// public String getSenderId() { -// return senderId; -// } - @Override - public void setSender(Connector s) { - this.senderId = s.getId(); - this.sender = s; - updateConnection(); } - private void updateConnection() { + protected void updateConnection() { if (getSender() != null && getReceiver() != null) { if (connections.get(getId(), getSender(), getReceiver()) != null) { connections.remove(this); @@ -95,15 +74,21 @@ private void updateConnection() { } } -// @Override -// public String getReceiverId() { -// return receiverId; -// } + @Override + public void setSender(Connector s) { + this.sender = s; + updateConnection(); + } + @Override public void setReceiver(Connector r) { - this.receiverId = r.getId(); this.receiver = r; + updateConnection(); + } + @Override + public void setId(String id) { + this.id = id; updateConnection(); } @@ -117,68 +102,34 @@ public String getId() { return id; } - @Override - public void setId(String id) { - this.id = id; - - updateConnection(); - } - - /** - * @return the vReq - */ @Override public VisualizationRequest getVisualizationRequest() { return visualizationRequestProperty().getValue(); } - /** - * @param vReq the vReq to set - */ @Override public void setVisualizationRequest(VisualizationRequest vReq) { - _visualizationRequestProperty().set(vReq); + writableVisualizationRequestProperty().set(vReq); } - private ObjectProperty _visualizationRequestProperty() { - if (vReqProperty == null) { - vReqProperty = new SimpleObjectProperty<>(); - setVisualizationRequest(new VisualizationRequestImpl()); + private ObjectProperty writableVisualizationRequestProperty() { + if (visualizationRequest == null) { + visualizationRequest = new SimpleObjectProperty<>(this, "visualizationRequest", new DefaultVisualizationRequest()); } - return vReqProperty; + return visualizationRequest; } @Override public ReadOnlyProperty visualizationRequestProperty() { - return _visualizationRequestProperty(); - } -// @Override -// public void setSkin(Skin skin) { -// skinProperty.set(skin); -// } -// -// @Override -// public Skin getSkin() { -// return skinProperty.get(); -// } -// -// @Override -// public ObjectProperty skinProperty() { -// return skinProperty; -// } - - /** - * @return the connections - */ + return writableVisualizationRequestProperty(); + } + @Override public Connections getConnections() { return connections; } - /** - * @return the type - */ @Override public String getType() { return type; @@ -187,8 +138,12 @@ public String getType() { @Override public int hashCode() { int hash = 3; - hash = 37 * hash + Objects.hashCode(this.senderId); - hash = 37 * hash + Objects.hashCode(this.receiverId); + if (getSender() != null) { + hash = 37 * hash + Objects.hashCode(getSender().getId()); + } + if (getReceiver() != null) { + hash = 37 * hash + Objects.hashCode(getReceiver().getId()); + } hash = 37 * hash + Objects.hashCode(this.id); hash = 37 * hash + Objects.hashCode(this.type); return hash; @@ -199,44 +154,42 @@ public boolean equals(Object obj) { if (obj == null) { return false; } - if (getClass() != obj.getClass()) { + if (getClass() != obj.getClass() || !(obj instanceof Connection)) { return false; } - final ConnectionBase other = (ConnectionBase) obj; - if (!Objects.equals(this.senderId, other.senderId)) { + + Connection other = (Connection) obj; + if (connectorIdsAreDifferent(sender, other.getSender())) { return false; } - if (!Objects.equals(this.receiverId, other.receiverId)) { + if (connectorIdsAreDifferent(receiver, other.getReceiver())) { return false; } - if (!Objects.equals(this.id, other.id)) { + if (!Objects.equals(this.id, other.getId())) { return false; } - if (!Objects.equals(this.type, other.type)) { + if (!Objects.equals(this.type, other.getType())) { return false; } return true; } - /** - * @return the sender - */ + protected boolean connectorIdsAreDifferent(Connector a, Connector b) { + return a != null && b != null && !Objects.equals(a.getId(), b.getId()); + } + @Override public Connector getSender() { return sender; } - /** - * @return the receiver - */ @Override public Connector getReceiver() { return receiver; } - + @Override public boolean isVisualizationRequestInitialized() { - return vReqProperty != null; + return visualizationRequest != null; } - } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectionResultImpl.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultConnectionResult.java similarity index 84% rename from VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectionResultImpl.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultConnectionResult.java index 37781dea..39a01eec 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ConnectionResultImpl.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultConnectionResult.java @@ -1,68 +1,71 @@ -/* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * Please cite the following publication(s): - * - * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - - * A Framework for Declarative GUI Programming on the Java Platform. - * Computing and Visualization in Science, 2011, in press. - * - * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of Michael Hoffer . - */ -package eu.mihosoft.vrl.workflow; - -/** - * This class provides a default implementation of {@code ConnectionResult} - * //TODO add documentation about the possible connection results. - * - * @author Michael Hoffer <info@michaelhoffer.de> - */ - -class ConnectionResultImpl implements ConnectionResult { - private final CompatibilityResult status; - private Connection connection; - - public ConnectionResultImpl(CompatibilityResult status, Connection connection) { - this.status = status; - - this.connection = connection; - } - - /** - * @return the status - */ - @Override - public CompatibilityResult getStatus() { - return status; - } - - /** - * @return the connection - */ - @Override - public Connection getConnection() { - return connection; - } -} +/* + * Copyright 2012-2017 Michael Hoffer . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Please cite the following publication(s): + * + * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - + * A Framework for Declarative GUI Programming on the Java Platform. + * Computing and Visualization in Science, 2011, in press. + * + * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of Michael Hoffer . + */ +package eu.mihosoft.vrl.workflow.impl; + +import eu.mihosoft.vrl.workflow.CompatibilityResult; +import eu.mihosoft.vrl.workflow.Connection; +import eu.mihosoft.vrl.workflow.ConnectionResult; + +/** + * This class provides a default implementation of {@code ConnectionResult} + * //TODO add documentation about the possible connection results. + * + * @author Michael Hoffer <info@michaelhoffer.de> + */ + +public class DefaultConnectionResult implements ConnectionResult { + private final CompatibilityResult status; + private final Connection connection; + + public DefaultConnectionResult(CompatibilityResult status, Connection connection) { + this.status = status; + this.connection = connection; + } + + /** + * @return the status + */ + @Override + public CompatibilityResult getStatus() { + return status; + } + + /** + * @return the connection + */ + @Override + public Connection getConnection() { + return connection; + } +} diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultConnections.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultConnections.java new file mode 100644 index 00000000..87e89ee2 --- /dev/null +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultConnections.java @@ -0,0 +1,55 @@ +/* + * Copyright 2012-2017 Michael Hoffer . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Please cite the following publication(s): + * + * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - + * A Framework for Declarative GUI Programming on the Java Platform. + * Computing and Visualization in Science, 2011, in press. + * + * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of Michael Hoffer . + */ +package eu.mihosoft.vrl.workflow.impl; + +import eu.mihosoft.vrl.workflow.Connection; +import eu.mihosoft.vrl.workflow.Connector; +import eu.mihosoft.vrl.workflow.base.AbstractConnections; + +/** + * This class provides a default implementation of the {@code Connections} + * interface. + * + * @author Michael Hoffer <info@michaelhoffer.de> + */ +public class DefaultConnections extends AbstractConnections { + public DefaultConnections(String type) { + super(type); + } + + @Override + protected Connection instantiateConnection(String id, Connector sender, Connector receiver) { + return new ConnectionBase(this, id, sender, receiver, type); + } +} diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultConnector.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultConnector.java new file mode 100644 index 00000000..5286e52a --- /dev/null +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultConnector.java @@ -0,0 +1,60 @@ +/* + * Copyright 2012-2017 Michael Hoffer . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Please cite the following publication(s): + * + * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - + * A Framework for Declarative GUI Programming on the Java Platform. + * Computing and Visualization in Science, 2011, in press. + * + * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of Michael Hoffer . + */ +package eu.mihosoft.vrl.workflow.impl; + +import eu.mihosoft.vrl.workflow.Connector; +import eu.mihosoft.vrl.workflow.ConnectorValueObject; +import eu.mihosoft.vrl.workflow.VNode; +import eu.mihosoft.vrl.workflow.base.AbstractConnector; + +/** + * This class provides the default implementation of a {@code Connector} in + * VWorkflows + * + * @author Michael Hoffer <info@michaelhoffer.de> + */ +public class DefaultConnector extends AbstractConnector { + public DefaultConnector(VNode node, Connector connector) { + super(node, connector); + } + + public DefaultConnector(VNode node, String type, String localId, boolean input) { + super(node, type, localId, input); + } + + @Override + protected ConnectorValueObject instantiateConnectorValueObject() { + return new DefaultConnectorValueObject(this); + } +} diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultConnectorValueObject.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultConnectorValueObject.java new file mode 100644 index 00000000..9138c26b --- /dev/null +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultConnectorValueObject.java @@ -0,0 +1,124 @@ +/* + * Copyright 2012-2017 Michael Hoffer . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Please cite the following publication(s): + * + * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - + * A Framework for Declarative GUI Programming on the Java Platform. + * Computing and Visualization in Science, 2011, in press. + * + * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of Michael Hoffer . + */ +package eu.mihosoft.vrl.workflow.impl; + +import eu.mihosoft.vrl.workflow.CompatibilityResult; +import eu.mihosoft.vrl.workflow.Connector; +import eu.mihosoft.vrl.workflow.ConnectorValueObject; +import eu.mihosoft.vrl.workflow.ValueObject; +import eu.mihosoft.vrl.workflow.base.AbstractConnectorValueObject; + +/** + * This class defines a default connector value object. ValueObjects are used to + * store data in connectors. It is a placeholder for a value object as it's + * get/setValue methods are not implemented. + * + * @author Michael Hoffer <info@michaelhoffer.de> + */ +public class DefaultConnectorValueObject extends AbstractConnectorValueObject { + public DefaultConnectorValueObject(Connector connector) { + super(connector); + } + + @Override + public CompatibilityResult compatible(final ValueObject sender, final String flowType) { + boolean differentObjects = sender != this; + + boolean compatibleType = false; + + int numConnectionsOfReceiver = getParent().getFlow(). + getConnections(flowType).getAllWith(connector).size(); + + boolean lessThanMaxNumberOfConnections = true; + + int maxNumConnections = connector.getMaxNumberOfConnections(); + + if (sender instanceof ConnectorValueObject) { + ConnectorValueObject senderConnectorVObj = + (ConnectorValueObject) sender; + compatibleType = getConnector().getType(). + equals(senderConnectorVObj.getConnector().getType()) + && getConnector().isInput() && senderConnectorVObj. + getConnector().isOutput(); + + int numConnectionsOfSender = senderConnectorVObj.getParent(). + getFlow().getConnections(flowType). + getAllWith(senderConnectorVObj.getConnector()).size(); + + maxNumConnections = Math.min(connector.getMaxNumberOfConnections(), + senderConnectorVObj.getConnector().getMaxNumberOfConnections()); + + lessThanMaxNumberOfConnections + = numConnectionsOfReceiver < maxNumConnections + && numConnectionsOfSender < maxNumConnections; + } + + String message = ""; + if (!differentObjects) { + message = "Connections can only established between different nodes." + + " Sender node cannot be equal to receiver node."; + } else if (!compatibleType) { + message = "Connections can only established between" + + " connectors of the same connection/flow type."; + } else if (!lessThanMaxNumberOfConnections) { + message = "Trying to create more than " + maxNumConnections + + " number of connections is not allowed."; + } + + final boolean compatible = differentObjects && compatibleType && lessThanMaxNumberOfConnections; + final String errorMessage = message; + String id = sender.getParent() + ":undefined"; + if (sender instanceof ConnectorValueObject) { + id = ((ConnectorValueObject) sender).getConnector().getId(); + } + final String senderId = id; + + return new CompatibilityResult() { + @Override + public boolean isCompatible() { + return compatible; + } + + @Override + public String getMessage() { + return "incompatible: " + senderId + " -> " + getConnector().getId() + ", reason: " + errorMessage; + } + + @Override + public String getStatus() { + throw new UnsupportedOperationException("Not supported yet."); + } + }; + } +} diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultFlowModel.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultFlowModel.java new file mode 100644 index 00000000..eaa7b3ce --- /dev/null +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultFlowModel.java @@ -0,0 +1,52 @@ +/* + * Copyright 2012-2017 Michael Hoffer . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Please cite the following publication(s): + * + * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - + * A Framework for Declarative GUI Programming on the Java Platform. + * Computing and Visualization in Science, 2011, in press. + * + * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of Michael Hoffer . + */ +package eu.mihosoft.vrl.workflow.impl; + +import eu.mihosoft.vrl.workflow.CompatibilityResult; +import eu.mihosoft.vrl.workflow.Connection; +import eu.mihosoft.vrl.workflow.ConnectionResult; +import eu.mihosoft.vrl.workflow.base.AbstractFlowModel; + +/** + * This class implements the flow model. The flow model manages the connections + * between nodes. + * + * @author Michael Hoffer <info@michaelhoffer.de> + */ +public class DefaultFlowModel extends AbstractFlowModel { + @Override + protected ConnectionResult instantiateConnectionResult(CompatibilityResult compatibilityResult, Connection connection) { + return new DefaultConnectionResult(compatibilityResult, connection); + } +} \ No newline at end of file diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/FlowNodeSkinLookupImpl.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultFlowNodeSkinLookup.java similarity index 63% rename from VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/FlowNodeSkinLookupImpl.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultFlowNodeSkinLookup.java index 919db2dc..90872844 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/FlowNodeSkinLookupImpl.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultFlowNodeSkinLookup.java @@ -1,212 +1,178 @@ -/* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * Please cite the following publication(s): - * - * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - - * A Framework for Declarative GUI Programming on the Java Platform. - * Computing and Visualization in Science, 2011, in press. - * - * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of Michael Hoffer . - */ - -package eu.mihosoft.vrl.workflow; - - - -import eu.mihosoft.vrl.workflow.skin.ConnectionSkin; -import eu.mihosoft.vrl.workflow.skin.FlowNodeSkinLookup; -import eu.mihosoft.vrl.workflow.skin.SkinFactory; -import eu.mihosoft.vrl.workflow.skin.VNodeSkin; -import java.util.ArrayList; - -import java.util.Collection; -import java.util.List; - -/** - * - * @author Michael Hoffer <info@michaelhoffer.de> - */ -public class FlowNodeSkinLookupImpl implements FlowNodeSkinLookup { - - private final VFlow root; - - public FlowNodeSkinLookupImpl(VFlow root) { - this.root = root; - } - - @Override - public List getById(String globalId) { - - List result = getNodeByGlobalId(root, globalId); - - return result; - } - - private List getNodeByGlobalId(VFlow parent, String id) { - - VFlow flow = getFlowThatContains(parent, id); - - if (flow != null) { - return flow.getNodeSkinsById(id); - } else { - return new ArrayList<>(); - } - } - - private VNodeSkin getNodeByGlobalId(SkinFactory skinFactory, VFlow parent, String id) { - -// System.out.println("id: " + id); - // find flow that contains the requested node - VFlow flow; - - if (parent.getModel().getId().equals(id)) { - flow = parent; - } else { - flow = getFlowThatContains(parent, id); - } - - if (flow == null) { - return null; - } -// -// System.out.println("found flow: " + flow.getModel().getId()); - - for (SkinFactory sF : flow.getSkinFactories()) { - if (getRootSkinFactoryOf(skinFactory) == getRootSkinFactoryOf(sF)) { - List s2 = flow.getNodeSkinsById(id); - return getBySkinFactory(sF, s2); - } - } -// -// System.out.println(" --> nothing found :("); - - return null; - } - - private SkinFactory getRootSkinFactoryOf(SkinFactory skinFactory) { - // find root parent factory - SkinFactory tmpFactory = skinFactory; - SkinFactory parentFactory = skinFactory; - - while (tmpFactory != null) { - tmpFactory = tmpFactory.getParent(); - if (tmpFactory != null) { - parentFactory = tmpFactory; - } - } - - return parentFactory; - } - - private VFlow getFlowThatContains(VFlow parent, String id) { - - // check if current controller contains node with specified id - for (VNode n : parent.getNodes()) { - if (n.getId().equals(id)) { - return parent; - } - } - - Collection subflows = parent.getSubControllers(); - - for (VFlow vFlow : subflows) { - VFlow result = getFlowThatContains(vFlow, id); - - if (result != null) { - return result; - } - } - - return null; - } - - private VNodeSkin getBySkinFactory(SkinFactory skinFactory, List candidates) { - - for (VNodeSkin vNodeSkin : candidates) { - - if (vNodeSkin.getSkinFactory() == skinFactory) { - return vNodeSkin; - } - } - - return null; - } - - @Override - public VNodeSkin getById(SkinFactory skinFactory, String globalId) { - - // support for connector ids, we wan't to return node skin if connector - // id is given - globalId = globalId.split(":c:")[0]; - - VNodeSkin result = getNodeByGlobalId(skinFactory, root, globalId); - -// if (result != null) { -// System.out.println("getById(): " + result); -// } else { -// System.out.println("NOT FOUND: getById(): " + null); -// } - return result; - } - - @Override - public ConnectionSkin getById(SkinFactory skinFactory, Connection c) { - - String sender = c.getSender().getId(); - String receiver = c.getReceiver().getId(); - - VFlowModel senderFlow = root.getNodeLookup().getById(sender.split(":c:")[0]).getFlow(); - VFlowModel receiverFlow = root.getNodeLookup().getById(receiver.split(":c:")[0]).getFlow(); - - if (senderFlow != receiverFlow) { - throw new UnsupportedOperationException( - "Only skins for connections that share the same parent can be searched"); - } - - VFlow flow = root.getFlowById(senderFlow.getId()); - - if (!(flow instanceof VFlowImpl)) { - System.err.println("flow: " + flow); - throw new UnsupportedOperationException( - "Unsupported flow class '" - + flow.getClass() - + "', should implement '" + VFlowImpl.class + "'"); - } - - VFlowImpl flowImpl = (VFlowImpl) flow; - - ConnectionSkin skin = flowImpl.getConnectionSkinMap(skinFactory).get( - VFlowImpl.connectionId(c)); - -// for (String key : flowImpl.getConnectionSkinMap(skinFactory).keySet()) { -// ConnectionSkin skinI = flowImpl.getConnectionSkinMap(skinFactory).get(key); -// System.out.println(" --> skin " + skinI + ": " + key + "==" + VFlowImpl.connectionId(c)); -// } -// -// System.out.println("skin for connection " + c + ": " + skin); - return skin; - } -} +/* + * Copyright 2012-2017 Michael Hoffer . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Please cite the following publication(s): + * + * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - + * A Framework for Declarative GUI Programming on the Java Platform. + * Computing and Visualization in Science, 2011, in press. + * + * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of Michael Hoffer . + */ +package eu.mihosoft.vrl.workflow.impl; + +import eu.mihosoft.vrl.workflow.Connection; +import eu.mihosoft.vrl.workflow.VFlow; +import eu.mihosoft.vrl.workflow.VFlowModel; +import eu.mihosoft.vrl.workflow.VNode; +import eu.mihosoft.vrl.workflow.skin.ConnectionSkin; +import eu.mihosoft.vrl.workflow.skin.FlowNodeSkinLookup; +import eu.mihosoft.vrl.workflow.skin.SkinFactory; +import eu.mihosoft.vrl.workflow.skin.VNodeSkin; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import static eu.mihosoft.vrl.workflow.util.ConnectionUtils.connectionId; + +/** + * @author Michael Hoffer <info@michaelhoffer.de> + */ +public class DefaultFlowNodeSkinLookup implements FlowNodeSkinLookup { + protected final VFlow root; + + public DefaultFlowNodeSkinLookup(VFlow root) { + this.root = root; + } + + @Override + public List getById(String globalId) { + return getNodeByGlobalId(root, globalId); + } + + protected List getNodeByGlobalId(VFlow parent, String id) { + VFlow flow = getFlowThatContains(parent, id); + + if (flow != null) { + return flow.getNodeSkinsById(id); + } else { + return new ArrayList<>(); + } + } + + protected VNodeSkin getNodeByGlobalId(SkinFactory skinFactory, VFlow parent, String id) { + // System.out.println("id: " + id); + // find flow that contains the requested node + VFlow flow; + + if (parent.getModel().getId().equals(id)) { + flow = parent; + } else { + flow = getFlowThatContains(parent, id); + } + + if (flow == null) { + return null; + } + // + // System.out.println("found flow: " + flow.getModel().getId()); + + for (SkinFactory sF : flow.getSkinFactories()) { + if (getRootSkinFactoryOf(skinFactory) == getRootSkinFactoryOf(sF)) { + List s2 = flow.getNodeSkinsById(id); + return getBySkinFactory(sF, s2); + } + } + // + // System.out.println(" --> nothing found :("); + + return null; + } + + protected SkinFactory getRootSkinFactoryOf(SkinFactory skinFactory) { + // find root parent factory + SkinFactory tmpFactory = skinFactory; + SkinFactory parentFactory = skinFactory; + + while (tmpFactory != null) { + tmpFactory = tmpFactory.getParent(); + if (tmpFactory != null) { + parentFactory = tmpFactory; + } + } + + return parentFactory; + } + + protected VFlow getFlowThatContains(VFlow parent, String id) { + // check if current controller contains node with specified id + for (VNode n : parent.getNodes()) { + if (n.getId().equals(id)) { + return parent; + } + } + + Collection subflows = parent.getSubControllers(); + + for (VFlow vFlow : subflows) { + VFlow result = getFlowThatContains(vFlow, id); + + if (result != null) { + return result; + } + } + + return null; + } + + protected VNodeSkin getBySkinFactory(SkinFactory skinFactory, List candidates) { + for (VNodeSkin vNodeSkin : candidates) { + if (vNodeSkin.getSkinFactory() == skinFactory) { + return vNodeSkin; + } + } + + return null; + } + + @Override + public VNodeSkin getById(SkinFactory skinFactory, String globalId) { + // support for connector ids, we wan't to return node skin if connector + // id is given + return getNodeByGlobalId(skinFactory, root, resolveId(globalId)); + } + + protected String resolveId(String encodedId) { + return encodedId.split(":c:")[0]; + } + + @Override + public ConnectionSkin getById(SkinFactory skinFactory, Connection c) { + String sender = c.getSender().getId(); + String receiver = c.getReceiver().getId(); + + VFlowModel senderFlow = root.getNodeLookup().getById(resolveId(sender)).getFlow(); + VFlowModel receiverFlow = root.getNodeLookup().getById(resolveId(receiver)).getFlow(); + + if (senderFlow != receiverFlow) { + throw new UnsupportedOperationException("Only skins for connections that share the same parent can be searched"); + } + + VFlow flow = root.getFlowById(senderFlow.getId()); + ConnectionSkin skin = flow.getConnectionSkinMap(skinFactory).get(connectionId(c)); + return skin; + } +} diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/IdGeneratorImpl.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultIdGenerator.java similarity index 89% rename from VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/IdGeneratorImpl.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultIdGenerator.java index 10103f9c..80a9b2d3 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/IdGeneratorImpl.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultIdGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -31,7 +31,9 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of Michael Hoffer . */ -package eu.mihosoft.vrl.workflow; +package eu.mihosoft.vrl.workflow.impl; + +import eu.mihosoft.vrl.workflow.IdGenerator; import java.util.HashSet; import java.util.Set; @@ -41,12 +43,11 @@ * * @author Michael Hoffer <info@michaelhoffer.de> */ -class IdGeneratorImpl implements IdGenerator { - +public class DefaultIdGenerator implements IdGenerator { private Set ids = new HashSet<>(); -// private int lastId = 0; + // private int lastId = 0; - public IdGeneratorImpl() { + public DefaultIdGenerator() { // } @@ -66,8 +67,8 @@ public String newId(String prefix) { // TODO improve id generation // Question: do we really want strings as id? int counter = 0;//lastId + 1; - - + + if (prefix != null && !prefix.isEmpty() && !prefix.endsWith(":")) { prefix = prefix + "-"; } @@ -81,7 +82,7 @@ public String newId(String prefix) { ids.add(id); -// lastId = counter; + // lastId = counter; return id; } @@ -93,13 +94,11 @@ public String newId() { @Override public Set getIds() { - Set result = new HashSet<>(ids); - return result; + return new HashSet<>(ids); } @Override public IdGenerator newChild() { return this; } - } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/NodeLookupImpl.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultNodeLookup.java similarity index 81% rename from VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/NodeLookupImpl.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultNodeLookup.java index f44d72b1..227f695a 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/NodeLookupImpl.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultNodeLookup.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -31,24 +31,28 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of Michael Hoffer . */ -package eu.mihosoft.vrl.workflow; +package eu.mihosoft.vrl.workflow.impl; + +import eu.mihosoft.vrl.workflow.Connector; +import eu.mihosoft.vrl.workflow.FlowModel; +import eu.mihosoft.vrl.workflow.NodeLookup; +import eu.mihosoft.vrl.workflow.VFlowModel; +import eu.mihosoft.vrl.workflow.VNode; import java.util.Objects; /** * This class allows nodes to be looked up by id. * Ids have the format {@code :}. - * + *

* The class can also be used to look up connectors. * * @author Michael Hoffer <info@michaelhoffer.de> */ -public class NodeLookupImpl implements NodeLookup { - +public class DefaultNodeLookup implements NodeLookup { private final VFlowModel root; -// private final Map cache = new HashMap<>(); - public NodeLookupImpl(VFlowModel root) { + public DefaultNodeLookup(VFlowModel root) { this.root = root; } @@ -58,7 +62,7 @@ public Connector getConnectorById(String globalId) { if (ids.length < 2) { throw new IllegalArgumentException("wrong connector id format: " - + globalId + ", correct format: node-id:c:connector-id"); + + globalId + ", correct format: node-id:c:connector-id"); } String nodeId = ids[0]; @@ -75,21 +79,11 @@ public Connector getConnectorById(String globalId) { @Override public VNode getById(String globalId) { - -// VNode result = cache.get(globalId); - -// if (result!=null)return result; - - VNode result = getNodeByGlobalId(root, globalId); - -// cache.put(globalId, result); - - return result; + return getNodeByGlobalId(root, globalId); } - private VNode getNodeByGlobalId(VFlowModel parent, String id) { - - if (Objects.equals(parent.getId(),id)) { + protected VNode getNodeByGlobalId(VFlowModel parent, String id) { + if (Objects.equals(parent.getId(), id)) { return parent; } @@ -106,7 +100,6 @@ private VNode getNodeByGlobalId(VFlowModel parent, String id) { } } - return null; } } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/PropertyStorageImpl.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultPropertyStorage.java similarity index 82% rename from VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/PropertyStorageImpl.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultPropertyStorage.java index bd35d06b..ae4dc30c 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/PropertyStorageImpl.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultPropertyStorage.java @@ -1,135 +1,137 @@ -/* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * Please cite the following publication(s): - * - * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - - * A Framework for Declarative GUI Programming on the Java Platform. - * Computing and Visualization in Science, 2011, in press. - * - * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of Michael Hoffer . - */ -package eu.mihosoft.vrl.workflow; - -import java.util.Collection; - -import javafx.collections.FXCollections; -import javafx.collections.MapChangeListener; -import javafx.collections.ObservableMap; - -import java.util.Optional; - -/** - * A simple property storage. - * - * @author Michael Hoffer <info@michaelhoffer.de> - */ -class PropertyStorageImpl implements PropertyStorage { - - private final ObservableMap map = FXCollections.observableHashMap(); - - /** - * Constructor. Creates a new property storage. - */ - public PropertyStorageImpl() { - // - } - - /** - * Sets a property. Existing properties are overwritten. - * - * @param key key - * @param property property - */ - @Override - public void set(String key, T property) { - map.put(key, property); - } - - /** - * Returns a property. - * - * @param property type - * @param key key - * @return the property; an empty {@link java.util.Optional} will be - * returned if the property does not exist or the type does not match - */ - @Override - public Optional get(String key) { - - Object value = map.get(key); - - try { - return Optional.ofNullable((T) value); - } catch (ClassCastException ex) { - return Optional.empty(); - } - } - - /** - * Deletes the requested property if present. Does nothing otherwise. - * - * @param key key - */ - @Override - public void remove(String key) { - map.remove(key); - } - - /** - * Indicates whether this storage contains the requested property. - * - * @param key key - * @return {@code true} if this storage contains the requested property; - * {@code false} - */ - @Override - public boolean contains(String key) { - return map.containsKey(key); - } - - /** - * Adds the specified listener to the property map. - * @param l change listener - */ - @Override - public void addListener(MapChangeListener l) { - map.addListener(l); - } - - /** - * Removes the specified listener from the property map. - * @param l change listener - */ - @Override - public void removeListener(MapChangeListener l) { - map.removeListener(l); - } - - @Override - public Collection getKeys() { - return map.keySet(); - } -} +/* + * Copyright 2012-2017 Michael Hoffer . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Please cite the following publication(s): + * + * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - + * A Framework for Declarative GUI Programming on the Java Platform. + * Computing and Visualization in Science, 2011, in press. + * + * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of Michael Hoffer . + */ +package eu.mihosoft.vrl.workflow.impl; + +import eu.mihosoft.vrl.workflow.PropertyStorage; +import javafx.collections.FXCollections; +import javafx.collections.MapChangeListener; +import javafx.collections.ObservableMap; + +import java.util.Collection; +import java.util.Optional; + +/** + * A simple property storage. + * + * @author Michael Hoffer <info@michaelhoffer.de> + */ +public class DefaultPropertyStorage implements PropertyStorage { + private final ObservableMap properties = FXCollections.observableHashMap(); + + /** + * Constructor. Creates a new property storage. + */ + public DefaultPropertyStorage() { + // + } + + /** + * Sets a property. Existing properties are overwritten. + * + * @param key key + * @param property property + */ + @Override + public void set(String key, T property) { + properties.put(key, property); + } + + /** + * Returns a property. + * + * @param property type + * @param key key + * + * @return the property; an empty {@link java.util.Optional} will be + * returned if the property does not exist or the type does not match + */ + @Override + public Optional get(String key) { + Object value = properties.get(key); + + try { + return Optional.ofNullable((T) value); + } catch (ClassCastException ex) { + return Optional.empty(); + } + } + + /** + * Deletes the requested property if present. Does nothing otherwise. + * + * @param key key + */ + @Override + public void remove(String key) { + properties.remove(key); + } + + /** + * Indicates whether this storage contains the requested property. + * + * @param key key + * + * @return {@code true} if this storage contains the requested property; + * {@code false} + */ + @Override + public boolean contains(String key) { + return properties.containsKey(key); + } + + /** + * Adds the specified listener to the property properties. + * + * @param l change listener + */ + @Override + public void addListener(MapChangeListener l) { + properties.addListener(l); + } + + /** + * Removes the specified listener from the property properties. + * + * @param l change listener + */ + @Override + public void removeListener(MapChangeListener l) { + properties.removeListener(l); + } + + @Override + public Collection getKeys() { + return properties.keySet(); + } +} diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ThruConnectorImpl.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultThruConnector.java similarity index 80% rename from VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ThruConnectorImpl.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultThruConnector.java index 8848f9f6..1f6dce97 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/ThruConnectorImpl.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultThruConnector.java @@ -1,69 +1,66 @@ -/* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * Please cite the following publication(s): - * - * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - - * A Framework for Declarative GUI Programming on the Java Platform. - * Computing and Visualization in Science, 2011, in press. - * - * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of Michael Hoffer . - */ -package eu.mihosoft.vrl.workflow; - -/** - * This class provides the default implementation of a {@code Connector} in - * VWorkflows - * - * @author Michael Hoffer <info@michaelhoffer.de> - */ -public class ThruConnectorImpl extends ConnectorImpl implements ThruConnector{ - - private VNode innerNode; - private Connector innerConnector; - - public ThruConnectorImpl(VNode node, String type, String localId, boolean input, VNode innerNode, Connector innerConnector) { - super(node, type, localId, input); - - this.innerNode = innerNode; - this.innerConnector = innerConnector; - } -// -// public ThruConnectorImpl(VNode node, Connector c) { -// super(node, c); -// } - - @Override - public VNode getInnerNode() { - return this.innerNode; - } - - @Override - public Connector getInnerConnector() { - return this.innerConnector; - } - - -} +/* + * Copyright 2012-2017 Michael Hoffer . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Please cite the following publication(s): + * + * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - + * A Framework for Declarative GUI Programming on the Java Platform. + * Computing and Visualization in Science, 2011, in press. + * + * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of Michael Hoffer . + */ +package eu.mihosoft.vrl.workflow.impl; + +import eu.mihosoft.vrl.workflow.Connector; +import eu.mihosoft.vrl.workflow.ThruConnector; +import eu.mihosoft.vrl.workflow.VNode; + +/** + * This class provides the default implementation of a {@code Connector} in + * VWorkflows + * + * @author Michael Hoffer <info@michaelhoffer.de> + */ +public class DefaultThruConnector extends DefaultConnector implements ThruConnector { + protected final VNode innerNode; + protected final Connector innerConnector; + + public DefaultThruConnector(VNode node, String type, String localId, boolean input, VNode innerNode, Connector innerConnector) { + super(node, type, localId, input); + + this.innerNode = innerNode; + this.innerConnector = innerConnector; + } + + @Override + public VNode getInnerNode() { + return this.innerNode; + } + + @Override + public Connector getInnerConnector() { + return this.innerConnector; + } +} diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultVFlow.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultVFlow.java new file mode 100644 index 00000000..c810d8b4 --- /dev/null +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultVFlow.java @@ -0,0 +1,90 @@ +/* + * Copyright 2012-2017 Michael Hoffer . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Please cite the following publication(s): + * + * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - + * A Framework for Declarative GUI Programming on the Java Platform. + * Computing and Visualization in Science, 2011, in press. + * + * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of Michael Hoffer . + */ +package eu.mihosoft.vrl.workflow.impl; + +import eu.mihosoft.vrl.workflow.IdGenerator; +import eu.mihosoft.vrl.workflow.NodeLookup; +import eu.mihosoft.vrl.workflow.VFlow; +import eu.mihosoft.vrl.workflow.VFlowModel; +import eu.mihosoft.vrl.workflow.base.AbstractVFlow; +import eu.mihosoft.vrl.workflow.skin.ConnectionSkin; +import eu.mihosoft.vrl.workflow.skin.FlowNodeSkinLookup; +import eu.mihosoft.vrl.workflow.skin.SkinFactory; +import eu.mihosoft.vrl.workflow.skin.VNodeSkin; + +import java.util.Collection; + +/** + * An implementation of the {@code VFlow} interface. This class manages the + * workflow + * + * @author Michael Hoffer <info@michaelhoffer.de> + */ +public class DefaultVFlow extends AbstractVFlow { + public DefaultVFlow(VFlowModel model) { + super(model); + } + + public DefaultVFlow(VFlowModel model, SkinFactory[] skinFactories) { + super(model, skinFactories); + } + + public DefaultVFlow(VFlow parent, VFlowModel model, SkinFactory[] skinFactories) { + super(parent, model, skinFactories); + } + + public DefaultVFlow(VFlowModel model, Collection> skinFactories) { + super(model, skinFactories); + } + + public DefaultVFlow(VFlow parent, VFlowModel model, Collection> skinFactories) { + super(parent, model, skinFactories); + } + + protected IdGenerator instantiateIdGenerator() { + return new DefaultIdGenerator(); + } + + protected FlowNodeSkinLookup instantiateSkinLookup() { + return new DefaultFlowNodeSkinLookup(this); + } + + protected VFlow instantiateVFlow(VFlowModel flowNode, Collection> childFactories) { + return new DefaultVFlow(this, flowNode, childFactories); + } + + protected NodeLookup instantiateNodeLookup(VFlowModel model) { + return new DefaultNodeLookup(model); + } +} \ No newline at end of file diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultVFlowModel.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultVFlowModel.java new file mode 100644 index 00000000..d1ff2bf5 --- /dev/null +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultVFlowModel.java @@ -0,0 +1,63 @@ +/* + * Copyright 2012-2017 Michael Hoffer . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Please cite the following publication(s): + * + * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - + * A Framework for Declarative GUI Programming on the Java Platform. + * Computing and Visualization in Science, 2011, in press. + * + * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of Michael Hoffer . + */ +package eu.mihosoft.vrl.workflow.impl; + +import eu.mihosoft.vrl.workflow.FlowModel; +import eu.mihosoft.vrl.workflow.VFlowModel; +import eu.mihosoft.vrl.workflow.VNode; +import eu.mihosoft.vrl.workflow.base.AbstractVFlowModel; + +/** + * @author Michael Hoffer <info@michaelhoffer.de> + */ +public class DefaultVFlowModel extends AbstractVFlowModel { + public DefaultVFlowModel(FlowModel parentFlow) { + super(parentFlow); + } + + @Override + protected FlowModel instantiateFlowModel() { + return new DefaultFlowModel(); + } + + @Override + protected VNode instantiateVNode(VFlowModel parentFlow) { + return new DefaultVNode(parentFlow); + } + + @Override + protected VFlowModel instantiateVFlowModel(FlowModel parent) { + return new DefaultVFlowModel(parent); + } +} \ No newline at end of file diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultVNode.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultVNode.java new file mode 100644 index 00000000..fea3ff00 --- /dev/null +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultVNode.java @@ -0,0 +1,82 @@ +/* + * Copyright 2012-2017 Michael Hoffer . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Please cite the following publication(s): + * + * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - + * A Framework for Declarative GUI Programming on the Java Platform. + * Computing and Visualization in Science, 2011, in press. + * + * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of Michael Hoffer . + */ +package eu.mihosoft.vrl.workflow.impl; + +import eu.mihosoft.vrl.workflow.Connector; +import eu.mihosoft.vrl.workflow.IdGenerator; +import eu.mihosoft.vrl.workflow.ThruConnector; +import eu.mihosoft.vrl.workflow.VFlowModel; +import eu.mihosoft.vrl.workflow.VNode; +import eu.mihosoft.vrl.workflow.ValueObject; +import eu.mihosoft.vrl.workflow.VisualizationRequest; +import eu.mihosoft.vrl.workflow.base.AbstractVNode; + +/** + * @author Michael Hoffer <info@michaelhoffer.de> + */ +public class DefaultVNode extends AbstractVNode { + public DefaultVNode(VFlowModel flow) { + super(flow); + } + + @Override + protected IdGenerator instantiateIdGenerator() { + return new DefaultIdGenerator(); + } + + @Override + protected ValueObject instantiateValueObject() { + return new DefaultValueObject(this); + } + + @Override + protected VisualizationRequest instantiateVisualizationRequest() { + return new DefaultVisualizationRequest(); + } + + @Override + protected Connector instantiateConnector(VNode node, String type, String localId, boolean input) { + return new DefaultConnector(node, type, localId, input); + } + + @Override + protected ThruConnector instantiateThruConnector(VNode node, String type, String localId, boolean input, VNode innerNode, Connector innerConnector) { + return new DefaultThruConnector(node, type, localId, input, innerNode, innerConnector); + } + + @Override + protected Connector instantiateConnector(VNode node, Connector connector) { + return new DefaultConnector(node, connector); + } +} diff --git a/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/ConnectionImplClassTest.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultValueObject.java similarity index 62% rename from VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/ConnectionImplClassTest.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultValueObject.java index 23e329fa..9d3c66b3 100644 --- a/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/ConnectionImplClassTest.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultValueObject.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -31,41 +31,43 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of Michael Hoffer . */ -package eu.mihosoft.vrl.workflow; +package eu.mihosoft.vrl.workflow.impl; -import org.junit.Assert; -import org.junit.Test; +import eu.mihosoft.vrl.workflow.CompatibilityResult; +import eu.mihosoft.vrl.workflow.VNode; +import eu.mihosoft.vrl.workflow.ValueObject; +import eu.mihosoft.vrl.workflow.base.AbstractValueObject; /** + * This class defines a value object you can assign a value. * * @author Michael Hoffer <info@michaelhoffer.de> */ -public class ConnectionImplClassTest { - - @Test - public void testImplClassWithConformingConstructor() { - VFlow flow = FlowFactory.newFlow(); - - flow.getConnections("mytype").setConnectionClass(ConnectionBase.class); +public class DefaultValueObject extends AbstractValueObject { + public DefaultValueObject() { } - public void testImplClassWithNonConformingConstructor() { - VFlow flow = FlowFactory.newFlow(); - - boolean exceptionThrown = false; - - try{ - flow.getConnections("mytype").setConnectionClass( - ConnectionBaseWithoutConformingConstructor.class); - } catch(IllegalArgumentException ex) { - exceptionThrown = true; - } - - Assert.assertTrue("IllegalArgumentException must be thrown!", exceptionThrown); + public DefaultValueObject(VNode parent) { + super(parent); } -} -class ConnectionBaseWithoutConformingConstructor extends ConnectionBase { - // - private ConnectionBaseWithoutConformingConstructor() {}; + @Override + public CompatibilityResult compatible(final ValueObject sender, final String flowType) { + return new CompatibilityResult() { + @Override + public boolean isCompatible() { + return sender != DefaultValueObject.this; + } + + @Override + public String getMessage() { + return "incompatible: " + sender.getParent().getId() + " -> " + getParent().getId(); + } + + @Override + public String getStatus() { + throw new UnsupportedOperationException("Not supported yet."); + } + }; + } } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VisualizationRequestImpl.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultVisualizationRequest.java similarity index 90% rename from VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VisualizationRequestImpl.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultVisualizationRequest.java index ca9c2183..7c3ebba3 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VisualizationRequestImpl.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/DefaultVisualizationRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -36,17 +36,16 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ -package eu.mihosoft.vrl.workflow; +package eu.mihosoft.vrl.workflow.impl; + +import eu.mihosoft.vrl.workflow.VisualizationRequest; /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ -class VisualizationRequestImpl extends PropertyStorageImpl implements VisualizationRequest { - +public class DefaultVisualizationRequest extends DefaultPropertyStorage implements VisualizationRequest { @Override public void setStyle(String style) { - if (style == null) { style = ""; } @@ -58,5 +57,4 @@ public void setStyle(String style) { public String getStyle() { return get(VisualizationRequest.KEY_STYLE).get().toString(); } - } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/NoDefaultConnectorValueObject.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/NoDefaultConnectorValueObject.java similarity index 92% rename from VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/NoDefaultConnectorValueObject.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/NoDefaultConnectorValueObject.java index dd283af3..349de8ab 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/NoDefaultConnectorValueObject.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/impl/NoDefaultConnectorValueObject.java @@ -1,70 +1,70 @@ -/* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * Please cite the following publication(s): - * - * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - - * A Framework for Declarative GUI Programming on the Java Platform. - * Computing and Visualization in Science, 2011, in press. - * - * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of Michael Hoffer . - */ -package eu.mihosoft.vrl.workflow; - -/** - * - * @author Michael Hoffer <info@michaelhoffer.de> - */ -public class NoDefaultConnectorValueObject extends DefaultValueObject { - - public NoDefaultConnectorValueObject() { - } - - public NoDefaultConnectorValueObject(VNode parent) { - super(parent); - } - - - - @Override - public CompatibilityResult compatible(final ValueObject sender, final String flowType) { - return new CompatibilityResult() { - @Override - public boolean isCompatible() { - return false; - } - - @Override - public String getMessage() { - return "No default connector has been specified for type: " + flowType + " in node" + getParent().getId(); - } - - @Override - public String getStatus() { - throw new UnsupportedOperationException("Not supported yet."); - } - }; - } -} +/* + * Copyright 2012-2017 Michael Hoffer . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Please cite the following publication(s): + * + * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - + * A Framework for Declarative GUI Programming on the Java Platform. + * Computing and Visualization in Science, 2011, in press. + * + * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of Michael Hoffer . + */ +package eu.mihosoft.vrl.workflow.impl; + +import eu.mihosoft.vrl.workflow.CompatibilityResult; +import eu.mihosoft.vrl.workflow.VNode; +import eu.mihosoft.vrl.workflow.ValueObject; + +/** + * @author Michael Hoffer <info@michaelhoffer.de> + */ +public class NoDefaultConnectorValueObject extends DefaultValueObject { + public NoDefaultConnectorValueObject() { + } + + public NoDefaultConnectorValueObject(VNode parent) { + super(parent); + } + + @Override + public CompatibilityResult compatible(final ValueObject sender, final String flowType) { + return new CompatibilityResult() { + @Override + public boolean isCompatible() { + return false; + } + + @Override + public String getMessage() { + return "No default connector has been specified for type: " + flowType + " in node" + getParent().getId(); + } + + @Override + public String getStatus() { + throw new UnsupportedOperationException("Not supported yet."); + } + }; + } +} diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/incubating/LayoutGenerator.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/incubating/LayoutGenerator.java index e51a455a..3a1a806c 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/incubating/LayoutGenerator.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/incubating/LayoutGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -36,68 +36,76 @@ import eu.mihosoft.vrl.workflow.VFlowModel; /** - * This interface describes a layout generator. A layout generator is used to + * This interface describes a layout generator. A layout generator is used to * calculate an aesthetically pleasing arrangement of nodes. - * + * * @author Tobias Mertz */ public interface LayoutGenerator { - + /** * Returns the workflow to be laid out. + * * @return VFlowModel */ - public VFlowModel getWorkflow(); - + VFlowModel getWorkflow(); + /** - * If set to true, the layout is applied to all subflows of the given + * If set to true, the layout is applied to all subflows of the given * workflow recursively. + * * @return boolean */ - public boolean getRecursive(); - + boolean getRecursive(); + /** - * If set to true, subflow nodes in the given workflow are automatically + * If set to true, subflow nodes in the given workflow are automatically * scaled to fit their contents. + * * @return boolean */ - public boolean getAutoscaleNodes(); - + boolean getAutoscaleNodes(); + /** * If set to true, debugging output will be printed in the command line. - * @return + * + * @return */ - public boolean getDebug(); - + boolean getDebug(); + /** * Sets the workflow to be laid out. + * * @param pworkflow VFlowModel */ - public void setWorkflow(VFlowModel pworkflow); - + void setWorkflow(VFlowModel pworkflow); + /** - * If set to true, the layout is applied to all subflows of the given + * If set to true, the layout is applied to all subflows of the given * workflow recursively. + * * @param precursive boolean */ - public void setRecursive(boolean precursive); - + void setRecursive(boolean precursive); + /** - * If set to true, subflow nodes in the given workflow are automatically + * If set to true, subflow nodes in the given workflow are automatically * scaled to fit their contents. + * * @param pautoscaleNodes boolean */ - public void setAutoscaleNodes(boolean pautoscaleNodes); - + void setAutoscaleNodes(boolean pautoscaleNodes); + /** * If set to true, debugging output will be printed in the command line. + * * @param pdebug boolean */ - public void setDebug(boolean pdebug); - + void setDebug(boolean pdebug); + /** * Generates the Layout. */ - public void generateLayout() ; - + void generateLayout(); + } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/incubating/LayoutGeneratorNaive.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/incubating/LayoutGeneratorNaive.java index 18e6c719..6a06aed3 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/incubating/LayoutGeneratorNaive.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/incubating/LayoutGeneratorNaive.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -39,24 +39,25 @@ import eu.mihosoft.vrl.workflow.Connections; import eu.mihosoft.vrl.workflow.VFlowModel; import eu.mihosoft.vrl.workflow.VNode; +import javafx.collections.ObservableList; +import javafx.collections.ObservableMap; + import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.Objects; import java.util.Set; -import javafx.collections.ObservableList; -import javafx.collections.ObservableMap; /** * This class provides a naive implementation for the LayoutGenerator interface. - * Nodes will be positioned in a layered arrangement, but there is no process + * Nodes will be positioned in a layered arrangement, but there is no process * for the minimization of line-crossings. - * + * * @author Tobias Mertz */ public class LayoutGeneratorNaive implements LayoutGenerator { - + // parameters: private VFlowModel workflow; private LinkedList> connectionList; @@ -70,7 +71,7 @@ public class LayoutGeneratorNaive implements LayoutGenerator { private double scaling; private double subflowscale; private boolean debug; - + // internal fields: private VNode[] nodes; private int nodecount; @@ -78,7 +79,7 @@ public class LayoutGeneratorNaive implements LayoutGenerator { private boolean cycle; private int[] layering; private int layercount; - + /** * Default constructor. * Debug is set to false. @@ -87,19 +88,20 @@ public LayoutGeneratorNaive() { this.debug = false; initialize(); } - + /** * Constructor with debug-functionality. - * Debug parameter can be set, all other parameters are initialized with + * Debug parameter can be set, all other parameters are initialized with * default values. + * * @param pdebug boolean */ public LayoutGeneratorNaive(boolean pdebug) { this.debug = pdebug; initialize(); - if(this.debug) System.out.println("Creating layout generator"); + if (this.debug) { System.out.println("Creating layout generator"); } } - + /** * Initializes the fields of the class needed in future methods. */ @@ -115,338 +117,369 @@ private void initialize() { this.scaling = -1.5; this.subflowscale = 2.0; } - + // + /** * Returns the workflow to be laid out. + * * @return VFlowModel */ @Override public VFlowModel getWorkflow() { return this.workflow; } - + /** * Returns a list of the nodes to be laid out. * default: the nodelist is gathered from the given workflow. + * * @return Collection */ public Collection getNodelist() { Collection nodelist = new ArrayList<>(); int i; - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { nodelist.add(this.nodes[i]); } return nodelist; } - + /** - * If set to true, the layout is applied to all subflows of the given + * If set to true, the layout is applied to all subflows of the given * workflow recursively. * default: true + * * @return boolean */ @Override public boolean getRecursive() { return this.recursive; } - + /** - * If set to true, subflow nodes in the given workflow are automatically + * If set to true, subflow nodes in the given workflow are automatically * scaled to fit their contents. * default: true + * * @return boolean */ @Override public boolean getAutoscaleNodes() { return this.autoscaleNodes; } - + /** * Returns the set input type. * 0 - VFlowModel (setWorkflow) * 2 - nodelist (setNodelist) - * The input must be delivered via the corresponding setter method before + * The input must be delivered via the corresponding setter method before * the call of generateLayout(). * default: 0 + * * @return int */ public int getGraphmode() { return this.graphmode; } - + /** - * If set to true, a depth-first-search is performed and all back edges are - * removed from the model graph. The layout is then applied without these + * If set to true, a depth-first-search is performed and all back edges are + * removed from the model graph. The layout is then applied without these * edges. * Is only run if the graph contains cycles. * default: true + * * @return boolean */ public boolean getLaunchRemoveCycles() { return this.launchRemoveCycles; } - + /** * If set to true, a new layering for the given graph is created. * default: true + * * @return boolean */ public boolean getLaunchCreateLayering() { return this.launchCreateLayering; } - + /** - * If set to true, the vertical position for each node is calculated and + * If set to true, the vertical position for each node is calculated and * changed. * Does not change the order of nodes on each layer. * default: true + * * @return boolean */ public boolean getLaunchCalculateVerticalPositions() { return this.launchCalculateVerticalPositions; } - + /** - * If set to true, the horizontal position for each layer is calculated and + * If set to true, the horizontal position for each layer is calculated and * changed. * default: true + * * @return boolean */ public boolean getLaunchCalculateHorizontalPositions() { return this.launchCalculateHorizontalPositions; } - + /** - * Returns the scaling parameter of the algorithm. + * Returns the scaling parameter of the algorithm. * Determines the distance between nodes. * default: -1.5 + * * @return double */ public double getScaling() { return this.scaling; } - + /** - * Returns the scaling factor that is used to scale subflow-nodes in the + * Returns the scaling factor that is used to scale subflow-nodes in the * autoscaleNodes procedure. * default: 2.0 + * * @return double */ public double getSubflowscale() { return this.subflowscale; } - + /** * If set to true, debugging output will be printed in the command line. * default: false + * * @return boolean */ @Override public boolean getDebug() { return this.debug; } - + /** * Returns the Graph modeled after the workflow. + * * @return LinkedList> */ public LinkedList> getModelGraph() { return this.connectionList; } - + /** * Returns the layering of the current graph as an array of layer indices. + * * @return int[] */ public int[] getLayering() { return this.layering; } // - + // + /** * Sets the workflow to be laid out. + * * @param pworkflow VFlowModel */ @Override public void setWorkflow(VFlowModel pworkflow) { this.workflow = pworkflow; } - + /** * Sets the list of nodes to be laid out. * default: the nodelist is gathered from the given workflow. + * * @param pnodelist Collection */ public void setNodelist(Collection pnodelist) { this.nodes = new VNode[pnodelist.size()]; int i = 0; Iterator it = pnodelist.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { this.nodes[i] = it.next(); i++; } } - + /** - * If set to true, the layout is applied to all subflows of the given + * If set to true, the layout is applied to all subflows of the given * workflow recursively. * default: true + * * @param precursive boolean */ @Override public void setRecursive(boolean precursive) { this.recursive = precursive; } - + /** - * If set to true, subflow nodes in the given workflow are automatically + * If set to true, subflow nodes in the given workflow are automatically * scaled to fit their contents. * default: true + * * @param pautoscaleNodes boolean */ @Override public void setAutoscaleNodes(boolean pautoscaleNodes) { this.autoscaleNodes = pautoscaleNodes; } - + /** * Sets the input type. * 0 - VFlowModel (setWorkflow) * 2 - nodelist (setNodelist) - * The input must be delivered via the corresponding setter method before + * The input must be delivered via the corresponding setter method before * the call of generateLayout(). * default: 0 + * * @param pgraphmode int */ public void setGraphmode(int pgraphmode) { this.graphmode = pgraphmode; } - + /** - * If set to true, a depth-first-search is performed and all back edges are - * removed from the model graph. The layout is then applied without these + * If set to true, a depth-first-search is performed and all back edges are + * removed from the model graph. The layout is then applied without these * edges. * Is only run if the graph contains cycles. - * default: true + * default: true + * * @param plaunchRemoveCycles boolean */ public void setLaunchRemoveCycles(boolean plaunchRemoveCycles) { this.launchRemoveCycles = plaunchRemoveCycles; } - - + + /** * If set to true, a new layering for the given graph is created. * default: true + * * @param plaunchCreateLayering boolean */ public void setLaunchCreateLayering(boolean plaunchCreateLayering) { this.launchCreateLayering = plaunchCreateLayering; } - + /** - * If set to true, the vertical position for each node is calculated and + * If set to true, the vertical position for each node is calculated and * changed. * Does not change the order of nodes on each layer. * default: true + * * @param plaunchCalculateVerticalPositions boolean */ public void setLaunchCalculateVerticalPositions( - boolean plaunchCalculateVerticalPositions) { - this.launchCalculateVerticalPositions = - plaunchCalculateVerticalPositions; + boolean plaunchCalculateVerticalPositions) { + this.launchCalculateVerticalPositions = + plaunchCalculateVerticalPositions; } - + /** - * If set to true, the horizontal position for each layer is calculated and + * If set to true, the horizontal position for each layer is calculated and * changed. * default: true + * * @param plaunchCalculateHorizontalPositions boolean */ public void setLaunchCalculateHorizontalPositions( - boolean plaunchCalculateHorizontalPositions) { - this.launchCalculateHorizontalPositions = - plaunchCalculateHorizontalPositions; + boolean plaunchCalculateHorizontalPositions) { + this.launchCalculateHorizontalPositions = + plaunchCalculateHorizontalPositions; } - + /** - * Sets the scaling parameter of the algorithm. + * Sets the scaling parameter of the algorithm. * Determines the distance between nodes. * default: -1.5 + * * @param pscaling double */ public void setScaling(double pscaling) { this.scaling = pscaling; } - + /** - * Sets the scaling factor that is used to scale subflow-nodes in the + * Sets the scaling factor that is used to scale subflow-nodes in the * autoscaleNodes procedure. * default: 2.0 + * * @param psubflowscale double */ public void setSubflowscale(double psubflowscale) { this.subflowscale = psubflowscale; } - + /** * If set to true, debugging output will be printed in the command line. * default: false + * * @param pdebug boolean */ @Override public void setDebug(boolean pdebug) { this.debug = pdebug; } - + /** * Sets the model graph. + * * @param pconnectionList LinkedList> */ public void setModelGraph(LinkedList> pconnectionList) { this.connectionList = pconnectionList; } - + /** * Sets the layering of the current graph as an array of layer indices. + * * @param playering int[] */ public void setLayering(int[] playering) { this.layering = playering; } // - + /** - * Sets up the model-fields. This includes nodearray, nodecount and the + * Sets up the model-fields. This includes nodearray, nodecount and the * model graph. * Uses either a VFlowModel or a nodelist depending on the graphmode * parameter. + * * @return boolean */ public boolean setUp() { int i; - switch(this.graphmode) { + switch (this.graphmode) { // VFlowModel: case 0: - if(this.workflow == null) return false; + if (this.workflow == null) { return false; } // gather nodelist from workflow - ObservableList nodesTemp = this.workflow.getNodes(); - if(nodesTemp == null) return false; + ObservableList nodesTemp = this.workflow.getNodes(); + if (nodesTemp == null) { return false; } this.nodecount = nodesTemp.size(); this.nodes = new VNode[this.nodecount]; // copy nodelist into nodearray for better performance in the future - for(i = 0; i < nodesTemp.size(); i++) { + for (i = 0; i < nodesTemp.size(); i++) { this.nodes[i] = nodesTemp.get(i); } break; // nodelist: case 2: - if(this.debug) System.out.println("laying out with nodelist"); - if(this.nodes == null) return false; + if (this.debug) { System.out.println("laying out with nodelist"); } + if (this.nodes == null) { return false; } this.nodecount = this.nodes.length; - if(this.nodecount == 0) return false; + if (this.nodecount == 0) { return false; } this.workflow = this.nodes[0].getFlow(); break; // default: @@ -457,77 +490,79 @@ public boolean setUp() { // get all edges this.connectionList = new LinkedList<>(); this.conncount = 0; - ObservableMap allConnections = - this.workflow.getAllConnections(); + ObservableMap allConnections = + this.workflow.getAllConnections(); // get all types of connections Set keys = allConnections.keySet(); Iterator it = keys.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { // get all connections for current type String currType = it.next(); Connections currConns = allConnections.get(currType); ObservableList connections = currConns.getConnections(); int currConnCount = connections.size(); - for(i = 0; i < currConnCount; i++) { + for (i = 0; i < currConnCount; i++) { Connection currConn = connections.get(i); // create a tuple of the sender and receiver of the current // connection and add it to the connectionlist Integer out = getNodeID(currConn.getSender().getNode()); Integer in = getNodeID(currConn.getReceiver().getNode()); - if((out != -1) && (in != -1)) { + if ((out != -1) && (in != -1)) { this.connectionList.add(new Pair<>(out, in)); this.conncount++; } } } this.cycle = checkCycles(); - if(this.debug) System.out.println("Setup complete with " + if (this.debug) { + System.out.println("Setup complete with " + this.nodecount + " nodes and " + this.conncount + " edges."); + } return true; } - + /** * Checks if the graph contains cycles. + * * @return boolean */ private boolean checkCycles() { int i; boolean[] checked = new boolean[this.nodecount]; - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { int j; // initialize checked with all entries set to false - for(j = 0; j < this.nodecount; j++) { + for (j = 0; j < this.nodecount; j++) { checked[j] = false; } LinkedList succs = new LinkedList<>(); - for(j = 0; j < this.conncount; j++) { - if(this.connectionList.get(j).getFirst() == i) { + for (j = 0; j < this.conncount; j++) { + if (this.connectionList.get(j).getFirst() == i) { succs.add(this.connectionList.get(j).getSecond()); } } Iterator it = succs.iterator(); // iterate through all successors of start node - while(it.hasNext()) { + while (it.hasNext()) { Integer currNode = it.next(); // if current node is the start node, the start node can be // reached -> there is a cycle - if(currNode == i) { - if(this.debug) System.out.println("graph contains cycles"); + if (currNode == i) { + if (this.debug) { System.out.println("graph contains cycles"); } return true; - } - else { + } else { // if current node is not the start node and has not yet // been checked, add all successors of current node to the // list, reset the iterator, set checked for current // node true. // -> all nodes that are reacheable from start node will // be checked once. - if(!checked[currNode]) { - for(j = 0; j < this.conncount; j++) { - if(Objects.equals(this.connectionList.get(j) - .getFirst(), currNode)) { + if (!checked[currNode]) { + for (j = 0; j < this.conncount; j++) { + if (Objects.equals(this.connectionList.get(j) + .getFirst(), currNode)) { succs.add(this.connectionList.get(j) - .getSecond()); + .getSecond()); it = succs.iterator(); checked[currNode] = true; } @@ -536,73 +571,76 @@ private boolean checkCycles() { } } } - if(this.debug) System.out.println("graph contains no cycles."); + if (this.debug) { System.out.println("graph contains no cycles."); } return false; } - + /** - * Performs a depth-first search and removes all back edges so that the + * Performs a depth-first search and removes all back edges so that the * resulting graph is cycle free. */ private void removeCycles() { int i; boolean[] checked = new boolean[this.nodecount]; // initialize checked with all entries set to false - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { checked[i] = false; } LinkedList path = new LinkedList<>(); // iterate through all nodes - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { // start recursive search with current node as startingpoint remCycR(i, path, checked); } } - + /** * Recursive helper-function to be used by removeCycles(). - * @param VNode curr: current node - * @param path LinkedList: the path from the root-node to the - * current node - * @param checked boolean[]: array of length nodecount showing which nodes - * were already checked - */ - private void remCycR(Integer curr, LinkedList path, - boolean[] checked) { - if(!checked[curr]) { + * + * @param VNode curr: current node + * @param path LinkedList: the path from the root-node to the + * current node + * @param checked boolean[]: array of length nodecount showing which nodes + * were already checked + */ + private void remCycR(Integer curr, LinkedList path, + boolean[] checked) { + if (!checked[curr]) { // add current node to path path.addFirst(curr); checked[curr] = true; int i; LinkedList succs = new LinkedList<>(); // get successors to current node - for(i = 0; i < this.conncount; i++) { - if(Objects.equals(this.connectionList.get(i).getFirst(), curr)) { + for (i = 0; i < this.conncount; i++) { + if (Objects.equals(this.connectionList.get(i).getFirst(), curr)) { succs.add(this.connectionList.get(i).getSecond()); } } // perform search on all successors. - if(!succs.isEmpty()) { + if (!succs.isEmpty()) { Iterator it = succs.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { Integer currSucc = it.next(); // if edge from curr to currSucc is a back edge - if(path.contains(currSucc)) { + if (path.contains(currSucc)) { // remove all edges from curr to currSucc Iterator> its = this.connectionList - .iterator(); - while(its.hasNext()) { + .iterator(); + while (its.hasNext()) { Pair currConn = its.next(); - if(Objects.equals(currConn.getFirst(), curr) - && Objects.equals(currConn.getSecond(), - currSucc)) { + if (Objects.equals(currConn.getFirst(), curr) + && Objects.equals(currConn.getSecond(), + currSucc)) { this.connectionList.remove(currConn); its = this.connectionList.iterator(); this.conncount--; } } - if(this.debug) System.out.println("removing edge from " + if (this.debug) { + System.out.println("removing edge from " + curr + " to " + currSucc); + } } // if edge from curr to currSucc is not a back edge else { @@ -614,60 +652,59 @@ private void remCycR(Integer curr, LinkedList path, path.removeFirst(); } } - + /** * Applies all steps of the layout, whose launch-parameters are set to true. */ @Override public void generateLayout() { - if(this.debug) System.out.println("Generating layout."); + if (this.debug) { System.out.println("Generating layout."); } // setup and check for errors - if(this.setUp()) { + if (this.setUp()) { // get origin point double minx = Double.POSITIVE_INFINITY; double miny = Double.POSITIVE_INFINITY; int i; - for(i = 0; i < this.nodecount; i++) { - if(this.nodes[i].getX() < minx) minx = this.nodes[i].getX(); - if(this.nodes[i].getY() < miny) miny = this.nodes[i].getY(); + for (i = 0; i < this.nodecount; i++) { + if (this.nodes[i].getX() < minx) { minx = this.nodes[i].getX(); } + if (this.nodes[i].getY() < miny) { miny = this.nodes[i].getY(); } } - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { this.nodes[i].setX(this.nodes[i].getX() - minx); this.nodes[i].setY(this.nodes[i].getY() - miny); } - - if(this.cycle) { - if(this.launchRemoveCycles) { + + if (this.cycle) { + if (this.launchRemoveCycles) { removeCycles(); - } - else { - if(this.debug) System.out.println("Cycles in graph. please " + } else { + if (this.debug) { + System.out.println("Cycles in graph. please " + "run with launchRemoveCycles set to true."); + } return; } } // apply layout to subflows - if(this.recursive) { + if (this.recursive) { runSubflows(); } // scale nodes according to their contents. - if(this.autoscaleNodes) { + if (this.autoscaleNodes) { autoscaleNodes(); } // apply layout - if(this.launchCreateLayering) createLayering(); - if(this.launchCalculateVerticalPositions) - calculateVerticalPositions(); - if(this.launchCalculateHorizontalPositions) - calculateHorizontalPositions(); + if (this.launchCreateLayering) { createLayering(); } + if (this.launchCalculateVerticalPositions) { calculateVerticalPositions(); } + if (this.launchCalculateHorizontalPositions) { calculateHorizontalPositions(); } // displace by origin point - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { this.nodes[i].setX(this.nodes[i].getX() + minx); this.nodes[i].setY(this.nodes[i].getY() + miny); } } } - + /** * Applies the layout with the same parameters to each subflow. */ @@ -679,30 +716,32 @@ private void runSubflows() { subgen.setLaunchRemoveCycles(this.launchRemoveCycles); // apply layout to each subflow int i; - for(i = 0; i < this.nodecount; i++) { - if(this.nodes[i] instanceof VFlowModel) { + for (i = 0; i < this.nodecount; i++) { + if (this.nodes[i] instanceof VFlowModel) { subgen.setWorkflow((VFlowModel) this.nodes[i]); subgen.generateLayout(); } } } - + /** * Scales subflow-nodes according to their contents. */ private void autoscaleNodes() { int i; - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { VFlowModel subflow; - if(!(this.nodes[i] instanceof VFlowModel)) continue; + if (!(this.nodes[i] instanceof VFlowModel)) { continue; } subflow = (VFlowModel) this.nodes[i]; // get node representation of the current subflow VNode flownode = this.nodes[i]; - if(this.debug) System.out.println("Resizing subflow-node " + if (this.debug) { + System.out.println("Resizing subflow-node " + flownode.getId()); + } // get nodes from the subflow Collection subnodes = subflow.getNodes(); - if(subnodes.isEmpty()) continue; + if (subnodes.isEmpty()) { continue; } Iterator nodeit = subnodes.iterator(); double minx = Double.POSITIVE_INFINITY; double maxx = Double.NEGATIVE_INFINITY; @@ -710,38 +749,48 @@ private void autoscaleNodes() { double maxy = Double.NEGATIVE_INFINITY; // iterate over all subflow nodes to get outermost coordinates of // subflow - while(nodeit.hasNext()) { + while (nodeit.hasNext()) { VNode currNode = nodeit.next(); double x = currNode.getX(); double y = currNode.getY(); - if(this.debug) System.out.println(currNode.getId() + " has " + if (this.debug) { + System.out.println(currNode.getId() + " has " + "position (" + x + "|" + y + ")"); - if(minx > x) minx = x; - if(maxx < (x + currNode.getWidth())) maxx = x + } + if (minx > x) { minx = x; } + if (maxx < (x + currNode.getWidth())) { + maxx = x + currNode.getWidth(); - if(miny > y) miny = y; - if(maxy < (y + currNode.getHeight())) maxy = y + } + if (miny > y) { miny = y; } + if (maxy < (y + currNode.getHeight())) { + maxy = y + currNode.getHeight(); + } } - if(this.debug) System.out.println("extreme positions of " - + flownode.getId() + " are min: (" + minx + "|" + miny + if (this.debug) { + System.out.println("extreme positions of " + + flownode.getId() + " are min: (" + minx + "|" + miny + ") max: (" + maxx + "|" + maxy + ")"); + } // calculate size of subflow double width = maxx - minx; double height = maxy - miny; - if(this.debug) System.out.println("Resizing subflow-node " + if (this.debug) { + System.out.println("Resizing subflow-node " + flownode.getId() + " from size (" + flownode.getWidth() + "|" + flownode.getHeight() + ") to size (" - + (width / subnodes.size() * this.subflowscale) + "|" + + (width / subnodes.size() * this.subflowscale) + "|" + (height / subnodes.size() * this.subflowscale) + ")"); + } // set size of node representing current subflow flownode.setWidth(width / subnodes.size() * this.subflowscale); flownode.setHeight(height / subnodes.size() * this.subflowscale); } } - + /** - * Creates a new layering, assigning each node the lowest layer possible, + * Creates a new layering, assigning each node the lowest layer possible, * while still having all of its preceeding nodes on a lower layer. */ private void createLayering() { @@ -750,30 +799,32 @@ private void createLayering() { this.layering = new int[this.nodecount]; int lockable = 0; boolean[] locked = new boolean[this.nodecount]; - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { this.layering[i] = 0; locked[i] = false; } - while(!allLocked(locked)) { + while (!allLocked(locked)) { Iterator> it = this.connectionList.iterator(); // iterate over all connections - while(it.hasNext()) { + while (it.hasNext()) { Pair curr = it.next(); // set all receivers of the current connection to the layer of // their receiver + 1 - if((!locked[curr.getSecond()]) - && (this.layering[curr.getSecond()] - < (this.layering[curr.getFirst()] + 1))) { - this.layering[curr.getSecond()] = - this.layering[curr.getFirst()] + 1; + if ((!locked[curr.getSecond()]) + && (this.layering[curr.getSecond()] + < (this.layering[curr.getFirst()] + 1))) { + this.layering[curr.getSecond()] = + this.layering[curr.getFirst()] + 1; } } - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { // layers that have been finalized - if(this.layering[i] == lockable) { + if (this.layering[i] == lockable) { locked[i] = true; - if(this.debug) System.out.println(this.nodes[i].getId() + if (this.debug) { + System.out.println(this.nodes[i].getId() + " locked on layer " + lockable); + } } } // each iteration, the next layer can be locked @@ -781,23 +832,25 @@ private void createLayering() { } this.layercount = lockable; } - + /** * Returns true if all nodes are on a locked layer. + * * @param locked boolean[] + * * @return boolean */ private boolean allLocked(boolean[] locked) { boolean result = true; int i; - for(i = 0; i < locked.length; i++) { - if(!locked[i]) result = false; + for (i = 0; i < locked.length; i++) { + if (!locked[i]) { result = false; } } return result; } - + /** - * Calculates the vertical positions of the nodes in each layer depending on + * Calculates the vertical positions of the nodes in each layer depending on * their height and the scaling parameter. * Does not sort nodes to reduce edge crossings. */ @@ -805,45 +858,46 @@ private void calculateVerticalPositions() { int i; int currlayer; int[] layer; - if(this.layering == null) return; - if(this.layercount == 0) return; - for(currlayer = 0; currlayer < this.layercount; currlayer++) { + if (this.layering == null) { return; } + if (this.layercount == 0) { return; } + for (currlayer = 0; currlayer < this.layercount; currlayer++) { // create array of the layer int nodeson = 0; // find number of nodes on current layer - for(i = 0; i < this.nodecount; i++) { - if(this.layering[i] == currlayer) nodeson++; + for (i = 0; i < this.nodecount; i++) { + if (this.layering[i] == currlayer) { nodeson++; } } int layeri = 0; layer = new int[nodeson]; // find nodes on current layer - for(i = 0; i < this.nodecount; i++) { - if(this.layering[i] == currlayer) { + for (i = 0; i < this.nodecount; i++) { + if (this.layering[i] == currlayer) { layer[layeri] = i; layeri++; } } // iterate over all nodes on current layer double posy = 0.; - for(i = 0; i < nodeson; i++) { - if(this.debug) System.out.println("Vertical position of " - + this.nodes[layer[i]].getId() + " on layer " + for (i = 0; i < nodeson; i++) { + if (this.debug) { + System.out.println("Vertical position of " + + this.nodes[layer[i]].getId() + " on layer " + currlayer + " set to " + posy); + } this.nodes[layer[i]].setY(posy); // increase position for next node by height of current node // and scaling - if(this.scaling < 0) { - posy = posy + this.nodes[layer[i]].getHeight() - * this.scaling * (-1); - } - else { - posy = posy + this.nodes[layer[i]].getHeight() - + this.scaling; + if (this.scaling < 0) { + posy = posy + this.nodes[layer[i]].getHeight() + * this.scaling * (-1); + } else { + posy = posy + this.nodes[layer[i]].getHeight() + + this.scaling; } } } } - + /** * Calculates horizontal positions of the layers depending on node width. */ @@ -852,56 +906,58 @@ private void calculateHorizontalPositions() { int currlayer; int[] layer; double posx = 0.; - if(this.layering == null) return; - if(this.layercount == 0) return; - for(currlayer = 0; currlayer < this.layercount; currlayer++) { + if (this.layering == null) { return; } + if (this.layercount == 0) { return; } + for (currlayer = 0; currlayer < this.layercount; currlayer++) { // create array of layer int nodeson = 0; // find number of nodes on current layer - for(i = 0; i < this.nodecount; i++) { - if(this.layering[i] == currlayer) nodeson++; + for (i = 0; i < this.nodecount; i++) { + if (this.layering[i] == currlayer) { nodeson++; } } int layeri = 0; layer = new int[nodeson]; // find nodes on current layer - for(i = 0; i < this.nodecount; i++) { - if(this.layering[i] == currlayer) { + for (i = 0; i < this.nodecount; i++) { + if (this.layering[i] == currlayer) { layer[layeri] = i; layeri++; } } // iterate over all nodes on current layer double maxwidth = Double.NEGATIVE_INFINITY; - for(i = 0; i < nodeson; i++) { - if(this.debug) System.out.println("Horizontal position of " - + this.nodes[layer[i]].getId() + " on layer " + for (i = 0; i < nodeson; i++) { + if (this.debug) { + System.out.println("Horizontal position of " + + this.nodes[layer[i]].getId() + " on layer " + currlayer + " set to " + posx); + } this.nodes[layer[i]].setX(posx); // find max width on current layer - if(this.nodes[layer[i]].getWidth() > maxwidth) { + if (this.nodes[layer[i]].getWidth() > maxwidth) { maxwidth = this.nodes[layer[i]].getWidth(); } } // increase position for next layer by max width and scaling - if(this.scaling < 0) { + if (this.scaling < 0) { posx = posx + maxwidth * this.scaling * (-1); - } - else { + } else { posx = posx + maxwidth + this.scaling; } } } - + /** * Returns index of the given node in the nodearray. + * * @param pnode VNode + * * @return Integer - */ + */ private Integer getNodeID(VNode pnode) { int i; - for(i = 0; i < this.nodecount; i++) { - if(this.nodes[i].equals(pnode)) - return i; + for (i = 0; i < this.nodecount; i++) { + if (this.nodes[i].equals(pnode)) { return i; } } return -1; } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/incubating/LayoutGeneratorSmart.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/incubating/LayoutGeneratorSmart.java index 3d0788ad..bf1d8e0a 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/incubating/LayoutGeneratorSmart.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/incubating/LayoutGeneratorSmart.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -34,10 +34,10 @@ package eu.mihosoft.vrl.workflow.incubating; import cern.colt.Arrays; -import edu.uci.ics.jung.algorithms.layout.ISOMLayout; +import edu.uci.ics.jung.algorithms.layout.DAGLayout; import edu.uci.ics.jung.algorithms.layout.FRLayout; +import edu.uci.ics.jung.algorithms.layout.ISOMLayout; import edu.uci.ics.jung.algorithms.layout.KKLayout; -import edu.uci.ics.jung.algorithms.layout.DAGLayout; import edu.uci.ics.jung.algorithms.layout.Layout; import edu.uci.ics.jung.graph.DirectedGraph; import edu.uci.ics.jung.graph.DirectedSparseGraph; @@ -46,6 +46,9 @@ import eu.mihosoft.vrl.workflow.Connections; import eu.mihosoft.vrl.workflow.VFlowModel; import eu.mihosoft.vrl.workflow.VNode; +import javafx.collections.ObservableList; +import javafx.collections.ObservableMap; + import java.awt.Dimension; import java.awt.geom.Point2D; import java.util.ArrayList; @@ -53,18 +56,16 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.Set; -import javafx.collections.ObservableList; -import javafx.collections.ObservableMap; -/** - * This class provides a sophisticated implementation for the LayoutGenerator +/** + * This class provides a sophisticated implementation for the LayoutGenerator * interface based on layout algorithms implemented in * the Java Universal Network/Graph Drawing Framework. - * + * * @author Tobias Mertz */ public class LayoutGeneratorSmart implements LayoutGenerator { - + // parameters: private VFlowModel workflow; private DirectedGraph jgraph; @@ -89,7 +90,7 @@ public class LayoutGeneratorSmart implements LayoutGenerator { private double direction; private double alignmentThreshold; private boolean debug; - + // internal fields: private VNode[] nodes; private Layout layout; @@ -98,7 +99,7 @@ public class LayoutGeneratorSmart implements LayoutGenerator { private Point2D graphcenter; private Pair[] origin; private boolean cycle; - + /** * Default constructor. * All parameters are initialized with default values. @@ -107,19 +108,20 @@ public LayoutGeneratorSmart() { this.debug = false; initialization(); } - + /** * Constructor with debug-functionality. - * Debug parameter can be set, all other parameters are initialized with + * Debug parameter can be set, all other parameters are initialized with * default values. + * * @param pdebug boolean */ public LayoutGeneratorSmart(boolean pdebug) { this.debug = pdebug; initialization(); - if(this.debug) System.out.println("Creating Layout Generator."); + if (this.debug) { System.out.println("Creating Layout Generator."); } } - + /** * Initializes the fields of the class needed in future methods. */ @@ -146,62 +148,68 @@ private void initialization() { this.direction = 0.; this.alignmentThreshold = (this.scaling - 1) * (-1); } - + // + /** * Returns the workflow to be laid out. + * * @return VFlowModel */ @Override public VFlowModel getWorkflow() { return this.workflow; } - + /** * Returns the model graph to be laid out. * default: a graph is generated automatically from the workflow given. + * * @return DirectedGraph */ public DirectedGraph getModelGraph() { return this.jgraph; } - + /** * Returns a list of the nodes to be laid out. * default: the nodelist is gathered from the given workflow. + * * @return Collection */ public Collection getNodelist() { Collection nodelist = new ArrayList<>(); int i; - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { nodelist.add(this.nodes[i]); } return nodelist; } - + /** - * If set to true, the layout is applied to all subflows of the given + * If set to true, the layout is applied to all subflows of the given * workflow recursively. * default: true + * * @return boolean */ @Override public boolean getRecursive() { return this.recursive; } - + /** - * If set to true, subflow nodes in the given workflow are automatically + * If set to true, subflow nodes in the given workflow are automatically * scaled to fit their contents. * default: true + * * @return boolean */ @Override public boolean getAutoscaleNodes() { return this.autoscaleNodes; } - + /** * Returns the Jung layout that is used in the first step of the algorithm. * 0 - ISOM Layout @@ -209,207 +217,226 @@ public boolean getAutoscaleNodes() { * 2 - KK Layout * 3 - DAG Layout (Does not terminate if the graph contains cycles) * default: 0 + * * @return int */ public int getLayoutSelector() { return this.layoutSelector; } - + /** * Returns the aspect ratio of the initial drawing area of the graph. * Width is determined via the longest path in the graph. * Height is determined by dividing the width by the aspect ratio. * default: 16:9 + * * @return double */ public double getAspectratio() { return this.aspectratio; } - + /** * Returns the set input type. * 0 - VFlowModel (setWorkflow) * 1 - jgraph (setModelGraph) * 2 - nodelist (setNodelist) - * The input must be delivered via the corresponding setter method before + * The input must be delivered via the corresponding setter method before * the call of generateLayout(). * default: 0 + * * @return int */ public int getGraphmode() { return this.graphmode; } - + /** - * If set to true, a depth-first-search is performed and all back edges are - * removed from the model graph. The layout is then applied without these + * If set to true, a depth-first-search is performed and all back edges are + * removed from the model graph. The layout is then applied without these * edges. * Is only run if the graph contains cycles. * default: true + * * @return boolean */ public boolean getLaunchRemoveCycles() { return this.launchRemoveCycles; } - + /** - * If set to true, disjunct parts of the model graph will be laid out - * separately and then arranged over each other to create the cumulative + * If set to true, disjunct parts of the model graph will be laid out + * separately and then arranged over each other to create the cumulative * layout. - * Is never run if launchRemoveCycles is false and the graph contains + * Is never run if launchRemoveCycles is false and the graph contains * cycles, because it does not terminate in this case. * default: true + * * @return boolean */ public boolean getLaunchSeparateDisjunctGraphs() { return this.launchSeparateDisjunctGraphs; } - + /** - * If set to true, edge types will be separated and a layout generated that + * If set to true, edge types will be separated and a layout generated that * follows edge type priorities. * There is no working implementation for this feature yet. * default: false + * * @return boolean */ public boolean getLaunchSeparateEdgeTypes() { return this.launchSeparateEdgeTypes; } - + /** - * If set to true, the specified algorithm from the JUNG-library is applied + * If set to true, the specified algorithm from the JUNG-library is applied * to the graph. * The algorithm is specified using setLayoutSelector(). * default: true + * * @return boolean */ public boolean getLaunchJungLayout() { return this.launchJungLayout; } - + /** - * If set to true, the graph is rotated to reach an average flow direction + * If set to true, the graph is rotated to reach an average flow direction * that is the direction specified. * default: true + * * @return boolean */ public boolean getLaunchRotate() { return this.launchRotate; } - + /** - * If set to true, nodes with an in-degree of 0 will be placed at the + * If set to true, nodes with an in-degree of 0 will be placed at the * leftmost edge of the drawing space. - * Is always run if launchSeparateDisjunctGraphs is true, launchRemoveCycles - * is false and the graph contains cycles, because separateDisjunctGraphs + * Is always run if launchSeparateDisjunctGraphs is true, launchRemoveCycles + * is false and the graph contains cycles, because separateDisjunctGraphs * does not terminate if the graph contains cycles. * default: false + * * @return boolean */ public boolean getLaunchOrigin() { return this.launchOrigin; } - + /** - * If set to true, all nodes will be pushed past their predecessors, so no + * If set to true, all nodes will be pushed past their predecessors, so no * edges have a direction inverse to the specified direction. - * Is never run if launchRemoveCycles is false and the graph contains + * Is never run if launchRemoveCycles is false and the graph contains * cycles, because it does not terminate in this case. * default: true + * * @return boolean */ public boolean getLaunchPushBack() { return this.launchPushBack; } - + /** - * If set to true, nodes that are placed on the same coordinates will be + * If set to true, nodes that are placed on the same coordinates will be * displaced slightly, so the forcePush step can move them accordingly. * default: true + * * @return boolean */ public boolean getLaunchDisplaceIdents() { return this.launchDisplaceIdents; } - + /** - * If set to true, all nodes will repel each other until no overlaps between + * If set to true, all nodes will repel each other until no overlaps between * nodes are left or the maximum amount of iterations has been reached. * default: true + * * @return boolean */ public boolean getLaunchForcePush() { return this.launchForcePush; } - + /** - * If set to true, nodes will be aligned either with each other or on a + * If set to true, nodes will be aligned either with each other or on a * global grid. * default: true + * * @return boolean */ public boolean getLaunchAlignNodes() { return this.launchAlignNodes; } - + /** - * Returns the maximum amount of iterations used by the force push step + * Returns the maximum amount of iterations used by the force push step * of the algorithm. * default: 500 + * * @return boolean */ public int getMaxiterations() { return this.maxiterations; } - + /** - * Returns the scaling parameter of the algorithm. + * Returns the scaling parameter of the algorithm. * Determines the distance between nodes. * default: 1.2 + * * @return double */ public double getScaling() { return this.scaling; } - + /** - * Returns the scaling factor that is used to scale subflow-nodes in the + * Returns the scaling factor that is used to scale subflow-nodes in the * autoscaleNodes procedure. * default: 2.0 + * * @return double */ public double getSubflowscale() { return this.subflowscale; } - + /** * Returns the desired average edge direction of the resulting graph as an * angle to the abscissa in degrees. * default: 0. + * * @return double */ public double getDirection() { return this.direction; } - + /** * Sets the alignment parameter used to align nodes with each other. - * If the value is positive it describes the size of a grid which nodes + * If the value is positive it describes the size of a grid which nodes * will be aligned on. - * If the value is negative its absolute value will be used as multiplier - * to the mean size of each pair of nodes which will then result in a - * threshold under which these two nodes will be positioned at the same + * If the value is negative its absolute value will be used as multiplier + * to the mean size of each pair of nodes which will then result in a + * threshold under which these two nodes will be positioned at the same * coordinate. * default: -(scaling - 1) + * * @return double */ public double getAlignmentThreshold() { return this.alignmentThreshold; } - + /** * If set to true, debugging output will be printed in the command line. * default: false + * * @return boolean */ @Override @@ -417,274 +444,299 @@ public boolean getDebug() { return this.debug; } // - + // + /** * Sets the workflow to be laid out. + * * @param pworkflow VFlowModel */ @Override public void setWorkflow(VFlowModel pworkflow) { this.workflow = pworkflow; } - + /** * Sets the model graph to be laid out. * default: a graph is generated automatically from the workflow given. + * * @param pjgraph DirectedGraph */ public void setModelGraph(DirectedGraph pjgraph) { this.jgraph = pjgraph; } - + /** * Sets the list of nodes to be laid out. * default: the nodelist is gathered from the given workflow. + * * @param pnodelist Collection */ public void setNodelist(Collection pnodelist) { this.nodes = new VNode[pnodelist.size()]; int i = 0; Iterator it = pnodelist.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { this.nodes[i] = it.next(); i++; } } - + /** - * If set to true, the layout is applied to all subflows of the given + * If set to true, the layout is applied to all subflows of the given * workflow recursively. * default: true + * * @param precursive boolean */ @Override public void setRecursive(boolean precursive) { this.recursive = precursive; } - + /** - * If set to true, subflow nodes in the given workflow are automatically + * If set to true, subflow nodes in the given workflow are automatically * scaled to fit their contents. * Can only be run if graphmode is set to 0. * default: true + * * @param pautoscaleNodes boolean */ @Override public void setAutoscaleNodes(boolean pautoscaleNodes) { this.autoscaleNodes = pautoscaleNodes; } - + /** - * Select the Jung layout that is supposed to be used in the first step of + * Select the Jung layout that is supposed to be used in the first step of * the algorithm. * 0 - ISOM Layout * 1 - FR Layout * 2 - KK Layout * 3 - DAG Layout (Does not terminate if the graph contains cycles) * default: 0 + * * @param playoutSelector int */ public void setLayoutSelector(int playoutSelector) { this.layoutSelector = playoutSelector; } - + /** * Sets the aspect ratio of the initial drawing area of the graph. - * Width of the drawing space is determined via the longest path in the + * Width of the drawing space is determined via the longest path in the * graph. * Height is determined by dividing the width by the aspect ratio. * default: 16:9 + * * @param paspectratio double */ public void setAspectratio(double paspectratio) { this.aspectratio = paspectratio; } - + /** * Sets the input type. * 0 - VFlowModel (setWorkflow) * 1 - jgraph (setModelGraph) * 2 - nodelist (setNodelist) - * The input must be delivered via the corresponding setter method before + * The input must be delivered via the corresponding setter method before * the call of generateLayout(). * default: 0 + * * @param pgraphmode int */ public void setGraphmode(int pgraphmode) { this.graphmode = pgraphmode; } - + /** - * If set to true, a depth-first-search is performed and all back edges are - * removed from the model graph. The layout is then applied without these + * If set to true, a depth-first-search is performed and all back edges are + * removed from the model graph. The layout is then applied without these * edges. * Is only run if the graph contains cycles. - * default: true + * default: true + * * @param plaunchRemoveCycles boolean */ public void setLaunchRemoveCycles(boolean plaunchRemoveCycles) { this.launchRemoveCycles = plaunchRemoveCycles; } - + /** - * If set to true, disjunct parts of the model graph will be laid out - * separately and then arranged over each other to create the cumulative + * If set to true, disjunct parts of the model graph will be laid out + * separately and then arranged over each other to create the cumulative * layout. - * Is never run if launchRemoveCycles is false and the graph contains + * Is never run if launchRemoveCycles is false and the graph contains * cycles, because it does not terminate in this case. * default: true + * * @param plaunchSeparateDisjunctGraphs boolean */ public void setLaunchSeparateDisjunctGraphs( - boolean plaunchSeparateDisjunctGraphs) { + boolean plaunchSeparateDisjunctGraphs) { this.launchSeparateDisjunctGraphs = plaunchSeparateDisjunctGraphs; } - + /** - * If set to true, edge types will be separated and a layout generated that + * If set to true, edge types will be separated and a layout generated that * follows edge type priorities. * There is no working implementation for this feature yet. * default: false + * * @param plaunchSeparateEdgeTypes boolean */ public void setLaunchSeparateEdgeTypes(boolean plaunchSeparateEdgeTypes) { this.launchSeparateEdgeTypes = plaunchSeparateEdgeTypes; } - + /** - * If set to true, the specified algorithm from the JUNG-library is applied + * If set to true, the specified algorithm from the JUNG-library is applied * to the graph. * The algorithm is specified using setLayoutSelector(). * default: true + * * @param plaunchJungLayout boolean */ public void setLaunchJungLayout(boolean plaunchJungLayout) { this.launchJungLayout = plaunchJungLayout; } - + /** - * If set to true, the graph is rotated to reach an average flow direction + * If set to true, the graph is rotated to reach an average flow direction * that is the direction specified. * default: true + * * @param plaunchRotate boolean */ public void setLaunchRotate(boolean plaunchRotate) { this.launchRotate = plaunchRotate; } - + /** - * If set to true, nodes with an in-degree of 0 will be placed at the + * If set to true, nodes with an in-degree of 0 will be placed at the * leftmost edge of the drawing space. - * Is always run if launchSeparateDisjunctGraphs is true, launchRemoveCycles - * is false and the graph contains cycles, because separateDisjunctGraphs + * Is always run if launchSeparateDisjunctGraphs is true, launchRemoveCycles + * is false and the graph contains cycles, because separateDisjunctGraphs * does not terminate if the graph contains cycles. * default: false + * * @param plaunchOrigin boolean */ public void setLaunchOrigin(boolean plaunchOrigin) { this.launchOrigin = plaunchOrigin; } - + /** - * If set to true, all nodes will be pushed past their predecessors, so no + * If set to true, all nodes will be pushed past their predecessors, so no * edges have a direction inverse to the specified direction. * (Does not terminate if the graph contains cycles) * default: true + * * @param plaunchPushBack boolean */ public void setLaunchPushBack(boolean plaunchPushBack) { this.launchPushBack = plaunchPushBack; } - + /** - * If set to true, nodes that are placed on the same coordinates will be + * If set to true, nodes that are placed on the same coordinates will be * displaced slightly, so the forcePush step can move them accordingly. * default: true + * * @param plaunchDisplaceIdents boolean */ public void setLaunchDisplaceIdents(boolean plaunchDisplaceIdents) { this.launchDisplaceIdents = plaunchDisplaceIdents; } - + /** - * If set to true, all nodes will repel each other until no overlaps between + * If set to true, all nodes will repel each other until no overlaps between * nodes are left or the maximum amount of iterations has been reached. * default: true + * * @param plaunchForcePush boolean */ public void setLaunchForcePush(boolean plaunchForcePush) { this.launchForcePush = plaunchForcePush; } - + /** - * If set to true, nodes will be aligned either with each other or on a + * If set to true, nodes will be aligned either with each other or on a * global grid. * default: true + * * @param plaunchAlignNodes boolean */ public void setLaunchAlignNodes(boolean plaunchAlignNodes) { this.launchAlignNodes = plaunchAlignNodes; } - + /** - * Sets the maximum amount of iterations for the force push step of the + * Sets the maximum amount of iterations for the force push step of the * algorithm. * default: 500 + * * @param pmaxiterations int */ public void setMaxiterations(int pmaxiterations) { this.maxiterations = pmaxiterations; } - + /** - * Sets the scaling parameter of the algorithm. + * Sets the scaling parameter of the algorithm. * Determines the distance between nodes. * default: 1.2 + * * @param pscaling double */ public void setScaling(double pscaling) { this.scaling = pscaling; } - + /** - * Sets the scaling factor that is used to scale subflow-nodes in the + * Sets the scaling factor that is used to scale subflow-nodes in the * autoscaleNodes procedure. * default: 2.0 + * * @param psubflowscale double */ public void setSubflowscale(double psubflowscale) { this.subflowscale = psubflowscale; } - + /** - * Sets the desired average edge direction as an angle to the abscissa in + * Sets the desired average edge direction as an angle to the abscissa in * degrees. * default: 0. + * * @param pdirection double */ public void setDirection(double pdirection) { this.direction = pdirection; } - + /** * Sets the alignment parameter used to align nodes with each other. - * If the value is positive it describes the size of a grid which nodes + * If the value is positive it describes the size of a grid which nodes * will be aligned on. - * If the value is negative its absolute value will be used as multiplier - * to the mean size of each pair of nodes which will then result in a - * threshold under which these two nodes will be positioned at the same + * If the value is negative its absolute value will be used as multiplier + * to the mean size of each pair of nodes which will then result in a + * threshold under which these two nodes will be positioned at the same * coordinate. * default: -(scaling - 1) + * * @param palignmentThreshold double */ public void setAlignmentThreshold(double palignmentThreshold) { this.alignmentThreshold = palignmentThreshold; } - + /** * If set to true, debugging output will be printed in the command line. * default: false + * * @param pdebug boolean */ @Override @@ -692,30 +744,31 @@ public void setDebug(boolean pdebug) { this.debug = pdebug; } // - + /** * Sets up the model-fields. These include the nodearray, nodecount, origin- * nodes and the model graph. - * Uses either a VFlowModel, a Jung-Graph or a nodelist depending on the + * Uses either a VFlowModel, a Jung-Graph or a nodelist depending on the * graphmode parameter. + * * @return boolean */ private boolean allNodesSetUp() { int i; - switch(this.graphmode) { + switch (this.graphmode) { // VFlowModel: case 0: - if(this.workflow == null) return false; + if (this.workflow == null) { return false; } // gather nodelist from workflow ObservableList nodesTemp = this.workflow.getNodes(); - if(nodesTemp == null) return false; + if (nodesTemp == null) { return false; } this.nodecount = nodesTemp.size(); - if(this.nodecount == 0) return false; + if (this.nodecount == 0) { return false; } this.nodes = new VNode[this.nodecount]; this.jgraph = new DirectedSparseGraph<>(); // copy nodelist into nodearray for better performance in the // future and add nodes to the jgraph - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { this.nodes[i] = nodesTemp.get(i); this.jgraph.addVertex(this.nodes[i]); } @@ -723,19 +776,19 @@ private boolean allNodesSetUp() { break; // jgraph: case 1: - if(this.debug) System.out.println("laying out jgraph."); - if(this.jgraph == null) return false; + if (this.debug) { System.out.println("laying out jgraph."); } + if (this.jgraph == null) { return false; } // gather nodelist from modelgraph Collection temp = this.jgraph.getVertices(); Iterator it = temp.iterator(); this.nodecount = temp.size(); - if(this.nodecount == 0) return false; + if (this.nodecount == 0) { return false; } this.conncount = this.jgraph.getEdgeCount(); this.nodes = new VNode[this.nodecount]; // copy nodelist into nodearray for better performance in the // future i = 0; - while(it.hasNext()) { + while (it.hasNext()) { this.nodes[i] = it.next(); i++; } @@ -743,14 +796,14 @@ private boolean allNodesSetUp() { break; // nodelist: case 2: - if(this.debug) System.out.println("laying out with nodelist"); - if(this.nodes == null) return false; + if (this.debug) { System.out.println("laying out with nodelist"); } + if (this.nodes == null) { return false; } this.nodecount = this.nodes.length; - if(this.nodecount == 0) return false; + if (this.nodecount == 0) { return false; } this.workflow = this.nodes[0].getFlow(); // get all connections this.jgraph = new DirectedSparseGraph<>(); - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { this.jgraph.addVertex(this.nodes[i]); } createGraph(this.workflow.getAllConnections()); @@ -766,9 +819,10 @@ private boolean allNodesSetUp() { this.cycle = checkCycles(); return true; } - + /** * Creates a jung graph from a map of connections. + * * @param allConnections ObservableMap */ private void createGraph(ObservableMap allConnections) { @@ -777,117 +831,123 @@ private void createGraph(ObservableMap allConnections) { // get all types of connections Set keys = allConnections.keySet(); Iterator it = keys.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { // get all connections for current type String currType = it.next(); Connections currConns = allConnections.get(currType); ObservableList connections = currConns.getConnections(); int currConnCount = connections.size(); - for(i = 0; i < currConnCount; i++) { + for (i = 0; i < currConnCount; i++) { Connection currConn = connections.get(i); // add an edge correspondig to the current connection to the // jgraph if both sender and receiver are part of the nodearray Integer sender = getNodeID(currConn.getSender().getNode()); Integer receiver = getNodeID(currConn.getReceiver().getNode()); - if((sender != -1) && (receiver != -1)) { - this.jgraph.addEdge(currConn, this.nodes[sender], - this.nodes[receiver]); + if ((sender != -1) && (receiver != -1)) { + this.jgraph.addEdge(currConn, this.nodes[sender], + this.nodes[receiver]); this.conncount++; } } } } - + /** * Returns all origin nodes of the graph. * Origin nodes are all nodes with an in-degree of 0. - * @return Pair[]: Array of Pairs. Each Pair contains the model-ID + * + * @return Pair[]: Array of Pairs. Each Pair contains the model-ID * of the node and its successor count. */ private Pair[] getOrigin() { int i; // add all nodes with in-degree of 0 to list LinkedList originL = new LinkedList<>(); - for(i = 0; i < this.nodecount; i++) { - if(this.jgraph.inDegree(this.nodes[i]) == 0) originL.add(i); + for (i = 0; i < this.nodecount; i++) { + if (this.jgraph.inDegree(this.nodes[i]) == 0) { originL.add(i); } } // create array for origin values int length = originL.size(); Pair[] origina = new Pair[length]; // add pairs of id and successorcount for all entries of the origin-list // to the origin array - for(i = 0; i < length; i++) { + for (i = 0; i < length; i++) { int curr = originL.removeFirst(); - origina[i] = + origina[i] = new Pair<>(curr, this.jgraph.getSuccessorCount( - this.nodes[curr])); - if(this.debug) System.out.println(this.nodes[curr].getId() - + " | In-Degree: " + this.jgraph.inDegree(this.nodes[curr]) - + " Successors: " + this.nodes[curr])); + if (this.debug) { + System.out.println(this.nodes[curr].getId() + + " | In-Degree: " + this.jgraph.inDegree(this.nodes[curr]) + + " Successors: " + this.jgraph.getSuccessorCount(this.nodes[curr])); + } } return origina; } /** * Calculates the average x and y coordinates of all nodes. + * * @return Point2D */ private Point2D getGraphCenter() { int i; double centerx = 0; double centery = 0; - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { centerx += this.nodes[i].getX(); centery += this.nodes[i].getY(); } centerx /= this.nodecount; centery /= this.nodecount; - if(this.debug) System.out.println("Center of graph is at: (" + if (this.debug) { + System.out.println("Center of graph is at: (" + centerx + "|" + centery + ")"); + } return new Point2D.Double(centerx, centery); } - + /** * Checks if the graph contains cycles. + * * @return boolean */ private boolean checkCycles() { int i; boolean[] checked = new boolean[this.nodecount]; - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { int j; // initialize checked with all entries set to false - for(j = 0; j < this.nodecount; j++) { + for (j = 0; j < this.nodecount; j++) { checked[j] = false; } // select start node VNode start = this.nodes[i]; - if(this.jgraph.getSuccessorCount(start) > 0) { + if (this.jgraph.getSuccessorCount(start) > 0) { Collection succsnomod = this.jgraph.getSuccessors(start); LinkedList succs = new LinkedList<>(); succs.addAll(succsnomod); Iterator it = succs.iterator(); // iterate through all successors of start node - while(it.hasNext()) { + while (it.hasNext()) { VNode currNode = it.next(); - if(getNodeID(currNode) == -1) continue; + if (getNodeID(currNode) == -1) { continue; } // if current node is the start node, the start node can be // reached -> there is a cycle - if(currNode.equals(start)) { - if(this.debug) { + if (currNode.equals(start)) { + if (this.debug) { System.out.println("graph contains cycles."); } return true; - } - else { + } else { // if current node is not the start node and has not yet // been checked, add all successors of current node to // the list, reset the iterator, set checked for current // node true. // -> all nodes that are reacheable from start node will // be checked once. - if(!checked[getNodeID(currNode)]) { + if (!checked[getNodeID(currNode)]) { succs.addAll(this.jgraph.getSuccessors(currNode)); it = succs.iterator(); checked[getNodeID(currNode)] = true; @@ -895,74 +955,77 @@ private boolean checkCycles() { } } } - + } - if(this.debug) System.out.println("graph contains no cycles."); - return false; + if (this.debug) { System.out.println("graph contains no cycles."); } + return false; } - + /** - * Performs a depth-first search and removes all back edges so that the + * Performs a depth-first search and removes all back edges so that the * resulting graph is cycle free. */ private void removeCycles() { int i; boolean[] checked = new boolean[this.nodecount]; // initialize checked with all entries set to false - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { checked[i] = false; } LinkedList path = new LinkedList<>(); // iterate through all origin nodes - for(i = 0; i < this.origin.length; i++) { + for (i = 0; i < this.origin.length; i++) { // select current node as start node and start recursive search VNode start = this.nodes[this.origin[i].getFirst()]; remCycR(start, path, checked); } - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { // start recursive search for all nodes that have not yet been // checked - if(!checked[i]) { + if (!checked[i]) { VNode start = this.nodes[i]; remCycR(start, path, checked); } } this.cycle = false; } - + /** * Recursive helper-function to be used by removeCycles(). - * @param VNode curr: current node - * @param path LinkedList: the path from the root-node to the current - * node - * @param checked boolean[]: array of length nodecount showing which nodes - * were already checked + * + * @param VNode curr: current node + * @param path LinkedList: the path from the root-node to the current + * node + * @param checked boolean[]: array of length nodecount showing which nodes + * were already checked */ private void remCycR(VNode curr, LinkedList path, boolean[] checked) { - if(!checked[getNodeID(curr)]) { + if (!checked[getNodeID(curr)]) { // add current node to path path.addFirst(curr); checked[getNodeID(curr)] = true; // perform search on all successors. Collection succs = this.jgraph.getSuccessors(curr); - if(!succs.isEmpty()) { + if (!succs.isEmpty()) { Iterator it = succs.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { VNode currSucc = it.next(); - if(getNodeID(currSucc) == -1) continue; + if (getNodeID(currSucc) == -1) { continue; } // if edge from curr to currSucc is a back edge - if(path.contains(currSucc)) { + if (path.contains(currSucc)) { // remove all edges from curr to currSucc - Collection conns = - this.jgraph.findEdgeSet(curr, currSucc); + Collection conns = + this.jgraph.findEdgeSet(curr, currSucc); Iterator its = conns.iterator(); - while(its.hasNext()) { + while (its.hasNext()) { Connection currConn = its.next(); this.jgraph.removeEdge(currConn); this.conncount--; } - if(this.debug) System.out.println("removing edge from " + if (this.debug) { + System.out.println("removing edge from " + curr.getId() + " to " + currSucc.getId()); + } it = succs.iterator(); } // if edge from curr to currSucc is not a back edge @@ -975,16 +1038,16 @@ private void remCycR(VNode curr, LinkedList path, boolean[] checked) { path.removeFirst(); } } - + /** * Checks the graph for multiple disjunct parts. * Gives each node an ID depending on which disjunct part it belongs to. * Then applies the layout with the given parameters to each disjunct part. - * Arranges the resulting graphs over each other to create the cumulative + * Arranges the resulting graphs over each other to create the cumulative * layout. */ private void separateDisjunctGraphs() { - if(this.debug) System.out.println("separating disjunct graphs"); + if (this.debug) { System.out.println("separating disjunct graphs"); } int currID; int maxID = -1; LinkedList nextnodes = new LinkedList<>(); @@ -992,62 +1055,65 @@ private void separateDisjunctGraphs() { int i; int j; // initialize graphID for all nodes to -1 - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { graphs[i] = -1; } // iterate through all origin nodes - for(i = 0; i < this.origin.length; i++) { + for (i = 0; i < this.origin.length; i++) { // add all reachable nodes to same graphID currID = maxID + 1; nextnodes.add(this.nodes[this.origin[i].getFirst()]); - while(!nextnodes.isEmpty()) { + while (!nextnodes.isEmpty()) { int currNode = getNodeID(nextnodes.removeFirst()); - if(graphs[currNode] == -1) { + if (graphs[currNode] == -1) { // if node has not yet been added to a graph, // it is added to the current graphID graphs[currNode] = currID; - } - else { + } else { // if node was already reached from other graphID, // all nodes in this iteration are connected with that // ID as well - if(this.debug) System.out.println("currID " + currID - + " graphid " + graphs[currNode] + "graph: " + if (this.debug) { + System.out.println("currID " + currID + + " graphid " + graphs[currNode] + "graph: " + Arrays.toString(graphs)); - for(j = 0; j < this.nodecount; j++) { - if(graphs[j] == currID) graphs[j] = graphs[currNode]; + } + for (j = 0; j < this.nodecount; j++) { + if (graphs[j] == currID) { graphs[j] = graphs[currNode]; } } currID = graphs[currNode]; - if(this.debug) System.out.println("graph now: " + if (this.debug) { + System.out.println("graph now: " + Arrays.toString(graphs)); + } } // add successors of current node to queue, so all reachable // nodes will be iterated over - if(this.jgraph.getSuccessorCount(this.nodes[currNode]) != 0) { - Collection succ = - this.jgraph.getSuccessors(this.nodes[currNode]); + if (this.jgraph.getSuccessorCount(this.nodes[currNode]) != 0) { + Collection succ = + this.jgraph.getSuccessors(this.nodes[currNode]); Iterator it = succ.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { VNode temp = it.next(); - if(getNodeID(temp) == -1) continue; - if(graphs[getNodeID(temp)] != currID) { + if (getNodeID(temp) == -1) { continue; } + if (graphs[getNodeID(temp)] != currID) { nextnodes.add(temp); } } } } // calculate new maxID - for(j = 0; j < this.nodecount; j++) { - if(graphs[j] > maxID) maxID = graphs[j]; + for (j = 0; j < this.nodecount; j++) { + if (graphs[j] > maxID) { maxID = graphs[j]; } } } - if(this.debug) { - for(i = 0; i < this.nodecount; i++) { - System.out.println(this.nodes[i].getId() + " belongs to graph " - + graphs[i]); + if (this.debug) { + for (i = 0; i < this.nodecount; i++) { + System.out.println(this.nodes[i].getId() + " belongs to graph " + + graphs[i]); } } - + // initialize subgenerator for subgraphs LayoutGeneratorSmart subgen = new LayoutGeneratorSmart(); subgen.setAspectratio(this.aspectratio); @@ -1076,26 +1142,30 @@ private void separateDisjunctGraphs() { double x = 0.; double[] xpos = new double[this.nodecount]; double[] ypos = new double[this.nodecount]; - + // iterate over all found graphIDs - for(i = 0; i <= maxID; i++) { - if(this.debug) System.out.println("--- laying out subgraph with ID " + for (i = 0; i <= maxID; i++) { + if (this.debug) { + System.out.println("--- laying out subgraph with ID " + i); + } double minx = Double.POSITIVE_INFINITY; double miny = Double.POSITIVE_INFINITY; double maxy = Double.NEGATIVE_INFINITY; // create subgraph for nodes with current graphID - DirectedGraph subgraph = - new DirectedSparseGraph<>(); - for(j = 0; j < this.nodecount; j++) { - if(graphs[j] == i) { - if(this.debug) System.out.println(this.nodes[j].getId() + DirectedGraph subgraph = + new DirectedSparseGraph<>(); + for (j = 0; j < this.nodecount; j++) { + if (graphs[j] == i) { + if (this.debug) { + System.out.println(this.nodes[j].getId() + " belongs to the subgraph with ID " + i); + } subgraph.addVertex(this.nodes[j]); - Collection conns = - this.jgraph.getIncidentEdges(this.nodes[j]); + Collection conns = + this.jgraph.getIncidentEdges(this.nodes[j]); Iterator it = conns.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { Connection currConn = it.next(); VNode sender = currConn.getSender().getNode(); VNode receiver = currConn.getReceiver().getNode(); @@ -1107,29 +1177,33 @@ private void separateDisjunctGraphs() { subgen.setModelGraph(subgraph); subgen.generateLayout(); // find outermost coordinates of graph - for(j = 0; j < this.nodecount; j++) { - if(graphs[j] == i) { - if(this.nodes[j].getX() < minx) minx = this.nodes[j].getX(); - if(this.nodes[j].getY() < miny) miny = this.nodes[j].getY(); - if((this.nodes[j].getY() - + this.nodes[j].getHeight()) > maxy) { + for (j = 0; j < this.nodecount; j++) { + if (graphs[j] == i) { + if (this.nodes[j].getX() < minx) { minx = this.nodes[j].getX(); } + if (this.nodes[j].getY() < miny) { miny = this.nodes[j].getY(); } + if ((this.nodes[j].getY() + + this.nodes[j].getHeight()) > maxy) { maxy = this.nodes[j].getY() + this.nodes[j].getHeight(); } } } - if(this.debug) System.out.println("graphID: " + i + " minx: " - + minx + " miny: " + miny + " maxy: " + maxy + if (this.debug) { + System.out.println("graphID: " + i + " minx: " + + minx + " miny: " + miny + " maxy: " + maxy + " will be set to: (" + x + "|" + y + ")"); + } // offset calculated node positions with maximum coordinates of // previous subgraphs - for(j = 0; j < this.nodecount; j++) { - if(graphs[j] == i) { + for (j = 0; j < this.nodecount; j++) { + if (graphs[j] == i) { double newx = x + this.nodes[j].getX() - minx; double newy = (y - miny) + this.nodes[j].getY(); - if(this.debug) System.out.println("changing position of " - + this.nodes[j].getId() + " from (" - + this.nodes[j].getX() + "|" + this.nodes[j].getY() + if (this.debug) { + System.out.println("changing position of " + + this.nodes[j].getId() + " from (" + + this.nodes[j].getX() + "|" + this.nodes[j].getY() + ") to (" + newx + "|" + newy + ")"); + } xpos[j] = newx; ypos[j] = newy; } @@ -1137,17 +1211,19 @@ private void separateDisjunctGraphs() { y += (maxy - miny) * this.scaling; } // apply positions to nodes - for(i = 0; i < this.nodecount; i++) { - this.nodes[i].setX(xpos[i]); - this.nodes[i].setY(ypos[i]); - if(this.debug) System.out.println(this.nodes[i].getId() - + " has final position: (" + xpos[i] + "|" + ypos[i] - + ")"); + for (i = 0; i < this.nodecount; i++) { + this.nodes[i].setX(xpos[i]); + this.nodes[i].setY(ypos[i]); + if (this.debug) { + System.out.println(this.nodes[i].getId() + + " has final position: (" + xpos[i] + "|" + ypos[i] + + ")"); + } } } - + /** - * Separates edge types and generates a layout for each edge type + * Separates edge types and generates a layout for each edge type * separately. * This is not a working implementation. */ @@ -1169,14 +1245,14 @@ private void separateEdgeTypes() { subgen.setLaunchRemoveCycles(this.launchRemoveCycles); subgen.setLaunchRotate(this.launchRotate); subgen.setLaunchSeparateDisjunctGraphs( - this.launchSeparateDisjunctGraphs); + this.launchSeparateDisjunctGraphs); subgen.setLaunchSeparateEdgeTypes(false); subgen.setLayoutSelector(this.layoutSelector); subgen.setMaxiterations(this.maxiterations); subgen.setRecursive(false); subgen.setScaling(this.scaling); subgen.setSubflowscale(this.subflowscale); - + // get connectiontypes LinkedList nodelist; VFlowModel flow = this.nodes[0].getFlow(); @@ -1185,25 +1261,25 @@ private void separateEdgeTypes() { Iterator keyit = keys.iterator(); nodelist = new LinkedList<>(); // iterate through connection types - while(keyit.hasNext()) { + while (keyit.hasNext()) { String currkey = keyit.next(); Connections currConns = allConns.get(currkey); ObservableList connList = currConns.getConnections(); Iterator connit = connList.iterator(); // add all nodes of current connection type to nodelist - while(connit.hasNext()) { + while (connit.hasNext()) { Connection currConn = connit.next(); VNode sender = currConn.getSender().getNode(); VNode receiver = currConn.getReceiver().getNode(); - if((getNodeID(sender) != -1) && (!nodelist.contains(sender))) { + if ((getNodeID(sender) != -1) && (!nodelist.contains(sender))) { nodelist.add(sender); } - if((getNodeID(receiver) != -1) - && (!nodelist.contains(receiver))) { + if ((getNodeID(receiver) != -1) + && (!nodelist.contains(receiver))) { nodelist.add(receiver); } } - if(nodelist.isEmpty()) continue; + if (nodelist.isEmpty()) { continue; } // create layout on current nodelist subgen.setNodelist(nodelist); subgen.generateLayout(); @@ -1212,46 +1288,46 @@ private void separateEdgeTypes() { subgen.setLaunchRotate(false); } } - + /** * Applies all steps of the layout, whose launch-parameters are set to true. */ @Override public void generateLayout() { - if(this.debug) System.out.println("Generating layout."); + if (this.debug) { System.out.println("Generating layout."); } // setup and check for errors - if(allNodesSetUp()) { + if (allNodesSetUp()) { // get origin point double minx = Double.POSITIVE_INFINITY; double miny = Double.POSITIVE_INFINITY; int i; - for(i = 0; i < this.nodecount; i++) { - if(this.nodes[i].getX() < minx) minx = this.nodes[i].getX(); - if(this.nodes[i].getY() < miny) miny = this.nodes[i].getY(); + for (i = 0; i < this.nodecount; i++) { + if (this.nodes[i].getX() < minx) { minx = this.nodes[i].getX(); } + if (this.nodes[i].getY() < miny) { miny = this.nodes[i].getY(); } } - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { this.nodes[i].setX(this.nodes[i].getX() - minx); this.nodes[i].setY(this.nodes[i].getY() - miny); } - - if(this.cycle && this.launchRemoveCycles) { + + if (this.cycle && this.launchRemoveCycles) { removeCycles(); this.origin = getOrigin(); } // apply layout to subflows - if(this.recursive) { + if (this.recursive) { runSubflows(); } // scale nodes according to their contents. - if(this.autoscaleNodes) { + if (this.autoscaleNodes) { autoscaleNodes(); } - if(this.launchSeparateDisjunctGraphs) { + if (this.launchSeparateDisjunctGraphs) { // only run if the graph contains no cycles - if(!this.cycle) { + if (!this.cycle) { separateDisjunctGraphs(); // displace by origin point - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { this.nodes[i].setX(this.nodes[i].getX() + minx); this.nodes[i].setY(this.nodes[i].getY() + miny); } @@ -1260,22 +1336,24 @@ public void generateLayout() { // run origin instead else { this.launchOrigin = true; - if(this.debug) System.out.println("Graph contains cycles ->" + if (this.debug) { + System.out.println("Graph contains cycles ->" + " origin used instead of seperate disjunct graphs" + "."); + } } } - if(this.launchSeparateEdgeTypes) { + if (this.launchSeparateEdgeTypes) { separateEdgeTypes(); // displace by origin point - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { this.nodes[i].setX(this.nodes[i].getX() + minx); this.nodes[i].setY(this.nodes[i].getY() + miny); } return; } // create jung-layout - switch(this.layoutSelector) { + switch (this.layoutSelector) { case 0: // ISOM Layout this.layout = new ISOMLayout<>(this.jgraph); break; @@ -1286,56 +1364,56 @@ public void generateLayout() { this.layout = new KKLayout<>(this.jgraph); break; case 3: // DAG Layout - if(!this.cycle) this.layout = new DAGLayout<>(this.jgraph); - else { + if (!this.cycle) { this.layout = new DAGLayout<>(this.jgraph); } else { this.layout = new ISOMLayout<>(this.jgraph); - if(this.debug) System.out.println("Graph contains " - + "cycles -> ISOM Layout used instead of DAG" + if (this.debug) { + System.out.println("Graph contains " + + "cycles -> ISOM Layout used instead of DAG" + " Layout."); + } } break; default: this.layout = new ISOMLayout<>(this.jgraph); break; } - if(this.launchJungLayout) stepLayoutApply(); + if (this.launchJungLayout) { stepLayoutApply(); } this.graphcenter = getGraphCenter(); - if(this.launchRotate) stepRotate(); - if(this.launchOrigin) stepOrigin(); - if(this.launchPushBack) { - if(!this.cycle) stepPushBack(); - else if(this.debug) System.out.println("Graph contains cycles " + if (this.launchRotate) { stepRotate(); } + if (this.launchOrigin) { stepOrigin(); } + if (this.launchPushBack) { + if (!this.cycle) { stepPushBack(); } else if (this.debug) { + System.out.println("Graph contains cycles " + "-> PushBack skipped."); + } } - if(this.launchDisplaceIdents) displaceIdents(); - if(this.launchAlignNodes) { + if (this.launchDisplaceIdents) { displaceIdents(); } + if (this.launchAlignNodes) { this.maxiterations /= 2; - if(this.launchForcePush) forcePush(); + if (this.launchForcePush) { forcePush(); } alignNodes(); - if(this.launchDisplaceIdents) displaceIdents(); - if(this.launchForcePush) forcePush(); - } - else { - if(this.launchForcePush) forcePush(); + if (this.launchDisplaceIdents) { displaceIdents(); } + if (this.launchForcePush) { forcePush(); } + } else { + if (this.launchForcePush) { forcePush(); } } // displace by origin point - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { this.nodes[i].setX(this.nodes[i].getX() + minx); this.nodes[i].setY(this.nodes[i].getY() + miny); } - if(this.debug) { - for(i = 0; i < this.nodecount; i++) { + if (this.debug) { + for (i = 0; i < this.nodecount; i++) { System.out.println(this.nodes[i].getId() + " has final " - + "position: (" + this.nodes[i].getX() + "|" - + this.nodes[i].getY() + ")"); + + "position: (" + this.nodes[i].getX() + "|" + + this.nodes[i].getY() + ")"); } } - } - else { - if(this.debug) System.out.println("Error on setup."); + } else { + if (this.debug) { System.out.println("Error on setup."); } } } - + /** * Applies the layout with the same parameters to each subflow. */ @@ -1353,7 +1431,7 @@ private void runSubflows() { subgen.setGraphmode(0); subgen.setLaunchRemoveCycles(this.launchRemoveCycles); subgen.setLaunchSeparateDisjunctGraphs( - this.launchSeparateDisjunctGraphs); + this.launchSeparateDisjunctGraphs); subgen.setLaunchSeparateEdgeTypes(this.launchSeparateEdgeTypes); subgen.setLaunchJungLayout(this.launchJungLayout); subgen.setLaunchRotate(this.launchRotate); @@ -1365,30 +1443,32 @@ private void runSubflows() { subgen.setMaxiterations(this.maxiterations); // apply layout to each subflow int i; - for(i = 0; i < this.nodecount; i++) { - if(this.nodes[i] instanceof VFlowModel) { + for (i = 0; i < this.nodecount; i++) { + if (this.nodes[i] instanceof VFlowModel) { subgen.setWorkflow((VFlowModel) this.nodes[i]); subgen.generateLayout(); } } } - + /** * Scales subflow-nodes according to their contents. */ private void autoscaleNodes() { int i; - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { VFlowModel subflow; - if(!(this.nodes[i] instanceof VFlowModel)) continue; + if (!(this.nodes[i] instanceof VFlowModel)) { continue; } subflow = (VFlowModel) this.nodes[i]; // get node representation of the current subflow VNode flownode = this.nodes[i]; - if(this.debug) System.out.println("Resizing subflow-node " + if (this.debug) { + System.out.println("Resizing subflow-node " + flownode.getId()); + } // get nodes from the subflow Collection subnodes = subflow.getNodes(); - if(subnodes.isEmpty()) continue; + if (subnodes.isEmpty()) { continue; } Iterator nodeit = subnodes.iterator(); double minx = Double.POSITIVE_INFINITY; double maxx = Double.NEGATIVE_INFINITY; @@ -1396,30 +1476,40 @@ private void autoscaleNodes() { double maxy = Double.NEGATIVE_INFINITY; // iterate over all subflow nodes to get outermost coordinates of // subflow - while(nodeit.hasNext()) { + while (nodeit.hasNext()) { VNode currNode = nodeit.next(); double x = currNode.getX(); double y = currNode.getY(); - if(this.debug) System.out.println(currNode.getId() + " has " + if (this.debug) { + System.out.println(currNode.getId() + " has " + "position (" + x + "|" + y + ")"); - if(minx > x) minx = x; - if(maxx < (x + currNode.getWidth())) maxx = x + } + if (minx > x) { minx = x; } + if (maxx < (x + currNode.getWidth())) { + maxx = x + currNode.getWidth(); - if(miny > y) miny = y; - if(maxy < (y + currNode.getHeight())) maxy = y + } + if (miny > y) { miny = y; } + if (maxy < (y + currNode.getHeight())) { + maxy = y + currNode.getHeight(); + } } - if(this.debug) System.out.println("extreme positions of " - + flownode.getId() + " are min: (" + minx + "|" + miny + if (this.debug) { + System.out.println("extreme positions of " + + flownode.getId() + " are min: (" + minx + "|" + miny + ") max: (" + maxx + "|" + maxy + ")"); + } // calculate size of subflow double width = maxx - minx; double height = maxy - miny; - if(this.debug) System.out.println("Resizing subflow-node " + if (this.debug) { + System.out.println("Resizing subflow-node " + flownode.getId() + " from size (" + flownode.getWidth() + "|" + flownode.getHeight() + ") to size (" - + (width / subnodes.size() * this.subflowscale) + "|" + + (width / subnodes.size() * this.subflowscale) + "|" + (height / subnodes.size() * this.subflowscale) + ")"); + } // set size of node representing current subflow flownode.setWidth(width / subnodes.size() * this.subflowscale); flownode.setHeight(height / subnodes.size() * this.subflowscale); @@ -1430,7 +1520,7 @@ private void autoscaleNodes() { * Applies the chosen layout implemented in the Jung Framework. */ private void stepLayoutApply() { - if(this.debug) System.out.println("--- applying layout."); + if (this.debug) { System.out.println("--- applying layout."); } // find cumulative width of longest path int maxpath = (int) Math.round(findMaxPathWidth() / (this.scaling * 2)); // calculate height from maxpath-width and aspectratio @@ -1438,18 +1528,21 @@ private void stepLayoutApply() { this.layout.setSize(new Dimension(maxpath, y)); // set layout coordinates int i; - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { Point2D coords; coords = this.layout.transform(this.nodes[i]); this.nodes[i].setX(coords.getX() - this.nodes[i].getWidth() / 2); this.nodes[i].setY(coords.getY() - this.nodes[i].getHeight() / 2); - if(this.debug) System.out.println(this.nodes[i].getId() + " | X: " + if (this.debug) { + System.out.println(this.nodes[i].getId() + " | X: " + coords.getX() + " Y: " + coords.getY()); + } } } - + /** * Finds the cumulative width of all nodes on the longest path in the graph. + * * @return double */ private double findMaxPathWidth() { @@ -1463,26 +1556,26 @@ private double findMaxPathWidth() { int i; // set maxPathFollowing for every node without successors to 0 // also add these nodes to the queue - for(i = 0; i < this.nodecount; i++) { - if(this.jgraph.getSuccessorCount(this.nodes[i]) == 0) { + for (i = 0; i < this.nodecount; i++) { + if (this.jgraph.getSuccessorCount(this.nodes[i]) == 0) { maxPathFollowing[i] = 0; fifo.add(i); } } // iterate through the queue - while(!fifo.isEmpty()) { + while (!fifo.isEmpty()) { Integer currNode = fifo.removeFirst(); // iterate over all successors of the current node - if(this.jgraph.getSuccessorCount(this.nodes[currNode]) != 0) { + if (this.jgraph.getSuccessorCount(this.nodes[currNode]) != 0) { nodelist = this.jgraph.getSuccessors(this.nodes[currNode]); it = nodelist.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { Integer currSucc = getNodeID(it.next()); - if(currSucc == -1) continue; + if (currSucc == -1) { continue; } int tempFollowing = 1 + maxPathFollowing[currSucc]; // set maxPathFollowing of the current node to // 1 + the largest maxPathFollowing of all successors - if(tempFollowing > maxPathFollowing[currNode]) { + if (tempFollowing > maxPathFollowing[currNode]) { maxPathFollowing[currNode] = tempFollowing; } } @@ -1490,15 +1583,15 @@ private double findMaxPathWidth() { // add all predecessors of the current node to the queue nodelist = this.jgraph.getPredecessors(this.nodes[currNode]); it = nodelist.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { Integer next = getNodeID(it.next()); - if(next == -1) continue; + if (next == -1) { continue; } fifo.add(next); } } // find max path and its start node - for(i = 0; i < this.nodecount; i++) { - if(maxPathFollowing[i] > maxPath) { + for (i = 0; i < this.nodecount; i++) { + if (maxPathFollowing[i] > maxPath) { maxPath = maxPathFollowing[i]; maxPathIndex = i; } @@ -1508,10 +1601,10 @@ private double findMaxPathWidth() { nodelist = this.jgraph.getSuccessors(this.nodes[maxPathIndex]); maxPath -= 1; it = nodelist.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { VNode currSucc = it.next(); - if(getNodeID(currSucc) == -1) continue; - if(maxPath == maxPathFollowing[getNodeID(currSucc)]) { + if (getNodeID(currSucc) == -1) { continue; } + if (maxPath == maxPathFollowing[getNodeID(currSucc)]) { maxPathWidth += this.nodes[getNodeID(currSucc)].getWidth(); maxPath--; nodelist = this.jgraph.getSuccessors(currSucc); @@ -1520,64 +1613,74 @@ private double findMaxPathWidth() { } return maxPathWidth; } - + /** - * Rotates the entire graph around its center point, so its new average + * Rotates the entire graph around its center point, so its new average * edge-direction is the direction specified. */ private void stepRotate() { - if(this.debug) System.out.println("--- starting rotation."); + if (this.debug) { System.out.println("--- starting rotation."); } int i; - if(this.conncount == 0) return; + if (this.conncount == 0) { return; } double centerx = this.graphcenter.getX(); double centery = this.graphcenter.getY(); - if(this.debug) System.out.println("center of rotation: (" + centerx + if (this.debug) { + System.out.println("center of rotation: (" + centerx + "|" + centery + ")"); - + } + // get average direction of edges double avgdirx = 0; double avgdiry = 0; Collection conns = this.jgraph.getEdges(); Iterator it = conns.iterator(); // iterate over all connections - while(it.hasNext()) { + while (it.hasNext()) { Connection currConn = it.next(); VNode senderNode = currConn.getSender().getNode(); VNode receiverNode = currConn.getReceiver().getNode(); - Point2D sender = new Point2D.Double(senderNode.getX(), - senderNode.getY()); - Point2D receiver = new Point2D.Double(receiverNode.getX(), - receiverNode.getY()); + Point2D sender = new Point2D.Double(senderNode.getX(), + senderNode.getY()); + Point2D receiver = new Point2D.Double(receiverNode.getX(), + receiverNode.getY()); // direction of connection as vector double dirx = receiver.getX() - sender.getX(); double diry = receiver.getY() - sender.getY(); avgdirx += dirx; avgdiry += diry; - if(this.debug) System.out.println("Edge from " - + currConn.getSender().getNode().getId() + " to " - + currConn.getReceiver().getNode().getId() - + " has direction: (" + dirx + "|" +diry + ") = " + if (this.debug) { + System.out.println("Edge from " + + currConn.getSender().getNode().getId() + " to " + + currConn.getReceiver().getNode().getId() + + " has direction: (" + dirx + "|" + diry + ") = " + (diry / dirx)); + } } avgdirx /= this.conncount; avgdiry /= this.conncount; - double avghyp = Math.sqrt(Math.pow(avgdirx, 2.) - + Math.pow(avgdiry, 2.)); - if(this.debug) System.out.println("average horizontal vector: " + double avghyp = Math.sqrt(Math.pow(avgdirx, 2.) + + Math.pow(avgdiry, 2.)); + if (this.debug) { + System.out.println("average horizontal vector: " + avgdirx); - if(this.debug) System.out.println("original average edge direction: " + } + if (this.debug) { + System.out.println("original average edge direction: " + ((avgdiry / avgdirx) / this.conncount)); + } double dirSin = Math.sin(this.direction * 2 * Math.PI / 360); double dirCos = Math.cos(this.direction * 2 * Math.PI / 360); // rotate graph around center so new average direction is 0 // ( -> x-direction) - for(i = 0; i < this.nodecount; i++) { - Point2D currCoords = new Point2D.Double(this.nodes[i].getX(), - this.nodes[i].getY()); - if(this.debug) System.out.println("Rotated Vertex " - + this.nodes[i].getId() + " from (" + currCoords.getX() + for (i = 0; i < this.nodecount; i++) { + Point2D currCoords = new Point2D.Double(this.nodes[i].getX(), + this.nodes[i].getY()); + if (this.debug) { + System.out.println("Rotated Vertex " + + this.nodes[i].getId() + " from (" + currCoords.getX() + "|" + currCoords.getY() + ")"); + } // move coordinates to point of origin double x = currCoords.getX() - centerx; double y = currCoords.getY() - centery; @@ -1596,15 +1699,18 @@ private void stepRotate() { this.nodes[i].setX(newx); this.nodes[i].setY(newy); this.layout.setLocation(this.nodes[i], newCoords); - if(this.debug) System.out.println("to (" + newx + "|" + newy + ")"); + if (this.debug) { System.out.println("to (" + newx + "|" + newy + ")"); } } - if(this.debug) System.out.println("new average edge direction: " + if (this.debug) { + System.out.println("new average edge direction: " + getAvgDir()); + } } - + /** - * Returns the average direction of all edges in the graph relative to the + * Returns the average direction of all edges in the graph relative to the * horizontal axis. + * * @return double */ private double getAvgDir() { @@ -1613,52 +1719,58 @@ private double getAvgDir() { Collection conns = this.jgraph.getEdges(); Iterator it = conns.iterator(); // iterate over all connections - while(it.hasNext()) { + while (it.hasNext()) { Connection currConn = it.next(); VNode senderNode = currConn.getSender().getNode(); VNode receiverNode = currConn.getReceiver().getNode(); - Point2D sender = new Point2D.Double(senderNode.getX(), - senderNode.getY()); - Point2D receiver = new Point2D.Double(receiverNode.getX(), - receiverNode.getY()); + Point2D sender = new Point2D.Double(senderNode.getX(), + senderNode.getY()); + Point2D receiver = new Point2D.Double(receiverNode.getX(), + receiverNode.getY()); // direction of connection as vector double dirx = receiver.getX() - sender.getX(); double diry = receiver.getY() - sender.getY(); avgdirx += dirx; avgdiry += diry; - if(this.debug) System.out.println("Edge from " - + currConn.getSender().getNode().getId() + " to " - + currConn.getReceiver().getNode().getId() - + " has direction: (" + dirx + "|" +diry + ") = " + if (this.debug) { + System.out.println("Edge from " + + currConn.getSender().getNode().getId() + " to " + + currConn.getReceiver().getNode().getId() + + " has direction: (" + dirx + "|" + diry + ") = " + (diry / dirx)); + } } avgdirx /= this.conncount; avgdiry /= this.conncount; return Math.atan(avgdiry / avgdirx); } - + /** * Places all nodes without predecessors at the leftmost edge of the graph. */ private void stepOrigin() { - if(this.debug) System.out.println("--- starting origin"); + if (this.debug) { System.out.println("--- starting origin"); } int i; // get lowest x coordinate, largest height and width in graph double minx = this.nodes[0].getX(); double maxw = 0.; double maxh = 0.; - for(i = 0; i < this.nodecount; i++) { - if(this.nodes[i].getX() < minx) minx = this.nodes[i].getX(); - if(this.nodes[i].getWidth() > maxw) maxw = + for (i = 0; i < this.nodecount; i++) { + if (this.nodes[i].getX() < minx) { minx = this.nodes[i].getX(); } + if (this.nodes[i].getWidth() > maxw) { + maxw = this.nodes[i].getWidth(); - if(this.nodes[i].getHeight() > maxh) maxh = + } + if (this.nodes[i].getHeight() > maxh) { + maxh = this.nodes[i].getHeight(); + } } // place origin nodes on lowest x coordinate double lastpos = - this.graphcenter.getY() + this.graphcenter.getY() - ((this.origin.length / 2) * maxh * this.scaling); - for(i = 0; i < this.origin.length; i++) { + for (i = 0; i < this.origin.length; i++) { Point2D coords = new Point2D.Double(); coords.setLocation((minx - (this.scaling * maxw)), lastpos); lastpos += this.scaling * (maxh); @@ -1668,180 +1780,193 @@ private void stepOrigin() { currNode.setY(coords.getY()); } } - + /** - * Pushes all successor nodes past their predecessors in the direction + * Pushes all successor nodes past their predecessors in the direction * specified, so no edges have a direction inverse to the specified * direction. */ private void stepPushBack() { - if(this.debug) System.out.println("--- starting push back."); + if (this.debug) { System.out.println("--- starting push back."); } LinkedList fifo = new LinkedList<>(); int i; // enter all origin nodes into fifo - for(i = 0; i < this.origin.length; i++) { + for (i = 0; i < this.origin.length; i++) { fifo.add(this.origin[i].getFirst()); } - while(!fifo.isEmpty()) { + while (!fifo.isEmpty()) { i = fifo.removeFirst(); // move node to the right if predecessor has larger // or equal x-coordinate - Collection nodelist = - this.jgraph.getPredecessors(this.nodes[i]); + Collection nodelist = + this.jgraph.getPredecessors(this.nodes[i]); Iterator it = nodelist.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { VNode pred = it.next(); - if(this.debug) System.out.println("handling connection from " + if (this.debug) { + System.out.println("handling connection from " + pred.getId() + " to " + this.nodes[i].getId()); - double preDiag = Math.sqrt(Math.pow((pred.getWidth() / 2), 2) - + Math.pow((pred.getHeight() / 2), 2)); + } + double preDiag = Math.sqrt(Math.pow((pred.getWidth() / 2), 2) + + Math.pow((pred.getHeight() / 2), 2)); double desDist = preDiag * this.scaling; // predecessor: - double xa = pred.getX() + pred.getWidth()/2; - double ya = pred.getY() + pred.getHeight()/2; + double xa = pred.getX() + pred.getWidth() / 2; + double ya = pred.getY() + pred.getHeight() / 2; // current node: - double xb = this.nodes[i].getX() + this.nodes[i].getWidth()/2; - double yb = this.nodes[i].getY() + this.nodes[i].getHeight()/2; + double xb = this.nodes[i].getX() + this.nodes[i].getWidth() / 2; + double yb = this.nodes[i].getY() + this.nodes[i].getHeight() / 2; // direction double xd = Math.cos(this.direction); double yd = Math.sin(this.direction); // projection - double xp = ((xd*(xb - xa)) + (yd*(yb - ya)))*xd - / (Math.pow(xd, 2) + Math.pow(yd, 2)); - double yp = ((xd*(xb - xa)) + (yd*(yb - ya)))*yd - / (Math.pow(xd, 2) + Math.pow(yd, 2)); - double projectionlen = Math.sqrt(Math.pow(xp, 2) - + Math.pow(yp, 2)); - double projtestlen = Math.sqrt(Math.pow((xp + xd), 2) - + Math.pow((yp + yd), 2)); - if((projectionlen < desDist) || (projtestlen < projectionlen)) { + double xp = ((xd * (xb - xa)) + (yd * (yb - ya))) * xd + / (Math.pow(xd, 2) + Math.pow(yd, 2)); + double yp = ((xd * (xb - xa)) + (yd * (yb - ya))) * yd + / (Math.pow(xd, 2) + Math.pow(yd, 2)); + double projectionlen = Math.sqrt(Math.pow(xp, 2) + + Math.pow(yp, 2)); + double projtestlen = Math.sqrt(Math.pow((xp + xd), 2) + + Math.pow((yp + yd), 2)); + if ((projectionlen < desDist) || (projtestlen < projectionlen)) { // parameter: - double phi = (-(xd*xp + yd*yp) + Math.sqrt(2*xd*xp*yd*yp - - Math.pow(xp*yd, 2) - Math.pow(yp*xd, 2) - + Math.pow(desDist*xd, 2) - + Math.pow(desDist*yd, 2))) / (Math.pow(xd, 2) - + Math.pow(yd, 2)); - if(this.debug) System.out.println("phi: " + phi); - xb = xb + phi*xd; - yb = yb + phi*yd; + double phi = (-(xd * xp + yd * yp) + Math.sqrt(2 * xd * xp * yd * yp + - Math.pow(xp * yd, 2) - Math.pow(yp * xd, 2) + + Math.pow(desDist * xd, 2) + + Math.pow(desDist * yd, 2))) / (Math.pow(xd, 2) + + Math.pow(yd, 2)); + if (this.debug) { System.out.println("phi: " + phi); } + xb = xb + phi * xd; + yb = yb + phi * yd; this.nodes[i].setX(xb); this.nodes[i].setY(yb); } } - if(this.debug) System.out.println("position of Node " - + this.nodes[i].getId() + " after push back : (" + if (this.debug) { + System.out.println("position of Node " + + this.nodes[i].getId() + " after push back : (" + this.nodes[i].getX() + "|" + this.nodes[i].getY() + ")"); + } // add successors of current node to the fifo nodelist = this.jgraph.getSuccessors(this.nodes[i]); it = nodelist.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { Integer next = getNodeID(it.next()); - if(next == -1) continue; + if (next == -1) { continue; } fifo.add(next); } } } - + /** * Displaces nodes that are in exactly the same location. */ private void displaceIdents() { // iterate over all pairs of nodes - if(this.debug) System.out.println("- Displacing nodes with identical " + if (this.debug) { + System.out.println("- Displacing nodes with identical " + "positions."); + } double displacement; - if(this.scaling < 0) { + if (this.scaling < 0) { displacement = this.scaling * (-1); - } - else { + } else { displacement = this.scaling; } int i; - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { int j; - for(j = 0; j < this.nodecount; j++) { - if(i == j) continue; + for (j = 0; j < this.nodecount; j++) { + if (i == j) { continue; } // if distance between nodes is 0 - if(getRealNodeDist(this.nodes[i], this.nodes[j]) == 0) { - if(this.debug) System.out.println(this.nodes[i].getId() - + " and " + this.nodes[j].getId() + if (getRealNodeDist(this.nodes[i], this.nodes[j]) == 0) { + if (this.debug) { + System.out.println(this.nodes[i].getId() + + " and " + this.nodes[j].getId() + " have the same position."); - Collection succs = - this.jgraph.getSuccessors(this.nodes[i]); - if(succs.contains(this.nodes[j])) { + } + Collection succs = + this.jgraph.getSuccessors(this.nodes[i]); + if (succs.contains(this.nodes[j])) { // if j is successor to i, move j to the right this.nodes[j].setX(this.nodes[j].getX() + displacement); - if(this.debug) System.out.print(" Moving " - + this.nodes[j].getId() + " by " + if (this.debug) { + System.out.print(" Moving " + + this.nodes[j].getId() + " by " + displacement); - } - else { + } + } else { succs = this.jgraph.getSuccessors(this.nodes[j]); - if(succs.contains(this.nodes[i])) { + if (succs.contains(this.nodes[i])) { // if i is successor to j, move i to the right - this.nodes[i].setX(this.nodes[i].getX() - + displacement); - if(this.debug) System.out.print(" Moving " - + this.nodes[i].getId() + " by " + this.nodes[i].setX(this.nodes[i].getX() + + displacement); + if (this.debug) { + System.out.print(" Moving " + + this.nodes[i].getId() + " by " + displacement); - } - else { + } + } else { // if the nodes are not successors to each other, // displace them vertically - this.nodes[i].setY(this.nodes[i].getY() - + displacement); - if(this.debug) System.out.print(" Moving " - + this.nodes[i].getId() + " by " + this.nodes[i].setY(this.nodes[i].getY() + + displacement); + if (this.debug) { + System.out.print(" Moving " + + this.nodes[i].getId() + " by " + displacement); + } } } } } } } - + /** * Applies force to each node, to push each other away and remove overlaps. */ private void forcePush() { - if(this.debug) System.out.println("--- starting force push"); + if (this.debug) { System.out.println("--- starting force push"); } int iteration; Boolean change = true; // go through all iterations - for(iteration = 0; iteration < this.maxiterations; iteration++) { - if(this.debug) System.out.println("iteration: " + (iteration + 1) + for (iteration = 0; iteration < this.maxiterations; iteration++) { + if (this.debug) { + System.out.println("iteration: " + (iteration + 1) + " of " + this.maxiterations); - if(!change) break; + } + if (!change) { break; } change = false; int i; // iterate over all pairs of nodes - for(i = 0; i < this.nodecount; i++) { + for (i = 0; i < this.nodecount; i++) { int j; - for(j = 0; j < this.nodecount; j++) { - if(j == i) continue; + for (j = 0; j < this.nodecount; j++) { + if (j == i) { continue; } double realDist = getRealNodeDist(this.nodes[i], - this.nodes[j]); + this.nodes[j]); double desDist = getDesiredNodeDist(this.nodes[i], - this.nodes[j]); + this.nodes[j]); // if the desired distance is larger than the existing // distance - if((realDist < desDist) && (realDist != 0)) { + if ((realDist < desDist) && (realDist != 0)) { change = true; // midpoints of both nodes: - double x1 = this.nodes[i].getX() - + (this.nodes[i].getWidth() / 2); - double y1 = this.nodes[i].getY() - + (this.nodes[i].getHeight() / 2); - double x2 = this.nodes[j].getX() - + (this.nodes[j].getWidth() / 2); - double y2 = this.nodes[j].getY() - + (this.nodes[j].getHeight() / 2); + double x1 = this.nodes[i].getX() + + (this.nodes[i].getWidth() / 2); + double y1 = this.nodes[i].getY() + + (this.nodes[i].getHeight() / 2); + double x2 = this.nodes[j].getX() + + (this.nodes[j].getWidth() / 2); + double y2 = this.nodes[j].getY() + + (this.nodes[j].getHeight() / 2); // vector between nodes: double vx = x2 - x1; double vy = y2 - y1; // displacement factor: - double phi = (desDist - realDist) - / Math.sqrt(Math.pow(vx, 2) + Math.pow(vy, 2)); + double phi = (desDist - realDist) + / Math.sqrt(Math.pow(vx, 2) + Math.pow(vy, 2)); // new positions of midpoints: double xf = x2 + (vx * phi) + 1.; double yf = y2 + (vy * phi) + 1.; @@ -1852,18 +1977,18 @@ private void forcePush() { this.nodes[j].setY(newy); Point2D coords = new Point2D.Double(newx, newy); this.layout.setLocation(this.nodes[j], coords); - if(this.debug) { - System.out.println(this.nodes[i].getId() - + " pushed " + this.nodes[j].getId() - + " from (" + x2 + "|" + y2 + ") to (" - + xf + "|" + yf + ")"); - System.out.println("distances before -> real: " - + realDist + "; desired: " + desDist); - System.out.println("distances after -> real: " - + getRealNodeDist(this.nodes[i], - this.nodes[j]) + "; desired: " - + getDesiredNodeDist(this.nodes[i], - this.nodes[j])); + if (this.debug) { + System.out.println(this.nodes[i].getId() + + " pushed " + this.nodes[j].getId() + + " from (" + x2 + "|" + y2 + ") to (" + + xf + "|" + yf + ")"); + System.out.println("distances before -> real: " + + realDist + "; desired: " + desDist); + System.out.println("distances after -> real: " + + getRealNodeDist(this.nodes[i], + this.nodes[j]) + "; desired: " + + getDesiredNodeDist(this.nodes[i], + this.nodes[j])); } } } @@ -1871,25 +1996,29 @@ private void forcePush() { displaceIdents(); } } - + /** * Returns the distance between the center points of two nodes. + * * @param node1 VNode * @param node2 VNode + * * @return double */ private double getRealNodeDist(VNode node1, VNode node2) { - double distx = (node1.getX() + (node1.getWidth() / 2)) - - (node2.getX() + (node2.getWidth() / 2)); - double disty = (node1.getY() + (node1.getHeight() / 2)) - - (node2.getY() + (node2.getHeight() / 2)); + double distx = (node1.getX() + (node1.getWidth() / 2)) + - (node2.getX() + (node2.getWidth() / 2)); + double disty = (node1.getY() + (node1.getHeight() / 2)) + - (node2.getY() + (node2.getHeight() / 2)); return Math.sqrt(Math.pow(distx, 2) + Math.pow(disty, 2)); } /** * Returns the desired distance between the center points of two nodes. + * * @param node1 VNode * @param node2 VNode + * * @return double */ private double getDesiredNodeDist(VNode node1, VNode node2) { @@ -1911,12 +2040,11 @@ private double getDesiredNodeDist(VNode node1, VNode node2) { double ycomp = Math.abs(2 * vy / h1); // determine if vector direction is closer to vertical or horizontal, // relative to the diagonal of the node. - if(xcomp >= ycomp) { + if (xcomp >= ycomp) { // calculate distance between centerpoint and edge of node // horizontal case: f1 = w1 / (Math.cos(Math.atan(vy / vx)) * 2); - } - else { + } else { // calculate distance between centerpoint and edge of node // vertical case: f1 = h1 / (Math.cos(Math.atan(vx / vy)) * 2); @@ -1925,17 +2053,16 @@ private double getDesiredNodeDist(VNode node1, VNode node2) { double f2; xcomp = Math.abs(2 * vx / w2); ycomp = Math.abs(2 * vy / h2); - if(xcomp >= ycomp) { - f2 = w2 / (Math.cos(Math.atan(vy / vx)) * 2); - } - else { + if (xcomp >= ycomp) { + f2 = w2 / (Math.cos(Math.atan(vy / vx)) * 2); + } else { f2 = h2 / (Math.cos(Math.atan(vx / vy)) * 2); } return (f1 + f2) * this.scaling; } - + /** - * Aligns nodes either pairwise to each other or to a global grid, + * Aligns nodes either pairwise to each other or to a global grid, * depending on the alignmentThreshold parameter. */ private void alignNodes() { @@ -1943,17 +2070,19 @@ private void alignNodes() { int j; boolean change; // iterate through all pairs of nodes - if(this.alignmentThreshold <= 0) { - if(this.debug) System.out.println("aligning nodes with similar " - + "coordinates."); - for(i = 0; i < this.nodecount; i++) { + if (this.alignmentThreshold <= 0) { + if (this.debug) { + System.out.println("aligning nodes with similar " + + "coordinates."); + } + for (i = 0; i < this.nodecount; i++) { VNode n1 = this.nodes[i]; double x1 = n1.getX(); double y1 = n1.getY(); double w1 = n1.getWidth(); double h1 = n1.getHeight(); - for(j = 0; j < this.nodecount; j++) { - if(i != j) { + for (j = 0; j < this.nodecount; j++) { + if (i != j) { VNode n2 = this.nodes[j]; double x2 = n2.getX(); double y2 = n2.getY(); @@ -1961,110 +2090,118 @@ private void alignNodes() { double h2 = n2.getHeight(); double threshold; // horizontal alignment - if(x1 != x2) { - threshold = (-1) * this.alignmentThreshold - * (w1 + w2) / 2; + if (x1 != x2) { + threshold = (-1) * this.alignmentThreshold + * (w1 + w2) / 2; change = false; // align by left side - if(Math.abs(x1 - x2) < threshold) { + if (Math.abs(x1 - x2) < threshold) { change = true; n1.setX((x1 + x2) / 2); n2.setX((x1 + x2) / 2); } // align by right side - else if(Math.abs((x1 + w1) - (x2 + w2)) - < threshold) { + else if (Math.abs((x1 + w1) - (x2 + w2)) + < threshold) { change = true; n1.setX(((x1 + w1 + x2 + w2) / 2) - w1); n2.setX(((x1 + w1 + x2 + w2) / 2) - w2); } // align by center - else if(Math.abs((x1 + (w1 / 2)) - (x2 + (w2 / 2))) - < threshold) { + else if (Math.abs((x1 + (w1 / 2)) - (x2 + (w2 / 2))) + < threshold) { change = true; - n1.setX((((2 * x1) + w1 + (2 * x2) + w2) / 4) - - (w1 / 2)); - n2.setX((((2 * x1) + w1 + (2 * x2) + w2) / 4) - - (w2 / 2)); + n1.setX((((2 * x1) + w1 + (2 * x2) + w2) / 4) + - (w1 / 2)); + n2.setX((((2 * x1) + w1 + (2 * x2) + w2) / 4) + - (w2 / 2)); } - if((this.debug) && (change)) { - System.out.println(n1.getId() - + " and " + n2.getId() - + " have been aligned at x coordinate " - + n1.getX()); + if ((this.debug) && (change)) { + System.out.println(n1.getId() + + " and " + n2.getId() + + " have been aligned at x coordinate " + + n1.getX()); } } // vertical alignment - if(y1 != y2) { + if (y1 != y2) { threshold = (h1 + h2) * (this.scaling - 1) / 2; change = false; // align by top side - if(Math.abs(y1 - y2) < threshold) { + if (Math.abs(y1 - y2) < threshold) { change = true; n1.setY((y1 + y2) / 2); n2.setY((y1 + y2) / 2); } // align by bottom side - else if(Math.abs((y1 + h1) - (y2 + h2)) - < threshold) { + else if (Math.abs((y1 + h1) - (y2 + h2)) + < threshold) { change = true; n1.setY(((y1 + h1 + y2 + h2) / 2) - h1); n2.setY(((y1 + h1 + y2 + h2) / 2) - h2); } // align by center - else if(Math.abs((y1 + (h1 / 2)) - (y2 - (h2 / 2))) - < threshold) { + else if (Math.abs((y1 + (h1 / 2)) - (y2 - (h2 / 2))) + < threshold) { change = true; - n1.setY((((2 * y1) + h1 + (2 * y2) + h2) / 4) - - (h1 / 2)); - n2.setY((((2 * y1) + h1 + (2 * y2) + h2) / 4) - - (h2 / 2)); + n1.setY((((2 * y1) + h1 + (2 * y2) + h2) / 4) + - (h1 / 2)); + n2.setY((((2 * y1) + h1 + (2 * y2) + h2) / 4) + - (h2 / 2)); } - if((this.debug) && (change)) { - System.out.println(n1.getId() - + " and " + n2.getId() - + " have been aligned at y coordinate " - + n1.getY()); + if ((this.debug) && (change)) { + System.out.println(n1.getId() + + " and " + n2.getId() + + " have been aligned at y coordinate " + + n1.getY()); } } } } } - } - else { - if(this.debug) System.out.println("aligning nodes on grid of size " + } else { + if (this.debug) { + System.out.println("aligning nodes on grid of size " + this.alignmentThreshold); - for(i = 0; i < this.nodecount; i++) { + } + for (i = 0; i < this.nodecount; i++) { double posX = this.nodes[i].getX(); double posY = this.nodes[i].getY(); // horizontal alignment double pos = Math.rint(posX / this.alignmentThreshold); - if(this.debug) System.out.println((posX + if (this.debug) { + System.out.println((posX / this.alignmentThreshold) + " is rounded: " + pos); + } this.nodes[i].setX(this.alignmentThreshold * pos); // vertical alignment pos = Math.rint(posY / this.alignmentThreshold); - if(this.debug) System.out.println((posY + if (this.debug) { + System.out.println((posY / this.alignmentThreshold) + " is rounded: " + pos); + } this.nodes[i].setY(this.alignmentThreshold * pos); - if(this.debug) System.out.println(this.nodes[i].getId() - + " aligned from (" + posX + "|" + posY + ") to (" - + this.nodes[i].getX() + "|" + this.nodes[i].getY() + if (this.debug) { + System.out.println(this.nodes[i].getId() + + " aligned from (" + posX + "|" + posY + ") to (" + + this.nodes[i].getX() + "|" + this.nodes[i].getY() + ")"); + } } } } - + /** * Returns index of the given node in the nodearray. + * * @param pnode VNode + * * @return Integer */ private Integer getNodeID(VNode pnode) { int i; - for(i = 0; i < this.nodecount; i++) { - if(this.nodes[i].equals(pnode)) - return i; + for (i = 0; i < this.nodecount; i++) { + if (this.nodes[i].equals(pnode)) { return i; } } return -1; } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/ConnectorIOImpl.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/ConnectorIOImpl.java index cdefab12..5c7f1591 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/ConnectorIOImpl.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/ConnectorIOImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -44,11 +44,12 @@ import javafx.beans.property.ReadOnlyProperty; import javafx.event.EventHandler; +import java.util.List; + /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ -class ConnectorIOImpl implements Connector { +public class ConnectorIOImpl implements Connector { private VNode node; private String type; @@ -65,7 +66,7 @@ public ConnectorIOImpl(VNode node, String type, String localId, boolean input, b this.input = input; this.output = output; } - + public ConnectorIOImpl(Connector c) { this(c.getNode(), c.getType(), c.getLocalId(), c.isInput(), c.isOutput()); this.vObj = c.getValueObject(); @@ -134,56 +135,61 @@ public ValueObject getValueObject() { @Override public ObjectProperty valueObjectProperty() { - throw new UnsupportedOperationException("Not supported yet."); // TODO NB-AUTOGEN + throw new UnsupportedOperationException("Not supported yet."); } @Override public void addConnectionEventListener(EventHandler handler) { - throw new UnsupportedOperationException("Not supported yet."); // TODO NB-AUTOGEN + throw new UnsupportedOperationException("Not supported yet."); } @Override public void removeConnectionEventListener(EventHandler handler) { - throw new UnsupportedOperationException("Not supported yet."); // TODO NB-AUTOGEN + throw new UnsupportedOperationException("Not supported yet."); } @Override public void addClickEventListener(EventHandler handler) { - throw new UnsupportedOperationException("Not supported yet."); // TODO NB-AUTOGEN + throw new UnsupportedOperationException("Not supported yet."); } @Override public void removeClickEventListener(EventHandler handler) { - throw new UnsupportedOperationException("Not supported yet."); // TODO NB-AUTOGEN + throw new UnsupportedOperationException("Not supported yet."); } @Override public void click(MouseButton btn, Object event) { - throw new UnsupportedOperationException("Not supported yet."); // TODO NB-AUTOGEN + throw new UnsupportedOperationException("Not supported yet."); } @Override public ReadOnlyProperty visualizationRequestProperty() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + throw new UnsupportedOperationException("Not supported yet."); } @Override public boolean isVisualizationRequestInitialized() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + throw new UnsupportedOperationException("Not supported yet."); } @Override public void setMaxNumberOfConnections(int numConnections) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + throw new UnsupportedOperationException("Not supported yet."); } @Override public int getMaxNumberOfConnections() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + throw new UnsupportedOperationException("Not supported yet."); } @Override public ObjectProperty maxNumberOfConnectionsProperty() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public List> getConnectionEventHandlers() { + throw new UnsupportedOperationException("Not supported yet."); } } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/IOConnector.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/IOConnector.java similarity index 88% rename from VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/IOConnector.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/IOConnector.java index 8c80748c..1f68e071 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/IOConnector.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/IOConnector.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -31,16 +31,18 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of Michael Hoffer . */ -package eu.mihosoft.vrl.workflow; +package eu.mihosoft.vrl.workflow.io; + +import eu.mihosoft.vrl.workflow.VNode; +import eu.mihosoft.vrl.workflow.impl.DefaultConnector; /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ -public final class IOConnector extends ConnectorImpl{ +public final class IOConnector extends DefaultConnector { public IOConnector(VNode node, String type, String localId, boolean input) { super(node, type, localId, input); } - + } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/PersistentConnection.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/PersistentConnection.java index 79f2aac2..7429b1c8 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/PersistentConnection.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/PersistentConnection.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -36,16 +36,15 @@ import eu.mihosoft.vrl.workflow.VisualizationRequest; /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ public class PersistentConnection { - + private String id; private String senderId; private String receiverId; private String type; - + private VisualizationRequest vReq; public PersistentConnection() { @@ -58,7 +57,7 @@ public PersistentConnection(String id, String senderId, String receiverId, Strin this.type = type; this.vReq = vReq; } - + /** * @return the id diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/PersistentConnector.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/PersistentConnector.java index 9061c66d..7ac89cb3 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/PersistentConnector.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/PersistentConnector.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -37,12 +37,11 @@ import eu.mihosoft.vrl.workflow.VisualizationRequest; /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ -public class PersistentConnector{ +public class PersistentConnector { -// private PersistentNode node; + // private PersistentNode node; private String type; private String localId; private VisualizationRequest vRequest; @@ -55,7 +54,7 @@ public class PersistentConnector{ public PersistentConnector(String type, String localId, boolean input, boolean output, boolean passthru) { this.type = type; this.localId = localId; -// this.node = node; + // this.node = node; this.input = input; this.output = output; this.passthru = passthru; @@ -73,9 +72,9 @@ public void setLocalId(String id) { this.localId = id; } -// public PersistentNode getNode() { -// return this.node; -// } + // public PersistentNode getNode() { + // return this.node; + // } public VisualizationRequest getVisualizationRequest() { @@ -101,12 +100,12 @@ public boolean isOutput() { return output; } -// /** -// * @param node the node to set -// */ -// public void setNode(PersistentNode node) { -// this.node = node; -// } + // /** + // * @param node the node to set + // */ + // public void setNode(PersistentNode node) { + // this.node = node; + // } /** * @return the valueObject @@ -119,7 +118,7 @@ public ValueObject getValueObject() { * @param valueObject the valueObject to set */ public void setValueObject(ValueObject valueObject) { - this.valueObject = valueObject; + this.valueObject = valueObject; } /** diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/PersistentFlow.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/PersistentFlow.java index 0170d49c..90b5a517 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/PersistentFlow.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/PersistentFlow.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -39,14 +39,13 @@ import java.util.List; /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ public class PersistentFlow extends PersistentNode { private List connections; private List nodes; -// private List connectionTypes; + // private List connectionTypes; private PersistentFlow parent; private boolean visible; @@ -59,13 +58,13 @@ public PersistentFlow(List connections, List connections, List nodes, String title, - double x, double y, double width, double height, - ValueObject valueObject, boolean visible, VisualizationRequest vReq, - List connectors) { + List connections, List nodes, String title, + double x, double y, double width, double height, + ValueObject valueObject, boolean visible, VisualizationRequest vReq, + List connectors) { super(id, title, x, y, width, height, valueObject, vReq, - connectors); + connectors); this.connections = connections; this.nodes = nodes; this.parent = parent; diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/PersistentNode.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/PersistentNode.java index 07047e86..72f6d6f0 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/PersistentNode.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/PersistentNode.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -41,7 +41,6 @@ import java.util.Map; /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ public class PersistentNode { @@ -55,16 +54,16 @@ public class PersistentNode { private VisualizationRequest vReq; private String id; private List connectors; - private Map mainInputs = new HashMap<>(); - private Map mainOutputs = new HashMap<>(); + private Map mainInputs = new HashMap<>(); + private Map mainOutputs = new HashMap<>(); public PersistentNode() { } public PersistentNode(String id, String title, - double x, double y, double width, double height, - ValueObject valueObject, VisualizationRequest vReq, - List connectors) { + double x, double y, double width, double height, + ValueObject valueObject, VisualizationRequest vReq, + List connectors) { this.x = x; this.y = y; @@ -76,8 +75,7 @@ public PersistentNode(String id, String title, this.id = id; this.connectors = WorkflowIO.listToSerializableList(connectors); } - - + /** * @return the x @@ -202,47 +200,47 @@ public List getConnectors() { * @param connectors the inputTypes to set */ public void setConnectors(List connectors) { - + for (PersistentConnector persistentConnector : connectors) { addConnector(persistentConnector); } } - - /** + + /** * @param connector the inputTypes to set */ - public void addConnector(PersistentConnector connector ) { + public void addConnector(PersistentConnector connector) { + + // connector.setNode(this); -// connector.setNode(this); - - connectors.add(connector); + connectors.add(connector); } /** * @return the mainInputs */ - public Map getMainInputs() { + public Map getMainInputs() { return mainInputs; } /** * @param mainInputs the mainInputs to set */ - public void setMainInputs(Map mainInputs) { + public void setMainInputs(Map mainInputs) { this.mainInputs = mainInputs; } /** * @return the mainOutputs */ - public Map getMainOutputs() { + public Map getMainOutputs() { return mainOutputs; } /** * @param mainOutputs the mainOutputs to set */ - public void setMainOutputs(Map mainOutputs) { + public void setMainOutputs(Map mainOutputs) { this.mainOutputs = mainOutputs; } } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/PersistentValueObject.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/PersistentValueObject.java index ef84c6d1..e27ac33a 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/PersistentValueObject.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/PersistentValueObject.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -45,7 +45,6 @@ /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ public class PersistentValueObject { diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/WorkflowIO.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/WorkflowIO.java index 93679401..48ed6eaa 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/WorkflowIO.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/io/WorkflowIO.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -35,18 +35,17 @@ import com.thoughtworks.xstream.XStream; import eu.mihosoft.vrl.workflow.Connector; -import eu.mihosoft.vrl.workflow.DefaultValueObject; -import eu.mihosoft.vrl.workflow.FlowFactory; import eu.mihosoft.vrl.workflow.IdGenerator; -import eu.mihosoft.vrl.workflow.NodeLookupImpl; -import eu.mihosoft.vrl.workflow.IOConnector; import eu.mihosoft.vrl.workflow.ThruConnector; -import eu.mihosoft.vrl.workflow.ThruConnectorImpl; -import eu.mihosoft.vrl.workflow.VConnections; import eu.mihosoft.vrl.workflow.VFlow; import eu.mihosoft.vrl.workflow.VFlowModel; import eu.mihosoft.vrl.workflow.VNode; import eu.mihosoft.vrl.workflow.ValueObject; +import eu.mihosoft.vrl.workflow.impl.DefaultNodeLookup; +import eu.mihosoft.vrl.workflow.impl.DefaultThruConnector; +import eu.mihosoft.vrl.workflow.impl.DefaultValueObject; +import eu.mihosoft.vrl.workflow.util.FlowFactory; +import eu.mihosoft.vrl.workflow.util.VConnections; import java.io.IOException; import java.io.InputStream; @@ -60,71 +59,70 @@ import java.util.Map; /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ public class WorkflowIO { - + public static VFlow loadFromXML(Path p) throws IOException { VFlow workflow = FlowFactory.newFlow(); - + VFlowModel flow = WorkflowIO.loadFromXML(p, workflow.getIdGenerator()); workflow.setNodeLookup(flow.getNodeLookup()); workflow.setModel(flow); - + return workflow; } - + public static VFlowModel loadFromXML(String xml, IdGenerator generator) { XStream xstream = new XStream(); - + configureStream(xstream); - + return flowFromPersistentFlow((PersistentFlow) xstream.fromXML(xml), generator); } - + public static VFlow loadFromXML(String xml) { VFlow workflow = FlowFactory.newFlow(); - + VFlowModel flow = WorkflowIO.loadFromXML(xml, workflow.getIdGenerator()); workflow.setNodeLookup(flow.getNodeLookup()); workflow.setModel(flow); - + return workflow; } - + public static VFlow loadFromXML(InputStream xmlStream) { VFlow workflow = FlowFactory.newFlow(); - + VFlowModel flow = WorkflowIO.loadFromXML(xmlStream, workflow.getIdGenerator()); workflow.setNodeLookup(flow.getNodeLookup()); workflow.setModel(flow); - + return workflow; } - + public static VFlowModel loadFromXML(Path p, IdGenerator generator) throws IOException { - + XStream xstream = new XStream(); - + configureStream(xstream); - + InputStream is = Files.newInputStream(p, StandardOpenOption.READ); - + PersistentFlow pFlow = (PersistentFlow) xstream.fromXML(is); - + return flowFromPersistentFlow(pFlow, generator); } - + public static VFlowModel loadFromXML(InputStream xmlStream, IdGenerator generator) { - + XStream xstream = new XStream(); - + configureStream(xstream); - + return flowFromPersistentFlow((PersistentFlow) xstream.fromXML(xmlStream), generator); } - + private static void configureStream(XStream xstream) { xstream.alias("flow", PersistentFlow.class); xstream.alias("node", PersistentNode.class); @@ -132,173 +130,173 @@ private static void configureStream(XStream xstream) { xstream.alias("vobj", PersistentValueObject.class); xstream.alias("connector", PersistentConnector.class); -// xstream.setMode(XStream.ID_REFERENCES); + // xstream.setMode(XStream.ID_REFERENCES); } - + public static void saveToXML(Path p, VFlowModel flow) throws IOException { - + OutputStream os = Files.newOutputStream(p, - StandardOpenOption.CREATE, - StandardOpenOption.WRITE, - StandardOpenOption.TRUNCATE_EXISTING); - + StandardOpenOption.CREATE, + StandardOpenOption.WRITE, + StandardOpenOption.TRUNCATE_EXISTING); + saveToXML(flow, os); } - + public static void saveToXML(VFlowModel flow, OutputStream xmlStream) { XStream xstream = new XStream(); - + configureStream(xstream); - + xstream.toXML(toPersistentNode(flow, null), xmlStream); } - + public static String saveToXML(VFlowModel flow) { XStream xstream = new XStream(); - + configureStream(xstream); - + String xml = xstream.toXML(toPersistentNode(flow, null)); - + return xml; } - + public static PersistentNode toPersistentNode(VNode node, PersistentFlow parent) { - + if (node instanceof VFlowModel) { - + VFlowModel flow = (VFlowModel) node; - + List connectionList = new ArrayList<>(); - + for (eu.mihosoft.vrl.workflow.Connections connections : flow.getAllConnections().values()) { for (eu.mihosoft.vrl.workflow.Connection c : connections.getConnections()) { connectionList.add( - new PersistentConnection(c.getId(), - c.getSender().getId(), - c.getReceiver().getId(), - c.getType(), - c.getVisualizationRequest())); + new PersistentConnection(c.getId(), + c.getSender().getId(), + c.getReceiver().getId(), + c.getType(), + c.getVisualizationRequest())); } } - + List nodeList = new ArrayList<>(); - + List connectionTypes = new ArrayList<>(); - + connectionTypes.addAll(flow.getAllConnections().keySet()); - + PersistentFlow pFlow = new PersistentFlow(parent, - node.getId(), - connectionList, - nodeList, - node.getTitle(), - node.getX(), - node.getY(), - node.getWidth(), - node.getHeight(), - node.getValueObject(), - flow.isVisible(), - node.getVisualizationRequest(), - new ArrayList()); - + node.getId(), + connectionList, + nodeList, + node.getTitle(), + node.getX(), + node.getY(), + node.getWidth(), + node.getHeight(), + node.getValueObject(), + flow.isVisible(), + node.getVisualizationRequest(), + new ArrayList()); + for (Connector c : node.getConnectors()) { pFlow.addConnector(toPersistentConnector(c)); } - + for (String mainType : node.getMainInputTypes()) { pFlow.getMainInputs().put(mainType, node.getMainInput(mainType).getLocalId()); } - + for (String mainType : node.getMainOutputTypes()) { pFlow.getMainOutputs().put(mainType, node.getMainOutput(mainType).getLocalId()); } - + for (VNode n : flow.getNodes()) { nodeList.add(toPersistentNode(n, pFlow)); } - + return pFlow; } else { PersistentNode pNode = new PersistentNode(node.getId(), - node.getTitle(), - node.getX(), - node.getY(), - node.getWidth(), - node.getHeight(), - node.getValueObject(), - node.getVisualizationRequest(), - new ArrayList()); - + node.getTitle(), + node.getX(), + node.getY(), + node.getWidth(), + node.getHeight(), + node.getValueObject(), + node.getVisualizationRequest(), + new ArrayList()); + for (Connector c : node.getConnectors()) { pNode.addConnector(toPersistentConnector(c)); } - + for (String mainType : node.getMainInputTypes()) { pNode.getMainInputs().put(mainType, node.getMainInput(mainType).getLocalId()); } - + for (String mainType : node.getMainOutputTypes()) { pNode.getMainOutputs().put(mainType, node.getMainOutput(mainType).getLocalId()); } - + return pNode; } } - + public static VFlowModel flowFromPersistentFlow( - PersistentFlow flow, IdGenerator generator) { - + PersistentFlow flow, IdGenerator generator) { + VFlowModel flowModel = createFlowFromPersistent(flow, null, generator); - + addConnectionsFromPersistentFlow(flow, flowModel, generator); - + return flowModel; } - + private static void addConnectionsFromPersistentFlow(PersistentFlow flow, VFlowModel flowModel, IdGenerator generator) { - + Map> flowConnections = new HashMap<>(); - + for (PersistentConnection c : flow.getConnections()) { List connectionsOfType = flowConnections.get(c.getType()); - + if (connectionsOfType == null) { connectionsOfType = new ArrayList<>(); flowConnections.put(c.getType(), connectionsOfType); } connectionsOfType.add(c); } - + for (String type : flowConnections.keySet()) { List connections = flowConnections.get(type); if (!connections.isEmpty()) { flowModel.addConnections(fromPersistentConnections(type, connections, flowModel), type); } } - + for (PersistentNode pn : flow.getNodes()) { VNode fn = flowModel.getNodeLookup().getById(pn.getId()); - + if (fn instanceof VFlowModel && pn instanceof PersistentFlow) { addConnectionsFromPersistentFlow((PersistentFlow) pn, (VFlowModel) fn, generator); } } } - + private static VFlowModel createFlowFromPersistent( - PersistentFlow flow, VFlowModel parent, IdGenerator generator) { - + PersistentFlow flow, VFlowModel parent, IdGenerator generator) { + VFlowModel result; - + if (parent == null) { result = FlowFactory.newFlowModel(); result.setIdGenerator(generator); - result.setNodeLookup(new NodeLookupImpl(result)); + result.setNodeLookup(new DefaultNodeLookup(result)); } else { result = parent.newFlowNode(); } - + result.setId(flow.getId()); generator.addId(flow.getId()); result.setTitle(flow.getTitle()); @@ -309,47 +307,47 @@ private static VFlowModel createFlowFromPersistent( result.setValueObject(toValueObject(result, flow.getValueObject())); result.setVisible(flow.isVisible()); result.setVisualizationRequest(flow.getVReq()); - + for (PersistentNode n : flow.getNodes()) { addFlowNode(result, n, generator); } - + for (PersistentConnector connector : flow.getConnectors()) { result.addConnector(fromPersistentConnector(connector, result)); } - + for (String type : flow.getMainInputs().keySet()) { result.setMainInput(result.getConnector(flow.getMainInputs().get(type))); } - + for (String type : flow.getMainOutputs().keySet()) { result.setMainOutput(result.getConnector(flow.getMainOutputs().get(type))); } -// -// Map> flowConnections = new HashMap<>(); -// -// for (PersistentConnection c : flow.getConnections()) { -// List connectionsOfType = flowConnections.get(c.getType()); -// -// if (connectionsOfType == null) { -// connectionsOfType = new ArrayList<>(); -// flowConnections.put(c.getType(), connectionsOfType); -// } -// connectionsOfType.add(c); -// } -// -// for (String type : flowConnections.keySet()) { -// List connections = flowConnections.get(type); -// if (!connections.isEmpty()) { -// result.addConnections(fromPersistentConnections(type, connections, result), type); -// } -// } + // + // Map> flowConnections = new HashMap<>(); + // + // for (PersistentConnection c : flow.getConnections()) { + // List connectionsOfType = flowConnections.get(c.getType()); + // + // if (connectionsOfType == null) { + // connectionsOfType = new ArrayList<>(); + // flowConnections.put(c.getType(), connectionsOfType); + // } + // connectionsOfType.add(c); + // } + // + // for (String type : flowConnections.keySet()) { + // List connections = flowConnections.get(type); + // if (!connections.isEmpty()) { + // result.addConnections(fromPersistentConnections(type, connections, result), type); + // } + // } return result; } - + private static void addFlowNode(VFlowModel flow, PersistentNode node, IdGenerator generator) { - + if (node instanceof PersistentFlow) { createFlowFromPersistent((PersistentFlow) node, flow, generator); } else { @@ -363,64 +361,64 @@ private static void addFlowNode(VFlowModel flow, PersistentNode node, IdGenerato result.setHeight(node.getHeight()); result.setValueObject(toValueObject(result, node.getValueObject())); result.setVisualizationRequest(node.getVReq()); - + for (PersistentConnector c : node.getConnectors()) { result.addConnector(fromPersistentConnector(c, result)); } } } -// public static PersistentConnection toPersistentConnection(eu.mihosoft.vrl.workflow.Connection c) { -// return new PersistentConnection(c.getId(), c.getSenderId(), c.getReceiverId(), c.getType(), c.getVisualizationRequest()); -// } + // public static PersistentConnection toPersistentConnection(eu.mihosoft.vrl.workflow.Connection c) { + // return new PersistentConnection(c.getId(), c.getSenderId(), c.getReceiverId(), c.getType(), c.getVisualizationRequest()); + // } public static eu.mihosoft.vrl.workflow.Connections fromPersistentConnections(String connectionType, List connections, VFlowModel flow) { eu.mihosoft.vrl.workflow.Connections result = VConnections.newConnections(connectionType); - + for (PersistentConnection c : connections) { Connector s = flow.getNodeLookup().getConnectorById(c.getSenderId()); Connector r = flow.getNodeLookup().getConnectorById(c.getReceiverId()); result.add(c.getId(), s, r, c.getVReq()); } - + return result; } - + public static List listToSerializableList(List input) { List result = new ArrayList<>(); result.addAll(input); return result; } - + public static Connector fromPersistentConnector(PersistentConnector pC, VNode n) { -// ConnectorIOImpl result -// = new ConnectorImpl(n, c.getType(), c.getLocalId(), c.isInput(), c.isOutput()); -// + // ConnectorIOImpl result + // = new ConnectorImpl(n, c.getType(), c.getLocalId(), c.isInput(), c.isOutput()); + // Connector c; if (pC.isPassthru()) { - + VFlowModel flowModel = (VFlowModel) n; - + if (pC.isInput()) { VNode innerNode = flowModel.newNode(); Connector innerConnector = innerNode.setMainInput( - innerNode.addInput(pC.getType())); - c = new ThruConnectorImpl(n, pC.getType(), - pC.getLocalId(), true, innerNode, innerConnector); + innerNode.addInput(pC.getType())); + c = new DefaultThruConnector(n, pC.getType(), + pC.getLocalId(), true, innerNode, innerConnector); } else { VNode innerNode = flowModel.newNode(); Connector innerConnector = innerNode.setMainOutput( - innerNode.addOutput(pC.getType())); - c = new ThruConnectorImpl(n, pC.getType(), - pC.getLocalId(), false, innerNode, innerConnector); + innerNode.addOutput(pC.getType())); + c = new DefaultThruConnector(n, pC.getType(), + pC.getLocalId(), false, innerNode, innerConnector); } - + } else { c = new IOConnector(n, pC.getType(), pC.getLocalId(), pC.isInput()); } - + c.setMaxNumberOfConnections(pC.getMaxNumConnections()); - + return c; } @@ -432,34 +430,35 @@ public static Connector fromPersistentConnector(PersistentConnector pC, VNode n) * referenced. * * @param c connector to convert + * * @return the equivalent persistent connector to the specified connector */ public static PersistentConnector toPersistentConnector(Connector c) { PersistentConnector pC = new PersistentConnector( - c.getType(), c.getLocalId(), c.isInput(), - c.isOutput(), c instanceof ThruConnector); - + c.getType(), c.getLocalId(), c.isInput(), + c.isOutput(), c instanceof ThruConnector); + pC.setMaxNumConnections(c.getMaxNumberOfConnections()); - + return pC; } - + public static PersistentValueObject toPersistentValueObject(ValueObject vObj) { return new PersistentValueObject(vObj.getParent().getId(), vObj.getValue(), vObj.getVisualizationRequest()); } - + public static ValueObject toValueObject(VNode node, PersistentValueObject vObj) { ValueObject result = new DefaultValueObject(); - + result.setParent(node); result.setValue(vObj.getValue()); - + for (String key : vObj.getStorage().keySet()) { result.getVisualizationRequest().set( - key, vObj.getStorage().get(key)); - } - + key, vObj.getStorage().get(key)); + } + return result; } - + } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/ConnectionSkin.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/ConnectionSkin.java index d8ab3a49..e92fc0a0 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/ConnectionSkin.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/ConnectionSkin.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -44,7 +44,7 @@ * * @author Michael Hoffer <info@michaelhoffer.de> */ -public interface ConnectionSkin extends Skin { +public interface ConnectionSkin extends Skin { /** * Returns the sender connector. * diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/ConnectionSkinFactory.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/ConnectionSkinFactory.java index 0005e7bc..dae0aeeb 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/ConnectionSkinFactory.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/ConnectionSkinFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -38,18 +38,22 @@ /** * Connection skin factory. - * @author Michael Hoffer <info@michaelhoffer.de> + * * @param connection model type + * + * @author Michael Hoffer <info@michaelhoffer.de> */ public interface ConnectionSkinFactory { /** * Creates a skin for the specified connection. - * @param c connection that shall be skinned + * + * @param c connection that shall be skinned * @param flow parent flow controller * @param type connection type + * * @return connection skin */ ConnectionSkin createSkin(Connection c, VFlow flow, String type); - + } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/ConnectionsSkin.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/ConnectionsSkin.java index a4af1b8b..a1167b6f 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/ConnectionsSkin.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/ConnectionsSkin.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/Constants.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/Constants.java index 01b94ca3..f4dd2fd3 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/Constants.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/Constants.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -36,9 +36,14 @@ /** * This class defines constants used library. It is currently used to wrap * the default CSS. + * * @author Michael Hoffer <info@michaelhoffer.de> */ -public class Constants { - public static final String DEFAULT_STYLE = - "/eu/mihosoft/vrl/fxconnections/resources/default.css"; +public final class Constants { + private Constants() { + // prevent instantiation + } + + public static final String DEFAULT_STYLE = + "/eu/mihosoft/vrl/fxconnections/resources/default.css"; } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/FlowNodeSkinLookup.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/FlowNodeSkinLookup.java index f11836a7..b8e7711d 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/FlowNodeSkinLookup.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/FlowNodeSkinLookup.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -49,19 +49,21 @@ public interface FlowNodeSkinLookup extends Lookup> { * Returns the skin of the specified node. * * @param skinFactory skin factory to search - * @param globalId global id of the requested node + * @param globalId global id of the requested node + * * @return the skin of the specified node or null if no such * skin exists */ - public VNodeSkin getById(SkinFactory skinFactory, String globalId); + VNodeSkin getById(SkinFactory skinFactory, String globalId); /** * Returns the skin of the specified connection. * * @param skinFactory skin factory to search - * @param c global id of the requested node + * @param c global id of the requested node + * * @return the skin of the specified connection or null if no * such skin exists */ - public ConnectionSkin getById(SkinFactory skinFactory, Connection c); + ConnectionSkin getById(SkinFactory skinFactory, Connection c); } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/Skin.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/Skin.java index 05377776..c555d710 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/Skin.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/Skin.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -39,49 +39,61 @@ /** * A skin is a toolkit independent visual representation of a model. - * - * @author Michael Hoffer <info@michaelhoffer.de> + * * @param model type that shall be skinned + * + * @author Michael Hoffer <info@michaelhoffer.de> */ public interface Skin { /** * Adds this skin to its view parent. */ - public void add(); + void add(); + /** * Removes this skin from its view parent. */ - public void remove(); + void remove(); + /** * Defines the model that shall be represented by this skin. + * * @param model model to set */ - public void setModel(T model); + void setModel(T model); + /** * Returns the model represented by this skin. + * * @return model represented by this skin */ - public T getModel(); + T getModel(); + /** * Returns the property the model represented by this skin. + * * @return model represented by this skin */ - public ObjectProperty modelProperty(); + ObjectProperty modelProperty(); + /** * Returns the flow controller that is used to manipulate the model. + * * @return the flow controller that is used to manipulate the model */ - public VFlow getController(); - + VFlow getController(); + /** * Defines the flow controller that shall be used to manipulate the model. + * * @param flow flow controller to set */ - public void setController(VFlow flow); - + void setController(VFlow flow); + /** * Returns the skin factory that created this skin. + * * @return the skin factory that created this skin */ - public SkinFactory getSkinFactory(); + SkinFactory getSkinFactory(); } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/SkinFactory.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/SkinFactory.java index f6819003..84096020 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/SkinFactory.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/SkinFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -38,9 +38,10 @@ * used by the corresponding flow controller {@link eu.mihosoft.vrl.workflow.VFlow#setSkinFactories(eu.mihosoft.vrl.workflow.skin.SkinFactory...) * }. * - * @author Michael Hoffer <info@michaelhoffer.de> * @param Connection skin type * @param Node skin type + * + * @author Michael Hoffer <info@michaelhoffer.de> */ public interface SkinFactory extends ConnectionSkinFactory, VNodeSkinFactory { @@ -49,6 +50,7 @@ public interface SkinFactory extends ConnectionS * of the model. * * @param parent parent skin + * * @return child skin factory */ SkinFactory createChild(Skin parent); @@ -59,6 +61,5 @@ public interface SkinFactory extends ConnectionS * @return parent skin factory or null if no such skin factory * exists */ - public SkinFactory getParent(); - + SkinFactory getParent(); } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/VNodeSkin.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/VNodeSkin.java index 5d2a556a..8ff264f7 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/VNodeSkin.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/VNodeSkin.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -37,9 +37,10 @@ /** * Node skin. - * - * @author Michael Hoffer <info@michaelhoffer.de> + * * @param node model type + * + * @author Michael Hoffer <info@michaelhoffer.de> */ public interface VNodeSkin extends Skin { diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/VNodeSkinFactory.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/VNodeSkinFactory.java index 89c1666e..84e5a7d9 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/VNodeSkinFactory.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/skin/VNodeSkinFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -38,18 +38,20 @@ /** * Node skin factory. - * @author Michael Hoffer <info@michaelhoffer.de> + * * @param node skin type + * + * @author Michael Hoffer <info@michaelhoffer.de> */ public interface VNodeSkinFactory { /** * Creates a node skin. - * @param n node that shall be skinned + * + * @param n node that shall be skinned * @param controller flow controller + * * @return requested node skin */ VNodeSkin createSkin(VNode n, VFlow controller); - - } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/util/ConnectionUtils.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/util/ConnectionUtils.java new file mode 100644 index 00000000..d6e91839 --- /dev/null +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/util/ConnectionUtils.java @@ -0,0 +1,53 @@ +/* + * Copyright 2012-2017 Michael Hoffer . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Please cite the following publication(s): + * + * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - + * A Framework for Declarative GUI Programming on the Java Platform. + * Computing and Visualization in Science, 2011, in press. + * + * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of Michael Hoffer . + */ +package eu.mihosoft.vrl.workflow.util; + +import eu.mihosoft.vrl.workflow.Connection; + +/** + * @author Andres Almiray + */ +public final class ConnectionUtils { + private ConnectionUtils() { + // prevent instantiation + } + + public static String connectionId(String id, String senderId, String receiverId) { + return "id=" + id + ";[" + senderId + "]->[" + receiverId + "]"; + } + + public static String connectionId(Connection connection) { + return connectionId(connection.getId(), connection.getSender().getId(), connection.getReceiver().getId()); + } +} diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/FlowFactory.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/util/FlowFactory.java similarity index 79% rename from VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/FlowFactory.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/util/FlowFactory.java index d28d5938..6c9870a1 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/FlowFactory.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/util/FlowFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -31,61 +31,74 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of Michael Hoffer . */ -package eu.mihosoft.vrl.workflow; +package eu.mihosoft.vrl.workflow.util; +import eu.mihosoft.vrl.workflow.IdGenerator; +import eu.mihosoft.vrl.workflow.VFlow; +import eu.mihosoft.vrl.workflow.VFlowModel; +import eu.mihosoft.vrl.workflow.impl.DefaultIdGenerator; +import eu.mihosoft.vrl.workflow.impl.DefaultVFlow; +import eu.mihosoft.vrl.workflow.impl.DefaultVFlowModel; import eu.mihosoft.vrl.workflow.skin.ConnectionSkin; import eu.mihosoft.vrl.workflow.skin.SkinFactory; import eu.mihosoft.vrl.workflow.skin.VNodeSkin; /** * A factory class to create {@code VFlow}s. + * * @author Michael Hoffer <info@michaelhoffer.de> */ public class FlowFactory { /** * Creates a new instance of a flow + * * @return the newly created {@code VFlow} */ public static VFlow newFlow() { VFlowModel model = FlowFactory.newFlowModel(); - - VFlow flow = new VFlowImpl(null,model); + + VFlow flow = new DefaultVFlow(model); return flow; } /** * Creates a new instance of a flow and specify its skin + * * @param skinFactory Defines the skin factory used to render the workflow + * * @return the newly created {@code VFlow} */ public static VFlow newFlow( - SkinFactory skinFactory) { + SkinFactory skinFactory) { VFlowModel model = FlowFactory.newFlowModel(); - VFlow flow = new VFlowImpl(null,model, skinFactory); + VFlow flow = new DefaultVFlow(model); + flow.setSkinFactories(skinFactory); return flow; } /** * Creates a new flow model - * @return + * + * @return */ public static VFlowModel newFlowModel() { - VFlowModel result = new VFlowModelImpl(null); + VFlowModel result = new DefaultVFlowModel(null); result.setId("ROOT"); return result; } - + /** * Returns a new id generator. + * * @return id generator */ public static IdGenerator newIdGenerator() { - return new IdGeneratorImpl(); + return new DefaultIdGenerator(); } } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/PathUtil.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/util/PathUtil.java similarity index 91% rename from VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/PathUtil.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/util/PathUtil.java index 94ae1673..078090df 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/PathUtil.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/util/PathUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -31,14 +31,16 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of Michael Hoffer . */ -package eu.mihosoft.vrl.workflow; +package eu.mihosoft.vrl.workflow.util; + +import eu.mihosoft.vrl.workflow.Connector; +import eu.mihosoft.vrl.workflow.VFlowModel; import java.util.ArrayList; import java.util.List; import java.util.Optional; /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ public class PathUtil { @@ -51,21 +53,20 @@ private static List computeSendersAndReceivers(Connector s, Connector List result = new ArrayList<>(); Optional commonAncestorResult = WorkflowUtil. - getCommonAncestor(s.getNode(), r.getNode()); + getCommonAncestor(s.getNode(), r.getNode()); if (!commonAncestorResult.isPresent()) { return result; } - + VFlowModel commonAncestor = commonAncestorResult.get(); List ancestorsOfS = WorkflowUtil.getAncestors(s.getNode()); List ancestorsOfR = WorkflowUtil.getAncestors(r.getNode()); - + int indexOfCommonAncestorInS = ancestorsOfS.indexOf(commonAncestor); int indexOfCommonAncestorInR = ancestorsOfR.indexOf(commonAncestor); - - + return result; } diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VConnections.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/util/VConnections.java similarity index 88% rename from VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VConnections.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/util/VConnections.java index 06b931df..9cf33999 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VConnections.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/util/VConnections.java @@ -1,51 +1,54 @@ -/* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * Please cite the following publication(s): - * - * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - - * A Framework for Declarative GUI Programming on the Java Platform. - * Computing and Visualization in Science, 2011, in press. - * - * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of Michael Hoffer . - */ -package eu.mihosoft.vrl.workflow; - -/** - * - * @author Michael Hoffer <info@michaelhoffer.de> - */ -public class VConnections { - - public static Connections newConnections(String type) { - return new ConnectionsImpl(type); - } - - public static void printConnections(Connections connections) { - for (Connection c : connections.getConnections()) { - System.out.println(c.toString()); - } - } -} +/* + * Copyright 2012-2017 Michael Hoffer . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Please cite the following publication(s): + * + * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - + * A Framework for Declarative GUI Programming on the Java Platform. + * Computing and Visualization in Science, 2011, in press. + * + * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of Michael Hoffer . + */ +package eu.mihosoft.vrl.workflow.util; + +import eu.mihosoft.vrl.workflow.Connection; +import eu.mihosoft.vrl.workflow.Connections; +import eu.mihosoft.vrl.workflow.impl.DefaultConnections; + +/** + * @author Michael Hoffer <info@michaelhoffer.de> + */ +public class VConnections { + + public static Connections newConnections(String type) { + return new DefaultConnections(type); + } + + public static void printConnections(Connections connections) { + for (Connection c : connections.getConnections()) { + System.out.println(c.toString()); + } + } +} diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/WorkflowUtil.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/util/WorkflowUtil.java similarity index 82% rename from VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/WorkflowUtil.java rename to VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/util/WorkflowUtil.java index 516bb410..0119bf7f 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/WorkflowUtil.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/util/WorkflowUtil.java @@ -1,307 +1,325 @@ -/* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * Please cite the following publication(s): - * - * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - - * A Framework for Declarative GUI Programming on the Java Platform. - * Computing and Visualization in Science, 2011, in press. - * - * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of Michael Hoffer . - */ -package eu.mihosoft.vrl.workflow; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import java.util.function.Predicate; - -/** - * Workflow utility class. - * - * @author Michael Hoffer <info@michaelhoffer.de> - */ -public class WorkflowUtil { - - public static final String CONTROL_FLOW = "control"; - public static final String DATA_FLOW = "data"; - public static final String EVENT_FLOW = "event"; - - - private WorkflowUtil() { - throw new AssertionError(); - } - - /** - * Returns a predicate that indicates whether a connector is connected with - * the specified connection type. - * - * Note: the predicate can be used to filter streams and collections. - * - * @param connectionType connection type (e.g. "data" or "control") - * @return a predicate that indicates whether a connector is connected with - * the specified connection type - * - * @see java.util.stream.Stream - */ - public static Predicate connectorConnected(String connectionType) { - return (Connector c) -> { - return c.getType().equals(connectionType) - && !c.getNode().getFlow(). - getConnections(connectionType). - getAllWith(c).isEmpty(); - }; - } - - /** - * Returns a predicate that indicates whether a connector is not connected - * with the specified connection type. - * - * @param connectionType connection type (e.g. "data" or "control") - * @return a predicate that indicates whether a connector is not connected - * with the specified connection type - * - * @see java.util.stream.Stream - */ - public static Predicate connectorNotConnected( - String connectionType) { - return connectorConnected(connectionType).negate(); - } - - /** - * Returns a predicate that indicates whether a node is connected with the - * specified connection type. - * - * @param connectionType connection type (e.g. "data" or "control") - * @return a predicate that indicates whether a node is connected with the - * specified connection type - * - * @see java.util.stream.Stream - */ - public static Predicate nodeConnected(String connectionType) { - return (VNode n) -> { - return !n.getInputs().filtered(connectorConnected(connectionType)). - isEmpty(); - }; - } - - /** - * Returns a predicate that indicates whether a node is not connected with - * the specified connection type. - * - * @param connectionType connection type (e.g. "data" or "control") - * @return a predicate that indicates whether a node is not connected with - * the specified connection type - * - * @see java.util.stream.Stream - */ - public static Predicate nodeNotConnected(String connectionType) { - return nodeConnected(connectionType).negate(); - } - - /** - * Returns a predicate that indicates whether the number of connections of - * the specified connector is bigger than the expected number of - * connections. Only connections of the specifed type are counted. - * - * @param expectedNumConn expected number of connections - * @param connectionType connection type (e.g. "data" or "control") - * @return a predicate that indicates whether the number of connections of - * the specified connector is bigger than the expected number of connections - * - * @see java.util.stream.Stream - */ - public static Predicate moreThanConnections(int expectedNumConn, - String connectionType) { - return (Connector c) -> { - return c.getType().equals(connectionType) - && c.getNode().getFlow(). - getConnections(connectionType). - getAllWith(c).size() > expectedNumConn; - }; - } - - /** - * Returns a predicate that indicates whether the number of connections of - * the specified connector is smaller than the expected number of - * connections. Only connections of the specifed type are counted. - * - * @param expectedNumConn expected number of connections - * @param connectionType connection type (e.g. "data" or "control") - * @return a predicate that indicates whether the number of connections of - * the specified connector is smaller than the expected number of - * connections - * - * @see java.util.stream.Stream - */ - public static Predicate lessThanConnections(int expectedNumConn, - String connectionType) { - return (Connector c) -> { - return c.getType().equals(connectionType) - && c.getNode().getFlow(). - getConnections(connectionType). - getAllWith(c).size() < expectedNumConn; - }; - } - - /** - * Returns a predicate that indicates whether the number of connections of - * the specified connector is equal to the expected number of connections. - * Only connections of the specifed type are counted. - * - * @param expectedNumConn expected number of connections - * @param connectionType connection type (e.g. "data" or "control") - * @return a predicate that indicates whether the number of connections of - * the specified connector is equal to the expected number of connections - * - * @see java.util.stream.Stream - */ - public static Predicate numberOfConnections(int expectedNumConn, - String connectionType) { - return (Connector c) -> { - return c.getType().equals(connectionType) - && c.getNode().getFlow(). - getConnections(connectionType). - getAllWith(c).size() == expectedNumConn; - }; - } - - public static boolean isRoot(VNode node, String connectionType) { - - Predicate notConnected = (Connector c) -> { - return c.getType().equals(connectionType) - && !c.getNode().getFlow(). - getConnections(connectionType). - getAllWith(c).isEmpty(); - }; - - Predicate rootNode = (VNode n) -> { - return n.getInputs().filtered(notConnected).isEmpty(); - }; - - return rootNode.test(node); - } - - public static List getPathInLayerFromRoot(VNode sender, String connectionType) { - - List result = new ArrayList<>(); - - if (sender.getMainOutput(connectionType)==null) { - return result; - } - - if (!isRoot(sender, connectionType)) { - System.err.println("sender is no root!"); - return result; - } - - result.add(sender); - - Connections connections = sender.getFlow().getConnections(connectionType); - Collection connectionsWithSender - = connections.getAllWith(sender.getMainOutput(connectionType)); - - while (!connectionsWithSender.isEmpty()) { - - VNode newSender = null; - - for (Connection c : connectionsWithSender) { - - if (newSender == c.getReceiver().getNode()) { - System.err.println("circular flow!"); - return result; - } - - newSender = c.getReceiver().getNode(); - - result.add(newSender); - break; // we only support one connection per controlflow conector - } - - if (newSender != null) { - connectionsWithSender - = connections.getAllWith( - newSender.getMainOutput(connectionType)); - } else { - connectionsWithSender.clear(); - } - } - - return result; - } - - - public static List connect(Connector s, Connector r) { - List result = new ArrayList<>(); - if (s.getNode().getFlow() == r.getNode().getFlow()) { - result.add(s.getNode().getFlow().connect(s, r)); - } - - return result; - } - - /** - * Returns the ancestors of the specified node. - * @param n node - * @return the ancestors of the specified node - */ - public static List getAncestors(VNode n) { - List result = new ArrayList<>(); - - VFlowModel parent = n.getFlow(); - - while(parent!=null) { - result.add(parent); - parent = parent.getFlow(); - } - - return result; - } - - /** - * Returns the first common ancestor of the specified nodes if such a parent node - * exists. - * @param n1 first node - * @param n2 second node - * @return the common ancestor of the specified nodes if such a parent node - * exists - */ - public static Optional getCommonAncestor(VNode n1, VNode n2) { - List ancestorsOfN1 = getAncestors(n1); - List ancestorsOfN2 = getAncestors(n2); - - for(VFlowModel a1 : ancestorsOfN1) { - for(VFlowModel a2 : ancestorsOfN2) { - if (a1.equals(a2)) { - return Optional.of(a1); - } - } - } - - return Optional.empty(); - } - -} +/* + * Copyright 2012-2017 Michael Hoffer . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Please cite the following publication(s): + * + * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - + * A Framework for Declarative GUI Programming on the Java Platform. + * Computing and Visualization in Science, 2011, in press. + * + * THIS SOFTWARE IS PROVIDED BY Michael Hoffer "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of Michael Hoffer . + */ +package eu.mihosoft.vrl.workflow.util; + +import eu.mihosoft.vrl.workflow.Connection; +import eu.mihosoft.vrl.workflow.ConnectionResult; +import eu.mihosoft.vrl.workflow.Connections; +import eu.mihosoft.vrl.workflow.Connector; +import eu.mihosoft.vrl.workflow.VFlowModel; +import eu.mihosoft.vrl.workflow.VNode; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.function.Predicate; + +/** + * Workflow utility class. + * + * @author Michael Hoffer <info@michaelhoffer.de> + */ +public class WorkflowUtil { + + public static final String CONTROL_FLOW = "control"; + public static final String DATA_FLOW = "data"; + public static final String EVENT_FLOW = "event"; + + + private WorkflowUtil() { + throw new AssertionError(); + } + + /** + * Returns a predicate that indicates whether a connector is connected with + * the specified connection type. + *

+ * Note: the predicate can be used to filter streams and collections. + * + * @param connectionType connection type (e.g. "data" or "control") + * + * @return a predicate that indicates whether a connector is connected with + * the specified connection type + * + * @see java.util.stream.Stream + */ + public static Predicate connectorConnected(String connectionType) { + return (Connector c) -> { + return c.getType().equals(connectionType) + && !c.getNode().getFlow(). + getConnections(connectionType). + getAllWith(c).isEmpty(); + }; + } + + /** + * Returns a predicate that indicates whether a connector is not connected + * with the specified connection type. + * + * @param connectionType connection type (e.g. "data" or "control") + * + * @return a predicate that indicates whether a connector is not connected + * with the specified connection type + * + * @see java.util.stream.Stream + */ + public static Predicate connectorNotConnected( + String connectionType) { + return connectorConnected(connectionType).negate(); + } + + /** + * Returns a predicate that indicates whether a node is connected with the + * specified connection type. + * + * @param connectionType connection type (e.g. "data" or "control") + * + * @return a predicate that indicates whether a node is connected with the + * specified connection type + * + * @see java.util.stream.Stream + */ + public static Predicate nodeConnected(String connectionType) { + return (VNode n) -> { + return !n.getInputs().filtered(connectorConnected(connectionType)). + isEmpty(); + }; + } + + /** + * Returns a predicate that indicates whether a node is not connected with + * the specified connection type. + * + * @param connectionType connection type (e.g. "data" or "control") + * + * @return a predicate that indicates whether a node is not connected with + * the specified connection type + * + * @see java.util.stream.Stream + */ + public static Predicate nodeNotConnected(String connectionType) { + return nodeConnected(connectionType).negate(); + } + + /** + * Returns a predicate that indicates whether the number of connections of + * the specified connector is bigger than the expected number of + * connections. Only connections of the specifed type are counted. + * + * @param expectedNumConn expected number of connections + * @param connectionType connection type (e.g. "data" or "control") + * + * @return a predicate that indicates whether the number of connections of + * the specified connector is bigger than the expected number of connections + * + * @see java.util.stream.Stream + */ + public static Predicate moreThanConnections(int expectedNumConn, + String connectionType) { + return (Connector c) -> { + return c.getType().equals(connectionType) + && c.getNode().getFlow(). + getConnections(connectionType). + getAllWith(c).size() > expectedNumConn; + }; + } + + /** + * Returns a predicate that indicates whether the number of connections of + * the specified connector is smaller than the expected number of + * connections. Only connections of the specifed type are counted. + * + * @param expectedNumConn expected number of connections + * @param connectionType connection type (e.g. "data" or "control") + * + * @return a predicate that indicates whether the number of connections of + * the specified connector is smaller than the expected number of + * connections + * + * @see java.util.stream.Stream + */ + public static Predicate lessThanConnections(int expectedNumConn, + String connectionType) { + return (Connector c) -> { + return c.getType().equals(connectionType) + && c.getNode().getFlow(). + getConnections(connectionType). + getAllWith(c).size() < expectedNumConn; + }; + } + + /** + * Returns a predicate that indicates whether the number of connections of + * the specified connector is equal to the expected number of connections. + * Only connections of the specifed type are counted. + * + * @param expectedNumConn expected number of connections + * @param connectionType connection type (e.g. "data" or "control") + * + * @return a predicate that indicates whether the number of connections of + * the specified connector is equal to the expected number of connections + * + * @see java.util.stream.Stream + */ + public static Predicate numberOfConnections(int expectedNumConn, + String connectionType) { + return (Connector c) -> { + return c.getType().equals(connectionType) + && c.getNode().getFlow(). + getConnections(connectionType). + getAllWith(c).size() == expectedNumConn; + }; + } + + public static boolean isRoot(VNode node, String connectionType) { + + Predicate notConnected = (Connector c) -> { + return c.getType().equals(connectionType) + && !c.getNode().getFlow(). + getConnections(connectionType). + getAllWith(c).isEmpty(); + }; + + Predicate rootNode = (VNode n) -> { + return n.getInputs().filtered(notConnected).isEmpty(); + }; + + return rootNode.test(node); + } + + public static List getPathInLayerFromRoot(VNode sender, String connectionType) { + + List result = new ArrayList<>(); + + if (sender.getMainOutput(connectionType) == null) { + return result; + } + + if (!isRoot(sender, connectionType)) { + System.err.println("sender is no root!"); + return result; + } + + result.add(sender); + + Connections connections = sender.getFlow().getConnections(connectionType); + Collection connectionsWithSender + = connections.getAllWith(sender.getMainOutput(connectionType)); + + while (!connectionsWithSender.isEmpty()) { + + VNode newSender = null; + + for (Connection c : connectionsWithSender) { + + if (newSender == c.getReceiver().getNode()) { + System.err.println("circular flow!"); + return result; + } + + newSender = c.getReceiver().getNode(); + + result.add(newSender); + break; // we only support one connection per controlflow conector + } + + if (newSender != null) { + connectionsWithSender + = connections.getAllWith( + newSender.getMainOutput(connectionType)); + } else { + connectionsWithSender.clear(); + } + } + + return result; + } + + + public static List connect(Connector s, Connector r) { + List result = new ArrayList<>(); + if (s.getNode().getFlow() == r.getNode().getFlow()) { + result.add(s.getNode().getFlow().connect(s, r)); + } + + return result; + } + + /** + * Returns the ancestors of the specified node. + * + * @param n node + * + * @return the ancestors of the specified node + */ + public static List getAncestors(VNode n) { + List result = new ArrayList<>(); + + VFlowModel parent = n.getFlow(); + + while (parent != null) { + result.add(parent); + parent = parent.getFlow(); + } + + return result; + } + + /** + * Returns the first common ancestor of the specified nodes if such a parent node + * exists. + * + * @param n1 first node + * @param n2 second node + * + * @return the common ancestor of the specified nodes if such a parent node + * exists + */ + public static Optional getCommonAncestor(VNode n1, VNode n2) { + List ancestorsOfN1 = getAncestors(n1); + List ancestorsOfN2 = getAncestors(n2); + + for (VFlowModel a1 : ancestorsOfN1) { + for (VFlowModel a2 : ancestorsOfN2) { + if (a1.equals(a2)) { + return Optional.of(a1); + } + } + } + + return Optional.empty(); + } + +} diff --git a/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/ConnectionEventTest.java b/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/ConnectionEventTest.java index 82256cbc..709d02dd 100644 --- a/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/ConnectionEventTest.java +++ b/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/ConnectionEventTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -33,6 +33,7 @@ */ package eu.mihosoft.vrl.workflow; +import eu.mihosoft.vrl.workflow.util.FlowFactory; import javafx.event.Event; import javafx.event.EventHandler; import javafx.event.EventType; @@ -41,10 +42,10 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import static org.junit.Assert.*; + +import static org.junit.Assert.assertTrue; /** - * * @author Michael Hoffer */ public class ConnectionEventTest { @@ -87,7 +88,7 @@ public void connectNodes() { class CountingListener implements EventHandler { private int counter = 0; - + private EventType lastEventType; @Override @@ -114,27 +115,27 @@ private void reset() { ConnectionResult resultInput = flow.connect(n1, n2, "control"); assertTrue("Connection must be valid", resultInput.getStatus().isCompatible()); // add event has been fired once - assertTrue("Add-Event must be fired exactly once!", - countingListenerInput.getCounter() == 1 && countingListenerInput.lastEventType == ConnectionEvent.ADD); + assertTrue("Add-Event must be fired exactly once!", + countingListenerInput.getCounter() == 1 && countingListenerInput.lastEventType == ConnectionEvent.ADD); // remove the connection resultInput.getConnection().getConnections().remove(resultInput.getConnection()); // remove event has been fired once assertTrue("Remove-Event must be fired exactly once!", - countingListenerInput.getCounter() == 2 && countingListenerInput.lastEventType == ConnectionEvent.REMOVE); - + countingListenerInput.getCounter() == 2 && countingListenerInput.lastEventType == ConnectionEvent.REMOVE); + // create test for output CountingListener countingListenerOutput = new CountingListener(); sender1.addConnectionEventListener(countingListenerOutput); ConnectionResult resultOutput = flow.connect(n1, n2, "control"); assertTrue("Connection must be valid", resultOutput.getStatus().isCompatible()); // add event has been fired once - assertTrue("Add-Event must be fired exactly once!", - countingListenerOutput.getCounter() == 1 && countingListenerOutput.lastEventType == ConnectionEvent.ADD); + assertTrue("Add-Event must be fired exactly once!", + countingListenerOutput.getCounter() == 1 && countingListenerOutput.lastEventType == ConnectionEvent.ADD); // remove the connection resultOutput.getConnection().getConnections().remove(resultOutput.getConnection()); // remove event has been fired once assertTrue("Remove-Event must be fired exactly once!", - countingListenerOutput.getCounter() == 2 && countingListenerOutput.lastEventType == ConnectionEvent.REMOVE); + countingListenerOutput.getCounter() == 2 && countingListenerOutput.lastEventType == ConnectionEvent.REMOVE); } } diff --git a/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/ConnectorTest.java b/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/ConnectorTest.java index e317e7d8..9f20238f 100644 --- a/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/ConnectorTest.java +++ b/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/ConnectorTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -33,11 +33,11 @@ */ package eu.mihosoft.vrl.workflow; +import eu.mihosoft.vrl.workflow.util.FlowFactory; import org.junit.Assert; import org.junit.Test; /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ public class ConnectorTest { @@ -45,40 +45,40 @@ public class ConnectorTest { @Test public void maxNumberOfConnectionsTest() { VFlow flow = FlowFactory.newFlow(); - + VNode sender = flow.newNode(); VNode receiver = flow.newNode(); - + Connector senderOut = sender.addOutput("mytype"); Connector receiverIn = receiver.addInput("mytype"); - + int maxConn = 1; - + senderOut.setMaxNumberOfConnections(maxConn); receiverIn.setMaxNumberOfConnections(maxConn); - + int senderMax = senderOut.getMaxNumberOfConnections(); - + Assert.assertTrue("Sender: expected max number of connections = " - + maxConn + ", got " + senderMax, maxConn == senderMax); - + + maxConn + ", got " + senderMax, maxConn == senderMax); + int receiverMax = receiverIn.getMaxNumberOfConnections(); - + Assert.assertTrue("Receiver: expected max number of connections = " - + maxConn + ", got " + receiverMax, maxConn == receiverMax); - + + maxConn + ", got " + receiverMax, maxConn == receiverMax); + ConnectionResult result = flow.connect(senderOut, receiverIn); - + Assert.assertTrue("Connection must be established. Connection-Msg: " + result.getStatus().getMessage(), - result.getStatus().isCompatible()); - + result.getStatus().isCompatible()); + ConnectionResult result2 = flow.connect(senderOut, receiverIn); - + Assert.assertTrue("Connection must not be established as the max " + "number of connections is already reached.", - !result2.getStatus().isCompatible()); - - + !result2.getStatus().isCompatible()); + + } } diff --git a/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/FlowUtil.java b/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/FlowUtil.java index f5372629..b3942c1a 100644 --- a/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/FlowUtil.java +++ b/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/FlowUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -42,7 +42,6 @@ import java.util.List; /** - * * @author Michael Hoffer */ public class FlowUtil { @@ -51,8 +50,8 @@ public class FlowUtil { * Creates a flow with specified width and depth. * * @param workflow parent workflow - * @param depth flow depth (number of nested nodes) - * @param width flow width (number of nodes per layer) + * @param depth flow depth (number of nested nodes) + * @param width flow width (number of nodes per layer) */ public static void createFlow(VFlow workflow, int depth, int width) { @@ -107,7 +106,7 @@ public static void createFlow(VFlow workflow, int depth, int width) { if (i >= connectionTypes.length) { workflow.connect(prevNodes.get(0).getOutputs().get(0), - n.getInputs().get(0)); + n.getInputs().get(0)); prevNodes.remove(0); } diff --git a/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/SkinTest.java b/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/SkinTest.java index 2da786c2..c54c21f9 100644 --- a/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/SkinTest.java +++ b/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/SkinTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -37,16 +37,17 @@ import eu.mihosoft.vrl.workflow.skin.Skin; import eu.mihosoft.vrl.workflow.skin.SkinFactory; import eu.mihosoft.vrl.workflow.skin.VNodeSkin; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; +import eu.mihosoft.vrl.workflow.util.FlowFactory; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import org.junit.Assert; import org.junit.Test; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ public class SkinTest { @@ -61,18 +62,18 @@ public void nodeSkinTest() { VNode n1 = flow.newNode(); Assert.assertTrue("Skin for n1 must be present.", - skinFactory.getNodeSkins().get(n1) != null); + skinFactory.getNodeSkins().get(n1) != null); Assert.assertTrue("Skin must be skin of n1.", - skinFactory.getNodeSkins().get(n1).getModel() == n1); + skinFactory.getNodeSkins().get(n1).getModel() == n1); VFlow sf1 = flow.newSubFlow(); Assert.assertTrue("Skin for sf1 must be present.", - skinFactory.getNodeSkins().get(sf1.getModel()) != null); + skinFactory.getNodeSkins().get(sf1.getModel()) != null); Optional sfSkinFactry - = skinFactory.getChildFactories().values().stream().findFirst(); + = skinFactory.getChildFactories().values().stream().findFirst(); Assert.assertTrue("Child factory must exist.", sfSkinFactry.isPresent()); @@ -80,10 +81,10 @@ public void nodeSkinTest() { sf1.setVisible(true); Assert.assertTrue("Skin for sn1 must be present.", - sfSkinFactry.get().getNodeSkins().get(sn1) != null); + sfSkinFactry.get().getNodeSkins().get(sn1) != null); Assert.assertTrue("Skin must be skin of n1.", - sfSkinFactry.get().getNodeSkins().get(sn1).getModel() == sn1); + sfSkinFactry.get().getNodeSkins().get(sn1).getModel() == sn1); } @@ -97,13 +98,13 @@ public void nodeSkinLookupTest() { VNode n1 = flow.newNode(); VNodeSkin lookupN1 = flow.getNodeSkinLookup(). - getById(skinFactory, n1.getId()); + getById(skinFactory, n1.getId()); Assert.assertTrue("Skin for n1 must be present.", - lookupN1 != null); + lookupN1 != null); Assert.assertTrue("Skin must be skin of n1.", - lookupN1.getModel() == n1); + lookupN1.getModel() == n1); } @Test @@ -117,30 +118,30 @@ public void nodeSkinLookupRemovalTest() { VNode n2 = flow.newNode(); VNodeSkin lookupN1 = flow.getNodeSkinLookup(). - getById(skinFactory, n1.getId()); + getById(skinFactory, n1.getId()); VNodeSkin lookupN2 = flow.getNodeSkinLookup(). - getById(skinFactory, n2.getId()); + getById(skinFactory, n2.getId()); Assert.assertTrue("Skin for n1 must be present.", - lookupN1 != null); + lookupN1 != null); Assert.assertTrue("Skin must be skin of n1.", - lookupN1.getModel() == n1); + lookupN1.getModel() == n1); Assert.assertTrue("Skin for n2 must be present.", - lookupN2 != null); + lookupN2 != null); Assert.assertTrue("Skin must be skin of n2.", - lookupN2.getModel() == n2); + lookupN2.getModel() == n2); flow.remove(n2); VNodeSkin lookupN2AfterRemoval = flow.getNodeSkinLookup(). - getById(skinFactory, n2.getId()); + getById(skinFactory, n2.getId()); Assert.assertTrue("Skin for n2 must be removed after node removal.", - lookupN2AfterRemoval == null); + lookupN2AfterRemoval == null); } @@ -155,37 +156,37 @@ public void nodeSkinRemoveSubFlowTest() { sf.setVisible(true); VNodeSkin lookupN1 = flow.getNodeSkinLookup(). - getById(skinFactory, sf.getModel().getId()); + getById(skinFactory, sf.getModel().getId()); Assert.assertTrue("Skin for sf must be present.", - lookupN1 != null); + lookupN1 != null); Assert.assertTrue("Skin must be skin of n1.", - lookupN1.getModel() == sf.getModel()); + lookupN1.getModel() == sf.getModel()); VNode n1 = sf.newNode(); VFlow sf1 = sf.newSubFlow(); boolean n1IsChildNode = sf.getNodes().stream().filter(n -> n == n1). - findFirst().isPresent(); + findFirst().isPresent(); boolean sf1IsChildNode = sf.getNodes().stream().filter(n -> sf1.getModel() == n). - findFirst().isPresent(); + findFirst().isPresent(); Assert.assertTrue("n1 must be child of sf", - n1IsChildNode); + n1IsChildNode); Assert.assertTrue("sf1 must be child of sf", - sf1IsChildNode); - -// flow.remove(sf.getModel()); -// -// VNodeSkinFactoryStub skinFactoryOfSF = (VNodeSkinFactoryStub) -// sf.getSkinFactories().iterator().next(); -// -// skinFactoryOfSF.getNodeSkins().values().forEach(ns -> { -// System.out.println("ns: " + ns.getModel().getId()); -// }); + sf1IsChildNode); + + // flow.remove(sf.getModel()); + // + // VNodeSkinFactoryStub skinFactoryOfSF = (VNodeSkinFactoryStub) + // sf.getSkinFactories().iterator().next(); + // + // skinFactoryOfSF.getNodeSkins().values().forEach(ns -> { + // System.out.println("ns: " + ns.getModel().getId()); + // }); } @Test @@ -203,13 +204,13 @@ public void connectionSkinLookupTest() { Connection connection = flow.connect(s, r).getConnection(); ConnectionSkin lookupC1 = flow.getNodeSkinLookup(). - getById(skinFactory, connection); + getById(skinFactory, connection); Assert.assertTrue("Skin for connection must be present.", - lookupC1 != null); + lookupC1 != null); Assert.assertTrue("Skin must be skin of connection.", - lookupC1.getModel() == connection); + lookupC1.getModel() == connection); } @Test @@ -229,33 +230,33 @@ public void connectionSkinRemovalLookupTest() { Connection connection2 = flow.connect(s1, r2).getConnection(); ConnectionSkin lookupC1 = flow.getNodeSkinLookup(). - getById(skinFactory, connection1); + getById(skinFactory, connection1); Assert.assertTrue("Skin for connection must be present.", - lookupC1 != null); + lookupC1 != null); Assert.assertTrue("Skin must be skin of connection.", - lookupC1.getModel() == connection1); + lookupC1.getModel() == connection1); ConnectionSkinStub lookupC2 = (ConnectionSkinStub) flow.getNodeSkinLookup(). - getById(skinFactory, connection2); + getById(skinFactory, connection2); Assert.assertTrue("Skin for connection must be present.", - lookupC2 != null); + lookupC2 != null); Assert.assertTrue("Skin must be skin of connection.", - lookupC2.getModel() == connection2); + lookupC2.getModel() == connection2); flow.getConnections("mytype").remove(connection2); Assert.assertTrue("Skin has to be removed after connection removal.", - lookupC2.isRemoved()); + lookupC2.isRemoved()); ConnectionSkinStub lookupC2AfterRemoval = (ConnectionSkinStub) flow.getNodeSkinLookup(). - getById(skinFactory, connection2); + getById(skinFactory, connection2); Assert.assertTrue("Skin has to be removed after connection removal.", - lookupC2AfterRemoval == null); + lookupC2AfterRemoval == null); } } @@ -322,8 +323,7 @@ public boolean isRemoved() { } } -final class ConnectionSkinStub implements ConnectionSkin { - +final class ConnectionSkinStub implements ConnectionSkin { private final ObjectProperty senderProperty = new SimpleObjectProperty<>(); private final ObjectProperty receiverProperty = new SimpleObjectProperty<>(); private final ObjectProperty modelProperty = new SimpleObjectProperty<>(); diff --git a/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/VFlowDiffTest.java b/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/VFlowDiffTest.java index 0d60c1c7..6927b541 100644 --- a/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/VFlowDiffTest.java +++ b/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/VFlowDiffTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -39,6 +39,7 @@ package eu.mihosoft.vrl.workflow; import eu.mihosoft.vrl.workflow.io.WorkflowIO; +import eu.mihosoft.vrl.workflow.util.FlowFactory; import org.junit.Test; import java.io.IOException; @@ -49,7 +50,6 @@ import java.util.logging.Logger; /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ public class VFlowDiffTest { @@ -57,11 +57,11 @@ public class VFlowDiffTest { @Test public void testSimpleDiff() { VFlow flow = createFlow(10, 5, 3, "control", "data", "event"); - -// VFlow flow = FlowFactory.newFlow(); -// -// FlowUtil.createFlow(flow, 5, 5); - + + // VFlow flow = FlowFactory.newFlow(); + // + // FlowUtil.createFlow(flow, 5, 5); + try { WorkflowIO.saveToXML(Paths.get("flow01.xml"), flow.getModel()); } catch (IOException ex) { @@ -79,8 +79,8 @@ private VFlow createFlow(int maxWidth, int depth, int maxNumConnectors, String.. for (VFlow flow : flows) { VNode prevNode = null; for (int w = 0; - w < Math.random() * (maxWidth / flows.size()) + 1; - w++) { + w < Math.random() * (maxWidth / flows.size()) + 1; + w++) { VNode n; if (Math.random() < 0.5) { @@ -95,8 +95,8 @@ private VFlow createFlow(int maxWidth, int depth, int maxNumConnectors, String.. for (String type : types) { for (int i = 0; - i < Math.random() * maxNumConnectors + 1; - i++) { + i < Math.random() * maxNumConnectors + 1; + i++) { n.addInput(type); n.addOutput(type); } @@ -106,14 +106,14 @@ private VFlow createFlow(int maxWidth, int depth, int maxNumConnectors, String.. if (prevNode != null) { List outputs - = prevNode.getOutputs(). - filtered(conn -> conn.getType(). - equals(type)); + = prevNode.getOutputs(). + filtered(conn -> conn.getType(). + equals(type)); List inputs - = n.getInputs(). - filtered(conn -> conn.getType(). - equals(type)); + = n.getInputs(). + filtered(conn -> conn.getType(). + equals(type)); for (Connector o : outputs) { for (Connector i : inputs) { diff --git a/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/VFlowIOTest.java b/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/VFlowIOTest.java index 0cd15fd0..08c4da51 100644 --- a/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/VFlowIOTest.java +++ b/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/VFlowIOTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -38,6 +38,7 @@ package eu.mihosoft.vrl.workflow; import eu.mihosoft.vrl.workflow.io.WorkflowIO; +import eu.mihosoft.vrl.workflow.util.FlowFactory; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; @@ -56,7 +57,6 @@ import static org.junit.Assert.assertTrue; /** - * * @author Michael Hoffer */ public class VFlowIOTest { @@ -167,7 +167,7 @@ public void saveAndLoadFlowString() { // compare both flows (samples) compare(flow1, flow2); } - + @Test public void saveAndLoadFlowStream() { @@ -187,11 +187,11 @@ public void saveAndLoadFlowStream() { assertTrue("saveToXML() must not throw an exception", couldSave); ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); - + boolean couldLoad = true; VFlow flow2 = null; try { - flow2 = WorkflowIO.loadFromXML(is); + flow2 = WorkflowIO.loadFromXML(is); } catch (Exception ex) { Logger.getLogger(VFlowIOTest.class.getName()).log(Level.SEVERE, null, ex); couldLoad = false; @@ -218,29 +218,29 @@ public void saveAndLoadFlowStream() { private void compare(VFlow flow1, VFlow flow2) { assertEquals("Both flows must have equal id", - flow1.getModel().getId(), flow2.getModel().getId()); + flow1.getModel().getId(), flow2.getModel().getId()); assertEquals("Both flows must have an equal number of subflows", - flow1.getSubControllers().size(), flow2.getSubControllers().size()); + flow1.getSubControllers().size(), flow2.getSubControllers().size()); assertEquals("Both flows must have an equal number of nodes", - flow1.getNodes().size(), flow2.getNodes().size()); + flow1.getNodes().size(), flow2.getNodes().size()); // Flows may have empty connection objects // (however, number of connections must be the same, see below) -// assertEquals("Both flows must have an equal number of connection types,", -// flow1.getAllConnections().values().size(), flow2.getAllConnections().values().size()); + // assertEquals("Both flows must have an equal number of connection types,", + // flow1.getAllConnections().values().size(), flow2.getAllConnections().values().size()); for (Connections connections1 : flow1.getAllConnections().values()) { Connections connections2 = flow2.getConnections(connections1.getType()); assertNotNull("Second flows must have a connections object of type " + connections1.getType(), - connections2); + connections2); assertEquals("Both flows must have an equal number of connections,", - connections1.getConnections().size(), - connections2.getConnections().size()); + connections1.getConnections().size(), + connections2.getConnections().size()); for (int i = 0; i < connections1.getConnections().size(); i++) { Connection c1 = connections1.getConnections().get(i); @@ -256,16 +256,16 @@ private void compare(VFlow flow1, VFlow flow2) { VNode n2 = flow2.getNodeLookup().getById(n1.getId()); assertNotNull("Second flow must contain a node with same id as in flow1: " - + n1.getId(), n2); + + n1.getId(), n2); assertEquals("Second node must contain the same number of connectors as node 1", - n1.getConnectors().size(), n2.getConnectors().size()); + n1.getConnectors().size(), n2.getConnectors().size()); for (int i = 0; i < n1.getConnectors().size(); i++) { assertEquals("Connectors must have equal id: ", - n1.getConnectors().get(i).getId(), - n2.getConnectors().get(i).getId()); + n1.getConnectors().get(i).getId(), + n2.getConnectors().get(i).getId()); } // TODO deep compare for valueobjects etc. @@ -283,7 +283,7 @@ private void compare(VFlow flow1, VFlow flow2) { } assertNotNull("Second flow must contain a subflow with same id as in flow1: " - + subFlow1.getModel().getId(), subFlow2); + + subFlow1.getModel().getId(), subFlow2); compare(subFlow1, subFlow2); } diff --git a/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/VFlowMergeTest.java b/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/VFlowMergeTest.java index 17d1e19b..9bec87b5 100644 --- a/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/VFlowMergeTest.java +++ b/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/VFlowMergeTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -38,10 +38,10 @@ */ package eu.mihosoft.vrl.workflow; +import eu.mihosoft.vrl.workflow.util.FlowFactory; import org.junit.Ignore; /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ public class VFlowMergeTest { @@ -52,7 +52,7 @@ public void testAdd() { addNodesToFlow(parent.newSubFlow(), 3, "control", "data"); VFlow subflow = FlowFactory.newFlow(); addNodesToFlow(subflow, 3, "control", "data"); -// parent.add(subflow); + // parent.add(subflow); VFlow expectedResult = FlowFactory.newFlow(); addNodesToFlow(expectedResult, 3, "control", "data"); diff --git a/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/VFlowTest.java b/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/VFlowTest.java index 437dcbc9..b7c89d0f 100644 --- a/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/VFlowTest.java +++ b/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/VFlowTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -37,6 +37,7 @@ */ package eu.mihosoft.vrl.workflow; +import eu.mihosoft.vrl.workflow.util.FlowFactory; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; @@ -53,7 +54,6 @@ import static org.junit.Assert.assertTrue; /** - * * @author Michael Hoffer */ public class VFlowTest { @@ -103,10 +103,10 @@ public void createNodes() { continue; } - assertNotEquals("flow.newNode() must not return equal nodes!", - flow.getNodes().get(i), flow.getNodes().get(j)); + assertNotEquals("flow.registerNode() must not return equal nodes!", + flow.getNodes().get(i), flow.getNodes().get(j)); assertNotEquals("nodes must not have equal ids!", - flow.getNodes().get(i).getId(), flow.getNodes().get(j).getId()); + flow.getNodes().get(i).getId(), flow.getNodes().get(j).getId()); } } } @@ -137,11 +137,11 @@ public void connectNodes() { if (prevNodes.size() >= connectionTypes.length) { -// System.out.print(" >> prevNodes: "); -// for (VNode vNode : prevNodes) { -// System.out.print(" " + vNode.getOutputs().get(0).getType()); -// } -// System.out.println(""); + // System.out.print(" >> prevNodes: "); + // for (VNode vNode : prevNodes) { + // System.out.print(" " + vNode.getOutputs().get(0).getType()); + // } + // System.out.println(""); for (int j = 0; j < prevNodes.size(); j++) { ConnectionResult[] results = new ConnectionResult[connectionTypes.length]; @@ -155,22 +155,22 @@ public void connectNodes() { Connector outputReceiver = receiverNode.getOutputs().get(0); results[j] = flow.connect(outputSender, inputReceiver); - + if (k == 0) { assertTrue("Connection between compatible types failed: " + outputSender.getType() + " -> " + inputReceiver.getType(), - results[j].getStatus().isCompatible()); + results[j].getStatus().isCompatible()); } else { assertFalse("Connection between incompatible types must fail: " + outputSender.getType() + " -> " + inputReceiver.getType(), - results[j].getStatus().isCompatible()); + results[j].getStatus().isCompatible()); } assertFalse("Connection between two outputs must fail", - flow.connect(outputSender, outputReceiver).getStatus().isCompatible()); + flow.connect(outputSender, outputReceiver).getStatus().isCompatible()); assertFalse("Connection between two inputs must fail", - flow.connect(inputSender, inputReceiver).getStatus().isCompatible()); + flow.connect(inputSender, inputReceiver).getStatus().isCompatible()); } // end for k } // end for j @@ -198,7 +198,7 @@ public void createSubflows() { System.out.println(" --> subnode class: " + subNode.getClass()); assertTrue("Node that represent flows must implement VFlowModel interface", - (subNode instanceof VFlowModel)); + (subNode instanceof VFlowModel)); } @Test @@ -218,6 +218,6 @@ public void connectorsParentNode() { System.out.println(" --> subnode class (as referenced by connector): " + connector.getNode().getClass()); assertTrue("Node that represent flows must implement VFlowModel interface", - (connector.getNode() instanceof VFlowModel)); + (connector.getNode() instanceof VFlowModel)); } } diff --git a/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/WorkflowUtilTest.java b/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/WorkflowUtilTest.java index be2cf974..4e6076a3 100644 --- a/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/WorkflowUtilTest.java +++ b/VWorkflows-Core/src/test/java/eu/mihosoft/vrl/workflow/WorkflowUtilTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -34,6 +34,11 @@ package eu.mihosoft.vrl.workflow; import eu.mihosoft.vrl.workflow.io.WorkflowIO; +import eu.mihosoft.vrl.workflow.util.FlowFactory; +import eu.mihosoft.vrl.workflow.util.WorkflowUtil; +import org.junit.Assert; +import org.junit.Test; + import java.io.IOException; import java.nio.file.Paths; import java.util.ArrayList; @@ -41,11 +46,8 @@ import java.util.Optional; import java.util.logging.Level; import java.util.logging.Logger; -import org.junit.Assert; -import org.junit.Test; /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ public class WorkflowUtilTest { @@ -64,12 +66,12 @@ public void createAncestorsTestCase(int depth, int width, int destDepth, int des if (destDepth < 0 || destDepth > depth) { throw new IllegalArgumentException("Illegal destDepth specified: " - + destDepth + ". Must be between 1 and " + depth + "."); + + destDepth + ". Must be between 1 and " + depth + "."); } if (destWidth < 0 || destWidth >= width) { throw new IllegalArgumentException("Illegal destDepth specified: " - + destDepth + ". Must be between 0 and " + (width - 1) + "."); + + destDepth + ". Must be between 0 and " + (width - 1) + "."); } VFlow flow = FlowFactory.newFlow(); @@ -90,7 +92,7 @@ public void createAncestorsTestCase(int depth, int width, int destDepth, int des Assert.assertTrue("Number of Ancestors must be equal to dest depth. " + "Expected " + destDepth + ", got " + numAncestors, - numAncestors == destDepth); + numAncestors == destDepth); } @@ -151,51 +153,51 @@ public void createCommonAncestorTestCase(int depth, int width, String n1Id, Stri Assert.assertTrue("Wrong common ancestor. " + "Expected " + commonAncestorId + ", got " + ancestor.getId(), - commonAncestorId.equals(ancestor.getId()) + commonAncestorId.equals(ancestor.getId()) ); } } - + @Test public void pathInLayerTest() { createPathInLayerTest(3, 6); createPathInLayerTest(1, 1); createPathInLayerTest(32, 32); createPathInLayerTest(2, 100); - + } - + private void createPathInLayerTest(int pathLength, int numNodes) { - + if (numNodes == 0 || pathLength == 0) { return; } - + if (numNodes < pathLength) { throw new IllegalArgumentException( - "path length must be less than number of nodes!"); + "path length must be less than number of nodes!"); } - + VFlow flow = FlowFactory.newFlow(); - - for(int i = 0; i < numNodes;i++) { + + for (int i = 0; i < numNodes; i++) { VNode n = flow.newNode(); n.setMainOutput(n.addOutput("mytype")); n.setMainInput(n.addInput("mytype")); } - - for(int i = 0; i < pathLength-1;i++) { + + for (int i = 0; i < pathLength - 1; i++) { VNode sender = flow.getNodes().get(i); - VNode receiver = flow.getNodes().get(i+1); + VNode receiver = flow.getNodes().get(i + 1); flow.connect(sender, receiver, "mytype"); } - - List path= WorkflowUtil.getPathInLayerFromRoot( - flow.getNodes().get(0), "mytype"); - - Assert.assertTrue("Expected number of nodes in path = "+pathLength - +", got " + path.size(), path.size()==pathLength); + + List path = WorkflowUtil.getPathInLayerFromRoot( + flow.getNodes().get(0), "mytype"); + + Assert.assertTrue("Expected number of nodes in path = " + pathLength + + ", got " + path.size(), path.size() == pathLength); } } diff --git a/VWorkflows-Core/vworkflows-core.gradle b/VWorkflows-Core/vworkflows-core.gradle index 9259cfce..81ba5a69 100644 --- a/VWorkflows-Core/vworkflows-core.gradle +++ b/VWorkflows-Core/vworkflows-core.gradle @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: diff --git a/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/CustomContextMenuDemo.java b/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/CustomContextMenuDemo.java index 8e4049f3..3c516341 100644 --- a/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/CustomContextMenuDemo.java +++ b/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/CustomContextMenuDemo.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -39,13 +39,13 @@ package eu.mihosoft.vrl.workflow.demo; import eu.mihosoft.vrl.workflow.Connection; -import eu.mihosoft.vrl.workflow.FlowFactory; import eu.mihosoft.vrl.workflow.VFlow; import eu.mihosoft.vrl.workflow.VNode; -import eu.mihosoft.vrl.workflow.fx.DefaultFXConnectionSkin; -import eu.mihosoft.vrl.workflow.fx.FXSkinFactory; -import eu.mihosoft.vrl.workflow.fx.VCanvas; +import eu.mihosoft.vrl.workflow.fx.scene.layout.VCanvas; +import eu.mihosoft.vrl.workflow.fx.skin.FXSkinFactory; +import eu.mihosoft.vrl.workflow.fx.skin.impl.DefaultFXConnectionSkin; import eu.mihosoft.vrl.workflow.skin.ConnectionSkin; +import eu.mihosoft.vrl.workflow.util.FlowFactory; import javafx.application.Application; import javafx.event.EventHandler; import javafx.scene.Parent; @@ -67,7 +67,7 @@ public void start(Stage primaryStage) throws Exception { StackPane contentPane = new StackPane(); VCanvas canvas = new VCanvas(); contentPane.getChildren().add(canvas); - createFlow((Pane)canvas.getContent()); + createFlow((Pane) canvas.getContent()); Scene scene = new Scene(contentPane, 1024, 768); diff --git a/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/Main.java b/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/Main.java index c5864b9e..f9a00d29 100644 --- a/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/Main.java +++ b/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/Main.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -47,7 +47,6 @@ import java.util.logging.Logger; /** - * * @author Michael Hoffer <info@michaelhoffer.de> */ public class Main extends Application { @@ -63,12 +62,13 @@ public class Main extends Application { public static void main(String[] args) { launch(args); } + private MainWindowFXMLController controller; @Override public void start(Stage primaryStage) { -// connectionTest(); + // connectionTest(); StackPane canvas = new StackPane(); @@ -80,7 +80,7 @@ public void start(Stage primaryStage) { fxmlLoader.load(); } catch (IOException ex) { Logger.getLogger(Main.class.getName()). - log(Level.SEVERE, null, ex); + log(Level.SEVERE, null, ex); } controller = fxmlLoader.getController(); @@ -94,17 +94,17 @@ public void start(Stage primaryStage) { Rectangle rect = new Rectangle(); rect.setStroke(new Color(1, 1, 1, 1)); rect.setFill(new Color(0, 0, 0, 0.5)); - -// MouseControlUtil. -// addSelectionRectangleGesture(controller.getRootPane(), rect); -// Playground.search01(); -// -// VRLShell shell = VShell.showInteractivScenicView(canvas); -// -// controller.registerShell(shell); + // MouseControlUtil. + // addSelectionRectangleGesture(controller.getRootPane(), rect); + + // Playground.search01(); + // + // VRLShell shell = VShell.showInteractivScenicView(canvas); + // + // controller.registerShell(shell); } - + } diff --git a/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/MainWindowFXMLController.java b/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/MainWindowFXMLController.java index bb2a539d..0e9b7758 100644 --- a/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/MainWindowFXMLController.java +++ b/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/MainWindowFXMLController.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -37,39 +37,47 @@ import eu.mihosoft.vrl.workflow.ClickEvent; import eu.mihosoft.vrl.workflow.Connection; import eu.mihosoft.vrl.workflow.Connector; -import eu.mihosoft.vrl.workflow.FlowFactory; -import eu.mihosoft.vrl.workflow.incubating.LayoutGenerator; -import eu.mihosoft.vrl.workflow.incubating.LayoutGeneratorNaive; -import eu.mihosoft.vrl.workflow.incubating.LayoutGeneratorSmart; import eu.mihosoft.vrl.workflow.MouseButton; import eu.mihosoft.vrl.workflow.VFlow; import eu.mihosoft.vrl.workflow.VFlowModel; import eu.mihosoft.vrl.workflow.VNode; import eu.mihosoft.vrl.workflow.VisualizationRequest; -import eu.mihosoft.vrl.workflow.fx.FlowNodeWindow; -import eu.mihosoft.vrl.workflow.fx.FXFlowNodeSkin; -import eu.mihosoft.vrl.workflow.fx.FXSkinFactory; -import eu.mihosoft.vrl.workflow.fx.InnerCanvas; -import eu.mihosoft.vrl.workflow.fx.NodeUtil; -import eu.mihosoft.vrl.workflow.fx.OptimizableContentPane; -import eu.mihosoft.vrl.workflow.fx.ScalableContentPane; -import eu.mihosoft.vrl.workflow.fx.VCanvas; +import eu.mihosoft.vrl.workflow.fx.scene.control.FlowNodeWindow; +import eu.mihosoft.vrl.workflow.fx.scene.layout.InnerCanvas; +import eu.mihosoft.vrl.workflow.fx.scene.layout.OptimizableContentPane; +import eu.mihosoft.vrl.workflow.fx.scene.layout.ScalableContentPane; +import eu.mihosoft.vrl.workflow.fx.scene.layout.VCanvas; +import eu.mihosoft.vrl.workflow.fx.skin.FXFlowNodeSkin; +import eu.mihosoft.vrl.workflow.fx.skin.FXSkinFactory; +import eu.mihosoft.vrl.workflow.fx.util.NodeUtil; +import eu.mihosoft.vrl.workflow.incubating.LayoutGenerator; +import eu.mihosoft.vrl.workflow.incubating.LayoutGeneratorNaive; +import eu.mihosoft.vrl.workflow.incubating.LayoutGeneratorSmart; import eu.mihosoft.vrl.workflow.io.WorkflowIO; -import java.io.File; +import eu.mihosoft.vrl.workflow.util.FlowFactory; import javafx.collections.ObservableList; +import javafx.embed.swing.SwingFXUtils; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; +import javafx.scene.Node; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.SnapshotParameters; import javafx.scene.control.CheckMenuItem; import javafx.scene.control.ContextMenu; import javafx.scene.control.MenuItem; +import javafx.scene.image.WritableImage; import javafx.scene.input.MouseEvent; import javafx.scene.layout.Pane; -import javafx.scene.Parent; -import javafx.scene.Scene; +import javafx.scene.transform.Translate; import javafx.stage.Stage; +import jfxtras.scene.control.window.Window; + +import javax.imageio.ImageIO; +import java.io.File; import java.io.IOException; import java.net.URL; import java.nio.file.Paths; @@ -82,13 +90,6 @@ import java.util.ResourceBundle; import java.util.logging.Level; import java.util.logging.Logger; -import javafx.embed.swing.SwingFXUtils; -import javafx.scene.Node; -import javafx.scene.SnapshotParameters; -import javafx.scene.image.WritableImage; -import javafx.scene.transform.Translate; -import javax.imageio.ImageIO; -import jfxtras.scene.control.window.Window; /** * FXML Controller class @@ -115,7 +116,7 @@ public class MainWindowFXMLController implements Initializable { */ @Override public void initialize(URL url, ResourceBundle rb) { - canvas = new VCanvas(); + canvas = new VCanvas(); Pane root = (Pane) canvas.getContent(); @@ -124,13 +125,13 @@ public void initialize(URL url, ResourceBundle rb) { rootPane = root; onGenerateAction(null); - + // layout interface: smartLayout = new LayoutGeneratorSmart(); naiveLayout = new LayoutGeneratorNaive(); - + fxmlLoaderSmart = new FXMLLoader(getClass() - .getResource("OptionsWindowFXML.fxml")); + .getResource("OptionsWindowFXML.fxml")); optionsstageSmart = new Stage(); optionsstageSmart.setTitle("Smart Layout Options"); try { @@ -142,9 +143,9 @@ public void initialize(URL url, ResourceBundle rb) { optionsSmart = fxmlLoaderSmart.getController(); optionsSmart.setGenerator(smartLayout); optionsSmart.setStage(optionsstageSmart); - + fxmlLoaderNaive = new FXMLLoader(getClass() - .getResource("OptionsWindowNaiveFXML.fxml")); + .getResource("OptionsWindowNaiveFXML.fxml")); optionsstageNaive = new Stage(); optionsstageNaive.setTitle("Naive Layout Options"); try { @@ -157,7 +158,7 @@ public void initialize(URL url, ResourceBundle rb) { optionsNaive.setGenerator(naiveLayout); optionsNaive.setStage(optionsstageNaive); } - + private Pane rootPane; private VCanvas canvas; VFlow workflow; @@ -194,18 +195,18 @@ public void onSaveAction(ActionEvent e) { System.out.println(" [done]"); } - + // @FXML private CheckMenuItem checkDebugLayout; // - + // @FXML public void onNaiveAction(ActionEvent e) { int i; this.naiveLayout.setDebug(this.checkDebugLayout.isSelected()); - switch(this.naiveLayout.getGraphmode()) { + switch (this.naiveLayout.getGraphmode()) { case 0: this.naiveLayout.setWorkflow(this.workflow.getModel()); this.naiveLayout.generateLayout(); @@ -213,26 +214,26 @@ public void onNaiveAction(ActionEvent e) { case 2: ObservableList obsnodes = workflow.getNodes(); LinkedList nodelist = new LinkedList<>(); - for(i = 0; i < obsnodes.size(); i++) { + for (i = 0; i < obsnodes.size(); i++) { VNode curr = obsnodes.get(i); - if(curr.isSelected()) { + if (curr.isSelected()) { nodelist.add(curr); } } - if(!nodelist.isEmpty()) { + if (!nodelist.isEmpty()) { this.smartLayout.setNodelist(nodelist); this.smartLayout.generateLayout(); } break; } - + } - + @FXML public void onSmartRunAction(ActionEvent e) { int i; this.smartLayout.setDebug(this.checkDebugLayout.isSelected()); - switch(this.smartLayout.getGraphmode()) { + switch (this.smartLayout.getGraphmode()) { case 0: this.smartLayout.setWorkflow(this.workflow.getModel()); this.smartLayout.generateLayout(); @@ -241,28 +242,28 @@ public void onSmartRunAction(ActionEvent e) { LayoutGeneratorSmart altlay = new LayoutGeneratorSmart(); altlay.setWorkflow(this.workflow.getModel()); altlay.generateLayout(); - DirectedGraph jgraph = - altlay.getModelGraph(); + DirectedGraph jgraph = + altlay.getModelGraph(); this.smartLayout.setModelGraph(jgraph); this.smartLayout.generateLayout(); break; case 2: ObservableList obsnodes = workflow.getNodes(); LinkedList nodelist = new LinkedList<>(); - for(i = 0; i < obsnodes.size(); i++) { + for (i = 0; i < obsnodes.size(); i++) { VNode curr = obsnodes.get(i); - if(curr.isSelected()) { + if (curr.isSelected()) { nodelist.add(curr); } } - if(!nodelist.isEmpty()) { + if (!nodelist.isEmpty()) { this.smartLayout.setNodelist(nodelist); this.smartLayout.generateLayout(); } break; } } - + @FXML public void onSmartOptionsAction(ActionEvent e) { optionsSmart.setWorkflow(workflow); @@ -270,7 +271,7 @@ public void onSmartOptionsAction(ActionEvent e) { optionsSmart.set(); optionsstageSmart.show(); } - + @FXML public void onNaiveOptionsAction(ActionEvent e) { optionsNaive.setWorkflow(workflow); @@ -278,13 +279,13 @@ public void onNaiveOptionsAction(ActionEvent e) { optionsNaive.set(); optionsstageNaive.show(); } - + @FXML public void onLayoutSnapshotAction(ActionEvent e) { String abspath = new File(".").getAbsolutePath(); - String path = abspath.substring(0, abspath.length()-1); + String path = abspath.substring(0, abspath.length() - 1); File dir = new File(path + "snapshots"); - if(!dir.exists()) { + if (!dir.exists()) { System.out.println("Creating directory: " + dir.getAbsolutePath()); dir.mkdir(); } @@ -305,20 +306,20 @@ public void onLayoutSnapshotAction(ActionEvent e) { } subSnaps((InnerCanvas) canvas.getContent(), path, now); } - + private void subSnaps(InnerCanvas inner, String path, String now) { ObservableList childnodes = inner.getChildrenUnmodifiable(); - for(Node n : childnodes) { - if((n instanceof FlowNodeWindow) && (n.isManaged())) { + for (Node n : childnodes) { + if ((n instanceof FlowNodeWindow) && (n.isManaged())) { FlowNodeWindow w = (FlowNodeWindow) n; List style = NodeUtil.getStylesheetsOfAncestors(w); FXFlowNodeSkin wskin = w.nodeSkinProperty().get(); VFlow cont = wskin.getController(); Collection subconts = cont.getSubControllers(); - for(VFlow currsub : subconts) { - if(currsub.getModel().equals(wskin.getModel())) { + for (VFlow currsub : subconts) { + if (currsub.getModel().equals(wskin.getModel())) { String title = currsub.getModel().getId().replace(':', '-'); - if((currsub.getNodes().size() > 0) && (currsub.isVisible())) { + if ((currsub.getNodes().size() > 0) && (currsub.isVisible())) { VCanvas subcanvas = new VCanvas(); FlowNodeWindow.addResetViewMenu(subcanvas); subcanvas.setMinScaleX(0.1); @@ -326,10 +327,10 @@ private void subSnaps(InnerCanvas inner, String path, String now) { subcanvas.setMaxScaleX(1); subcanvas.setMaxScaleY(1); subcanvas.setTranslateToMinNodePos(true); - + FXSkinFactory fxSkinFactory = w.nodeSkinProperty().get().getSkinFactory().newInstance((Parent) subcanvas.getContent(), null); currsub.addSkinFactories(fxSkinFactory); - + Scene subscene = new Scene(subcanvas, (int) Math.round(rootPane.getWidth()), (int) Math.round(rootPane.getHeight())); subscene.getStylesheets().setAll(style); WritableImage wim = new WritableImage((int) Math.round(subscene.getWidth()), (int) Math.round(subscene.getHeight())); @@ -341,7 +342,7 @@ private void subSnaps(InnerCanvas inner, String path, String now) { } catch (IOException ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); } - if(w.getWorkflowContentPane() instanceof InnerCanvas) { + if (w.getWorkflowContentPane() instanceof InnerCanvas) { subSnaps((InnerCanvas) w.getWorkflowContentPane(), path, now); } } @@ -351,7 +352,7 @@ private void subSnaps(InnerCanvas inner, String path, String now) { } } // - + // @FXML public void onOriginalAction(ActionEvent e) { @@ -359,222 +360,222 @@ public void onOriginalAction(ActionEvent e) { VFlowModel flow = workflow.getModel(); originalTest(flow); } - + private void originalTest(VFlowModel flow) { ObservableList nodes = flow.getNodes(); - if(nodes.isEmpty()) return; + if (nodes.isEmpty()) { return; } flow.connect(nodes.get(1).getOutputs().get(1), nodes.get(3).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(3).getOutputs().get(1), nodes.get(8).getInputs() - .get(3)); + .get(3)); flow.connect(nodes.get(5).getOutputs().get(1), nodes.get(1).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(5).getOutputs().get(3), nodes.get(7).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(7).getOutputs().get(1), nodes.get(8).getInputs() - .get(0)); + .get(0)); flow.connect(nodes.get(8).getOutputs().get(2), nodes.get(9).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(3).getOutputs().get(0), nodes.get(6).getInputs() - .get(0)); + .get(0)); flow.connect(nodes.get(6).getOutputs().get(0), nodes.get(0).getInputs() - .get(0)); + .get(0)); flow.connect(nodes.get(0).getOutputs().get(0), nodes.get(9).getInputs() - .get(0)); + .get(0)); Iterator it = nodes.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { VNode curr = it.next(); - if(curr instanceof VFlowModel) { + if (curr instanceof VFlowModel) { originalTest((VFlowModel) curr); } } } - + @FXML public void onAdditionalEdgeAction(ActionEvent e) { onGenerateAction(e); VFlowModel flow = workflow.getModel(); additionalEdgeTest(flow); } - + private void additionalEdgeTest(VFlowModel flow) { ObservableList nodes = flow.getNodes(); - if(nodes.isEmpty()) return; + if (nodes.isEmpty()) { return; } flow.connect(nodes.get(1).getOutputs().get(1), nodes.get(3).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(3).getOutputs().get(1), nodes.get(8).getInputs() - .get(3)); + .get(3)); flow.connect(nodes.get(5).getOutputs().get(1), nodes.get(1).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(5).getOutputs().get(3), nodes.get(7).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(7).getOutputs().get(1), nodes.get(8).getInputs() - .get(0)); + .get(0)); flow.connect(nodes.get(8).getOutputs().get(2), nodes.get(9).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(3).getOutputs().get(0), nodes.get(6).getInputs() - .get(0)); + .get(0)); flow.connect(nodes.get(6).getOutputs().get(0), nodes.get(0).getInputs() - .get(0)); + .get(0)); flow.connect(nodes.get(0).getOutputs().get(0), nodes.get(9).getInputs() - .get(0)); + .get(0)); flow.connect(nodes.get(2).getOutputs().get(2), nodes.get(8).getInputs() - .get(4)); + .get(4)); Iterator it = nodes.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { VNode curr = it.next(); - if(curr instanceof VFlowModel) { + if (curr instanceof VFlowModel) { additionalEdgeTest((VFlowModel) curr); } } } - + @FXML public void onAdditionalGraphAction(ActionEvent e) { onGenerateAction(e); VFlowModel flow = workflow.getModel(); additionalGraphTest(flow); } - + private void additionalGraphTest(VFlowModel flow) { ObservableList nodes = flow.getNodes(); - if(nodes.isEmpty()) return; + if (nodes.isEmpty()) { return; } flow.connect(nodes.get(1).getOutputs().get(1), nodes.get(3).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(3).getOutputs().get(1), nodes.get(8).getInputs() - .get(3)); + .get(3)); flow.connect(nodes.get(5).getOutputs().get(1), nodes.get(1).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(8).getOutputs().get(2), nodes.get(9).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(3).getOutputs().get(0), nodes.get(6).getInputs() - .get(0)); + .get(0)); flow.connect(nodes.get(6).getOutputs().get(0), nodes.get(0).getInputs() - .get(0)); + .get(0)); flow.connect(nodes.get(0).getOutputs().get(0), nodes.get(9).getInputs() - .get(0)); + .get(0)); flow.connect(nodes.get(2).getOutputs().get(1), nodes.get(4).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(4).getOutputs().get(1), nodes.get(7).getInputs() - .get(1)); + .get(1)); Iterator it = nodes.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { VNode curr = it.next(); - if(curr instanceof VFlowModel) { + if (curr instanceof VFlowModel) { additionalGraphTest((VFlowModel) curr); } } } - + @FXML public void onTriLaneAction(ActionEvent e) { onGenerateAction(e); VFlowModel flow = workflow.getModel(); triLaneTest(flow); } - + private void triLaneTest(VFlowModel flow) { ObservableList nodes = flow.getNodes(); - if(nodes.isEmpty()) return; + if (nodes.isEmpty()) { return; } flow.connect(nodes.get(0).getOutputs().get(1), nodes.get(1).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(0).getOutputs().get(1), nodes.get(5).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(0).getOutputs().get(1), nodes.get(6).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(1).getOutputs().get(1), nodes.get(2).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(1).getOutputs().get(1), nodes.get(7).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(5).getOutputs().get(1), nodes.get(3).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(6).getOutputs().get(1), nodes.get(7).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(2).getOutputs().get(1), nodes.get(8).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(7).getOutputs().get(1), nodes.get(8).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(3).getOutputs().get(1), nodes.get(8).getInputs() - .get(1)); + .get(1)); Iterator it = nodes.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { VNode curr = it.next(); - if(curr instanceof VFlowModel) { + if (curr instanceof VFlowModel) { triLaneTest((VFlowModel) curr); } } } - + @FXML public void onDifferentSizesAction(ActionEvent e) { onGenerateAction(e); VFlowModel flow = workflow.getModel(); differentSizesTest(flow); } - + private void differentSizesTest(VFlowModel flow) { ObservableList nodes = flow.getNodes(); - if(nodes.isEmpty()) return; + if (nodes.isEmpty()) { return; } flow.connect(nodes.get(1).getOutputs().get(1), nodes.get(3).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(3).getOutputs().get(1), nodes.get(8).getInputs() - .get(3)); + .get(3)); flow.connect(nodes.get(5).getOutputs().get(1), nodes.get(1).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(5).getOutputs().get(3), nodes.get(7).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(7).getOutputs().get(1), nodes.get(8).getInputs() - .get(0)); + .get(0)); flow.connect(nodes.get(8).getOutputs().get(2), nodes.get(9).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(3).getOutputs().get(0), nodes.get(6).getInputs() - .get(0)); + .get(0)); flow.connect(nodes.get(6).getOutputs().get(0), nodes.get(0).getInputs() - .get(0)); + .get(0)); flow.connect(nodes.get(0).getOutputs().get(0), nodes.get(9).getInputs() - .get(0)); + .get(0)); nodes.get(5).setHeight(nodes.get(5).getHeight() * 1.5); nodes.get(5).setWidth(nodes.get(5).getWidth() * 1.5); nodes.get(7).setHeight(nodes.get(7).getHeight() * 2); nodes.get(8).setWidth(nodes.get(8).getWidth() * 2); Iterator it = nodes.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { VNode curr = it.next(); - if(curr instanceof VFlowModel) { + if (curr instanceof VFlowModel) { differentSizesTest((VFlowModel) curr); } } } - + @FXML public void onCycleAction(ActionEvent e) { onGenerateAction(e); VFlowModel flow = workflow.getModel(); cycleTest(flow); } - + private void cycleTest(VFlowModel flow) { ObservableList nodes = flow.getNodes(); - if(nodes.isEmpty()) return; + if (nodes.isEmpty()) { return; } flow.connect(nodes.get(0).getOutputs().get(1), nodes.get(1).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(1).getOutputs().get(1), nodes.get(2).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(2).getOutputs().get(1), nodes.get(3).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(2).getOutputs().get(1), nodes.get(4).getInputs() - .get(1)); + .get(1)); flow.connect(nodes.get(4).getOutputs().get(1), nodes.get(0).getInputs() - .get(1)); + .get(1)); Iterator it = nodes.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { VNode curr = it.next(); - if(curr instanceof VFlowModel) { + if (curr instanceof VFlowModel) { cycleTest((VFlowModel) curr); } } } - + @FXML public void onTestTree1(ActionEvent e) { // generation @@ -585,25 +586,25 @@ public void onTestTree1(ActionEvent e) { // edges ObservableList nodes = workflow.getNodes(); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(1) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(2) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(1).getOutputs().get(1), nodes.get(3) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(1).getOutputs().get(1), nodes.get(4) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(2).getOutputs().get(1), nodes.get(5) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(2).getOutputs().get(1), nodes.get(6) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(3).getOutputs().get(1), nodes.get(7) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(4).getOutputs().get(1), nodes.get(8) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(5).getOutputs().get(1), nodes.get(9) - .getInputs().get(1)); + .getInputs().get(1)); } - + @FXML public void onTestTree2(ActionEvent e) { // generation @@ -614,25 +615,25 @@ public void onTestTree2(ActionEvent e) { // edges ObservableList nodes = workflow.getNodes(); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(1) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(2) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(3) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(1).getOutputs().get(1), nodes.get(4) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(1).getOutputs().get(1), nodes.get(5) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(2).getOutputs().get(1), nodes.get(6) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(2).getOutputs().get(1), nodes.get(7) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(2).getOutputs().get(1), nodes.get(8) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(3).getOutputs().get(1), nodes.get(9) - .getInputs().get(1)); + .getInputs().get(1)); } - + @FXML public void onTestTree3(ActionEvent e) { // generation @@ -643,25 +644,25 @@ public void onTestTree3(ActionEvent e) { // edges ObservableList nodes = workflow.getNodes(); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(1) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(2) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(1).getOutputs().get(1), nodes.get(3) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(2).getOutputs().get(1), nodes.get(4) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(2).getOutputs().get(1), nodes.get(5) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(3).getOutputs().get(1), nodes.get(6) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(3).getOutputs().get(1), nodes.get(7) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(5).getOutputs().get(1), nodes.get(8) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(5).getOutputs().get(1), nodes.get(9) - .getInputs().get(1)); + .getInputs().get(1)); } - + @FXML public void onTestNontree1(ActionEvent e) { // generation @@ -672,31 +673,31 @@ public void onTestNontree1(ActionEvent e) { // edges ObservableList nodes = workflow.getNodes(); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(1) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(2) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(6) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(1).getOutputs().get(1), nodes.get(3) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(1).getOutputs().get(1), nodes.get(4) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(2).getOutputs().get(1), nodes.get(4) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(2).getOutputs().get(1), nodes.get(5) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(2).getOutputs().get(1), nodes.get(6) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(3).getOutputs().get(1), nodes.get(7) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(3).getOutputs().get(1), nodes.get(8) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(5).getOutputs().get(1), nodes.get(9) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(6).getOutputs().get(1), nodes.get(9) - .getInputs().get(1)); + .getInputs().get(1)); } - + @FXML public void onTestNontree2(ActionEvent e) { // generation @@ -707,31 +708,31 @@ public void onTestNontree2(ActionEvent e) { // edges ObservableList nodes = workflow.getNodes(); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(1) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(2) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(1).getOutputs().get(1), nodes.get(2) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(1).getOutputs().get(1), nodes.get(3) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(2).getOutputs().get(1), nodes.get(4) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(2).getOutputs().get(1), nodes.get(5) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(3).getOutputs().get(1), nodes.get(6) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(3).getOutputs().get(1), nodes.get(7) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(4).getOutputs().get(1), nodes.get(8) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(5).getOutputs().get(1), nodes.get(9) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(6).getOutputs().get(1), nodes.get(8) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(7).getOutputs().get(1), nodes.get(9) - .getInputs().get(1)); + .getInputs().get(1)); } - + @FXML public void onTestNontree3(ActionEvent e) { // generation @@ -742,29 +743,29 @@ public void onTestNontree3(ActionEvent e) { // edges ObservableList nodes = workflow.getNodes(); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(2) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(4) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(1).getOutputs().get(1), nodes.get(2) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(1).getOutputs().get(1), nodes.get(3) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(2).getOutputs().get(1), nodes.get(4) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(2).getOutputs().get(1), nodes.get(5) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(3).getOutputs().get(1), nodes.get(6) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(3).getOutputs().get(1), nodes.get(7) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(5).getOutputs().get(1), nodes.get(8) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(6).getOutputs().get(1), nodes.get(8) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(8).getOutputs().get(1), nodes.get(9) - .getInputs().get(1)); + .getInputs().get(1)); } - + @FXML public void onTestCyclic1(ActionEvent e) { // generation @@ -775,27 +776,27 @@ public void onTestCyclic1(ActionEvent e) { // edges ObservableList nodes = workflow.getNodes(); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(2) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(1).getOutputs().get(1), nodes.get(3) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(2).getOutputs().get(1), nodes.get(3) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(3).getOutputs().get(1), nodes.get(5) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(4).getOutputs().get(1), nodes.get(2) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(5).getOutputs().get(1), nodes.get(7) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(6).getOutputs().get(1), nodes.get(4) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(6).getOutputs().get(1), nodes.get(8) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(7).getOutputs().get(1), nodes.get(6) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(7).getOutputs().get(1), nodes.get(9) - .getInputs().get(1)); + .getInputs().get(1)); } - + @FXML public void onTestCyclic2(ActionEvent e) { // generation @@ -806,33 +807,33 @@ public void onTestCyclic2(ActionEvent e) { // edges ObservableList nodes = workflow.getNodes(); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(1) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(2) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(1).getOutputs().get(1), nodes.get(4) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(2).getOutputs().get(1), nodes.get(3) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(3).getOutputs().get(1), nodes.get(5) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(4).getOutputs().get(1), nodes.get(2) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(4).getOutputs().get(1), nodes.get(6) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(4).getOutputs().get(1), nodes.get(8) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(5).getOutputs().get(1), nodes.get(4) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(6).getOutputs().get(1), nodes.get(7) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(6).getOutputs().get(1), nodes.get(8) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(7).getOutputs().get(1), nodes.get(5) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(8).getOutputs().get(1), nodes.get(9) - .getInputs().get(1)); + .getInputs().get(1)); } - + @FXML public void onTestCyclic3(ActionEvent e) { // generation @@ -843,29 +844,29 @@ public void onTestCyclic3(ActionEvent e) { // edges ObservableList nodes = workflow.getNodes(); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(1) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(5) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(1).getOutputs().get(1), nodes.get(2) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(2).getOutputs().get(1), nodes.get(3) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(3).getOutputs().get(1), nodes.get(4) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(4).getOutputs().get(1), nodes.get(5) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(5).getOutputs().get(1), nodes.get(6) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(6).getOutputs().get(1), nodes.get(7) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(7).getOutputs().get(1), nodes.get(8) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(8).getOutputs().get(1), nodes.get(9) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(9).getOutputs().get(1), nodes.get(0) - .getInputs().get(1)); + .getInputs().get(1)); } - + @FXML public void onTestSizes1(ActionEvent e) { // generation @@ -876,30 +877,30 @@ public void onTestSizes1(ActionEvent e) { // edges ObservableList nodes = workflow.getNodes(); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(1) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(4) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(1).getOutputs().get(1), nodes.get(2) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(2).getOutputs().get(1), nodes.get(3) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(3).getOutputs().get(1), nodes.get(5) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(4).getOutputs().get(1), nodes.get(5) - .getInputs().get(1)); + .getInputs().get(1)); nodes.get(4).setWidth(nodes.get(4).getWidth() * 1.5); nodes.get(4).setHeight(nodes.get(4).getHeight() * 1.5); VFlowModel node5 = (VFlowModel) nodes.get(4); // subflow VNode n; int i; - for(i = 0; i < 4; i++) { + for (i = 0; i < 4; i++) { n = node5.newNode(); n.setTitle("Node " + n.getId()); n.addInput("event").getVisualizationRequest().set( - VisualizationRequest.KEY_CONNECTOR_AUTO_LAYOUT, true); + VisualizationRequest.KEY_CONNECTOR_AUTO_LAYOUT, true); n.addOutput("event").getVisualizationRequest().set( - VisualizationRequest.KEY_CONNECTOR_AUTO_LAYOUT, true); + VisualizationRequest.KEY_CONNECTOR_AUTO_LAYOUT, true); for (final Connector connector : n.getConnectors()) { connector.addClickEventListener(new EventHandler() { @Override @@ -910,10 +911,10 @@ public void handle(ClickEvent t) { if (t.getEvent() instanceof MouseEvent) { MouseEvent evt = (MouseEvent) t.getEvent(); ContextMenu menu = new ContextMenu(new MenuItem( - "Connector: " + connector.getId() - + ", btn: " + t.getButton())); + "Connector: " + connector.getId() + + ", btn: " + t.getButton())); menu.show(rootPane, evt.getScreenX(), - evt.getScreenY()); + evt.getScreenY()); } } }); @@ -925,17 +926,17 @@ public void handle(ClickEvent t) { } ObservableList subnodes = node5.getNodes(); node5.connect(subnodes.get(0).getOutputs().get(0), subnodes.get(1) - .getInputs().get(0)); + .getInputs().get(0)); node5.connect(subnodes.get(0).getOutputs().get(0), subnodes.get(2) - .getInputs().get(0)); + .getInputs().get(0)); node5.connect(subnodes.get(0).getOutputs().get(0), subnodes.get(3) - .getInputs().get(0)); + .getInputs().get(0)); node5.connect(subnodes.get(1).getOutputs().get(0), subnodes.get(3) - .getInputs().get(0)); + .getInputs().get(0)); node5.connect(subnodes.get(2).getOutputs().get(0), subnodes.get(3) - .getInputs().get(0)); + .getInputs().get(0)); } - + @FXML public void onTestSizes2(ActionEvent e) { // generation @@ -946,27 +947,27 @@ public void onTestSizes2(ActionEvent e) { // edges ObservableList nodes = workflow.getNodes(); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(1) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(2) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(0).getOutputs().get(1), nodes.get(3) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(1).getOutputs().get(1), nodes.get(6) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(2).getOutputs().get(1), nodes.get(4) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(3).getOutputs().get(1), nodes.get(5) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(4).getOutputs().get(1), nodes.get(7) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(5).getOutputs().get(1), nodes.get(8) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(6).getOutputs().get(1), nodes.get(9) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(7).getOutputs().get(1), nodes.get(9) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(8).getOutputs().get(1), nodes.get(9) - .getInputs().get(1)); + .getInputs().get(1)); nodes.get(2).setWidth(nodes.get(2).getWidth() * 2); nodes.get(5).setWidth(nodes.get(5).getWidth() * 2); nodes.get(7).setWidth(nodes.get(7).getWidth() * 2); @@ -974,7 +975,7 @@ public void onTestSizes2(ActionEvent e) { nodes.get(5).setHeight(nodes.get(5).getHeight() * 2); nodes.get(7).setHeight(nodes.get(7).getHeight() * 2); } - + @FXML public void onTestSizes3(ActionEvent e) { // generation @@ -985,33 +986,33 @@ public void onTestSizes3(ActionEvent e) { // edges ObservableList nodes = workflow.getNodes(); workflow.connect(nodes.get(1).getOutputs().get(1), nodes.get(2) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(2).getOutputs().get(1), nodes.get(4) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(2).getOutputs().get(1), nodes.get(8) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(3).getOutputs().get(1), nodes.get(1) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(3).getOutputs().get(1), nodes.get(6) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(4).getOutputs().get(1), nodes.get(5) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(5).getOutputs().get(1), nodes.get(3) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(5).getOutputs().get(1), nodes.get(6) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(6).getOutputs().get(1), nodes.get(8) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(7).getOutputs().get(1), nodes.get(0) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(7).getOutputs().get(1), nodes.get(5) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(8).getOutputs().get(1), nodes.get(4) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(8).getOutputs().get(1), nodes.get(0) - .getInputs().get(1)); + .getInputs().get(1)); workflow.connect(nodes.get(9).getOutputs().get(1), nodes.get(5) - .getInputs().get(1)); + .getInputs().get(1)); nodes.get(0).setWidth(nodes.get(0).getWidth() * 3); nodes.get(1).setWidth(nodes.get(1).getWidth() * 0.5); nodes.get(2).setWidth(nodes.get(2).getWidth() * 1.5); @@ -1029,21 +1030,21 @@ public void onTestSizes3(ActionEvent e) { nodes.get(8).setHeight(nodes.get(8).getHeight() * 3); nodes.get(9).setHeight(nodes.get(9).getHeight() * 3); } - + @FXML public void onTestRunAll(ActionEvent e) { System.out.println("starting..."); String abspath = new File(".").getAbsolutePath(); - String path = abspath.substring(0, abspath.length()-1); + String path = abspath.substring(0, abspath.length() - 1); LayoutGenerator layouter; File dir = new File(path + "testimages"); - if(!dir.exists()) { + if (!dir.exists()) { System.out.println("Creating directory: " + dir.getAbsolutePath()); dir.mkdir(); } path += "testimages/"; dir = new File(path + "smart"); - if(!dir.exists()) { + if (!dir.exists()) { System.out.println("Creating directoriy: " + dir.getAbsolutePath()); dir.mkdir(); } @@ -1051,7 +1052,7 @@ public void onTestRunAll(ActionEvent e) { System.out.println("--- testing LayoutGeneratorSmart"); runTests(layouter, (path + "smart/"), e); dir = new File(path + "naive"); - if(!dir.exists()) { + if (!dir.exists()) { System.out.println("Creating directory: " + dir.getAbsolutePath()); dir.mkdir(); } @@ -1060,13 +1061,14 @@ public void onTestRunAll(ActionEvent e) { runTests(layouter, (path + "naive/"), e); System.out.println("...finished"); } - + /** - * Runs all tests for the given layout generator and saves snapshots of the + * Runs all tests for the given layout generator and saves snapshots of the * results in the given path. + * * @param layouter LayoutGenerator - * @param path String - * @param e ActionEvent + * @param path String + * @param e ActionEvent */ private void runTests(LayoutGenerator layouter, String path, ActionEvent e) { WritableImage wim = new WritableImage(1600, 800); @@ -1076,260 +1078,260 @@ private void runTests(LayoutGenerator layouter, String path, ActionEvent e) { int i; // test tree 1 System.out.println("Testing - TestTree1"); - for(i = 0; i < 10; i++) { + for (i = 0; i < 10; i++) { onTestTree1(e); layouter.setWorkflow(workflow.getModel()); layouter.generateLayout(); try { rootPane.snapshot(parameter, wim); dir = new File(path + "TestTree1"); - if(!dir.exists()) { - System.out.println("Creating directory: " + path - + "TestTree1"); + if (!dir.exists()) { + System.out.println("Creating directory: " + path + + "TestTree1"); dir.mkdir(); } File out = new File(path + "TestTree1/" + i + ".png"); ImageIO.write(SwingFXUtils.fromFXImage(wim, null), "png", out); } catch (IOException ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, - ex); + ex); } } // test tree 2 System.out.println("Testing - TestTree2"); - for(i = 0; i < 10; i++) { + for (i = 0; i < 10; i++) { onTestTree2(e); layouter.setWorkflow(workflow.getModel()); layouter.generateLayout(); try { rootPane.snapshot(parameter, wim); dir = new File(path + "TestTree2"); - if(!dir.exists()) { - System.out.println("Creating directory: " + path - + "TestTree2"); + if (!dir.exists()) { + System.out.println("Creating directory: " + path + + "TestTree2"); dir.mkdir(); } File out = new File(path + "TestTree2/" + i + ".png"); ImageIO.write(SwingFXUtils.fromFXImage(wim, null), "png", out); } catch (IOException ex) { - Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, - ex); + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, + ex); } } // test tree 3 System.out.println("Testing - TestTree3"); - for(i = 0; i < 10; i++) { + for (i = 0; i < 10; i++) { onTestTree3(e); layouter.setWorkflow(workflow.getModel()); layouter.generateLayout(); try { rootPane.snapshot(parameter, wim); dir = new File(path + "TestTree3"); - if(!dir.exists()) { - System.out.println("Creating directory: " + path - + "TestTree3"); + if (!dir.exists()) { + System.out.println("Creating directory: " + path + + "TestTree3"); dir.mkdir(); } File out = new File(path + "TestTree3/" + i + ".png"); ImageIO.write(SwingFXUtils.fromFXImage(wim, null), "png", out); } catch (IOException ex) { - Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, - ex); + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, + ex); } } // test nontree 1 System.out.println("Testing - TestNontree1"); - for(i = 0; i < 10; i++) { + for (i = 0; i < 10; i++) { onTestNontree1(e); layouter.setWorkflow(workflow.getModel()); layouter.generateLayout(); try { rootPane.snapshot(parameter, wim); dir = new File(path + "TestNontree1"); - if(!dir.exists()) { - System.out.println("Creating directory: " + path - + "TestNontree1"); + if (!dir.exists()) { + System.out.println("Creating directory: " + path + + "TestNontree1"); dir.mkdir(); } File out = new File(path + "TestNontree1/" + i + ".png"); ImageIO.write(SwingFXUtils.fromFXImage(wim, null), "png", out); } catch (IOException ex) { - Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, - ex); + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, + ex); } } // test nontree 2 System.out.println("Testing - TestNontree2"); - for(i = 0; i < 10; i++) { + for (i = 0; i < 10; i++) { onTestNontree2(e); layouter.setWorkflow(workflow.getModel()); layouter.generateLayout(); try { rootPane.snapshot(parameter, wim); dir = new File(path + "TestNontree2"); - if(!dir.exists()) { - System.out.println("Creating directory: " + path - + "TestNontree2"); + if (!dir.exists()) { + System.out.println("Creating directory: " + path + + "TestNontree2"); dir.mkdir(); } File out = new File(path + "TestNontree2/" + i + ".png"); ImageIO.write(SwingFXUtils.fromFXImage(wim, null), "png", out); } catch (IOException ex) { - Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, - ex); + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, + ex); } } // test nontree 3 System.out.println("Testing - TestNontree3"); - for(i = 0; i < 10; i++) { + for (i = 0; i < 10; i++) { onTestNontree3(e); layouter.setWorkflow(workflow.getModel()); layouter.generateLayout(); try { rootPane.snapshot(parameter, wim); dir = new File(path + "TestNontree3"); - if(!dir.exists()) { - System.out.println("Creating directory: " + path - + "TestNontree3"); + if (!dir.exists()) { + System.out.println("Creating directory: " + path + + "TestNontree3"); dir.mkdir(); } File out = new File(path + "TestNontree3/" + i + ".png"); ImageIO.write(SwingFXUtils.fromFXImage(wim, null), "png", out); } catch (IOException ex) { - Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, - ex); + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, + ex); } } // test cyclic 1 System.out.println("Testing - TestCyclic1"); - for(i = 0; i < 10; i++) { + for (i = 0; i < 10; i++) { onTestCyclic1(e); layouter.setWorkflow(workflow.getModel()); layouter.generateLayout(); try { rootPane.snapshot(parameter, wim); dir = new File(path + "TestCyclic1"); - if(!dir.exists()) { - System.out.println("Creating directory: " + path - + "TestCyclic1"); + if (!dir.exists()) { + System.out.println("Creating directory: " + path + + "TestCyclic1"); dir.mkdir(); } File out = new File(path + "TestCyclic1/" + i + ".png"); ImageIO.write(SwingFXUtils.fromFXImage(wim, null), "png", out); } catch (IOException ex) { - Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, - ex); + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, + ex); } } // test cyclic 2 System.out.println("Testing - TestCyclic2"); - for(i = 0; i < 10; i++) { + for (i = 0; i < 10; i++) { onTestCyclic2(e); layouter.setWorkflow(workflow.getModel()); layouter.generateLayout(); try { rootPane.snapshot(parameter, wim); dir = new File(path + "TestCyclic2"); - if(!dir.exists()) { - System.out.println("Creating directory: " + path - + "TestCyclic2"); + if (!dir.exists()) { + System.out.println("Creating directory: " + path + + "TestCyclic2"); dir.mkdir(); } File out = new File(path + "TestCyclic2/" + i + ".png"); ImageIO.write(SwingFXUtils.fromFXImage(wim, null), "png", out); } catch (IOException ex) { - Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, - ex); + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, + ex); } } // test cyclic 3 System.out.println("Testing - TestCyclic3"); - for(i = 0; i < 10; i++) { + for (i = 0; i < 10; i++) { onTestCyclic3(e); layouter.setWorkflow(workflow.getModel()); layouter.generateLayout(); try { rootPane.snapshot(parameter, wim); dir = new File(path + "TestCyclic3"); - if(!dir.exists()) { - System.out.println("Creating directory: " + path - + "TestCyclic3"); + if (!dir.exists()) { + System.out.println("Creating directory: " + path + + "TestCyclic3"); dir.mkdir(); } File out = new File(path + "TestCyclic3/" + i + ".png"); ImageIO.write(SwingFXUtils.fromFXImage(wim, null), "png", out); } catch (IOException ex) { - Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, - ex); + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, + ex); } } // test sizes 1 System.out.println("Testing - TestSizes1"); - for(i = 0; i < 10; i++) { + for (i = 0; i < 10; i++) { onTestSizes1(e); layouter.setWorkflow(workflow.getModel()); layouter.generateLayout(); try { rootPane.snapshot(parameter, wim); dir = new File(path + "TestSizes1"); - if(!dir.exists()) { - System.out.println("Creating directory: " + path - + "TestSizes1"); + if (!dir.exists()) { + System.out.println("Creating directory: " + path + + "TestSizes1"); dir.mkdir(); } File out = new File(path + "TestSizes1/" + i + ".png"); ImageIO.write(SwingFXUtils.fromFXImage(wim, null), "png", out); } catch (IOException ex) { - Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, - ex); + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, + ex); } } // test sizes 2 System.out.println("Testing - TestSizes2"); - for(i = 0; i < 10; i++) { + for (i = 0; i < 10; i++) { onTestSizes2(e); layouter.setWorkflow(workflow.getModel()); layouter.generateLayout(); try { rootPane.snapshot(parameter, wim); dir = new File(path + "TestSizes2"); - if(!dir.exists()) { - System.out.println("Creating directory: " + path - + "TestSizes2"); + if (!dir.exists()) { + System.out.println("Creating directory: " + path + + "TestSizes2"); dir.mkdir(); } File out = new File(path + "TestSizes2/" + i + ".png"); ImageIO.write(SwingFXUtils.fromFXImage(wim, null), "png", out); } catch (IOException ex) { - Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, - ex); + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, + ex); } } // test sizes 3 System.out.println("Testing - TestSizes3"); - for(i = 0; i < 10; i++) { + for (i = 0; i < 10; i++) { onTestSizes3(e); layouter.setWorkflow(workflow.getModel()); layouter.generateLayout(); try { rootPane.snapshot(parameter, wim); dir = new File(path + "TestSizes3"); - if(!dir.exists()) { - System.out.println("Creating directory: " + path - + "TestSizes3"); + if (!dir.exists()) { + System.out.println("Creating directory: " + path + + "TestSizes3"); dir.mkdir(); } File out = new File(path + "TestSizes3/" + i + ".png"); ImageIO.write(SwingFXUtils.fromFXImage(wim, null), "png", out); } catch (IOException ex) { - Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, - ex); + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, + ex); } } } - + // - + @FXML public void onStableAction(ActionEvent e) { LayoutGeneratorSmart layouter = new LayoutGeneratorSmart(false); @@ -1349,13 +1351,14 @@ public void onGenerateAction(ActionEvent e) { updateUI(); workflowTest(workflow, 5, 10); -// workflowTest(workflow, 2, 2); + // workflowTest(workflow, 2, 2); System.out.println(" [done]"); System.out.println(" --> #nodes: " + counter); } + @FXML public Pane contentPane; @@ -1399,22 +1402,22 @@ public void workflowTest(VFlow workflow, int depth, int width) { } n.setTitle("Node " + n.getId()); - -// n.getVisualizationRequest().set(VisualizationRequest.KEY_MAX_CONNECTOR_SIZE, 10.0); + + // n.getVisualizationRequest().set(VisualizationRequest.KEY_MAX_CONNECTOR_SIZE, 10.0); String type = connectionTypes[i % connectionTypes.length]; n.setMainInput(n.addInput(type)).getVisualizationRequest().set(VisualizationRequest.KEY_CONNECTOR_AUTO_LAYOUT, true); n.setMainInput(n.addInput("event")).getVisualizationRequest().set(VisualizationRequest.KEY_CONNECTOR_AUTO_LAYOUT, true); - -// n.getVisualizationRequest().set(VisualizationRequest.KEY_DISABLE_EDITING, true); + + // n.getVisualizationRequest().set(VisualizationRequest.KEY_DISABLE_EDITING, true); for (int j = 0; j < 3; j++) { n.addInput(type).getVisualizationRequest().set(VisualizationRequest.KEY_CONNECTOR_AUTO_LAYOUT, true); } -// n.addInput(type); -// n.addInput(type); + // n.addInput(type); + // n.addInput(type); n.addOutput(type).getVisualizationRequest().set(VisualizationRequest.KEY_CONNECTOR_AUTO_LAYOUT, true); n.setMainOutput(n.addOutput("event")).getVisualizationRequest().set(VisualizationRequest.KEY_CONNECTOR_AUTO_LAYOUT, true); n.addOutput(type).getVisualizationRequest().set(VisualizationRequest.KEY_CONNECTOR_AUTO_LAYOUT, true); @@ -1457,42 +1460,41 @@ private void updateUI() { rootPane.getChildren().clear(); -// ScalableContentPane minimapPane1 = createMinimap("Minimap 1"); -// ScalableContentPane minimapPane2 = createMinimap("Minimap 2"); -// -// if (workflow == null) { -// return; -// } + // ScalableContentPane minimapPane1 = createMinimap("Minimap 1"); + // ScalableContentPane minimapPane2 = createMinimap("Minimap 2"); + // + // if (workflow == null) { + // return; + // } workflow.getModel().setVisible(true); FXSkinFactory skinFactory = new FXSkinFactory(rootPane); workflow.setSkinFactories(skinFactory); - - - -// skinFactory.setConnectionFillColor("control", new Color(1.0, 1.0, 0.0, 0.75)); -// skinFactory.setConnectionStrokeColor("control", new Color(120 / 255.0, 140 / 255.0, 1, 0.42)); -// -// skinFactory.setConnectionFillColor("data", new Color(0.1, 0.1, 0.1, 0.5)); -// skinFactory.setConnectionStrokeColor("data", new Color(120 / 255.0, 140 / 255.0, 1, 0.42)); -// -// skinFactory.setConnectionFillColor("event", new Color(255.0 / 255.0, 100.0 / 255.0, 1, 0.5)); -// skinFactory.setConnectionStrokeColor("event", new Color(120 / 255.0, 140 / 255.0, 1, 0.42)); -// workflow.addSkinFactories(new FXSkinFactory(minimapPane1.getContentPane()), -// new FXSkinFactory(minimapPane2.getContentPane())); -// ScalableContentPane minimapPane3 = createMinimap("Minimap 3"); -// ScalableContentPane minimapPane4 = createMinimap("Minimap 4"); -// -// if (specialViewFlow1 != null) { -// specialViewFlow1.addSkinFactories(new FXSkinFactory(minimapPane3.getContentPane())); -// } -// -// if (specialViewFlow2 != null) { -// specialViewFlow2.addSkinFactories(new FXSkinFactory(minimapPane4.getContentPane())); -// } -// -// workflow.newSubFlow(); + + + // skinFactory.setConnectionFillColor("control", new Color(1.0, 1.0, 0.0, 0.75)); + // skinFactory.setConnectionStrokeColor("control", new Color(120 / 255.0, 140 / 255.0, 1, 0.42)); + // + // skinFactory.setConnectionFillColor("data", new Color(0.1, 0.1, 0.1, 0.5)); + // skinFactory.setConnectionStrokeColor("data", new Color(120 / 255.0, 140 / 255.0, 1, 0.42)); + // + // skinFactory.setConnectionFillColor("event", new Color(255.0 / 255.0, 100.0 / 255.0, 1, 0.5)); + // skinFactory.setConnectionStrokeColor("event", new Color(120 / 255.0, 140 / 255.0, 1, 0.42)); + // workflow.addSkinFactories(new FXSkinFactory(minimapPane1.getContentPane()), + // new FXSkinFactory(minimapPane2.getContentPane())); + // ScalableContentPane minimapPane3 = createMinimap("Minimap 3"); + // ScalableContentPane minimapPane4 = createMinimap("Minimap 4"); + // + // if (specialViewFlow1 != null) { + // specialViewFlow1.addSkinFactories(new FXSkinFactory(minimapPane3.getContentPane())); + // } + // + // if (specialViewFlow2 != null) { + // specialViewFlow2.addSkinFactories(new FXSkinFactory(minimapPane4.getContentPane())); + // } + // + // workflow.newSubFlow(); } private ScalableContentPane createMinimap(String title) { @@ -1512,7 +1514,7 @@ private ScalableContentPane createMinimap(String title) { rootPane.getChildren().add(minimap); return minimapPane; } -// void registerShell(VRLShell shell) { -// shell.addConstant("flow", workflow); -// } + // void registerShell(VRLShell shell) { + // shell.addConstant("flow", workflow); + // } } diff --git a/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/NodeControlFXMLController.java b/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/NodeControlFXMLController.java index 3f575daa..b9f33156 100644 --- a/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/NodeControlFXMLController.java +++ b/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/NodeControlFXMLController.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -51,5 +51,5 @@ public class NodeControlFXMLController implements Initializable { @Override public void initialize(URL url, ResourceBundle rb) { // TODO - } + } } diff --git a/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/OptionsWindowFXMLController.java b/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/OptionsWindowFXMLController.java index a94cdb36..69c11afa 100644 --- a/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/OptionsWindowFXMLController.java +++ b/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/OptionsWindowFXMLController.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -35,9 +35,9 @@ import edu.uci.ics.jung.graph.DirectedGraph; import eu.mihosoft.vrl.workflow.Connection; -import eu.mihosoft.vrl.workflow.incubating.LayoutGeneratorSmart; import eu.mihosoft.vrl.workflow.VFlow; import eu.mihosoft.vrl.workflow.VNode; +import eu.mihosoft.vrl.workflow.incubating.LayoutGeneratorSmart; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.fxml.FXML; @@ -56,15 +56,14 @@ /** * FXML Controller Class - * - * + * * @author Tobias Mertz */ public class OptionsWindowFXMLController implements Initializable { @FXML public Pane contentPane; - + private LayoutGeneratorSmart generator; private Stage optionsstage; private VFlow workflow; @@ -73,8 +72,9 @@ public class OptionsWindowFXMLController implements Initializable { /** * Initializes the controller class. + * * @param url URL - * @param rb ResourceBundle + * @param rb ResourceBundle */ @Override public void initialize(URL url, ResourceBundle rb) { @@ -95,65 +95,65 @@ public void initialize(URL url, ResourceBundle rb) { graphmodelist.add(this.graphmodes[1]); graphmodelist.add(this.graphmodes[2]); } - + // @FXML private CheckBox checkForcePush; - + @FXML private CheckBox checkSeparateDisjunctGraphs; - + @FXML private CheckBox checkSeparateEdgeTypes; - + @FXML private CheckBox checkDisplaceIdents; - + @FXML private TextField tfMaxiterations; - + @FXML private CheckBox checkRecursive; - + @FXML private TextField tfAspectratio; - + @FXML private TextField tfScaling; - + @FXML private ComboBox selLayout; - + @FXML private CheckBox checkAlignNodes; - + @FXML private CheckBox checkRemoveCycles; - + @FXML private CheckBox checkOrigin; - + @FXML private TextField tfSubflowscale; - + @FXML private CheckBox checkRotate; - + @FXML private CheckBox checkPushBack; - + @FXML private CheckBox checkAutoscaleNodes; - + @FXML private CheckBox checkJungLayout; - + @FXML private ComboBox selGraphmode; - + @FXML private TextField tfDirection; - + @FXML private TextField tfAlignmentThreshold; // @@ -162,25 +162,25 @@ public void initialize(URL url, ResourceBundle rb) { public void setGenerator(LayoutGeneratorSmart pgenerator) { this.generator = pgenerator; } - + public void setStage(Stage poptionsstage) { this.optionsstage = poptionsstage; } - + public void setWorkflow(VFlow pworkflow) { this.workflow = pworkflow; } // - + // public LayoutGeneratorSmart getGenerator() { return this.generator; } - + public Stage getStage() { return this.optionsstage; } - + public VFlow getWorkflow() { return this.workflow; } @@ -197,12 +197,12 @@ void onCancelPress(ActionEvent e) { set(); this.optionsstage.close(); } - + @FXML void onShowPress(ActionEvent e) { int i; accept(); - switch(this.generator.getGraphmode()) { + switch (this.generator.getGraphmode()) { case 0: this.generator.setWorkflow(this.workflow.getModel()); this.generator.generateLayout(); @@ -211,69 +211,69 @@ void onShowPress(ActionEvent e) { LayoutGeneratorSmart altlay = new LayoutGeneratorSmart(); altlay.setWorkflow(this.workflow.getModel()); altlay.generateLayout(); - DirectedGraph jgraph = - altlay.getModelGraph(); + DirectedGraph jgraph = + altlay.getModelGraph(); this.generator.setModelGraph(jgraph); this.generator.generateLayout(); break; case 2: ObservableList obsnodes = workflow.getNodes(); LinkedList nodelist = new LinkedList<>(); - for(i = 0; i < obsnodes.size(); i++) { + for (i = 0; i < obsnodes.size(); i++) { VNode curr = obsnodes.get(i); - if(curr.isSelected()) { + if (curr.isSelected()) { nodelist.add(curr); } } - if(!nodelist.isEmpty()) { + if (!nodelist.isEmpty()) { this.generator.setNodelist(nodelist); this.generator.generateLayout(); } break; } } - + /** - * Sets the values of all menu items to the current values of the layout + * Sets the values of all menu items to the current values of the layout * generator. */ public void set() { this.checkForcePush.setSelected(this.generator.getLaunchForcePush()); this.checkSeparateDisjunctGraphs.setSelected(this.generator - .getLaunchSeparateDisjunctGraphs()); + .getLaunchSeparateDisjunctGraphs()); this.checkSeparateEdgeTypes.setSelected(this.generator - .getLaunchSeparateEdgeTypes()); + .getLaunchSeparateEdgeTypes()); this.checkDisplaceIdents.setSelected(this.generator - .getLaunchDisplaceIdents()); + .getLaunchDisplaceIdents()); this.tfMaxiterations.setText(Integer.toString(this.generator - .getMaxiterations())); + .getMaxiterations())); this.checkRecursive.setSelected(this.generator.getRecursive()); this.tfAspectratio.setText(Double.toString(this.generator - .getAspectratio())); + .getAspectratio())); this.tfScaling.setText(Double.toString(this.generator.getScaling())); this.selLayout.setValue(this.layouts[this.generator - .getLayoutSelector()]); + .getLayoutSelector()]); this.checkAlignNodes.setSelected(this.generator.getLaunchAlignNodes()); this.checkRemoveCycles.setSelected(this.generator - .getLaunchRemoveCycles()); + .getLaunchRemoveCycles()); this.checkOrigin.setSelected(this.generator.getLaunchOrigin()); this.tfSubflowscale.setText(Double.toString(this.generator - .getSubflowscale())); + .getSubflowscale())); this.checkRotate.setSelected(this.generator.getLaunchRotate()); this.checkPushBack.setSelected(this.generator.getLaunchPushBack()); this.checkAutoscaleNodes.setSelected(this.generator - .getAutoscaleNodes()); + .getAutoscaleNodes()); this.checkJungLayout.setSelected(this.generator.getLaunchJungLayout()); this.selGraphmode.setValue(this.graphmodes[this.generator - .getGraphmode()]); + .getGraphmode()]); this.tfDirection.setText(Double.toString(this.generator - .getDirection())); + .getDirection())); this.tfAlignmentThreshold.setText(Double.toString(this.generator - .getAlignmentThreshold())); + .getAlignmentThreshold())); } /** - * Sets the values of all parameters of the layout generator to the current + * Sets the values of all parameters of the layout generator to the current * values of the menu items. */ private void accept() { @@ -282,11 +282,11 @@ private void accept() { String temp; this.generator.setLaunchForcePush(this.checkForcePush.isSelected()); this.generator.setLaunchSeparateDisjunctGraphs(this - .checkSeparateDisjunctGraphs.isSelected()); + .checkSeparateDisjunctGraphs.isSelected()); this.generator.setLaunchSeparateEdgeTypes(this.checkSeparateEdgeTypes - .isSelected()); + .isSelected()); this.generator.setLaunchDisplaceIdents(this.checkDisplaceIdents - .isSelected()); + .isSelected()); i = this.generator.getMaxiterations(); temp = this.tfMaxiterations.getText(); try { @@ -313,14 +313,14 @@ private void accept() { } this.generator.setScaling(j); temp = this.selLayout.getValue(); - for(i = 0; i < this.layouts.length; i++) { - if(this.layouts[i].equals(temp)) { + for (i = 0; i < this.layouts.length; i++) { + if (this.layouts[i].equals(temp)) { this.generator.setLayoutSelector(i); } } this.generator.setLaunchAlignNodes(this.checkAlignNodes.isSelected()); this.generator.setLaunchRemoveCycles(this.checkRemoveCycles - .isSelected()); + .isSelected()); this.generator.setLaunchOrigin(this.checkOrigin.isSelected()); j = this.generator.getSubflowscale(); temp = this.tfSubflowscale.getText(); @@ -335,8 +335,8 @@ private void accept() { this.generator.setAutoscaleNodes(this.checkAutoscaleNodes.isSelected()); this.generator.setLaunchJungLayout(this.checkJungLayout.isSelected()); temp = this.selGraphmode.getValue(); - for(i = 0; i < this.graphmodes.length; i++) { - if(this.graphmodes[i].equals(temp)) { + for (i = 0; i < this.graphmodes.length; i++) { + if (this.graphmodes[i].equals(temp)) { this.generator.setGraphmode(i); } } diff --git a/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/OptionsWindowNaiveFXMLController.java b/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/OptionsWindowNaiveFXMLController.java index e84a932d..87b57b5b 100644 --- a/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/OptionsWindowNaiveFXMLController.java +++ b/VWorkflows-Demo/src/main/java/eu/mihosoft/vrl/workflow/demo/OptionsWindowNaiveFXMLController.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 Michael Hoffer . All rights reserved. + * Copyright 2012-2017 Michael Hoffer . All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -33,9 +33,9 @@ */ package eu.mihosoft.vrl.workflow.demo; -import eu.mihosoft.vrl.workflow.incubating.LayoutGeneratorNaive; import eu.mihosoft.vrl.workflow.VFlow; import eu.mihosoft.vrl.workflow.VNode; +import eu.mihosoft.vrl.workflow.incubating.LayoutGeneratorNaive; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.fxml.FXML; @@ -54,14 +54,14 @@ /** * FXML Controller Class - * + * * @author Tobias Mertz */ public class OptionsWindowNaiveFXMLController implements Initializable { - + @FXML public Pane contentPane; - + private LayoutGeneratorNaive generator; private Stage optionsstage; private VFlow workflow; @@ -69,8 +69,9 @@ public class OptionsWindowNaiveFXMLController implements Initializable { /** * Initializes the controller class. + * * @param url URL - * @param rb ResourceBundle + * @param rb ResourceBundle */ @Override public void initialize(URL url, ResourceBundle rb) { @@ -82,7 +83,7 @@ public void initialize(URL url, ResourceBundle rb) { graphmodelist.add(this.graphmodes[1]); graphmodelist.add(this.graphmodes[2]); } - + // @FXML private CheckBox checkCalcVertPos; @@ -111,30 +112,30 @@ public void initialize(URL url, ResourceBundle rb) { @FXML private CheckBox checkCalcHorPos; // - + // public void setGenerator(LayoutGeneratorNaive pgenerator) { this.generator = pgenerator; } - + public void setStage(Stage poptionsstage) { this.optionsstage = poptionsstage; } - + public void setWorkflow(VFlow pworkflow) { this.workflow = pworkflow; } // - + // public LayoutGeneratorNaive getGenerator() { return this.generator; } - + public Stage getStage() { return this.optionsstage; } - + public VFlow getWorkflow() { return this.workflow; } @@ -156,7 +157,7 @@ void onCancelPress(ActionEvent event) { void onShowPress(ActionEvent event) { int i; accept(); - switch(this.generator.getGraphmode()) { + switch (this.generator.getGraphmode()) { case 0: this.generator.setWorkflow(this.workflow.getModel()); this.generator.generateLayout(); @@ -164,45 +165,45 @@ void onShowPress(ActionEvent event) { case 2: ObservableList obsnodes = workflow.getNodes(); LinkedList nodelist = new LinkedList<>(); - for(i = 0; i < obsnodes.size(); i++) { + for (i = 0; i < obsnodes.size(); i++) { VNode curr = obsnodes.get(i); - if(curr.isSelected()) { + if (curr.isSelected()) { nodelist.add(curr); } } - if(!nodelist.isEmpty()) { + if (!nodelist.isEmpty()) { this.generator.setNodelist(nodelist); this.generator.generateLayout(); } break; } } - + /** - * Sets the values of all menu items to the current values of the layout + * Sets the values of all menu items to the current values of the layout * generator. */ public void set() { this.checkAutoscaleNodes.setSelected(this.generator - .getAutoscaleNodes()); + .getAutoscaleNodes()); this.checkCalcHorPos.setSelected(this.generator - .getLaunchCalculateHorizontalPositions()); + .getLaunchCalculateHorizontalPositions()); this.checkCalcVertPos.setSelected(this.generator - .getLaunchCalculateVerticalPositions()); + .getLaunchCalculateVerticalPositions()); this.checkCreateLayering.setSelected(this.generator - .getLaunchCreateLayering()); + .getLaunchCreateLayering()); this.checkRecursive.setSelected(this.generator.getRecursive()); this.checkRemoveCycles.setSelected(this.generator - .getLaunchRemoveCycles()); + .getLaunchRemoveCycles()); this.selGraphmode.setValue(this.graphmodes[this.generator - .getGraphmode()]); + .getGraphmode()]); this.tfScaling.setText(Double.toString(this.generator.getScaling())); this.tfSubflowscale.setText(Double.toString(this.generator - .getSubflowscale())); + .getSubflowscale())); } - + /** - * Sets the values of all parameters of the layout generator to the current + * Sets the values of all parameters of the layout generator to the current * values of the menu items. */ private void accept() { @@ -211,18 +212,18 @@ private void accept() { String temp; this.generator.setAutoscaleNodes(this.checkAutoscaleNodes.isSelected()); this.generator.setLaunchCalculateHorizontalPositions( - this.checkCalcHorPos.isSelected()); + this.checkCalcHorPos.isSelected()); this.generator.setLaunchCalculateVerticalPositions( - this.checkCalcVertPos.isSelected()); + this.checkCalcVertPos.isSelected()); this.generator.setLaunchCreateLayering(this.checkCreateLayering - .isSelected()); + .isSelected()); this.generator.setRecursive(this.checkRecursive.isSelected()); this.generator.setLaunchRemoveCycles(this.checkRemoveCycles - .isSelected()); + .isSelected()); temp = this.selGraphmode.getValue(); - for(i = 0; i < this.graphmodes.length; i++) { - if(this.graphmodes[i].equals(temp)) { - if(i != 1) this.generator.setGraphmode(i); + for (i = 0; i < this.graphmodes.length; i++) { + if (this.graphmodes[i].equals(temp)) { + if (i != 1) { this.generator.setGraphmode(i); } } } j = this.generator.getScaling(); diff --git a/VWorkflows-Demo/src/main/resources/eu/mihosoft/vrl/workflow/demo/MainWindowFXML.fxml b/VWorkflows-Demo/src/main/resources/eu/mihosoft/vrl/workflow/demo/MainWindowFXML.fxml index 77c46729..268492d5 100644 --- a/VWorkflows-Demo/src/main/resources/eu/mihosoft/vrl/workflow/demo/MainWindowFXML.fxml +++ b/VWorkflows-Demo/src/main/resources/eu/mihosoft/vrl/workflow/demo/MainWindowFXML.fxml @@ -1,7 +1,7 @@ - - + - - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - + + + + diff --git a/VWorkflows-Demo/src/main/resources/eu/mihosoft/vrl/workflow/demo/NodeControlFXML.fxml b/VWorkflows-Demo/src/main/resources/eu/mihosoft/vrl/workflow/demo/NodeControlFXML.fxml index d26b254b..f0adf236 100644 --- a/VWorkflows-Demo/src/main/resources/eu/mihosoft/vrl/workflow/demo/NodeControlFXML.fxml +++ b/VWorkflows-Demo/src/main/resources/eu/mihosoft/vrl/workflow/demo/NodeControlFXML.fxml @@ -1,7 +1,7 @@ - - - + + diff --git a/VWorkflows-Demo/src/main/resources/eu/mihosoft/vrl/workflow/demo/OptionsWindowFXML.fxml b/VWorkflows-Demo/src/main/resources/eu/mihosoft/vrl/workflow/demo/OptionsWindowFXML.fxml index a1a8d3b3..9f875004 100644 --- a/VWorkflows-Demo/src/main/resources/eu/mihosoft/vrl/workflow/demo/OptionsWindowFXML.fxml +++ b/VWorkflows-Demo/src/main/resources/eu/mihosoft/vrl/workflow/demo/OptionsWindowFXML.fxml @@ -1,7 +1,7 @@ - - - - - - - - - - - - - - - - - - - - - - -