/** * */ package agg.editor.impl; import java.util.Enumeration; import java.util.List; import java.util.Vector; import agg.util.Pair; import agg.util.XMLHelper; import agg.xt_basis.Arc; import agg.xt_basis.BadMappingException; import agg.xt_basis.Graph; import agg.xt_basis.GraphKind; import agg.xt_basis.GraphObject; import agg.xt_basis.NestedApplCond; import agg.xt_basis.Node; import agg.xt_basis.OrdinaryMorphism; import agg.xt_basis.Type; import agg.xt_basis.TypeException; /** * @author olga * */ public class EdNestedApplCond extends EdPAC { EdNestedApplCond itsParent; EdGraph itsSource; List<EdNestedApplCond> itsACs = new Vector<EdNestedApplCond>(0,1); boolean badMapping = false; String errMsg = ""; public EdNestedApplCond(final EdNestedApplCond parent) { super(); this.itsParent = parent; } public EdNestedApplCond(final EdNestedApplCond parent, EdTypeSet types) { super(types); this.itsParent = parent; } public EdNestedApplCond(final EdNestedApplCond parent, OrdinaryMorphism m) { super(m); this.itsParent = parent; } public EdNestedApplCond(final EdNestedApplCond parent, OrdinaryMorphism m, EdTypeSet types) { super(m, types); this.itsParent = parent; List<NestedApplCond> list = ((NestedApplCond)m).getNestedACs(); for (int i=0; i<list.size(); i++) { this.createNestedAC(list.get(i)); } } public void setUndoManager(EditUndoManager anUndoManager) { this.undoManager = anUndoManager; for (int j = 0; j < this.getNestedACs().size(); j++) { this.getNestedACs().get(j).setUndoManager(this.undoManager); } } void addEdit(EdGraphObject src, EdGraphObject tar, String kind, String presentation) { Vector<String> v = new Vector<String>(); v.add(String.valueOf(src.hashCode())); v.add(String.valueOf(tar.hashCode())); this.undoObj = new Pair<String, Vector<?>>(kind, v); undoManagerAddEdit(presentation); } public void addCreatedMappingToUndo(EdGraphObject src, EdGraphObject tar) { if (this.undoManager == null || !this.undoManager.isEnabled() || !this.isEditable() || this.morphism == null) { return; } GraphObject oldImg = this.morphism.getImage(src.getBasisObject()); if (oldImg != null) { EdGraphObject go = this.findGraphObject(oldImg); if (go != null) addDeletedMappingToUndo(src, go); } addEdit(src, tar, EditUndoManager.AC_MAPPING_CREATE_DELETE, "Undo Create AC Mapping"); } public void addDeletedMappingToUndo(EdGraphObject src, EdGraphObject tar) { if (this.undoManager == null || !this.undoManager.isEnabled() || !this.isEditable() || this.morphism == null) { return; } if (tar.isNode()) { addDeletedMappingOfInOutEdgesToUndo((EdNode) src, (EdNode) tar, src.getContext(), tar.getContext(), this.morphism, EditUndoManager.AC_MAPPING_DELETE_CREATE, "Undo Delete AC Mapping"); } addEdit(src, tar, EditUndoManager.AC_MAPPING_DELETE_CREATE, "Undo Delete AC Mapping"); } private void addDeletedMappingOfInOutEdgesToUndo(EdNode orig, EdNode img, EdGraph origG, EdGraph imgG, OrdinaryMorphism morph, String kind, String msg) { Vector<EdArc> inArcs = origG.getIncomingArcs(orig); for (int i = 0; i < inArcs.size(); i++) { EdArc origEdArc = inArcs.get(i); GraphObject obj = morph.getImage(origEdArc.getBasisArc()); if(obj != null) { Arc imgArc = (Arc) obj; EdArc imgEdArc = imgG.findArc(imgArc); if (imgEdArc != null) { addEdit(origEdArc, imgEdArc, kind, msg); } } } Vector<EdArc> outArcs = origG.getOutgoingArcs(orig); for (int i = 0; i < outArcs.size(); i++) { EdArc origEdArc = outArcs.get(i); if (inArcs.contains(origEdArc)) continue; GraphObject obj = morph.getImage(origEdArc.getBasisArc()); if(obj != null) { Arc imgArc = (Arc) obj; EdArc imgEdArc = imgG.findArc(imgArc); if (imgEdArc != null) { addEdit(origEdArc, imgEdArc, kind, msg); } } } } /** Allows to edit this rule application condition. */ public void setEditable(boolean b) { this.editable = b; for (int i=0; i<this.itsACs.size(); i++) { this.itsACs.get(i).setEditable(b); } } public void setRule(EdRule er) { super.setRule(er); for (int i=0; i<this.itsACs.size(); i++) { this.itsACs.get(i).setRule(er); } } public void setGraGra(EdGraGra egra) { if (egra == null) { return; } super.setGraGra(egra); for (int i=0; i<this.itsACs.size(); i++) { this.itsACs.get(i).setGraGra(egra); } } public void setSourceGraph(EdGraph g) { if (this.morphism.getSource() == g.getBasisGraph()) this.itsSource = g; } public EdGraph getSource() { return this.itsSource; } public NestedApplCond getNestedMorphism() { return (NestedApplCond) this.morphism; } public void removeNestedAC(final EdNestedApplCond cond) { if (this.itsACs.contains(cond)) { this.getNestedMorphism().removeNestedAC(cond.getNestedMorphism()); this.itsACs.remove(cond); } } public boolean removeNestedACMapping(EdGraphObject leftObj, EdNestedApplCond ac) { if (!this.editable) return false; if (ac.getMorphism().getImage(leftObj.getBasisObject()) != null) { ac.getMorphism().removeMapping(leftObj.getBasisObject()); this.updateNestedAC(ac); return true; } return false; } public List<EdNestedApplCond> getNestedACs() { return this.itsACs; } public List<EdNestedApplCond> getEnabledNestedACs() { List<EdNestedApplCond> list = new Vector<EdNestedApplCond>(this.itsACs.size()); for (int i = 0; i < this.itsACs.size(); i++) { EdNestedApplCond ac = this.itsACs.get(i); if (ac.getMorphism().isEnabled()) list.add(ac); list.addAll(ac.getEnabledNestedACs()); } return list; } public List<EdNestedApplCond> getEnabledACs() { List<EdNestedApplCond> list = new Vector<EdNestedApplCond>(this.itsACs.size()); // list.add(this); for (int i = 0; i < this.itsACs.size(); i++) { EdNestedApplCond ac = this.itsACs.get(i); if (ac.getMorphism().isEnabled()) list.add(ac); } return list; } /** Gets my Nested AC specified by the name */ public EdNestedApplCond getNestedAC(String acname) { for (int i = 0; i < this.itsACs.size(); i++) { EdNestedApplCond ac = this.itsACs.get(i); if (ac.getName().equals(acname)) return ac; else { EdNestedApplCond ac1 = ac.getNestedAC(acname); if (ac1 != null) return ac1; } } return null; } public EdNestedApplCond getNestedAC(int indx) { if (indx >= 0 && indx < this.itsACs.size()) return this.itsACs.get(indx); return null; } public EdNestedApplCond getApplCondByImageGraph(final Graph g) { for (int i = 0; i < this.itsACs.size(); i++) { EdNestedApplCond cond = this.itsACs.get(i); if (cond.getMorphism().getImage() == g) return cond; } return null; } public int getSizeOfNestedACs() { return this.itsACs.size(); } /** Creates a new Nested AC layout with name specified by the String nameStr. */ public EdPAC createNestedAC(String nameStr, boolean isIdentic) { if (this.morphism == null || !this.editable) return null; EdNestedApplCond eAC = new EdNestedApplCond(this, ((NestedApplCond)this.morphism).createNestedAC(), this.typeSet); eAC.setName(nameStr); eAC.setRule(this.getRule()); eAC.setGraGra(this.eGra); eAC.setEditable(this.isEditable()); eAC.getBasisGraph().setKind(GraphKind.AC); eAC.setUndoManager(this.undoManager); eAC.setSourceGraph(this); if (isIdentic && eAC.isEditable()) identicNestedAC(eAC); this.itsACs.add(eAC); if (this.eGra != null) this.eGra.setChanged(true); return eAC; } /** * Creates a new Nested AC layout of the used object specified by the * OrdinaryMorphism ac */ public EdPAC createNestedAC(OrdinaryMorphism ac) { if (this.morphism == null || !this.editable) return null; EdNestedApplCond eAC = new EdNestedApplCond(this, ac, this.typeSet); eAC.getBasisGraph().setName(ac.getName()); eAC.getBasisGraph().setKind(GraphKind.AC); eAC.setName(ac.getName()); eAC.setRule(this.getRule()); eAC.setGraGra(this.eGra); eAC.setUndoManager(this.undoManager); eAC.setSourceGraph(this); this.itsACs.add(eAC); if (this.eGra != null) this.eGra.setChanged(true); return eAC; } /** * Adds a new Nested AC layout * @param ac */ public boolean addNestedAC(EdNestedApplCond ac) { if (this.morphism == null) return false; if (ac.getTypeSet().getBasisTypeSet().compareTo( this.typeSet.getBasisTypeSet())) { if (((NestedApplCond)this.morphism) .addNestedAC((NestedApplCond)ac.getMorphism())) { Vector<Type> v = ac.getMorphism().getUsedTypes(); this.morphism.getSource().getTypeSet().adaptTypes(v.elements(), false); this.typeSet.refreshTypes(); ac.getBasisGraph().setKind(GraphKind.AC); ac.setRule(this.getRule()); ac.setGraGra(this.eGra); ac.setUndoManager(this.undoManager); ac.setSourceGraph((EdGraph)this.getRule().getApplCondByImageGraph(ac.getMorphism().getSource())); ac.itsParent = this; this.itsACs.add(ac); if (this.eGra != null) this.eGra.setChanged(true); return true; } return false; } return false; } public EdNestedApplCond getParent() { return this.itsParent; } /** Makes an identic nested AC. */ public void identicNestedAC(EdNestedApplCond ac) { OrdinaryMorphism morph = ac.getMorphism(); // Remove all of my mappings. morph.clear(); // Remove my image. morph.getImage().clear(); // Remove my visible image; ac.clear(); for (int i = 0; i < this.getNodes().size(); i++) { EdNode en = this.getNodes().elementAt(i); identicNode(en, ac, morph); } for (int j = 0; j < this.getArcs().size(); j++) { EdArc ea = this.getArcs().elementAt(j); identicArc(ea, ac, morph); } this.updateNestedAC(ac); } /** * Sets the layout from another EdGraph. The basis graphs may be different. * The corresponding graph objects are found by its index. */ public void setLayoutByIndex(EdGraph layout, boolean ofNodesOnly) { if (layout instanceof EdNestedApplCond) { super.setLayoutByIndex(layout, ofNodesOnly); if (this.itsACs.size() == ((EdNestedApplCond)layout).getNestedACs().size()) { for (int i=0; i<this.itsACs.size(); i++) { EdNestedApplCond c = this.itsACs.get(i); EdNestedApplCond c1 = ((EdNestedApplCond)layout).getNestedACs().get(i); if (c1 != null) { c.setLayoutByIndex(c1, ofNodesOnly); } } } else { for (int i=0; i<this.itsACs.size(); i++) { EdNestedApplCond c = this.itsACs.get(i); if (c.getParent() == null) c.setLayoutByIndex(c.getRule().getLeft(), ofNodesOnly); else c.setLayoutByIndex(c.getParent(), ofNodesOnly); } } } else super.setLayoutByIndex(layout, ofNodesOnly); } /** Updates GAC layout after reading GAC graph objects */ public void updateNestedAC(EdNestedApplCond ac) { EdNode enL = null; EdNode enAC = null; EdArc eaL = null; EdArc eaAC = null; ac.clearMarks(); Enumeration<GraphObject> domain = ac.getMorphism().getDomain(); while (domain.hasMoreElements()) { GraphObject bOrig = domain.nextElement(); GraphObject bImage = ac.getMorphism().getImage(bOrig); enL = this.findNode(bOrig); if (enL != null) { if (enL.isMorphismMarkEmpty()) enL.addMorphismMark(enL.getMyKey()); enAC = ac.findNode(bImage); if (enAC != null) enAC.addMorphismMark(enL.getMorphismMark()); } eaL = this.findArc(bOrig); if (eaL != null) { if (eaL.isMorphismMarkEmpty()) eaL.addMorphismMark(eaL.getMyKey()); eaAC = ac.findArc(bImage); if (eaAC != null) eaAC.addMorphismMark(eaL.getMorphismMark()); } } } public void updateNestedACs() { for (int i = 0; i < this.itsACs.size(); i++) { EdNestedApplCond ac = this.itsACs.get(i); this.updateNestedAC(ac); ac.updateNestedACs(); } } private EdNode identicNode(EdNode en, EdGraph eg, OrdinaryMorphism morph) { this.badMapping = false; this.errMsg = ""; EdNode cn = null; Node bn = null; try { bn = eg.getBasisGraph().copyNode(en.getBasisNode()); } catch (TypeException e) { } if (bn != null) { cn = eg.addNode(bn, en.getType()); cn.setReps(en.getX(), en.getY(), en.isVisible(), false); // cn.getLNode().setFrozen(true); cn.getLNode().setFrozenByDefault(true); eg.addCreatedToUndo(cn); eg.undoManagerEndEdit(); try { this.addCreatedMappingToUndo(en, cn); morph.addMapping(en.getBasisNode(), bn); this.undoManagerEndEdit(); } catch(BadMappingException ex) { this.badMapping = true; this.errMsg = ex.getMessage(); } } return cn; } private EdArc identicArc(EdArc ea, EdGraph eg, OrdinaryMorphism morph) { this.badMapping = false; this.errMsg = ""; EdArc ca = null; Arc ba = null; GraphObject bSrc = morph.getImage(ea.getBasisArc().getSource()); GraphObject bTar = morph.getImage(ea.getBasisArc().getTarget()); try { ba = eg.getBasisGraph().copyArc(ea.getBasisArc(), (Node) bSrc, (Node) bTar); } catch (TypeException e) { e.printStackTrace(); } if (ba != null) { try { ca = eg.addArc(ba, ea.getType()); ca.setReps(ea.isDirected(), ea.isVisible(), false); ca.setTextOffset(ea.getTextOffset().x, ea.getTextOffset().y); if (ea.isLine()) { if (ea.hasAnchor()) { ca.setAnchor(ea.getAnchor()); ca.getLArc().setFrozenByDefault(true); } } else { // is Loop if (ea.hasAnchor()) { ca.setXY(ea.getX(), ea.getY()); ca.setWidth(ea.getWidth()); ca.setHeight(ea.getHeight()); } } eg.addCreatedToUndo(ca); eg.undoManagerEndEdit(); this.errMsg = ""; try { this.addCreatedMappingToUndo(ea, ca); morph.addMapping(ea.getBasisArc(), ba); this.undoManagerEndEdit(); } catch (BadMappingException ex) { this.badMapping = true; this.errMsg = ex.getMessage(); } } catch (TypeException tex) { this.badMapping = true; this.errMsg = tex.getMessage(); } } return ca; } public Vector<EdGraphObject> getOriginal(EdGraphObject image) { Vector<EdGraphObject> vec = new Vector<EdGraphObject>(2); Enumeration<GraphObject> en = this.morphism.getInverseImage(image.getBasisObject()); while (en.hasMoreElements()) { GraphObject obj = en.nextElement(); EdGraphObject go = null; if (this.itsParent == null) go = this.itsRule.getLeft().findGraphObject(obj); else go = this.itsParent.findGraphObject(obj); if (go != null) vec.add(go); } return vec; } public boolean deleteGraphObjectsOfType( final EdType t, boolean addToUndo) { boolean alldone = true; for (int n=0; n<this.itsACs.size(); n++) { EdNestedApplCond ac = this.itsACs.get(n); alldone = alldone && ac.deleteGraphObjectsOfType(t, addToUndo); } alldone = alldone && this.deleteGraphObjectsOfTypeFromGraph(t, addToUndo); return alldone; } public boolean deleteGraphObjectsOfType( final EdGraphObject tgo, boolean addToUndo) { boolean alldone = true; for (int n=0; n<this.itsACs.size(); n++) { EdNestedApplCond ac = this.itsACs.get(n); alldone = alldone && ac.deleteGraphObjectsOfType(tgo, addToUndo); } alldone = alldone && this.deleteGraphObjectsOfTypeFromGraph(tgo, addToUndo); return alldone; } protected List<EdGraphObject> getGraphObjectsOfType( final EdGraphObject tgo, final EdGraph g) { List<EdGraphObject> list = new Vector<EdGraphObject>(); if (tgo.isArc()) { for (int i=0; i<g.arcs.size(); i++) { EdArc go = g.arcs.get(i); if (tgo.getType() == go.getType() && ((EdArc)tgo).getSource().getType().isParentOf(go.getSource().getType()) && ((EdArc)tgo).getTarget().getType().isParentOf(go.getTarget().getType())) { list.add(go); } } } else { for (int i=0; i<g.nodes.size(); i++) { EdNode go = g.nodes.get(i); if (tgo.getType() == go.getType()) { list.add(go); } } } return list; } protected List<EdGraphObject> getGraphObjectsOfType( final EdType t, final EdGraph g) { List<EdGraphObject> list = new Vector<EdGraphObject>(); if (t.isArcType()) { for (int i=0; i<g.arcs.size(); i++) { EdArc go = g.arcs.get(i); if (t == go.getType()) { list.add(go); } } } else { for (int i=0; i<g.nodes.size(); i++) { EdNode go = g.nodes.get(i); if (t == go.getType()) { list.add(go); } } } return list; } protected void storeMappingOfGraphObjectsOfType( final EdGraphObject tgo, final EdGraph src) { List<EdGraphObject> list = getGraphObjectsOfType(tgo, src); for (int n=0; n<this.itsACs.size(); n++) { EdNestedApplCond ac = this.itsACs.get(n); // ac.storeMappingOfGraphObjectsOfType(tgo, ac); for (int i=0; i<list.size(); i++) { EdGraphObject go = list.get(i); EdGraphObject rgo = ac.findGraphObject( ac.getMorphism().getImage(go.getBasisObject())); if (rgo != null) { ac.itsRule.addDeletedACMappingToUndo(go, rgo); ac.itsRule.undoManagerEndEdit(); } } ac.storeMappingOfGraphObjectsOfType(tgo, ac); } } protected void storeMappingOfGraphObjectsOfType( final EdType t, final EdGraph src) { List<EdGraphObject> list = getGraphObjectsOfType(t, src); for (int n=0; n<this.itsACs.size(); n++) { EdNestedApplCond ac = this.itsACs.get(n); // ac.storeMappingOfGraphObjectsOfType(t, ac); for (int i=0; i<list.size(); i++) { EdGraphObject go = list.get(i); EdGraphObject rgo = ac.findGraphObject( ac.getMorphism().getImage(go.getBasisObject())); if (rgo != null) { ac.itsRule.addDeletedACMappingToUndo(go, rgo); ac.itsRule.undoManagerEndEdit(); } } ac.storeMappingOfGraphObjectsOfType(t, ac); } } protected EdGraphObject findRestoredObjectOfAC(EdGraphObject go) { for (int i = 0; i < this.itsACs.size(); i++) { EdNestedApplCond ac = this.itsACs.get(i); EdGraphObject obj = ac.findRestoredObject(go); if (obj != null) { return obj; } else { obj = ac.findRestoredObjectOfAC(go); if (obj != null) { return obj; } } } return null; } protected EdGraphObject findGraphObjectOfAC(String goHashCode) { for (int i = 0; i < this.itsACs.size(); i++) { EdNestedApplCond ac = this.itsACs.get(i); EdGraphObject obj = ac.findGraphObject(goHashCode); if (obj != null) { return obj; } else { obj = ac.findGraphObjectOfAC(goHashCode); if (obj != null) { return obj; } } } return null; } public void XreadObject(XMLHelper h) { super.XreadObject(h); h.peekObject(this.bGraph, this); for (int j = 0; j < this.itsACs.size(); j++) { EdPAC ac = this.itsACs.get(j); h.enrichObject(ac); } } public void XwriteObject(XMLHelper h) { super.XwriteObject(h); if (h.openObject(this.bGraph, this)) { for (int j = 0; j < this.itsACs.size(); j++) { h.addObject("", this.itsACs.get(j), true); } } } }