All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jadex.xml.bean.JavaWriter Maven / Gradle / Ivy

Go to download

Jadex XML is an XML data binding framework for Java and also for other representations. The main idea of Jadex XML is that neither the XML-Schema on the one side nor the Java classes on the other side should define other binding. Instead, a separate mapping between both is used as a mediation. This allows designing the XML representation independent of the Java side but still being able to connect both as desired. This idea was first put forward by the JiBX data binding framework. Jadex XML pushes it further by combining it with the configuration by exception principle. The framework can detect obvious correspondences between both sides automatically and only needs configuration information when translations are necessary. The configuration information is currently specified directly in form of Java configuration classes.

There is a newer version: 4.0.267
Show newest version
package jadex.xml.bean;


import java.io.OutputStream;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.URI;
import java.net.URL;
import java.security.cert.Certificate;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Currency;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.LogRecord;

import jadex.commons.Base64;
import jadex.commons.MethodInfo;
import jadex.commons.SReflect;
import jadex.commons.Tuple;
import jadex.commons.Tuple2;
import jadex.commons.Tuple3;
import jadex.commons.collection.LRU;
import jadex.commons.collection.MultiCollection;
import jadex.commons.transformation.IObjectStringConverter;
import jadex.commons.transformation.traverser.SStackTraceElementHelper;
import jadex.xml.AccessInfo;
import jadex.xml.AttributeConverter;
import jadex.xml.AttributeInfo;
import jadex.xml.IAttributeConverter;
import jadex.xml.MappingInfo;
import jadex.xml.ObjectInfo;
import jadex.xml.SubobjectInfo;
import jadex.xml.TypeInfo;
import jadex.xml.XMLInfo;
import jadex.xml.stax.QName;
import jadex.xml.writer.AWriter;
import jadex.xml.writer.IObjectWriterHandler;
import jadex.xml.writer.XMLWriterFactory;


/**
 * Java specific reader that supports collection classes and arrays.
 */
public class JavaWriter
{
	//-------- attributes --------
	
	/** The static writer instance. */
	protected static volatile AWriter writer;
	
	/** The object handler. */
	protected static volatile IObjectWriterHandler handler;
	
	
	//-------- constructors --------
	
	/**
	 *  Create a new reader.
	 */
	public JavaWriter()
	{
	}
	
	//-------- methods --------
	
	/**
	 *  Join sets of typeinfos.
	 *  @param typeinfos The user specific type infos. 
	 *  @return The joined type infos.
	 */
	public static Set joinTypeInfos(Set typeinfos)
	{
		Set ret = getTypeInfos();
		if(typeinfos!=null)
			ret.addAll(typeinfos);
		return ret;
	}
	
	/**
	 *  Get the java type infos.
	 *  
	 *  Supported types:
	 *  
	 *  - java.util.Map
	 *  - jadex.commons.collection.MultiCollection
	 *  - java.util.List
	 *  - java.util.Set
	 *  - Array
	 *  - java.util.Color
	 *  - java.util.Date
	 *  - java.util.Calendar
	 *  - java.util.Currency
	 *  - java.lang.Class
	 *  - java.net.URL
	 *  - java.logging.Level
	 *  - java.logging.LogRecord
	 *  - java.net.InetAddress
	 *  - java.awt.image.RenderedImage
	 *  - java.lang.String
	 *  - java.lang.Boolean
	 *	- java.lang.Integer
	 *	- java.lang.Double
	 *	- java.lang.Float
	 *	- java.lang.Long
	 *	- java.lang.Short
	 *	- java.lang.Byte
	 *	- java.lang.Character
	 *	- java.lang.enum
	 *	- boolean/Boolean Array
	 *	- int/Integer Array
	 *	- double/Double Array
	 *	- float/Float array
	 *	- long/Long array
	 *	- short/Short Array
	 *	- byte/Byte Array
	 *	- java.lang.Character
	 *	- jadex.commons.Tuple
	 *	- jadex.commons.Tuple2
	 *  - jadex.commons.Tuple3
	 *  - java.util.UUID
	 *  - java.lang.Throwable
	 */
	public static Set getTypeInfos()
	{
		Set typeinfos = new HashSet();
		
		try
		{
			// jadex.commons.collection.LRU
			TypeInfo ti_lru = new TypeInfo(null, new ObjectInfo(LRU.class),
				new MappingInfo(null,
				new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("maxEntries", null))
				},
				new SubobjectInfo[]{
				new SubobjectInfo(new AccessInfo("cleaner")),
				new SubobjectInfo(new AccessInfo("entries", null, null, null,
				new BeanAccessInfo(null, Map.class.getMethod("entrySet", new Class[0]))), null, true)
			}));
			typeinfos.add(ti_lru);
			
			// java.util.Map
			TypeInfo ti_map = new TypeInfo(null, new ObjectInfo(Map.class),
				new MappingInfo(null, new SubobjectInfo[]{
				new SubobjectInfo(new AccessInfo("entries", null, null, null,
				new BeanAccessInfo(null, Map.class.getMethod("entrySet", new Class[0]))), null, true)
			}));
			typeinfos.add(ti_map);
			
			// Cannot let xmltag be null, because class name then contains $ which is not allowed in a tag
			// Note: XMLinfo is necessary because it cannot be written as 'Map$Entry'
			TypeInfo ti_mapentry = new TypeInfo(new XMLInfo("entry"),
				new ObjectInfo(Map.Entry.class), new MappingInfo(null, new SubobjectInfo[]{
				new SubobjectInfo(new AccessInfo("key", null, null, null,  
				new BeanAccessInfo(null, Map.Entry.class.getMethod("getKey", new Class[0])))),
				new SubobjectInfo(new AccessInfo("value", null, null, null, 
				new BeanAccessInfo(null, Map.Entry.class.getMethod("getValue", new Class[0]))))
			}));
			typeinfos.add(ti_mapentry);
			
			// jadex.commons.collection.MultiCollection
			TypeInfo ti_mc = new TypeInfo(null, new ObjectInfo(MultiCollection.class),
				new MappingInfo(null, new SubobjectInfo[]{
				new SubobjectInfo(new AccessInfo("entries", null, null, null,
				new BeanAccessInfo(null, Map.class.getMethod("entrySet", new Class[0]))), null, true)
			}));
			typeinfos.add(ti_mc);
			
			// java.util.List
			TypeInfo ti_list = new TypeInfo(null, new ObjectInfo(List.class), new MappingInfo(null,
				new SubobjectInfo[]{
				new SubobjectInfo(new AccessInfo("entries", AccessInfo.THIS), null, true)
			}));
			typeinfos.add(ti_list);
			
			// java.util.Set
			TypeInfo ti_set = new TypeInfo(null, new ObjectInfo(Set.class), new MappingInfo(null,
				new SubobjectInfo[]{
				new SubobjectInfo(new AccessInfo("entries", AccessInfo.THIS), null, true)
			}));
			typeinfos.add(ti_set);
			
			// jadex.commons.MethodInfo	// Hack!!! also use parameterTypes for backwards compatibility.
			TypeInfo ti_mi = new TypeInfo(null, new ObjectInfo(MethodInfo.class), 
			new MappingInfo(null, null, null, null, new SubobjectInfo[]{
				//new SubobjectInfo(new AccessInfo("parameterTypes", "parameterTypes"), null, false),
				new SubobjectInfo(new AccessInfo("parameterTypeInfos", "parameterTypeInfos"), null, false)
			}, true, null, null));
					
//					new AttributeInfo[]{
//					new AttributeInfo(new AccessInfo("parameterTypes", "parameterTypes")),
//					new AttributeInfo(new AccessInfo("parameterTypeInfos", "parameterTypeInfos"))},
//					null
//				));
			typeinfos.add(ti_mi);
			
			// Array
			TypeInfo ti_array = new TypeInfo(null, new ObjectInfo(Object[].class),
				new MappingInfo(null, new SubobjectInfo[]{
				new SubobjectInfo(new AccessInfo("entries", AccessInfo.THIS), null, true)
			}));
			typeinfos.add(ti_array);
			
			// java.util.UnmodifyableSet
			// java.util.UnmodifyableList
//			TypeInfo ti_unlist = new TypeInfo(null, new ObjectInfo(Collections.UnmodifiableList.class), new MappingInfo(null,
//				new SubobjectInfo[]{
//				new SubobjectInfo(new AccessInfo("entries", AccessInfo.THIS), null, true)
//			}));
//			typeinfos.add(ti_unlist);
			// java.util.UnmodifyableMap
			
		
			
			// java.util.Date
			// Ignores several redundant bean attributes for performance reasons.
			TypeInfo ti_date = new TypeInfo(null, new ObjectInfo(Date.class), 
				new MappingInfo(null, new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("time", null)),
				new AttributeInfo(new AccessInfo("hours", null, AccessInfo.IGNORE_READWRITE)),
				new AttributeInfo(new AccessInfo("minutes", null, AccessInfo.IGNORE_READWRITE)),
				new AttributeInfo(new AccessInfo("seconds", null, AccessInfo.IGNORE_READWRITE)),
				new AttributeInfo(new AccessInfo("month", null, AccessInfo.IGNORE_READWRITE)),
				new AttributeInfo(new AccessInfo("year", null, AccessInfo.IGNORE_READWRITE)),
				new AttributeInfo(new AccessInfo("date", null, AccessInfo.IGNORE_READWRITE))},
				null
			));
			typeinfos.add(ti_date);
			
			// java.util.Calendar
			// Ignores several redundant bean attributes for performance reasons.
			IObjectStringConverter cconv = new IObjectStringConverter()
			{
				public String convertObject(Object val, Object context)
				{
					String	ret	= val.getClass().getName();
					return ret;
				}
			};
			IObjectStringConverter c2conv = new IObjectStringConverter()
			{
				public String convertObject(Object val, Object context)
				{
					String	ret	= ""+((Date)val).getTime();
					return ret;
				}
			};
			TypeInfo ti_calendar = new TypeInfo(new XMLInfo(new QName("typeinfo:java.util", "Calendar")), new ObjectInfo(Calendar.class), 
				new MappingInfo(null, new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("time", null), new AttributeConverter(null, c2conv)),
				new AttributeInfo(new AccessInfo("classname", AccessInfo.THIS), new AttributeConverter(null, cconv))},
//				new AttributeInfo(new AccessInfo("hours", null, AccessInfo.IGNORE_READWRITE)),
//				new AttributeInfo(new AccessInfo("minutes", null, AccessInfo.IGNORE_READWRITE)),
//				new AttributeInfo(new AccessInfo("seconds", null, AccessInfo.IGNORE_READWRITE)),
//				new AttributeInfo(new AccessInfo("month", null, AccessInfo.IGNORE_READWRITE)),
//				new AttributeInfo(new AccessInfo("year", null, AccessInfo.IGNORE_READWRITE)),
//				new AttributeInfo(new AccessInfo("date", null, AccessInfo.IGNORE_READWRITE))},
				null
			));
			typeinfos.add(ti_calendar);

			// java.util.Currency
			// Ignores several redundant bean attributes for performance reasons.
			TypeInfo ti_currency = new TypeInfo(new XMLInfo(new QName("typeinfo:java.util", "Currency")), new ObjectInfo(Currency.class), 
				new MappingInfo(null, new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("currencyCode", null))},
				null
			));
			typeinfos.add(ti_currency);

			// java.text.SimpleDateFormat
			// Pattern managed with applyPattern(String) and String toPattern() grrrr.
			TypeInfo ti_simpledateformat = new TypeInfo(new XMLInfo(new QName("typeinfo:java.text", "SimpleDateFormat")), new ObjectInfo(SimpleDateFormat.class), 
				new MappingInfo(null, null, null, new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("pattern", null, null, null,
					new BeanAccessInfo(SimpleDateFormat.class.getMethod("applyPattern", String.class),
						SimpleDateFormat.class.getMethod("toPattern"))))},
				null, false, null, null
			));
			typeinfos.add(ti_simpledateformat);

			// java.sql.Timestamp
			// Ignores several redundant bean attributes for performance reasons.
			TypeInfo ti_timestamp = new TypeInfo(null, new ObjectInfo(Timestamp.class), 
				new MappingInfo(null, new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("time", null)),
				new AttributeInfo(new AccessInfo("hours", null, AccessInfo.IGNORE_READWRITE)),
				new AttributeInfo(new AccessInfo("minutes", null, AccessInfo.IGNORE_READWRITE)),
				new AttributeInfo(new AccessInfo("seconds", null, AccessInfo.IGNORE_READWRITE)),
				new AttributeInfo(new AccessInfo("month", null, AccessInfo.IGNORE_READWRITE)),
				new AttributeInfo(new AccessInfo("year", null, AccessInfo.IGNORE_READWRITE)),
				new AttributeInfo(new AccessInfo("date", null, AccessInfo.IGNORE_READWRITE))},
				null
			));
			typeinfos.add(ti_timestamp);
			
			// java.lang.Class
			IObjectStringConverter clconv = new IObjectStringConverter()
			{
				public String convertObject(Object val, Object context)
				{
//					String	ret	= ""+((Class)val).getCanonicalName();
					// Todo: SReflect doesn not work for some case!? (Lars)
					String	ret	= SReflect.getClassName((Class)val);
					return ret;
				}
			};
			TypeInfo ti_class = new TypeInfo(null, new ObjectInfo(Class.class), new MappingInfo(null, new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("classname", AccessInfo.THIS), new AttributeConverter(null, clconv))},
				null
			));
			typeinfos.add(ti_class);
			
			// java.net.URL
			TypeInfo ti_url = new TypeInfo(null, new ObjectInfo(URL.class), 
				new MappingInfo(null, new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("protocol", null)),
				new AttributeInfo(new AccessInfo("host", null)),
				new AttributeInfo(new AccessInfo("port", null)),
				new AttributeInfo(new AccessInfo("file", null))},
				null
			));
			typeinfos.add(ti_url);
			
			// java.net.URL
			TypeInfo ti_uri = new TypeInfo(null, new ObjectInfo(URI.class), 
				new MappingInfo(null, new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("uri", AccessInfo.THIS), new IAttributeConverter()
				{
					public String convertObject(Object val, Object context)
					{
						return val.toString();
					}
					
					public Object convertString(String val, Object context) throws Exception
					{
						return new URI(val);
					}
				})},
				null
			));
			typeinfos.add(ti_uri);
			
			// java.logging.Level
			TypeInfo ti_level = new TypeInfo(null, new ObjectInfo(Level.class), 
				new MappingInfo(null, new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("name", null))},
//				new AttributeInfo(new AccessInfo("value", null, null, null, 
//					new BeanAccessInfo(null, Level.class.getMethod("intValue", new Class[0])))),
//				new AttributeInfo(new AccessInfo("resourceBundleName", null))},
				null
			));
			typeinfos.add(ti_level);
			
			// java.logging.LogRecord
			TypeInfo ti_record = new TypeInfo(null, new ObjectInfo(LogRecord.class), 
				new MappingInfo(null, new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("level", null), new AttributeConverter(null, new IObjectStringConverter()
				{
					public String convertObject(Object val, Object context)
					{
						return ((Level)val).getName();
					}
				})),
				new AttributeInfo(new AccessInfo("level", null)),
				new AttributeInfo(new AccessInfo("message", null))},
				null
			));
			typeinfos.add(ti_record);
			
			// java.net.InetAddress
			// The following hack ensures that all subclasses of InetAdress will be stored using the same tag
			// todo: make this more easily possible
			TypeInfo ti_inetaddr = new TypeInfo(new XMLInfo(new QName("typeinfo:java.net", "InetAddress")), new ObjectInfo(InetAddress.class), 
				new MappingInfo(null, new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("hostAddress", null))},
				null
			));
			typeinfos.add(ti_inetaddr);
			
			// byte/Byte Array
			IObjectStringConverter bytesconv = new IObjectStringConverter()
			{
				public String convertObject(Object val, Object context)
				{
					byte[] bytes = Base64.encode((byte[])val);
					return new String(bytes);
				}
			};
			
			// java.security.Certificate
			TypeInfo ti_cert = new TypeInfo(new XMLInfo(new QName("typeinfo:java.security.cert", "Certificate")), new ObjectInfo(Certificate.class), 
				new MappingInfo(null, new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("data", "encoded"), new AttributeConverter(null, bytesconv)),
				new AttributeInfo(new AccessInfo("type", null))},
				null
			));
			typeinfos.add(ti_cert);
						
			// java.lang.String
//			TypeInfo ti_string = new TypeInfo(null, new ObjectInfo(String.class), new MappingInfo(null, new AttributeInfo[]{
//				new AttributeInfo(new AccessInfo("content", AccessInfo.THIS))}));
			TypeInfo ti_string = new TypeInfo(null, new ObjectInfo(String.class), new MappingInfo(null, null,
				new AttributeInfo(new AccessInfo((String)null, AccessInfo.THIS))));
			typeinfos.add(ti_string);
			
			// java.lang.Boolean
			TypeInfo ti_boolean = new TypeInfo(null, new ObjectInfo(Boolean.class), new MappingInfo(null, new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("content", AccessInfo.THIS))}));
			typeinfos.add(ti_boolean);
			
			// java.lang.Integer
			TypeInfo ti_integer = new TypeInfo(null, new ObjectInfo(Integer.class), new MappingInfo(null, new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("content", AccessInfo.THIS))}));
			typeinfos.add(ti_integer);
			
			// java.lang.Double
			TypeInfo ti_double = new TypeInfo(null, new ObjectInfo(Double.class), new MappingInfo(null, new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("content", AccessInfo.THIS))}));
			typeinfos.add(ti_double);
			
			// java.lang.Float
			TypeInfo ti_float = new TypeInfo(null, new ObjectInfo(Float.class), new MappingInfo(null, new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("content", AccessInfo.THIS))}));
			typeinfos.add(ti_float);
			
			// java.lang.Long
			TypeInfo ti_long = new TypeInfo(null, new ObjectInfo(Long.class), new MappingInfo(null, new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("content", AccessInfo.THIS))}));
			typeinfos.add(ti_long);
			
			// java.lang.Short
			TypeInfo ti_short = new TypeInfo(null, new ObjectInfo(Short.class), new MappingInfo(null, new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("content", AccessInfo.THIS))}));
			typeinfos.add(ti_short);
			
			// java.lang.Byte
			IObjectStringConverter byteconv = new IObjectStringConverter()
			{
				public String convertObject(Object val, Object context)
				{
					return new String(Base64.encode(new byte[]{((Byte)val).byteValue()}));
				}
			};
			TypeInfo ti_byte = new TypeInfo(null, new ObjectInfo(Byte.class), new MappingInfo(null, new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("content", AccessInfo.THIS), new AttributeConverter(null, byteconv))}));
			typeinfos.add(ti_byte);
			
			// java.lang.Character
			TypeInfo ti_character = new TypeInfo(null, new ObjectInfo(Character.class), new MappingInfo(null, new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("content", AccessInfo.THIS))}));
			typeinfos.add(ti_character);
			
			// java.lang.enum
			IObjectStringConverter enumconv = new IObjectStringConverter()
			{
				public String convertObject(Object val, Object context)
				{
					Enum en = (Enum)val;
					String clazz = SReflect.getClassName(val.getClass());
					String name = en.name();
					return clazz+"="+name;
				}
			};
			TypeInfo ti_enum = new TypeInfo(new XMLInfo(new QName("typeinfo:java.lang", "Enum")), new ObjectInfo(Enum.class), new MappingInfo(null, new AttributeInfo[]{
				new AttributeInfo(new AccessInfo("content", AccessInfo.THIS), new AttributeConverter(null, enumconv))}));
			typeinfos.add(ti_enum);
			
			// Shortcut notations for simple array types
			
			// boolean/Boolean Array
			IObjectStringConverter booleanconv = new IObjectStringConverter()
			{
				public String convertObject(Object val, Object context)
				{
					boolean[] data = (boolean[])val;
					StringBuilder bul = new StringBuilder();
					for(int i=0; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy