/** * Returns the decoded object for the element with the specified ID in * {@link #document}. If the object is not known then {@link #lookup(String)} * is used to find an object. If no object is found, then the element with * the respective ID from the document is parsed using {@link #decode(Node)}. * * @param id ID of the object to be returned. * @return Returns the object for the given ID. */ public Object getObject(String id) { Object obj = null; if (id != null) { obj = objects.get(id); if (obj == null) { obj = lookup(id); if (obj == null) { Node node = getElementById(id); if (node != null) { obj = decode(node); } } } } return obj; }
/** * Returns the element with the given ID from the document. * * @param id ID of the element to be returned. * @return Returns the element for the given ID. */ public Node getElementById(String id) { if (elements == null) { elements = new Hashtable<String, Node>(); addElement(document.getDocumentElement()); } return elements.get(id); }
/** * Writes the given value as a child node of the given node. */ protected void writeComplexAttribute(mxCodec enc, Object obj, String attr, Object value, Node node) { Node child = enc.encode(value); if (child != null) { if (attr != null) { mxCodec.setAttribute(child, "as", attr); } node.appendChild(child); } else { System.err.println("mxObjectCodec.encode: No node for " + getName() + "." + attr + ": " + value); } }
/** * Decodes the given XML node using {@link #decode(Node, Object)}. * * @param node XML node to be decoded. * @return Returns an object that represents the given node. */ public Object decode(Node node) { return decode(node, null); }
/** * Encoding of cell hierarchies is built-into the core, but is a * higher-level function that needs to be explicitely used by the * respective object encoders (eg. mxModelCodec, mxChildChangeCodec * and mxRootChangeCodec). This implementation writes the given cell * and its children as a (flat) sequence into the given node. The * children are not encoded if the optional includeChildren is false. * The function is in charge of adding the result into the given node * and has no return value. * * @param cell mxCell to be encoded. * @param node Parent XML node to add the encoded cell into. * @param includeChildren Boolean indicating if the method * should include all descendents. */ public void encodeCell(mxICell cell, Node node, boolean includeChildren) { node.appendChild(encode(cell)); if (includeChildren) { int childCount = cell.getChildCount(); for (int i = 0; i < childCount; i++) { encodeCell(cell.getChildAt(i), node, includeChildren); } } }
@Override public Node afterEncode(mxCodec enc, Object obj, Node node) { if (obj instanceof mxChildChange) { mxChildChange change = (mxChildChange) obj; Object child = change.getChild(); if (isReference(obj, "child", child, true)) { // Encodes as reference (id) mxCodec.setAttribute(node, "child", enc.getId(child)); } else { // At this point, the encoder is no longer able to know which cells // are new, so we have to encode the complete cell hierarchy and // ignore the ones that are already there at decoding time. Note: // This can only be resolved by moving the notify event into the // execute of the edit. enc.encodeCell((mxICell) child, node, true); } } return node; }
change.setChild(dec.decodeCell(tmp, false)); if (dec.lookup(id) == null) dec.decodeCell(tmp, true); change.setChild((mxICell) dec.getObject(childRef));
/** * Encodes the value of each member in then given obj * into the given node using {@link #encodeFields(mxCodec, Object, Node)} * and {@link #encodeElements(mxCodec, Object, Node)}. * * @param enc Codec that controls the encoding process. * @param obj Object to be encoded. * @param node XML node that contains the encoded object. */ protected void encodeObject(mxCodec enc, Object obj, Node node) { mxCodec.setAttribute(node, "id", enc.getId(obj)); encodeFields(enc, obj, node); encodeElements(enc, obj, node); }
Object tmp = enc.getId(value); if (fieldname == null || enc.isEncodeDefaults() || defaultValue == null || !defaultValue.equals(value))
object = dec.lookup(ref); Node element = dec.getElementById(ref);
change.setRoot(dec.decodeCell(tmp, false)); dec.decodeCell(tmp, true);
@Override public Node afterEncode(mxCodec enc, Object obj, Node node) { if (obj instanceof mxRootChange) { enc.encodeCell((mxICell) ((mxRootChange) obj).getRoot(), node, true); } return node; }
/** * Reads the given attribute into the specified object. */ protected void decodeAttribute(mxCodec dec, Node attr, Object obj) { String name = attr.getNodeName(); if (!name.equalsIgnoreCase("as") && !name.equalsIgnoreCase("id")) { Object value = attr.getNodeValue(); String fieldname = getFieldName(name); if (isReference(obj, fieldname, value, false)) { Object tmp = dec.getObject(String.valueOf(value)); if (tmp == null) { log.log(Level.FINEST, "mxObjectCodec.decode: No object for " + getName() + "." + fieldname + "=" + value); return; // exit } value = tmp; } if (!isExcluded(obj, fieldname, value, false)) { setFieldValue(obj, fieldname, value); } } }
/** * Encodes an mxCell and wraps the XML up inside the * XML of the user object (inversion). */ public Node afterEncode(mxCodec enc, Object obj, Node node) { if (obj instanceof mxCell) { mxCell cell = (mxCell) obj; if (cell.getValue() instanceof Node) { // Wraps the graphical annotation up in the // user object (inversion) by putting the // result of the default encoding into // a clone of the user object (node type 1) // and returning this cloned user object. Element tmp = (Element) node; node = enc.getDocument().importNode((Node) cell.getValue(), true); node.appendChild(tmp); // Moves the id attribute to the outermost // XML node, namely the node which denotes // the object boundaries in the file. String id = tmp.getAttribute("id"); ((Element) node).setAttribute("id", id); tmp.removeAttribute("id"); } } return node; }
/** * Decodes the given XML node using {@link #decode(Node, Object)}. * * @param node XML node to be decoded. * @return Returns an object that represents the given node. */ public Object decode(Node node) { return decode(node, null); }
/** * Writes the given value as a child node of the given node. */ protected void writeComplexAttribute(mxCodec enc, Object obj, String attr, Object value, Node node) { Node child = enc.encode(value); if (child != null) { if (attr != null) { mxCodec.setAttribute(child, "as", attr); } node.appendChild(child); } else { log.log(Level.FINEST, "mxObjectCodec.encode: No node for " + getName() + "." + attr + ": " + value); } }
/** * Encoding of cell hierarchies is built-into the core, but is a * higher-level function that needs to be explicitely used by the * respective object encoders (eg. mxModelCodec, mxChildChangeCodec * and mxRootChangeCodec). This implementation writes the given cell * and its children as a (flat) sequence into the given node. The * children are not encoded if the optional includeChildren is false. * The function is in charge of adding the result into the given node * and has no return value. * * @param cell mxCell to be encoded. * @param node Parent XML node to add the encoded cell into. * @param includeChildren Boolean indicating if the method * should include all descendents. */ public void encodeCell(mxICell cell, Node node, boolean includeChildren) { node.appendChild(encode(cell)); if (includeChildren) { int childCount = cell.getChildCount(); for (int i = 0; i < childCount; i++) { encodeCell(cell.getChildAt(i), node, includeChildren); } } }
@Override public Node afterEncode(mxCodec enc, Object obj, Node node) { if (obj instanceof mxChildChange) { mxChildChange change = (mxChildChange) obj; Object child = change.getChild(); if (isReference(obj, "child", child, true)) { // Encodes as reference (id) mxCodec.setAttribute(node, "child", enc.getId(child)); } else { // At this point, the encoder is no longer able to know which cells // are new, so we have to encode the complete cell hierarchy and // ignore the ones that are already there at decoding time. Note: // This can only be resolved by moving the notify event into the // execute of the edit. enc.encodeCell((mxICell) child, node, true); } } return node; }
change.setChild(dec.decodeCell(tmp, false)); if (dec.lookup(id) == null) dec.decodeCell(tmp, true); change.setChild((mxICell) dec.getObject(childRef));