/* AwtLinkRelation.java * * Copyright (c) 1999-2000, Ted Nelson and Tuomas Lukka * * You may use and distribute under the terms of either the GNU Lesser * General Public License, either version 2 of the license or, * at your choice, any later version. Alternatively, you may use and * distribute under the terms of the XPL. * * See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of * the licenses. * * This software 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 README * file for more details. * */ /* * Written by Kimmo Wideroos */ package org.gzigzag.module; import org.gzigzag.*; import java.awt.*; import java.util.*; //class AwtLinkRelation /*extends AwtRelation*/ { public class AwtLinkRelation implements AwtAccursable { public static boolean dbg = false; protected static void p(String s) { if(dbg) ZZLogger.log(s); } protected static void pa(String s) { ZZLogger.log(s); } static String LINK_TO = "to"; static String LINK_FROM = "from"; ZZCell cell; public AwtLinkRelation(ZZCell cell) { this.cell = cell; } public ZZCell getCell() { return cell; } public static ZZCell make(ZZCell from, ZZCell to) { return make(from, to, false); } public static ZZCell make(ZZCell from, ZZCell to, boolean directed) { ZZCell new_link, lc1, lc2; boolean lr1, lr2; if(!valid(from, to)) { pa("LINK NOT VALID!!!"); return null; } //remove(from, to); lr1 = isLinkRoot(from); lr2 = isLinkRoot(to); if(lr1 == lr2) { // new central link needed lc1 = from.h(AwtDim.link, 1).N(AwtDim.link); setLinkType(lc1, LINK_FROM); lc2 = to.h(AwtDim.link, 1).N(AwtDim.link); setLinkType(lc2, LINK_TO); lc1.connect("d.2", lc2); new_link = lc1.N("d.2", -1); new_link.setText(""+(from.t())+"->"+(to.t())); } else { // attach single artefact to actual link cell if(lr1) { new_link = from.h("d.2", 1).N("d.2"); new_link.connect(AwtDim.link, -1, to.h(AwtDim.link, 1)); setLinkType(new_link, LINK_TO); } else { new_link = to.h("d.2", 1).N("d.2"); new_link.connect(AwtDim.link, -1, from.h(AwtDim.link, 1)); setLinkType(new_link, LINK_FROM); } } return new_link; } static public void remove(ZZCell from, ZZCell to) { ZZCell to_be_removed = link(from, to); remove(to_be_removed); } static public void change(ZZCell from, ZZCell to) { ZZCell to_be_changed = link(from, to); change(to_be_changed); } static public void change(ZZCell lc) { if(lc == null) return; if(isLinkRelation(lc)) changeLinkType(lc); else if(one2one(lc)) for(ZZCell c=lc.s("d.2"); c!=null; c=c.s("d.2")){ changeLinkType(c); } } /* is link 'from' - 'to' valid? No loops allowed. * returns true, if valid. */ static public boolean valid(ZZCell from, ZZCell to) { ZZCell lc, maybe_lc, layer; ZZCell[] as1, as2; // artefacts int i; // links not allowed between layers!! if(AwtLayer.valid(from) || AwtLayer.valid(to)) return false; // if source and target are both artefacts, they should // be on the same layer if(AwtArtefact.valid(from) && AwtArtefact.valid(to)) { layer = AwtLayer.getLayer(from); if(!AwtLayer.isMember(layer, to)) return false; } if(!isLinkRoot(from) && !isLinkRoot(to)) return !one2one(from, to); lc = to; maybe_lc = from; if(isLinkRoot(from)) { lc = from; maybe_lc = to; } as1 = getTreeArtefacts(lc); Hashtable hash = new Hashtable(); for(i=0; i 0 && as2.length > 0) { layer = AwtLayer.getLayer(as1[0]); if(!AwtLayer.isMember(layer, as2[0])) return false; } // artefs are not allowed to exist several time // in same link tree. for(i=0; imintree) continue; mintree = ntree; tree = tow; } } // 'tree' now is the root of smallest tree containing // both 'to' and 'from' if(tree == null) return null; if(fromIsLink) lc_from = from.h(AwtDim.link, 1); else lc_from = findLinkCell(from, tree); if(toIsLink) lc_to = to.h(AwtDim.link, 1); else lc_to = findLinkCell(to, tree); to_level = getLevel(lc_to); from_level = getLevel(lc_from); ZZCell r = null; if(lc_to.h("d.2").equals(lc_from.h("d.2")) && to_level == from_level) { //if(!one2one(lc_to)) return; // remove whole linkroot r = lc_to.h("d.2"); } if(to_level > from_level) r = lc_to; if(to_level < from_level) r = lc_from; return r; } static public void remove(ZZCell lc) { ZZCell nxt = null; if(lc.s("d.2", -1) != null && one2one(lc)) remove(lc.h("d.2")); if(lc.s("d.2", -1) == null) nxt = lc.h(AwtDim.link, 1, true); if(nxt != null && one2one(nxt)) remove(nxt.h("d.2")); lc.excise(AwtDim.link); // is 'lc' linkroot? if(lc.s("d.2", -1) == null) { ZZCell[] lcs = lc.readRank("d.2", 1, false, null); for(int i=0; i