package jadex.rules.state.io.xml; import jadex.commons.SReflect; import jadex.rules.state.IOAVState; import jadex.rules.state.OAVAttributeType; import jadex.rules.state.OAVJavaType; import jadex.rules.state.OAVObjectType; import jadex.xml.AttributeInfo; import jadex.xml.BasicTypeConverter; import jadex.xml.IContext; import jadex.xml.Namespace; import jadex.xml.ObjectInfo; import jadex.xml.SXML; import jadex.xml.writer.AbstractObjectWriterHandler; import jadex.xml.writer.WriteContext; import java.util.Collection; import java.util.LinkedHashSet; import java.util.Set; import javax.xml.namespace.QName; /** * OAV version for fetching write info for an object. */ public class OAVObjectWriterHandler extends AbstractObjectWriterHandler { //-------- constructors -------- /** * Create a new writer. */ public OAVObjectWriterHandler(Set typeinfos) { this(false, typeinfos); } /** * Create a new writer. */ public OAVObjectWriterHandler(boolean gentypetags, Set typeinfos) { this(gentypetags, false, typeinfos); } /** * Create a new writer. */ public OAVObjectWriterHandler(boolean gentypetags, boolean prefertags, Set typeinfos) { this(gentypetags, prefertags, true, typeinfos); } /** * Create a new writer. */ public OAVObjectWriterHandler(boolean gentypetags, boolean prefertags, boolean flattening ,Set typeinfos) { super(gentypetags, prefertags, flattening, typeinfos); } //-------- methods -------- /** * Get the object type * @param object The object. * @return The object type. */ public Object getObjectType(Object object, IContext context) { return ((IOAVState)context).getType(object); } /** * Get the tag name for an object. */ public QName getTagName(Object object, IContext context) { QName ret; IOAVState state = (IOAVState)context; if(state.containsObject(object)) { String typename = state.getType(object).getName(); ret = new QName(typename); } else { String clazzname = SReflect.getClassName(object.getClass()); Namespace ns; int idx = clazzname.lastIndexOf("."); String pck = SXML.PROTOCOL_TYPEINFO+clazzname.substring(0, idx); String tag = clazzname.substring(idx+1); WriteContext wc = (WriteContext)context; ns = wc.getNamespace(pck); ret = new QName(ns.getURI(), tag, ns.getPrefix()); } return ret; } /** * Get the tag with namespace. */ public QName getTagWithPrefix(QName tag, IContext context) { WriteContext wc = (WriteContext)context; Namespace ns = wc.getNamespace(tag.getNamespaceURI()); return new QName(ns.getURI(), tag.getLocalPart(), ns.getPrefix()); } // /** // * Get or create a namespace. // * @param uri The namespace uri. // */ // protected Namespace getNamespace(String uri) // { // Namespace ns = (Namespace)namespacebypackage.get(uri); // if(ns==null) // { // String prefix = "p"+nscnt; // ns = new Namespace(prefix, uri); // namespacebypackage.put(uri, ns); // nscnt++; // } // return ns; // } /** * Get a value from an object. */ protected Object getValue(Object object, Object attr, IContext context, Object info) { Object ret; try { OAVAttributeType attribute = (OAVAttributeType)attr; IOAVState state = (IOAVState)context; if(((OAVAttributeType)attr).getMultiplicity().equals(OAVAttributeType.NONE)) { ret = state.getAttributeValue(object, attribute); } else { ret = state.getAttributeValues(object, attribute); } } catch(Error e) { e.printStackTrace(); throw new RuntimeException(e); } return ret; } /** * Get the property. */ protected Object getProperty(Object info) { Object ret = null; if(info instanceof AttributeInfo) { ret = ((AttributeInfo)info).getAttributeIdentifier(); } else if(info instanceof OAVAttributeType) { ret = info; } else { throw new RuntimeException("Unknown property type: "+info); } return ret; } /** * Get the name of a property. * Cuts off all before "_has_" (hack?!). */ protected String getPropertyName(Object property) { String ret = ((OAVAttributeType)property).getName(); int idx = ret.indexOf("_has_"); if(idx!=-1) ret = ret.substring(idx+5); return ret; } /** * Test if a value is a basic type. */ protected boolean isBasicType(Object property, Object value) { OAVObjectType atype = ((OAVAttributeType)property).getType(); return atype instanceof OAVJavaType && BasicTypeConverter.isBuiltInType(((OAVJavaType)atype).getClazz()); } /** * Get the properties of an object. */ protected Collection getProperties(Object object, IContext context, boolean includefields) { Collection ret = new LinkedHashSet(); IOAVState state = (IOAVState)context; OAVObjectType type = state.getType(object); while(type!=null && !(type instanceof OAVJavaType)) { Collection props = type.getDeclaredAttributeTypes(); ret.addAll(props); type = type.getSupertype(); } return ret; } /** * Get the default value. */ protected Object getDefaultValue(Object property) { Object ret = null; if(property instanceof OAVAttributeType) ret = ((OAVAttributeType)property).getDefaultValue(); else ret = super.getDefaultValue(property); return ret; } /** * 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 && info.getTypeInfo() instanceof OAVObjectType) { OAVObjectType otype = (OAVObjectType)info.getTypeInfo(); ret = ((IOAVState)context).getType(object).isSubtype(otype); } 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) { OAVAttributeType attr = (OAVAttributeType)property; ret = value.getClass().equals(attr.getType()); } return ret; } }