jadex.xml.bean.BeanObjectWriterHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jadex-serialization-xml Show documentation
Show all versions of jadex-serialization-xml Show documentation
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.
package jadex.xml.bean;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import jadex.commons.SAccess;
import jadex.commons.IFilter;
import jadex.commons.SReflect;
import jadex.commons.SUtil;
import jadex.commons.transformation.BasicTypeConverter;
import jadex.commons.transformation.BeanIntrospectorFactory;
import jadex.commons.transformation.STransformation;
import jadex.commons.transformation.annotations.Classname;
import jadex.commons.transformation.traverser.BeanProperty;
import jadex.commons.transformation.traverser.IBeanIntrospector;
import jadex.xml.AccessInfo;
import jadex.xml.AttributeInfo;
import jadex.xml.IAttributeConverter;
import jadex.xml.IContext;
import jadex.xml.IPreProcessor;
import jadex.xml.ISubObjectConverter;
import jadex.xml.Namespace;
import jadex.xml.ObjectInfo;
import jadex.xml.SXML;
import jadex.xml.SubobjectInfo;
import jadex.xml.TypeInfo;
import jadex.xml.stax.QName;
import jadex.xml.writer.AWriteContext;
import jadex.xml.writer.AbstractObjectWriterHandler;
/**
* Java bean version for fetching write info for an object.
*/
public class BeanObjectWriterHandler extends AbstractObjectWriterHandler
{
//-------- attributes --------
/** The bean introspector (also scans for public fields). */
protected IBeanIntrospector introspector = BeanIntrospectorFactory.getInstance().getBeanIntrospector();
/** The namespaces by package. */
// protected Map namespacebypackage = new HashMap();
// protected int nscnt;
/** No type infos. */
protected Set> no_typeinfos;
/** The filter based post processors. */
protected Map, IPreProcessor> preprocessors;
//-------- constructors --------
/**
* Create a new writer (gentypetags=false, prefertags=true, flattening=true).
*/
public BeanObjectWriterHandler(Set typeinfos)
{
this(typeinfos, false);
}
/**
* Create a new writer (prefertags=true, flattening=true).
*/
public BeanObjectWriterHandler(Set typeinfos, boolean gentypetags)
{
this(typeinfos, gentypetags, false);
}
/**
* Create a new writer (flattening=true).
*/
public BeanObjectWriterHandler(Set typeinfos, boolean gentypetags, boolean prefertags)
{
this(typeinfos, gentypetags, prefertags, true);
}
/**
* Create a new writer.
*/
public BeanObjectWriterHandler(Set typeinfos, boolean gentypetags, boolean prefertags ,boolean flattening)
{
super(gentypetags, prefertags, flattening, typeinfos);
this.no_typeinfos = Collections.synchronizedSet(new HashSet());
}
//-------- methods --------
/**
* Get the most specific mapping info.
* @param tag The tag.
* @param fullpath The full path.
* @return The most specific mapping info.
*/
public synchronized TypeInfo getTypeInfo(Object object, QName[] fullpath, IContext context)
{
Object type = getObjectType(object, context);
if(no_typeinfos.contains(type))
return null;
TypeInfo ret = super.getTypeInfo(object, fullpath, context);
// Hack! due to HashMap.Entry is not visible as class
if(ret==null)
{
if(type instanceof Class)
{
// Try if interface or supertype is registered
List> tocheck = new ArrayList>();
tocheck.add((Class>)type);
for(int i=0; i clazz = (Class>)tocheck.get(i);
// Set tis = getTypeInfoManager().getTypeInfosByType(clazz);
// ret = getTypeInfoManager().findTypeInfo(tis, fullpath);
ret = getTypeInfoManager().getTypeInfo(clazz, fullpath);
// Set tis = getTypeInfoManager().getTypeInfosByType(clazz);
// if(tis.size()==1)
// ret = (TypeInfo)tis.iterator().next();
if(ret==null)
{
Class>[] interfaces = clazz.getInterfaces();
for(int j=0; j)type).isArray())
{
// System.out.println("array: "+type);
// ret = getTypeInfoManager().findTypeInfo(getTypeInfoManager().getTypeInfosByType(Object[].class), fullpath);
ret = getTypeInfoManager().getTypeInfo(Object[].class, fullpath);
}
// Add concrete class for same info if it is used
if(ret!=null)
{
ObjectInfo cri =ret.getObjectInfo();
ObjectInfo cricpy = cri!=null? new ObjectInfo(type, cri.getPostProcessor()): new ObjectInfo(type);
TypeInfo ti = new TypeInfo(ret.getXMLInfo(),
cricpy, ret.getMappingInfo(), ret.getLinkInfo());
getTypeInfoManager().addTypeInfo(ti);
}
else
{
// if(no_typeinfos==null)
// no_typeinfos = new HashSet();
no_typeinfos.add((Class>)type);
}
}
}
return ret;
}
/**
* Get the object type
* @param object The object.
* @return The object type.
*/
public Object getObjectType(Object object, IContext context)
{
return object.getClass();
}
/**
* Get the tag name for an object.
*/
public QName getTagName(Object object, IContext context)
{
// try
// {
String pck;
String tag;
if(object!=null)
{
Class> clazz = object.getClass();
String clazzname = STransformation.registerClass(clazz);
// if(clazzname.indexOf("IRemoteMessageListener")!=-1)
// {
// System.out.println("sdilfugkl");
// }
int idx = clazzname.lastIndexOf(".");
pck = idx!=-1? SXML.PROTOCOL_TYPEINFO+clazzname.substring(0, idx): SXML.PROTOCOL_TYPEINFO;
tag = idx!=-1? clazzname.substring(idx+1): clazzname;
// Special case inner class, replace $ with -
tag = tag.replace("$", "-");
// Special case array, replace [] with __ and length
if(clazz.isArray())
{
int dim = SUtil.getArrayDimension(object);
tag = tag.substring(0, tag.indexOf("["))+"__"+dim;//+"__"+Array.getLength(object);
// for(int i=0; i getProperties(Object object, IContext context, boolean includemethods, boolean includefields)
{
return object==null? Collections.EMPTY_LIST: introspector.getBeanProperties(object.getClass(), includemethods, includefields).values();
}
/**
* Find a get method with some prefix.
* @param object The object.
* @param name The name.
* @param prefixes The prefixes to test.
*/
protected Method findGetMethod(Object object, String name, String[] prefixes)
{
Method method = null;
for(int i=0; i clazz = object.getClass();
method = SReflect.getExportedMethod(clazz, methodname, new Class[0]);
}
catch(Exception e)
{
// nop
}
}
// if(method==null)
// throw new RuntimeException("No getter found for: "+name);
return method;
}
/**
* Test if a value is compatible with the defined typeinfo.
*/
protected boolean isTypeCompatible(Object object, ObjectInfo info, IContext context)
{
boolean ret = true;
if(info!=null && object!=null && info.getTypeInfo() instanceof Class)
{
Class> clazz = (Class>)info.getTypeInfo();
ret = clazz.isAssignableFrom(object.getClass());
}
return ret;
}
/**
* Test if a value is decodable to the same type.
* Works for basic (final) types only and checks if the
* two types are of same class.
*/
protected boolean isDecodableToSameType(Object property, Object value, IContext context)
{
boolean ret = true;
if(value!=null)
{
ret = false;
if(property instanceof BeanProperty)
{
BeanProperty prop = (BeanProperty)property;
// Do not allow strings -> avoids strings being written as attributes by default.
ret = !(value instanceof String) && value.getClass().equals(SReflect.getWrappedType(prop.getSetterType()));
}
else if(property instanceof Classname)
{
// Allow XML class name as attribute
ret = true;
}
}
return ret;
}
/**
* Get the pre-processor.
* @return The pre-processor
*/
public synchronized IPreProcessor[] getPreProcessors(Object object, Object typeinfo)
{
List ret = new ArrayList();
IPreProcessor tiproc = typeinfo instanceof TypeInfo? ((TypeInfo)typeinfo).getPreProcessor(): null;
if(tiproc!=null)
ret.add(tiproc);
if(preprocessors!=null)
{
for(Iterator> it = preprocessors.keySet().iterator(); it.hasNext(); )
{
IFilter
© 2015 - 2025 Weber Informatics LLC | Privacy Policy