commonsrc.ingenias.editor.Model Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of core Show documentation
Show all versions of core Show documentation
The INGENIAS Meta-Editor core. It is a set of facilities to generate an editor from a detailed xml description
/**
* Copyright (C) 2010 Jorge J. Gomez-Sanz, ruben Fuentes
*
* This file is part of the INGENME tool. INGENME is an open source meta-editor
* which produces customized editors for user-defined modeling languages
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 3 of the License
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see
**/
package ingenias.editor;
import ingenias.editor.cell.NAryEdge;
import ingenias.editor.entities.NAryEdgeEntity;
import ingenias.editor.events.AnyChangeListener;
import ingenias.editor.events.EventRedirector;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;
import org.jgraph.graph.DefaultEdge;
import org.jgraph.graph.DefaultGraphCell;
import org.jgraph.graph.DefaultGraphModel;
import org.jgraph.graph.DefaultPort;
import org.jgraph.graph.Edge;
import org.jgraph.graph.GraphCell;
import org.jgraph.graph.Port;
//
// Custom Model
//
// A Custom Model that does not allow Self-References
public class Model
extends DefaultGraphModel
implements java.io.Serializable {
// It is used to revet disconnections.
private Port previousPort = null;
private IDEState ids=null;
private boolean messagesOn=true;
private boolean hardChange;
private int idCounter;
public Model(IDEState ids) {
this.ids=ids;
}
// Override Superclass Method implements java.io.Serializable
public boolean acceptsSource(Object edge, Object port) {
//System.out.println("acceptsSource");//////////
// Source only Valid if not Equal Target
// return (((Edge) edge).getTarget() != port);
if ( ( (Edge) edge).getTarget() == port) {
return false;
}
else {
return true;
}
}
public String getNewId() {
idCounter=0;
Vector rels;
rels = RelationshipManager.getRelationshipsVector(ids.gm);
HashSet trels=new HashSet ();
for (NAryEdgeEntity nedge:rels){
trels.add(nedge.getId());
}
while (trels.contains(""+idCounter) ||
ids.om.findUserObject(""+idCounter).size()>0 ||
ids.gm.getModel(""+idCounter)!=null){
idCounter++;
}
return ""+idCounter;
}
public String getNewId(String fromID) {
idCounter=0;
Vector rels = RelationshipManager.getRelationshipsVector(ids.gm);
Hashtable trels=new Hashtable();
for (NAryEdgeEntity nedge:rels){
if (nedge.getId().equals(fromID+idCounter))
idCounter++;
}
while (ids.om.findUserObject(fromID+idCounter).size()>0){
idCounter++;
}
while (ids.gm.getModel(fromID+idCounter)!=null){
idCounter++;
}
return fromID+idCounter;
}
// Override Superclass Method implements java.io.Serializable
public boolean acceptsTarget(Object edge, Object port) {
//System.out.println("acceptsTarget");//////////
// Target only Valid if not Equal Source
//return (((Edge) edge).getSource() != port);
if ( ( (Edge) edge).getSource() == port) {
return false;
}
else {
return true;
}
}
protected void connect(Object edge, Object port, boolean isSource,
boolean insert) {
// connect is called 4 times when connecting an edge: 2 to disconnect the edge from
// the previous source and target and 2 more to connect it to the current
// source and target.
// remove = disconnect.
// port = Port connected or disconnected from the edge.
if (!insert) {
// If the action is a disconnection from a relationship previousPort
// takes note of the original port.
if (this.getParent( ( (Edge) edge).getSource())instanceof NAryEdge) {
previousPort = (Port) ( (Edge) edge).getTarget();
}
super.connect(edge, port, isSource, insert);
}
else {
// Check if an edge moving is correct according to destination.
boolean applicable = true;
/*if (this.getParent( ( (Edge) edge).getSource())instanceof NAryEdge) {
NAryEdge nEdge = (NAryEdge)this.getParent( ( (Edge) edge).getSource());
GraphCell[] selectedNodes = new GraphCell[] {
(GraphCell)this.getParent(port)};
//(GraphCell)((DefaultPort)port).getParent()};
applicable = (nEdge.assignRoles(selectedNodes, false).size() > 0);
////////// acceptConnection(GraphModel model, GraphCell[] selected) {
//////////undoManager.undo(graph.getGraphLayoutCache())
// An edge has always a source and a target.
if (!applicable)
System.err.println("cannot find a proper role for "+edge+" "+port+ " "+selectedNodes.length);
}
else if (port == null) {
applicable = false;
System.err.println("port is null when connecting "+edge+" "+port);
}*/
// If the movement is correct connect.
if (applicable) {
if ( (isSource && this.acceptsSource(edge, port)) ||
(!isSource && this.acceptsTarget(edge, port))) {
super.connect(edge, port, isSource, insert);
}
// If the movement is incorrect and the previous port is known,
// reconnect with that previous port.
}
else if (previousPort != null) {
super.connect(edge, previousPort, false, false);
previousPort = null;
}
}
}
public void defaultRemove(Object[] roots) {
super.remove(roots);
}
private void removeIfObjectAppearsOnlyOnce(Object[] objectsToRemove) {
Vector reviewed = new Vector();
for (int i = 0; i < objectsToRemove.length; i++) {
if (objectsToRemove[i] instanceof DefaultGraphCell &&
( (DefaultGraphCell) objectsToRemove[i]).getUserObject()instanceof
ingenias.editor.entities.Entity &&
! ( ( (DefaultGraphCell) objectsToRemove[i]).getUserObject()
instanceof ingenias.editor.entities.NAryEdgeEntity)) {
ingenias.editor.entities.Entity ent =
(ingenias.editor.entities.Entity) ( (DefaultGraphCell)
objectsToRemove[i]).
getUserObject();
if (!reviewed.contains(ent)) {
reviewed.add(ent);
ids.om.removeEntity(ent);
}
}
}
}
private Vector getElementsToRemove(Object[] roots) {
// Prepare elements to be removed.
// Expand NAryEdges with related binary edges.
Vector elementsToRemove = new Vector();
for (int i = 0; i < roots.length; i++) {
// If a n-edge is selected, related binary relationships has to be removed too.
if (roots[i] instanceof NAryEdge) {
NAryEdge nEdge = (NAryEdge) roots[i];
// this.rm.removeRelationship( (ingenias.editor.entities.Entity) nEdge.getUserObject() );
Object[] objects = nEdge.getRepresentation();
for (int j = 0; j < objects.length; j++) {
elementsToRemove.add(objects[j]);
// If it is a Vertex, binary edges connected with it has to be deleted.
}
}
else if ( (roots[i] instanceof DefaultGraphCell) &&
! (roots[i] instanceof DefaultEdge) &&
! (roots[i] instanceof DefaultPort)) {
Iterator itEdges = DefaultGraphModel.getEdges(this,
new Object[] {roots[i]}).iterator();
while (itEdges.hasNext()) {
DefaultEdge de = (DefaultEdge) itEdges.next();
elementsToRemove.add(de);
}
//ObjectManager.getInstance().removeEntity((Entity)((DefaultGraphCell)roots[i]).getUserObject());
}
else if (roots[i] instanceof DefaultEdge) {
DefaultEdge de = (DefaultEdge) roots[i];
NAryEdgeEntity naryedge = null;
DefaultGraphCell naryedgetarget = null;
DefaultGraphCell source = (DefaultGraphCell) ( (DefaultPort) de.
getSource()).getParent();
DefaultGraphCell target = (DefaultGraphCell) ( (DefaultPort) de.
getTarget()).getParent();
if (source.getUserObject()instanceof ingenias.editor.entities.
NAryEdgeEntity) {
naryedge = (ingenias.editor.entities.NAryEdgeEntity) source.
getUserObject();
naryedgetarget = target;
}
else
if (target.getUserObject()instanceof ingenias.editor.entities.
NAryEdgeEntity){
naryedge = (NAryEdgeEntity) target.getUserObject();
naryedgetarget = source;
}
if (naryedge!=null){
naryedge.removeObject(""+naryedgetarget.hashCode());
String[] strs = naryedge.getIds();
String ids = "";
for (int k = 0; k < strs.length; k++) {
ids = ids + strs[k];
}
Log.getInstance().logSYS(ids);
}
}
}
return elementsToRemove;
}
public void remove(Object[] roots) {
// All operations are done with GraphCell[].
GraphCell[] objectsToRemove = new GraphCell[roots.length];
for (int i = 0; i < roots.length; i++) {
objectsToRemove[i] = (GraphCell) roots[i];
}
if ( !this.checkRelatedNAryEdges(objectsToRemove)) {
// remove all associated relationships first
// if an edge or a nary entity was selected, this will complete the selection
EventRedirector.expandSelectionToRelationshipsAndEdgesExcludingOtherExtremes(roots, ids.editor.getGraph());
Object[] complete=ids.editor.getGraph().getSelectionCells();
Vector onlyrelationships=new Vector();
Vector others=new Vector();
for (int k=0;k