1 21 22 package org.lucane.applications.whiteboard.graph; 23 24 import java.awt.Color ; 25 import java.awt.Dimension ; 26 import java.awt.Font ; 27 import java.awt.Point ; 28 import java.awt.Rectangle ; 29 import java.awt.geom.Point2D ; 30 import java.io.BufferedOutputStream ; 31 import java.io.File ; 32 import java.io.FileOutputStream ; 33 import java.io.InputStream ; 34 import java.io.OutputStream ; 35 import java.net.URL ; 36 import java.net.URLDecoder ; 37 import java.net.URLEncoder ; 38 import java.util.HashSet ; 39 import java.util.Hashtable ; 40 import java.util.Iterator ; 41 import java.util.LinkedList ; 42 import java.util.List ; 43 import java.util.Map ; 44 import java.util.Set ; 45 import java.util.Stack ; 46 import java.util.StringTokenizer ; 47 48 import javax.swing.BorderFactory ; 49 import javax.swing.Icon ; 50 import javax.swing.ImageIcon ; 51 import javax.swing.JCheckBox ; 52 import javax.swing.JComponent ; 53 import javax.swing.border.BevelBorder ; 54 import javax.swing.border.Border ; 55 import javax.swing.border.LineBorder ; 56 import javax.swing.filechooser.FileFilter ; 57 import javax.xml.parsers.DocumentBuilder ; 58 import javax.xml.parsers.DocumentBuilderFactory ; 59 60 import org.jgraph.JGraph; 61 import org.jgraph.graph.AttributeMap; 62 import org.jgraph.graph.ConnectionSet; 63 import org.jgraph.graph.DefaultEdge; 64 import org.jgraph.graph.DefaultGraphCell; 65 import org.jgraph.graph.DefaultPort; 66 import org.jgraph.graph.Edge; 67 import org.jgraph.graph.GraphConstants; 68 import org.jgraph.graph.GraphModel; 69 import org.lucane.applications.whiteboard.graph.cells.DiamondCell; 70 import org.lucane.applications.whiteboard.graph.cells.EllipseCell; 71 import org.lucane.applications.whiteboard.graph.cells.ImageCell; 72 import org.lucane.applications.whiteboard.graph.cells.RoundRectangleCell; 73 import org.lucane.applications.whiteboard.graph.cells.TextCell; 74 import org.w3c.dom.Document ; 75 import org.w3c.dom.Node ; 76 77 84 public class DefaultGraphModelFileFormatXML { 85 86 private static DefaultGraphModelFileFormatXML _instance = 87 new DefaultGraphModelFileFormatXML(); 88 89 public static final String EMPTY = new String ("Empty"); 90 91 public static final String PARENT = new String ("Parent"); 92 93 protected static Map cells = new Hashtable (); 94 95 protected static Map attrs = new Hashtable (); 96 97 protected static Map objs = new Hashtable (); 98 99 protected static List delayedAttributes; 100 101 protected static List connectionSetIDs; 102 103 protected Map cellMap = new Hashtable (); 104 105 protected AttributeCollection attrCol = new AttributeCollection(); 106 107 protected Map userObjectMap = new Hashtable (); 108 109 111 FileFilter fileFilter; 112 113 117 JComponent compZipSelect; 118 119 121 public static final String COMPRESS_WITH_ZIP = "CompressWithZip"; 122 123 public static DefaultGraphModelFileFormatXML instance() { 124 if ( null == _instance ) { 125 _instance = new DefaultGraphModelFileFormatXML(); 126 } 127 return _instance; 128 } 129 130 133 protected DefaultGraphModelFileFormatXML() { 134 fileFilter = new FileFilter () { 135 138 public boolean accept(File f) { 139 if (f == null) 140 return false; 141 if (f.getName() == null) 142 return false; 143 if (f.getName().endsWith(".jgx")) 144 return true; 145 if (f.isDirectory()) 146 return true; 147 148 return false; 149 } 150 151 154 public String getDescription() { 155 return "FileDesc.JGraphpadDiagramXml"; 156 } 157 }; 158 compZipSelect = new JCheckBox ("zipCompress"); 159 } 160 161 163 public String getFileExtension(){ 164 return "jgx"; 165 } 166 167 168 172 public FileFilter getFileFilter() { 173 return fileFilter; 174 } 175 176 179 public JComponent getReadAccessory() { 180 return null; 181 } 182 183 188 public JComponent getWriteAccessory() { 189 return null; } 191 192 197 public void write( 198 URL file, 199 JGraph gpGraph, 200 GraphModel graphModel) 201 throws Exception { 202 203 209 OutputStream out = null; 210 out = new FileOutputStream (file.getFile()); 211 out = new BufferedOutputStream (out); 212 out.write(toString(gpGraph).getBytes()); 213 out.flush(); 214 out.close(); 215 } 216 217 222 public Hashtable getWriteProperties(JComponent accessory) { 223 Hashtable properties = new Hashtable (); 224 if (!(accessory instanceof JCheckBox )){ 225 return properties; 226 } 227 properties.put(COMPRESS_WITH_ZIP, new Boolean (((JCheckBox )accessory).isSelected() )); 228 return properties; 229 } 230 231 238 public GraphModel read( 239 URL file, 240 Hashtable properties, 241 JGraph gpGraph) 242 throws Exception { 243 244 try { 245 read(file.openStream(), gpGraph); 246 } catch (Exception ex2) { 247 if (file.toString().toLowerCase().startsWith("http") || 248 file.toString().toLowerCase().startsWith("ftp") ) { 249 } else { 251 throw ex2; 252 } 253 } 254 255 return gpGraph.getModel(); 256 } 257 258 262 public Hashtable getReadProperties(JComponent accessory) { 263 return null; 264 } 265 266 270 public static void read(InputStream in, JGraph graph) throws Exception { 271 GraphModel model = graph.getModel(); 272 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 274 DocumentBuilder db = dbf.newDocumentBuilder(); 276 Document doc = db.parse(in); 278 Node modelNode = null; 280 Node objsNode = null; 281 Node attrsNode = null; 282 Node viewNode = null; 283 284 delayedAttributes = new LinkedList (); 285 connectionSetIDs = new LinkedList (); 286 287 288 for (int i = 0; 289 i < doc.getDocumentElement().getChildNodes().getLength(); 290 i++) { 291 Node node = doc.getDocumentElement().getChildNodes().item(i); 292 if (node.getNodeName().toLowerCase().equals("model")) { 293 modelNode = node; 294 } else if (node.getNodeName().toLowerCase().equals("user")) { 295 objsNode = node; 296 } else if (node.getNodeName().toLowerCase().equals("attrs")) { 297 attrsNode = node; 298 } else if (node.getNodeName().toLowerCase().equals("view")) { 299 viewNode = node; 300 } 301 } 302 objs = decodeUserObjects(objsNode); 303 attrs = parseAttrs(attrsNode); 304 attrs = augmentAttrs(attrs); 305 Map settings = decodeMap(viewNode, false, false); 306 ConnectionSet cs = new ConnectionSet(); 307 Hashtable cells = new Hashtable (); 308 DefaultGraphCell[] insert = parseChildren(modelNode, cells, cs); 309 310 Iterator it = connectionSetIDs.iterator(); 312 while (it.hasNext()) { 313 ConnectionID cid = (ConnectionID) it.next(); 314 Object cell = cid.getCell(); 315 String tid = cid.getTargetID(); 316 if (tid != null) { 317 Object port = cells.get(tid); 318 if (port != null) { 319 cs.connect(cell, port, cid.isSource()); 320 } 321 } 322 } 323 324 Map nested = new Hashtable (); 326 it = delayedAttributes.iterator(); 327 while (it.hasNext()) { 328 DelayedAttributeID att = (DelayedAttributeID) it.next(); 329 Map attr = (Map ) attrs.get(att.getMapID()); 330 if (attr != null) { 331 AttributeMap attr_temp = new AttributeMap(attr); 332 attr = (Map )attr_temp.clone(); 333 if (att.getBounds() != null) 334 GraphConstants.setBounds(attr, att.getBounds()); 335 if (att.getPoints() != null) 336 GraphConstants.setPoints(attr, att.getPoints()); 337 nested.put(att.getCell(), attr); 338 } 339 } 340 341 applySettings(settings, graph); 343 344 model.insert(insert, nested, cs, null, null); 346 } 347 348 public static void applySettings(Map s, JGraph graph) { 349 Object tmp; 350 351 tmp = s.get("editable"); 352 if (tmp != null) 353 graph.setEditable(new Boolean (tmp.toString()).booleanValue()); 354 355 tmp = s.get("bendable"); 356 if (tmp != null) 357 graph.setBendable(new Boolean (tmp.toString()).booleanValue()); 358 359 tmp = s.get("cloneable"); 360 if (tmp != null) 361 graph.setCloneable(new Boolean (tmp.toString()).booleanValue()); 362 363 tmp = s.get("connectable"); 364 if (tmp != null) 365 graph.setConnectable(new Boolean (tmp.toString()).booleanValue()); 366 367 tmp = s.get("disconnectable"); 368 if (tmp != null) 369 graph.setDisconnectable(new Boolean (tmp.toString()).booleanValue()); 370 371 tmp = s.get("disconnectOnMove"); 372 if (tmp != null) 373 graph.setDisconnectOnMove(new Boolean (tmp.toString()).booleanValue()); 374 375 tmp = s.get("doubleBuffered"); 376 if (tmp != null) 377 graph.setDoubleBuffered(new Boolean (tmp.toString()).booleanValue()); 378 379 tmp = s.get("dragEnabled"); 380 if (tmp != null) 381 graph.setDragEnabled(new Boolean (tmp.toString()).booleanValue()); 382 383 tmp = s.get("dropEnabled"); 384 if (tmp != null) 385 graph.setDropEnabled(new Boolean (tmp.toString()).booleanValue()); 386 387 tmp = s.get("moveable"); 388 if (tmp != null) 389 graph.setMoveable(new Boolean (tmp.toString()).booleanValue()); 390 391 tmp = s.get("sizeable"); 392 if (tmp != null) 393 graph.setSizeable(new Boolean (tmp.toString()).booleanValue()); 394 395 tmp = s.get("selectNewCells"); 396 if (tmp != null) 397 graph.setSelectNewCells(new Boolean (tmp.toString()).booleanValue()); 398 399 tmp = s.get("gridVisible"); 400 if (tmp != null) 401 graph.setGridVisible(new Boolean (tmp.toString()).booleanValue()); 402 403 tmp = s.get("gridEnabled"); 404 if (tmp != null) 405 graph.setGridEnabled(new Boolean (tmp.toString()).booleanValue()); 406 407 tmp = s.get("gridSize"); 408 if (tmp != null) 409 graph.setGridSize(Double.parseDouble(tmp.toString())); 410 411 tmp = s.get("gridMode"); 412 if (tmp != null) 413 graph.setGridMode(Integer.parseInt(tmp.toString())); 414 415 tmp = s.get("scale"); 416 if (tmp != null) 417 graph.setScale(Double.parseDouble(tmp.toString())); 418 419 tmp = s.get("antiAlias"); 420 if (tmp != null) 421 graph.setAntiAliased(new Boolean (tmp.toString()).booleanValue()); 422 423 } 424 425 public static Map augmentAttrs(Map attrs) { 426 Map newAttrs = new Hashtable (); 427 Iterator it = attrs.entrySet().iterator(); 428 while (it.hasNext()) { 429 Map.Entry entry = (Map.Entry ) it.next(); 430 Object key = entry.getKey(); 431 Map map = (Map ) entry.getValue(); 432 Stack s = new Stack (); 433 s.add(map); 434 Object parentID = map.get(PARENT); 435 Object hook = null; 436 while (parentID != null) { 437 hook = attrs.get(parentID); 438 s.add(hook); 439 parentID = ((Map ) hook).get(PARENT); 440 } 441 Map newMap = new Hashtable (); 442 while (!s.isEmpty()) { 443 newMap.putAll((Map ) s.pop()); 444 } 445 newMap.remove(PARENT); 446 Iterator it2 = newMap.entrySet().iterator(); 448 while (it2.hasNext()) { 449 entry = (Map.Entry ) it2.next(); 450 if (entry.getValue() == EMPTY) 451 it2.remove(); 452 } 453 newAttrs.put(key, newMap); 454 } 455 return newAttrs; 456 } 457 458 public static DefaultGraphCell parseCell( 459 Node node, 460 Hashtable cells, 461 ConnectionSet cs) { 462 DefaultGraphCell cell = null; 463 if (node.getNodeName().toLowerCase().equals("a")) { 464 Node key = node.getAttributes().getNamedItem("id"); 465 Node type = node.getAttributes().getNamedItem("class"); 466 if (key != null && type != null) { 467 Node value = node.getAttributes().getNamedItem("val"); 468 Object userObject = ""; 469 if (value != null) 470 userObject = objs.get(value.getNodeValue()); 471 cell = createCell(type.getNodeValue(), userObject); 472 473 if (cell != null) { 474 cells.put(key.getNodeValue(), cell); 475 476 DefaultGraphCell[] children = 477 parseChildren(node, cells, cs); 478 for (int i = 0; i < children.length; i++) 479 cell.add(children[i]); 480 481 Node source = node.getAttributes().getNamedItem("src"); 482 Node target = node.getAttributes().getNamedItem("tgt"); 483 if (source != null) { 484 ConnectionID cid = 485 new ConnectionID(cell, source.getNodeValue(), true); 486 connectionSetIDs.add(cid); 487 } 488 if (target != null) { 489 ConnectionID cid = 490 new ConnectionID( 491 cell, 492 target.getNodeValue(), 493 false); 494 connectionSetIDs.add(cid); 495 } 496 497 Node boundsNode = node.getAttributes().getNamedItem("rect"); 498 Rectangle bounds = null; 499 if (boundsNode != null) { 500 Object rectangle = decodeValue(Rectangle .class, boundsNode.getNodeValue()); 501 if (rectangle instanceof Rectangle ) 502 bounds = (Rectangle ) rectangle; 503 } 504 505 Node pointsNode = node.getAttributes().getNamedItem("pts"); 506 List points = null; 507 if (pointsNode != null) { 508 Object pointList = decodeValue(List .class, pointsNode.getNodeValue()); 509 if (pointList instanceof List ) 510 points = (List ) pointList; 511 } 512 513 Node attr = node.getAttributes().getNamedItem("attr"); 514 String mapID = null; 515 if (attr != null) 516 mapID = attr.getNodeValue(); 517 518 if (mapID != null) 519 delayedAttributes.add( 520 new DelayedAttributeID( 521 cell, 522 bounds, 523 points, 524 mapID)); 525 } 526 } 527 } 528 return cell; 529 } 530 531 public static DefaultGraphCell[] parseChildren( 532 Node node, 533 Hashtable cells, 534 ConnectionSet cs) { 535 List list = new LinkedList (); 536 for (int i = 0; i < node.getChildNodes().getLength(); i++) { 537 Node child = node.getChildNodes().item(i); 538 DefaultGraphCell cell = parseCell(child, cells, cs); 539 if (cell != null) 540 list.add(cell); 541 } 542 DefaultGraphCell[] dgc = new DefaultGraphCell[list.size()]; 543 list.toArray(dgc); 544 return dgc; 545 } 546 547 public static Map parseAttrs(Node node) { 548 Hashtable map = new Hashtable (); 549 for (int i = 0; i < node.getChildNodes().getLength(); i++) { 550 Node child = node.getChildNodes().item(i); 551 if (child.getNodeName().toLowerCase().equals("map")) { 552 Node key = child.getAttributes().getNamedItem("id"); 553 Node pid = child.getAttributes().getNamedItem("pid"); 554 Map attrs = decodeMap(child, true, false); 555 if (key != null && attrs.size() > 0) { 556 if (pid != null) 557 attrs.put( 558 PARENT, 559 pid.getNodeValue()); 560 map.put(key.getNodeValue(), attrs); 561 } 562 } 563 } 564 return map; 565 } 566 567 570 public static Map createDefaultAttributes() { 571 AttributeMap map = new AttributeMap(); 573 GraphConstants.setBorderColor(map, Color.black); 575 return map; 577 } 578 579 public static class DelayedAttributeID { 580 581 protected Object cell; 582 583 protected Rectangle bounds; 584 585 protected List points; 586 587 protected String mapID; 588 589 public DelayedAttributeID( 590 Object cell, 591 Rectangle bounds, 592 List points, 593 String mapID) { 594 this.cell = cell; 595 this.bounds = bounds; 596 this.points = points; 597 this.mapID = mapID; 598 } 599 600 603 public Object getCell() { 604 return cell; 605 } 606 607 610 public Rectangle getBounds() { 611 return bounds; 612 } 613 614 617 public String getMapID() { 618 return mapID; 619 } 620 621 624 public List getPoints() { 625 return points; 626 } 627 628 631 public void setBounds(Rectangle rectangle) { 632 bounds = rectangle; 633 } 634 635 638 public void setCell(Object object) { 639 cell = object; 640 } 641 642 645 public void setMapID(String string) { 646 mapID = string; 647 } 648 649 652 public void setPoints(List list) { 653 points = list; 654 } 655 656 } 657 658 public static class ConnectionID { 659 660 protected Object cell; 661 662 protected String targetID; 663 664 protected boolean source; 665 666 public ConnectionID(Object cell, String targetID, boolean source) { 667 this.cell = cell; 668 this.targetID = targetID; 669 this.source = source; 670 } 671 672 675 public Object getCell() { 676 return cell; 677 } 678 679 682 public boolean isSource() { 683 return source; 684 } 685 686 689 public String getTargetID() { 690 return targetID; 691 } 692 693 696 public void setCell(Object object) { 697 cell = object; 698 } 699 700 703 public void setSource(boolean b) { 704 source = b; 705 } 706 707 710 public void setTargetID(String string) { 711 targetID = string; 712 } 713 714 } 715 716 717 721 722 public String toString(JGraph graph) { 723 userObjectMap.clear(); 724 cellMap.clear(); 725 attrs.clear(); 726 727 String xml = "<jgx-1.01>\n"; 728 729 GraphModel model = graph.getModel(); 730 xml += "<model>\n"; 731 xml += outputModel(model, "\t", null); 732 xml += "</model>\n"; 733 734 xml += "<attrs>\n"; 735 xml += outputAttributes("\t"); 736 xml += "</attrs>\n"; 737 738 xml += "<user>\n"; 739 xml += encodeUserObjects("\t", userObjectMap); 740 xml += "</user>\n"; 741 742 xml += "<view>\n"; 743 xml += outputView(graph, "\t"); 744 xml += "</view>\n"; 745 746 xml += "</jgx-1.01>\n"; 748 return xml; 749 } 750 751 public String outputView(JGraph graph, String indent) { 752 String xml = indent + "<a key=\"editable\" val=\""+graph.isEditable()+"\"/>\n" 753 + indent + "<a key=\"bendable\" val=\""+graph.isBendable()+"\"/>\n" 754 + indent + "<a key=\"cloneable\" val=\""+graph.isCloneable()+"\"/>\n" 755 + indent + "<a key=\"connectable\" val=\""+graph.isConnectable()+"\"/>\n" 756 + indent + "<a key=\"disconnectable\" val=\""+graph.isDisconnectable()+"\"/>\n" 757 + indent + "<a key=\"disconnectOnMove\" val=\""+graph.isDisconnectOnMove()+"\"/>\n" 758 + indent + "<a key=\"doubleBuffered\" val=\""+graph.isDoubleBuffered()+"\"/>\n" 759 + indent + "<a key=\"dragEnabled\" val=\""+graph.isDragEnabled()+"\"/>\n" 760 + indent + "<a key=\"dropEnabled\" val=\""+graph.isDropEnabled()+"\"/>\n" 761 + indent + "<a key=\"moveable\" val=\""+graph.isMoveable()+"\"/>\n" 762 + indent + "<a key=\"sizeable\" val=\""+graph.isSizeable()+"\"/>\n" 763 + indent + "<a key=\"selectNewCells\" val=\""+graph.isSelectNewCells()+"\"/>\n" 764 + indent + "<a key=\"gridVisible\" val=\""+graph.isGridVisible()+"\"/>\n" 765 + indent + "<a key=\"gridEnabled\" val=\""+graph.isGridEnabled()+"\"/>\n" 766 + indent + "<a key=\"gridSize\" val=\""+graph.getGridSize()+"\"/>\n" 767 + indent + "<a key=\"gridMode\" val=\""+graph.getGridMode()+"\"/>\n" 768 + indent + "<a key=\"scale\" val=\""+graph.getScale()+"\"/>\n" 769 + indent + "<a key=\"antiAlias\" val=\""+graph.isAntiAliased()+"\"/>\n"; 770 return xml; 771 } 772 773 public String outputModel(GraphModel model, String indent, Object parent) { 774 String xml = new String (""); 775 int max = 776 (parent != null) 777 ? model.getChildCount(parent) 778 : model.getRootCount(); 779 for (int i = 0; i < max; i++) { 780 Object cell = 781 (parent != null) 782 ? model.getChild(parent, i) 783 : model.getRootAt(i); 784 if (cell != null) 785 xml += outputCell(indent, model, cell); 786 } 787 return xml; 788 } 789 790 public String outputCell(String indent, GraphModel model, Object cell) { 791 Map map = new Hashtable (model.getAttributes(cell)); 792 Rectangle r = (Rectangle ) map.remove(GraphConstants.BOUNDS); 793 Object value = map.remove(GraphConstants.VALUE); 794 if (GraphConstants.getFont(map).equals(GraphConstants.DEFAULTFONT)) 795 map.remove(GraphConstants.FONT); 796 Object source = model.getSource(cell); 797 Object target = model.getTarget(cell); 798 if (GraphConstants.getRouting(map) != null) 799 map.remove(GraphConstants.POINTS); 800 String sourceID = ""; 801 String targetID = ""; 802 if (source != null) 803 sourceID = " SRC=\"" + getID(source) + "\""; 804 if (target != null) 805 targetID = " tgt=\"" + getID(target) + "\""; 806 String bounds = ""; 807 String valueS = ""; 808 if (r != null && !model.isEdge(cell) && !model.isPort(cell) && !r.equals(DefaultGraphCell.defaultBounds)) 809 bounds = " rect=\"" + encodeValue(r) + "\""; 810 List p = GraphConstants.getPoints(map); 811 map.remove(GraphConstants.POINTS); 812 String points = ""; 813 if (p != null) { 814 String tmp = encodeValue(p); 815 if (tmp.length() > 0) 816 points = " pts=\"" + tmp + "\""; 817 } 818 if (value != null) 819 valueS = " val=\"" + getUserObjectID(value) + "\""; 820 String attrID = ""; 821 if (map.size() > 0) 822 attrID = " attr=\"" + attrCol.addMap(map) + "\""; 823 String xml = 824 new String ( 825 indent 826 + "<a class=\"" 827 + getType(cell) 828 + "\" id=\"" 829 + getID(cell) 830 + "\"" 831 + valueS 832 + sourceID 833 + targetID 834 + bounds 835 + points 836 + attrID); 837 if (model.getChildCount(cell) > 0) 838 xml += ">\n" 839 + outputModel(model, indent + "\t", cell) 840 + indent 841 + "</a>\n"; 842 else 843 xml += "/>\n"; 844 return xml; 845 } 846 847 public int getUserObjectID(Object object) { 848 Integer index = (Integer ) userObjectMap.get(object); 849 if (index != null) 850 return index.intValue(); 851 index = new Integer (userObjectMap.size() + 1); 852 userObjectMap.put(object, index); 853 return index.intValue(); 854 } 855 856 public int getID(Object object) { 857 Integer index = (Integer ) cellMap.get(object); 858 if (index != null) 859 return index.intValue(); 860 index = new Integer (cellMap.size() + 1); 861 cellMap.put(object, index); 862 return index.intValue(); 863 } 864 865 public String outputAttributes(String indent) { 866 Set set = new HashSet (); 867 set.add(PARENT); 868 set.add(GraphConstants.BOUNDS); 869 set.add(GraphConstants.POINTS); 870 871 String xml = new String (); 872 for (int i = 0; i < attrCol.maps.size(); i++) { 873 Map map = (Map ) attrCol.maps.get(i); 874 Object hook = map.get(PARENT); 875 String hookS = ""; 876 if (hook != null) 877 hookS = " pid=\"" + attrCol.maps.indexOf(hook) + "\""; 878 xml += indent + "<map id=\"" + i + "\"" + hookS + ">\n"; 879 xml += encodeMap(indent + "\t", map, false, set, false); 880 xml += indent + "</map>\n"; 881 } 882 return xml; 883 } 884 885 public class AttributeCollection { 886 887 public List maps = new LinkedList (); 888 889 public int addMap(Map attr) { 890 Iterator it = maps.iterator(); 891 Map storeMap = new Hashtable (attr); 892 Map hook = storeMap; 893 while (it.hasNext()) { 894 Map ref = (Map ) it.next(); 895 Map diff = diffMap(ref, attr); 896 if (diff.size() < storeMap.size()) { 897 hook = ref; 898 storeMap = diff; 899 } 900 } 901 if (storeMap.size() == 0 && hook != storeMap) 902 return maps.indexOf(hook); 903 if (hook != storeMap) 904 storeMap.put(PARENT, hook); 905 maps.add(storeMap); 906 return maps.indexOf(storeMap); 907 } 908 909 public void clear() { 910 maps.clear(); 911 } 912 913 923 public Map diffMap(Map oldState, Map newState) { 924 Stack s = new Stack (); 926 s.add(oldState); 927 Object hook = oldState.get(PARENT); 928 while (hook instanceof Map ) { 929 s.add(hook); 930 hook = ((Map ) hook).get(PARENT); 931 } 932 oldState = new Hashtable (); 933 while (!s.isEmpty()) { 934 oldState.putAll((Map ) s.pop()); 935 } 936 Map diff = new Hashtable (); 937 Iterator it = newState.entrySet().iterator(); 938 while (it.hasNext()) { 939 Map.Entry entry = (Map.Entry ) it.next(); 940 Object key = entry.getKey(); 941 Object oldValue = oldState.remove(key); 942 if (key != PARENT) { 943 Object newValue = entry.getValue(); 944 if (oldValue == null || !oldValue.equals(newValue)) 945 diff.put(key, newValue); 946 } 947 } 948 it = oldState.keySet().iterator(); 949 while (it.hasNext()) { 950 Object key = it.next(); 951 if (!oldState.get(key).equals("")) 952 diff.put(key, ""); 953 } 954 diff.remove(PARENT); 955 return diff; 956 } 957 958 } 959 960 961 965 public static String [] knownKeys = 966 new String [] { 967 GraphConstants.ABSOLUTE, 968 GraphConstants.AUTOSIZE, 969 GraphConstants.BACKGROUND, 970 GraphConstants.BEGINFILL, 971 GraphConstants.BEGINSIZE, 972 GraphConstants.BENDABLE, 973 GraphConstants.BORDER, 974 GraphConstants.BORDERCOLOR, 975 GraphConstants.BOUNDS, 976 GraphConstants.CONNECTABLE, 977 GraphConstants.DASHPATTERN, 978 GraphConstants.DISCONNECTABLE, 979 GraphConstants.EDITABLE, 980 GraphConstants.ENDFILL, 981 GraphConstants.ENDSIZE, 982 GraphConstants.FONT, 983 GraphConstants.FOREGROUND, 984 GraphConstants.HORIZONTAL_ALIGNMENT, 985 GraphConstants.VERTICAL_ALIGNMENT, 986 GraphConstants.ICON, 987 GraphConstants.LABELPOSITION, 988 GraphConstants.LINEBEGIN, 989 GraphConstants.LINECOLOR, 990 GraphConstants.LINEEND, 991 GraphConstants.LINESTYLE, 992 GraphConstants.LINEWIDTH, 993 GraphConstants.MOVEABLE, 994 GraphConstants.OFFSET, 995 GraphConstants.OPAQUE, 996 GraphConstants.POINTS, 997 GraphConstants.ROUTING, 998 GraphConstants.SIZE, 999 GraphConstants.SIZEABLE, 1000 GraphConstants.VALUE }; 1001 1002 public static Class [] keyTypes = 1003 new Class [] { 1004 Boolean .class, 1005 Boolean .class, 1006 Color .class, 1007 Boolean .class, 1008 Integer .class, 1009 Boolean .class, 1010 Border .class, 1011 Color .class, 1012 Rectangle .class, 1013 Boolean .class, 1014 float[].class, 1015 Boolean .class, 1016 Boolean .class, 1017 Boolean .class, 1018 Integer .class, 1019 Font .class, 1020 Color .class, 1021 Integer .class, 1022 Integer .class, 1023 Icon .class, 1024 Point .class, 1025 Integer .class, 1026 Color .class, 1027 Integer .class, 1028 Integer .class, 1029 Float .class, 1030 Boolean .class, 1031 Point .class, 1032 Boolean .class, 1033 List .class, 1034 Edge.Routing.class, 1035 Dimension .class, 1036 Boolean .class, 1037 Object .class }; 1038 1039 public static String encodeMap( 1040 String indent, 1041 Map attributes, 1042 boolean invert, 1043 Set excludeAttributes, 1044 boolean URLencodeValues) { 1045 String xml = new String (""); 1046 Iterator it = attributes.entrySet().iterator(); 1047 while (it.hasNext()) { 1048 Map.Entry entry = (Map.Entry ) it.next(); 1049 Object key = entry.getKey(); 1050 if (excludeAttributes == null 1051 || !excludeAttributes.contains(key)) { 1052 Object value = entry.getValue(); 1053 if (invert) { 1054 Object tmp = key; 1055 key = value; 1056 value = tmp; 1057 } 1058 if (URLencodeValues) { 1059 try { 1060 key = URLEncoder.encode(key.toString(), "UTF-8"); 1061 value = URLEncoder.encode(encodeValue(value), "UTF-8"); 1062 } catch (Exception e) { 1063 System.err.println(e.getMessage()); 1064 } 1065 } 1066 xml += indent 1067 + "<a key=\"" 1068 + encodeKey(key.toString()) 1069 + "\" val=\"" 1070 + encodeValue(value) 1071 + "\"/>\n"; 1072 } 1073 } 1074 return xml; 1075 } 1076 1077 public static String encodeUserObjects( 1078 String indent, 1079 Map userObjects) { 1080 String xml = new String (""); 1081 Iterator it = userObjects.entrySet().iterator(); 1082 while (it.hasNext()) { 1083 Map.Entry entry = (Map.Entry ) it.next(); 1084 Object key = entry.getValue(); 1085 Object value = entry.getKey(); 1086 { 1095 try { 1096 value = URLEncoder.encode(encodeValue(value), "UTF-8"); 1097 } catch (Exception e) { 1098 System.err.println(e.getMessage()); 1099 } 1100 xml += indent 1101 + "<a key=\"" 1102 + encodeKey(key.toString()) 1103 + "\" val=\"" 1104 + value 1105 + "\"/>\n"; 1106 } 1107 } 1108 return xml; 1109 } 1110 1111 public static String encodeKey(String key) { 1112 return key; 1116 } 1117 1118 public static String encodeValue(Object value) { 1119 String ret = ""; 1120 if (value instanceof Rectangle ) { 1121 Rectangle r = (Rectangle ) value; 1122 ret = r.x + "," + r.y + "," + r.width + "," + r.height; 1123 } else if (value instanceof List ) { List list = (List ) value; 1125 String s = ""; 1126 for (int i = 0; i < list.size(); i++) { 1127 if (list.get(i) instanceof Point2D ) { 1128 Point2D pt = (Point2D ) list.get(i); 1129 s = s + pt.getX() + "," + pt.getY() + ","; 1130 } 1131 } 1132 ret = (s.length() > 0) ? s.substring(0, s.length() - 1) : s; 1133 } else if (value instanceof Font ) { 1134 Font font = (Font ) value; 1135 ret = font.getName() 1136 + "," 1137 + font.getSize() 1138 + "," 1139 + font.getStyle(); 1140 } else if (value instanceof Color ) { 1141 Color color = (Color ) value; 1142 ret = Integer.toString(color.getRed()) 1143 + "," 1144 + Integer.toString(color.getGreen()) 1145 + "," 1146 + Integer.toString(color.getBlue()); 1147 } else if (value instanceof Point ) { 1148 Point point = (Point ) value; 1149 ret = point.x + "," + point.y; 1150 } else if (value instanceof float[]) { 1151 float[] f = (float[]) value; 1152 String s = ""; 1153 for (int i = 0; i < f.length; i++) { 1154 s = s + Float.toString(f[i]) + ","; 1155 } 1156 ret = s.substring(0, s.length() - 1); 1157 } else if (value instanceof Border ) { 1158 if (value instanceof LineBorder ) { 1159 LineBorder lb = (LineBorder ) value; 1160 ret = "L," 1161 + lb.getLineColor().getRGB() 1162 + "," 1163 + lb.getThickness(); 1164 } else if (value instanceof BevelBorder ) { 1165 BevelBorder bb = (BevelBorder ) value; 1166 ret = "B," + bb.getBevelType(); 1167 } 1168 } else if (value instanceof Edge.Routing) { 1172 if (value instanceof DefaultEdge.DefaultRouting) 1173 ret = "simple"; 1174 } else if (value != null) 1175 ret = value.toString(); 1176 return ret; 1177 } 1178 1179 public static Map decodeMap(Node node, boolean useKnownKeys, boolean URLdecodeValues) { 1180 Hashtable map = new Hashtable (); 1181 for (int i = 0; i < node.getChildNodes().getLength(); i++) { 1182 Node child = node.getChildNodes().item(i); 1183 if (child.getNodeName().toLowerCase().equals("a")) { 1184 Node key = child.getAttributes().getNamedItem("key"); 1185 Node value = child.getAttributes().getNamedItem("val"); 1186 if (key != null && value != null) { 1187 String keyVal = key.getNodeValue().toString(); 1188 Object valueS = value.getNodeValue().toString(); 1189 if (useKnownKeys) { 1190 int index = -1; 1191 for (int j=0; j<knownKeys.length; j++) 1192 if (keyVal.equals(knownKeys[j])) 1193 index = j; 1194 if (index != -1) 1195 valueS = 1196 decodeValue(keyTypes[index], valueS.toString()); 1197 } else if (URLdecodeValues) { 1198 1199 try { 1200 keyVal = URLDecoder.decode(keyVal.toString(), "UTF-8"); 1201 valueS = URLDecoder.decode(valueS.toString(), "UTF-8"); 1202 } catch (Exception e) { 1203 System.err.println(e.getMessage()); 1204 } 1205 } 1206 if (valueS != null) 1207 map.put(keyVal, valueS); 1208 } 1209 } 1210 } 1211 return map; 1212 } 1213 1214 public static Map decodeUserObjects(Node node) { 1215 Hashtable map = new Hashtable (); 1216 for (int i = 0; i < node.getChildNodes().getLength(); i++) { 1217 Node child = node.getChildNodes().item(i); 1218 if (child.getNodeName().toLowerCase().equals("a")) { 1219 Node key = child.getAttributes().getNamedItem("key"); 1220 Node value = child.getAttributes().getNamedItem("val"); 1221 if (key != null) { 1222 String keyVal = key.getNodeValue().toString(); 1223 if (value != null) { 1224 Object valueS = value.getNodeValue().toString(); 1225 if (valueS != null) { 1226 try { 1227 valueS = URLDecoder.decode(valueS.toString(), "UTF-8"); 1228 } catch (Exception e) { 1229 System.err.println(e.getMessage()); 1230 } 1231 map.put(keyVal, valueS); 1232 } 1233 } else { 1234 Map properties = decodeMap(child, false, true); 1235 if (properties != null) 1236 map.put(keyVal, properties); 1237 } 1238 } 1239 } 1240 } 1241 return map; 1242 } 1243 1244 public static String [] tokenize(String s, String token) { 1245 StringTokenizer tokenizer = new StringTokenizer (s, token); 1246 String [] tok = new String [tokenizer.countTokens()]; 1247 int i = 0; 1248 while (tokenizer.hasMoreElements()) { 1249 tok[i++] = tokenizer.nextToken(); 1250 } 1251 return tok; 1252 } 1253 1254 public static Object decodeValue(Class key, String value) { 1255 if (key != String .class 1256 && key != Object .class 1257 && (value == null || value.equals(""))) 1258 return EMPTY; 1259 if (key == Rectangle .class) { 1260 String [] tok = tokenize(value, ","); 1261 if (tok.length == 4) { 1262 int x = Integer.parseInt(tok[0]); 1263 int y = Integer.parseInt(tok[1]); 1264 int w = Integer.parseInt(tok[2]); 1265 int h = Integer.parseInt(tok[3]); 1266 return new Rectangle (x, y, w, h); 1267 } 1268 } else if (key == List .class) { List list = new LinkedList (); 1270 String [] tok = tokenize(value, ","); 1271 for (int i = 0; i < tok.length; i = i + 2) { 1272 double x = Double.parseDouble(tok[i]); 1273 double y = Double.parseDouble(tok[i + 1]); 1274 AttributeMap dummyMap = new AttributeMap(); 1275 Point2D point = dummyMap.createPoint(x,y); 1276 list.add(point); 1277 } 1278 return list; 1279 } else if (key == Font .class) { 1280 String [] tok = tokenize(value, ","); 1281 if (tok.length == 3) { 1282 String name = tok[0]; 1283 int size = Integer.parseInt(tok[1]); 1284 int style = Integer.parseInt(tok[2]); 1285 return new Font (name, style, size); 1286 } 1287 } else if (key == Color .class) { 1288 String [] tok = tokenize(value, ","); 1289 if (tok.length == 3) { 1290 int r = Integer.parseInt(tok[0]); 1291 int g = Integer.parseInt(tok[1]); 1292 int b = Integer.parseInt(tok[2]); 1293 return new Color (r, g, b); 1294 } 1295 return new Color (Integer.parseInt(value)); 1296 } else if (key == Point .class) { 1297 String [] tok = tokenize(value, ","); 1298 if (tok.length == 2) { 1299 int x = Integer.parseInt(tok[0]); 1300 int y = Integer.parseInt(tok[1]); 1301 return new Point (x, y); 1302 } 1303 } else if (key == float[].class) { 1304 String [] tok = tokenize(value, ","); 1305 float[] f = new float[tok.length]; 1306 for (int i = 0; i < tok.length; i++) 1307 f[i] = Float.parseFloat(tok[i]); 1308 return f; 1309 } else if (key == Integer .class) { 1310 return new Integer (value); 1311 } else if (key == Border .class) { 1312 String [] tok = tokenize(value, ","); 1313 if (tok[0].equals("L")) { Color c = new Color (Integer.parseInt(tok[1])); 1315 int thickness = Integer.parseInt(tok[2]); 1316 return BorderFactory.createLineBorder(c, thickness); 1317 } else if (tok[0].equals("B")) { int type = Integer.parseInt(tok[1]); 1319 return BorderFactory.createBevelBorder(type); 1320 } 1321 return BorderFactory.createLineBorder(Color.black, 1); 1322 } else if (key == Boolean .class) { 1323 return new Boolean (value); 1324 } else if (key == Float .class) { 1325 return new Float (value); 1326 } else if (key == Icon .class) { 1327 return new ImageIcon (value); 1328 } else if (key == Edge.Routing.class) { 1329 if (value.equals("simple")) 1330 return GraphConstants.ROUTING_SIMPLE; 1331 } 1332 return value; 1333 } 1334 1335 1339 public static DefaultGraphCell createCell(String type, Object userObject) { 1340 if (type.equals("rect")) 1343 return new DefaultGraphCell(userObject); 1344 else if (type.equals("text")) 1345 return new TextCell(userObject); 1346 else if (type.equals("diamond")) 1347 return new DiamondCell(userObject); 1348 else if (type.equals("roundrect")) 1349 return new RoundRectangleCell(userObject); 1350 else if (type.equals("ellipse")) 1351 return new EllipseCell(userObject); 1352 else if (type.equals("image")) return new ImageCell(userObject); 1354 else if (type.equals("port")) 1355 return new DefaultPort(userObject); 1356 else if (type.equals("edge")) 1357 return new DefaultEdge(userObject); 1358 return null; 1359 } 1360 1361 public static String getType(Object cell) { 1362 if (cell instanceof DefaultPort) 1363 return "port"; 1364 else if (cell instanceof TextCell) 1365 return "text"; 1366 else if (cell instanceof DiamondCell) 1367 return "diamond"; 1368 else if (cell instanceof RoundRectangleCell) 1369 return "roundrect"; 1370 else if (cell instanceof EllipseCell) 1371 return "ellipse"; 1372 else if (cell instanceof ImageCell) 1373 return "image"; 1374 else if (cell instanceof DefaultEdge) 1375 return "edge"; 1376 return "rect"; 1377 } 1378 1379} 1380 | Popular Tags |