⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mxobjectcodec.java

📁 经典的java图像处理程序源码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/** * $Id: mxObjectCodec.java,v 1.19 2008/10/22 13:33:45 gaudenz Exp $ * Copyright (c) 2006, Gaudenz Alder */package com.mxgraph.io;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.util.Collection;import java.util.HashSet;import java.util.Hashtable;import java.util.Iterator;import java.util.Map;import java.util.Set;import org.w3c.dom.Element;import org.w3c.dom.NamedNodeMap;import org.w3c.dom.Node;import com.mxgraph.util.mxUtils;/** * Generic codec for Java objects. See below for a detailed description of * the encoding/decoding scheme. *  * Note: Since booleans are numbers in JavaScript, all boolean values are * encoded into 1 for true and 0 for false. */public class mxObjectCodec{	/**	 * Immutable empty set.	 */	private static Set EMPTY_SET = new HashSet();	/**	 * Holds the template object associated with this codec.	 */	Object template;	/**	 * Array containing the variable names that should be ignored by the codec.	 */	Set exclude;	/**	 * Array containing the variable names that should be turned into or	 * converted from references. See <mxCodec.getId> and <mxCodec.getObject>.	 */	Set idrefs;	/**	 * Maps from from fieldnames to XML attribute names.	 */	Map mapping;	/**	 * Maps from from XML attribute names to fieldnames.	 */	Map reverse;	/**	 * Constructs a new codec for the specified template object.	 */	public mxObjectCodec(Object template)	{		this(template, null, null, null);	}	/**	 * Constructs a new codec for the specified template object. The variables	 * in the optional exclude array are ignored by the codec. Variables in the	 * optional idrefs array are turned into references in the XML. The	 * optional mapping may be used to map from variable names to XML	 * attributes. The argument is created as follows:	 * 	 * @param template Prototypical instance of the object to be encoded/decoded.	 * @param exclude Optional array of fieldnames to be ignored.	 * @param idrefs Optional array of fieldnames to be converted to/from references.	 * @param mapping Optional mapping from field- to attributenames.	 */	public mxObjectCodec(Object template, String[] exclude, String[] idrefs,			Map mapping)	{		this.template = template;		if (exclude != null)		{			this.exclude = new HashSet();			for (int i = 0; i < exclude.length; i++)			{				this.exclude.add(exclude[i]);			}		}		else		{			this.exclude = EMPTY_SET;		}		if (idrefs != null)		{			this.idrefs = new HashSet();			for (int i = 0; i < idrefs.length; i++)			{				this.idrefs.add(idrefs[i]);			}		}		else		{			this.idrefs = EMPTY_SET;		}		if (mapping == null)		{			mapping = new Hashtable();		}		this.mapping = mapping;		reverse = new Hashtable();		Iterator it = mapping.entrySet().iterator();		while (it.hasNext())		{			Map.Entry e = (Map.Entry) it.next();			reverse.put(e.getValue().toString(), e.getKey().toString());		}	}	/**	 * Returns the template object associated with this codec.	 * 	 * @return Returns the template object.	 */	public Object getTemplate()	{		return template;	}	/**	 * Returns a new instance of the template object for representing the given	 * node.	 * 	 * @param node XML node that the object is going to represent.	 * @return Returns a new template instance.	 */	protected Object cloneTemplate(Node node)	{		Object obj = null;		try		{			obj = template.getClass().newInstance();			// Special case: Check if the collection			// should be a map. This is if the first			// child has an "as"-attribute. This			// assumes that all childs will have			// as attributes in this case. This is			// required because in JavaScript, the			// map and array object are the same.			if (obj instanceof Collection)			{				node = node.getFirstChild();				if (node != null && node.hasAttributes()						&& node.getAttributes().getNamedItem("as") != null)				{					obj = new Hashtable();				}			}		}		catch (InstantiationException e)		{			// ignore			e.printStackTrace();		}		catch (IllegalAccessException e)		{			// ignore			e.printStackTrace();		}		return obj;	}	/**	 * Returns true if the given attribute is to be ignored by the codec. This	 * implementation returns true if the given fieldname is in	 * {@link #exclude}.	 * 	 * @param obj Object instance that contains the field.	 * @param attr Fieldname of the field.	 * @param value Value of the field.	 * @param isWrite Boolean indicating if the field is being encoded or	 * decoded. isWrite is true if the field is being encoded, else it is	 * being decoded.	 * @return Returns true if the given attribute should be ignored.	 */	public boolean isExcluded(Object obj, String attr, Object value,			boolean isWrite)	{		return exclude.contains(attr);	}	/**	 * Returns true if the given fieldname is to be treated as a textual	 * reference (ID). This implementation returns true if the given fieldname	 * is in {@link #idrefs}.	 * 	 * @param obj Object instance that contains the field.	 * @param attr Fieldname of the field.	 * @param value Value of the field.	 * @param isWrite Boolean indicating if the field is being encoded or	 * decoded. isWrite is true if the field is being encoded, else it is being	 * decoded.	 * @return Returns true if the given attribute should be handled as a	 * reference.	 */	public boolean isReference(Object obj, String attr, Object value,			boolean isWrite)	{		return idrefs.contains(attr);	}	/**	 * Encodes the specified object and returns a node representing then given	 * object. Calls beforeEncode after creating the node and afterEncode	 * with the resulting node after processing.	 * 	 * Enc is a reference to the calling encoder. It is used to encode complex	 * objects and create references.	 * 	 * This implementation encodes all variables of an object according to the	 * following rules:	 * 	 * <ul>	 * <li>If the variable name is in {@link #exclude} then it is ignored.</li>	 * <li>If the variable name is in {@link #idrefs} then	 * {@link mxCodec#getId(Object)} is used to replace the object with its ID.	 * </li>	 * <li>The variable name is mapped using {@link #mapping}.</li>	 * <li>If obj is an array and the variable name is numeric (ie. an index) then it	 * is not encoded.</li>	 * <li>If the value is an object, then the codec is used to create a child	 * node with the variable name encoded into the "as" attribute.</li>	 * <li>Else, if {@link com.mxgraph.io.mxCodec#isEncodeDefaults()} is true or	 * the value differs from the template value, then ...	 * <ul>	 * <li>... if obj is not an array, then the value is mapped to an	 * attribute.</li>	 * <li>... else if obj is an array, the value is mapped to an add child	 * with a value attribute or a text child node, if the value is a function.	 * </li>	 * </ul>	 * </li>	 * </ul>	 * 	 * If no ID exists for a variable in {@link #idrefs} or if an object cannot be	 * encoded, a warning is printed to System.err.	 * 	 * @param enc Codec that controls the encoding process.	 * @param obj Object to be encoded.	 * @return Returns the resulting XML node that represents the given object. 	 */	public Node encode(mxCodec enc, Object obj)	{		String name = mxCodecRegistry.getName(obj.getClass());		Node node = enc.document.createElement(name);		obj = beforeEncode(enc, obj, node);		encodeObject(enc, obj, node);		return afterEncode(enc, obj, node);	}	/**	 * 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);	}	/**	 * Encodes the declared fields of the given object into the given node.	 * 	 * @param enc Codec that controls the encoding process.	 * @param obj Object whose fields should be encoded.	 * @param node XML node that contains the encoded object.	 */	protected void encodeFields(mxCodec enc, Object obj, Node node)	{		Class type = obj.getClass();		while (type != null)		{			Field[] fields = type.getDeclaredFields();			for (int i = 0; i < fields.length; i++)			{				Field f = fields[i];				if ((f.getModifiers() & Modifier.TRANSIENT) != Modifier.TRANSIENT)				{					String fieldname = f.getName();					Object value = getFieldValue(obj, fieldname);					encodeValue(enc, obj, fieldname, value, node);				}			}			type = type.getSuperclass();		}	}	/**	 * Encodes the child objects of arrays, maps and collections.	 * 	 * @param enc Codec that controls the encoding process.	 * @param obj Object whose child objects should be encoded.	 * @param node XML node that contains the encoded object.	 */	protected void encodeElements(mxCodec enc, Object obj, Node node)	{		if (obj.getClass().isArray())		{			Object[] tmp = (Object[]) obj;			for (int i = 0; i < tmp.length; i++)			{				encodeValue(enc, obj, null, tmp[i], node);			}		}		else if (obj instanceof Map)		{			Iterator it = ((Map) obj).entrySet().iterator();			while (it.hasNext())			{				Map.Entry e = (Map.Entry) it.next();				encodeValue(enc, obj, String.valueOf(e.getKey()), e.getValue(),						node);			}		}		else if (obj instanceof Collection)		{			Iterator it = ((Collection) obj).iterator();			while (it.hasNext())			{				Object value = it.next();				encodeValue(enc, obj, null, value, node);			}		}	}	/**	 * Converts the given value according to the mappings	 * and id-refs in this codec and uses	 * {@link #writeAttribute(mxCodec, Object, String, Object, Node)}	 * to write the attribute into the given node.	 * 	 * @param enc Codec that controls the encoding process.	 * @param obj Object whose field is going to be encoded.	 * @param fieldname Name if the field to be encoded.	 * @param value Value of the property to be encoded.	 * @param node XML node that contains the encoded object.	 */	protected void encodeValue(mxCodec enc, Object obj, String fieldname,			Object value, Node node)	{		if (value != null && !isExcluded(obj, fieldname, value, true))		{			if (isReference(obj, fieldname, value, true))			{				Object tmp = enc.getId(value);				if (tmp == null)				{					System.err.println("mxObjectCodec.encode: No ID for "							+ mxCodecRegistry.getName(obj.getClass()) + "."							+ fieldname + "=" + value);					return; // exit				}				value = tmp;			}			Object defaultValue = getFieldValue(template, fieldname);			if (fieldname == null || enc.isEncodeDefaults()					|| defaultValue == null || !defaultValue.equals(value))			{				writeAttribute(enc, obj, getAttributeName(fieldname), value,						node);			}		}	}	/**	 * Returns true if the given object is a primitive value.	 * 	 * @param value Object that should be checked.	 * @return Returns true if the given object is a primitive value.	 */	protected boolean isPrimitiveValue(Object value)	{		return value instanceof String || value instanceof Boolean				|| value instanceof Character || value instanceof Byte				|| value instanceof Short || value instanceof Integer				|| value instanceof Long || value instanceof Float				|| value instanceof Double || value.getClass().isPrimitive();	}	/**	 * Writes the given value into node using writePrimitiveAttribute	 * or writeComplexAttribute depending on the type of the value.	 */	protected void writeAttribute(mxCodec enc, Object obj, String attr,			Object value, Node node)	{		value = convertValueToXml(value);		if (isPrimitiveValue(value))		{			writePrimitiveAttribute(enc, obj, attr, value, node);		}		else		{			writeComplexAttribute(enc, obj, attr, value, node);		}	}	/**	 * Writes the given value as an attribute of the given node.	 */	protected void writePrimitiveAttribute(mxCodec enc, Object obj,			String attr, Object value, Node node)	{		if (attr == null || obj instanceof Map)		{			Node child = enc.document.createElement("add");			if (attr != null)			{				mxCodec.setAttribute(child, "as", attr);			}			mxCodec.setAttribute(child, "value", value);			node.appendChild(child);		}		else		{			mxCodec.setAttribute(node, attr, value);		}	}	/**	 * 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 "					+ mxCodecRegistry.getName(obj.getClass()) + "." + attr					+ ": " + value);		}	}	/**	 * Converts true to "1" and false to "0". All other values are ignored.	 */	protected Object convertValueToXml(Object value)	{		if (value instanceof Boolean)		{			value = ((Boolean) value).booleanValue() ? "1" : "0";		}		return value;	}	/**	 * Converts XML attribute values to object of the given type.	 */	protected Object convertValueFromXml(Class type, Object value)	{		if (value instanceof String && type.isPrimitive())		{			String tmp = (String) value;			if (type.equals(boolean.class))			{				if (tmp.equals("1") || tmp.equals("0"))				{					tmp = (tmp.equals("1")) ? "true" : "false";				}				value = new Boolean(tmp);			}			else if (type.equals(char.class))			{				value = new Character(tmp.charAt(0));			}			else if (type.equals(byte.class))			{				value = new Byte(tmp);			}			else if (type.equals(short.class))			{				value = new Short(tmp);			}			else if (type.equals(int.class))			{				value = new Integer(tmp);			}			else if (type.equals(long.class))			{				value = new Long(tmp);			}			else if (type.equals(float.class))			{				value = new Float(tmp);			}			else if (type.equals(double.class))			{				value = new Double(tmp);			}		}		return value;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -