
com.revolsys.gis.esri.gdb.xml.model.EsriGdbXmlSerializer Maven / Gradle / Ivy
The newest version!
package com.revolsys.gis.esri.gdb.xml.model;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.namespace.QName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.revolsys.gis.esri.gdb.xml.EsriGeodatabaseXmlConstants;
import com.revolsys.util.CaseConverter;
import com.revolsys.util.JavaBeanUtil;
import com.revolsys.xml.XmlConstants;
import com.revolsys.xml.XsiConstants;
import com.revolsys.xml.io.XmlWriter;
public class EsriGdbXmlSerializer implements EsriGeodatabaseXmlConstants {
private static final Logger LOG = LoggerFactory.getLogger(EsriGdbXmlSerializer.class);
public static String toString(final Object object) {
final StringWriter writer = new StringWriter();
final EsriGdbXmlSerializer serializer = new EsriGdbXmlSerializer(null,
writer);
serializer.serialize(object);
writer.flush();
return writer.toString();
}
private final Map, Set> classPropertyTagNamesMap = new HashMap, Set>();
private final Map, QName> classTagNameMap = new HashMap, QName>();
private final Map, QName> classXsiTagNameMap = new HashMap, QName>();
private final Map tagNameXsiTagNameMap = new HashMap();
private final Map tagNameChildTagNameMap = new HashMap();
private final Map tagNameListElementTagNameMap = new HashMap();
private final Map, Map> classPropertyMethodMap = new HashMap, Map>();
private XmlWriter out;
private boolean writeNamespaces;
private boolean writeFirstNamespace;
private boolean writeNull;
private final Map, QName> classTypeNameMap = new LinkedHashMap, QName>();
private final Set xsiTypeTypeNames = new HashSet();
private EsriGdbXmlSerializer() {
addTagNameXsiTagName(METADATA, XML_PROPERTY_SET);
addTagNameChildTagName(METADATA, XML_DOC);
addClassProperties(SpatialReference.class, SPATIAL_REFERENCE, null, WKT,
X_ORIGIN, Y_ORIGIN, XY_SCALE, Z_ORIGIN, Z_SCALE, M_ORIGIN, M_SCALE,
XY_TOLERANCE, Z_TOLERANCE, M_TOLERANCE, HIGH_PRECISION, WKID);
addClassProperties(GeographicCoordinateSystem.class, SPATIAL_REFERENCE,
GEOGRAPHIC_COORDINATE_SYSTEM);
addClassProperties(ProjectedCoordinateSystem.class, SPATIAL_REFERENCE,
PROJECTED_COORDINATE_SYSTEM);
addClassProperties(GeometryDef.class, GEOMETRY_DEF, GEOMETRY_DEF,
AVG_NUM_POINTS, GEOMETRY_TYPE, HAS_M, HAS_Z, SPATIAL_REFERENCE,
GRID_SIZE_0, GRID_SIZE_1, GRID_SIZE_2);
addClassProperties(Domain.class, DOMAIN, null, DOMAIN_NAME, FIELD_TYPE,
MERGE_POLICY, SPLIT_POLICY, DESCRIPTION, OWNER, CODED_VALUES);
addClassProperties(CodedValueDomain.class, DOMAIN, CODED_VALUE_DOMAIN);
addTagNameXsiTagName(CODED_VALUES, ARRAY_OF_CODED_VALUE);
addClassProperties(CodedValue.class, CODED_VALUE, CODED_VALUE, NAME, CODE);
addClassProperties(Field.class, FIELD, FIELD, NAME, TYPE, IS_NULLABLE,
LENGTH, PRECISION, SCALE, REQUIRED, EDIATBLE, DOMAIN_FIXED, GEOMETRY_DEF,
ALIAS_NAME, MODEL_NAME, DEFAULT_VALUE, DOMAIN);
addTagNameXsiTagName(FIELD_ARRAY, ARRAY_OF_FIELD);
addTagNameXsiTagName(FIELDS, FIELDS);
addTagNameChildTagName(FIELDS, FIELD_ARRAY);
addClassProperties(Index.class, INDEX, INDEX, NAME, IS_UNIQUE,
IS_ASCENDING, FIELDS);
addTagNameXsiTagName(INDEX_ARRAY, ARRAY_OF_INDEX);
addTagNameXsiTagName(INDEXES, INDEXES);
addTagNameChildTagName(INDEXES, INDEX_ARRAY);
addClassProperties(PropertySetProperty.class, PROPERTY_SET_PROPERTY, null,
KEY, VALUE);
addTagNameXsiTagName(PROPERTY_ARRAY, ARRAY_OF_PROPERTY_SET_PROPERTY);
addTagNameXsiTagName(EXTENSION_PROPERTIES, PROPERTY_SET);
addTagNameChildTagName(EXTENSION_PROPERTIES, PROPERTY_ARRAY);
addTagNameListElementTagName(RELATIONSHIP_CLASS_NAMES, NAME);
addTagNameXsiTagName(RELATIONSHIP_CLASS_NAMES, NAMES);
addTagNameListElementTagName(SUBTYPES, SUBTYPE);
addClassProperties(Subtype.class, SUBTYPE, null, SUBTYPE_NAME,
SUBTYPE_CODE, FIELD_INFOS);
addClassProperties(SubtypeFieldInfo.class, SUBTYPE_FIELD_INFO, null,
FIELD_NAME, DOMAIN_NAME, DEFAULT_VALUE);
addClassProperties(EnvelopeN.class, ENVELOPE, ENVELOPE_N, X_MIN, Y_MIN,
X_MAX, Y_MAX, Z_MIN, Z_MAX, M_MIN, M_MAX, SPATIAL_REFERENCE);
addTagNameXsiTagName(CONTROLLER_MEMBERSHIPS, ARRAY_OF_CONTROLLER_MEMBERSHIP);
addClassProperties(DataElement.class, DATA_ELEMENT, DATA_ELEMENT,
CATALOG_PATH, NAME, CHILDREN_EXPANDED, FULL_PROPS_RETRIEVED,
METADATA_RETRIEVED, METADATA, CHILDREN);
addClassProperties(DEDataset.class, DATA_ELEMENT, DE_DATASET, DATASET_TYPE,
DSID, VERSIONED, CAN_VERSION, CONFIGURATION_KEYWORD);
addClassProperties(DEGeoDataset.class, DATA_ELEMENT, DE_GEO_DATASET,
EXTENT, SPATIAL_REFERENCE);
addClassProperties(DEFeatureDataset.class, DATA_ELEMENT,
DE_FEATURE_DATASET, EXTENT, SPATIAL_REFERENCE);
addClassProperties(DETable.class, DATA_ELEMENT, DE_TABLE, HAS_OID,
OBJECT_ID_FIELD_NAME, FIELDS, INDEXES, CLSID, EXTCLSID,
RELATIONSHIP_CLASS_NAMES, ALIAS_NAME, MODEL_NAME, HAS_GLOBAL_ID,
GLOBAL_ID_FIELD_NAME, RASTER_FIELD_NAME, EXTENSION_PROPERTIES,
SUBTYPE_FIELD_NAME, DEFAULT_SUBTYPE_CODE, SUBTYPES,
CONTROLLER_MEMBERSHIPS);
addClassProperties(DEFeatureClass.class, DATA_ELEMENT, DE_FEATURE_CLASS,
FEATURE_TYPE, SHAPE_TYPE, SHAPE_FIELD_NAME, HAS_M, HAS_Z,
HAS_SPATIAL_INDEX, AREA_FIELD_NAME, LENGTH_FIELD_NAME, EXTENT,
SPATIAL_REFERENCE);
addTagNameXsiTagName(DATASET_DEFINITIONS, ARRAY_OF_DATA_ELEMENT);
addTagNameXsiTagName(DOMAINS, ARRAY_OF_DOMAIN);
addClassProperties(WorkspaceDefinition.class, WORKSPACE_DEFINITION,
WORKSPACE_DEFINITION, WORKSPACE_TYPE, VERSION, DOMAINS,
DATASET_DEFINITIONS, METADATA);
addTagNameListElementTagName(WORKSPACE_DATA, DATASET_DATA);
addTagNameXsiTagName(WORKSPACE_DATA, WORKSPACE_DATA);
addClassProperties(Workspace.class, WORKSPACE, null, WORKSPACE_DEFINITION,
WORKSPACE_DATA);
classTypeNameMap.put(Byte.class, XmlConstants.XS_BYTE);
classTypeNameMap.put(Short.class, XmlConstants.XS_SHORT);
classTypeNameMap.put(Integer.class, XmlConstants.XS_INT);
classTypeNameMap.put(Float.class, XmlConstants.XS_FLOAT);
classTypeNameMap.put(Double.class, XmlConstants.XS_DOUBLE);
classTypeNameMap.put(Double.class, XmlConstants.XS_STRING);
xsiTypeTypeNames.add(CODE);
}
public EsriGdbXmlSerializer(final String esriNamespaceUri, final Writer out) {
this(out);
if (esriNamespaceUri != null) {
this.out.setNamespaceAlias(_NAMESPACE_URI, esriNamespaceUri);
}
}
public EsriGdbXmlSerializer(final Writer out) {
this();
this.out = new XmlWriter(out);
this.out.setIndent(true);
this.out.startDocument("UTF-8");
this.out.setPrefix(XmlConstants.XML_SCHEMA);
this.out.setPrefix(XsiConstants.TYPE);
writeNamespaces = false;
writeFirstNamespace = true;
}
private void addClassProperties(final Class> objectClass,
final QName tagName, final QName xsiTagName,
final Collection propertyNames) {
classTagNameMap.put(objectClass, tagName);
addClassXsiTagName(objectClass, xsiTagName);
final Set allPropertyNames = new LinkedHashSet();
addSuperclassPropertyNames(allPropertyNames, objectClass.getSuperclass());
allPropertyNames.addAll(propertyNames);
classPropertyTagNamesMap.put(objectClass, allPropertyNames);
}
private void addClassProperties(final Class> objectClass,
final QName tagName, final QName xsiTagName, final QName... propertyNames) {
addClassProperties(objectClass, tagName, xsiTagName,
Arrays.asList(propertyNames));
}
protected void addClassPropertyMethod(final Class> objectClass,
final QName propertyName, final String methodName) {
Map classMethods = classPropertyMethodMap.get(objectClass);
if (classMethods == null) {
classMethods = new HashMap();
classPropertyMethodMap.put(objectClass, classMethods);
}
final Method method = JavaBeanUtil.getMethod(EsriGdbXmlSerializer.class,
methodName, Object.class);
classMethods.put(propertyName, method);
}
private void addClassXsiTagName(final Class> objectClass,
final QName tagName) {
if (tagName != null) {
classXsiTagNameMap.put(objectClass, tagName);
}
}
private void addSuperclassPropertyNames(final Set allPropertyNames,
final Class> objectClass) {
if (!objectClass.equals(Object.class)) {
addSuperclassPropertyNames(allPropertyNames, objectClass.getSuperclass());
final Set propertyNames = classPropertyTagNamesMap.get(objectClass);
if (propertyNames != null) {
allPropertyNames.addAll(propertyNames);
}
}
}
private void addTagNameChildTagName(final QName tagName,
final QName xsiTagName) {
tagNameChildTagNameMap.put(tagName, xsiTagName);
}
private void addTagNameListElementTagName(final QName tagName,
final QName xsiTagName) {
tagNameListElementTagNameMap.put(tagName, xsiTagName);
}
private void addTagNameXsiTagName(final QName tagName, final QName xsiTagName) {
tagNameXsiTagNameMap.put(tagName, xsiTagName);
}
public void close() {
out.flush();
out.close();
}
private void endTag(final QName tagName) {
final QName childTagName = tagNameChildTagNameMap.get(tagName);
if (childTagName != null) {
endTag(childTagName);
}
out.endTag();
}
private Method getClassPropertyMethod(final Class> objectClass,
final QName propertyName) {
final Map propertyMethodMap = classPropertyMethodMap.get(objectClass);
if (propertyMethodMap == null) {
return null;
} else {
return propertyMethodMap.get(propertyName);
}
}
public void serialize(final Object object) {
final Class extends Object> objectClass = object.getClass();
QName tagName = classTagNameMap.get(objectClass);
if (tagName == null) {
final Package classPackage = objectClass.getPackage();
final String packageName = classPackage.getName();
final String className = objectClass.getSimpleName();
tagName = new QName(packageName, className);
}
if (!startTag(tagName)) {
writeXsiTypeAttribute(tagName, objectClass);
}
serializeObjectProperties(tagName, object);
endTag(tagName);
}
@SuppressWarnings("rawtypes")
private void serializeObjectProperties(final QName tagName,
final Object object) {
if (object != null) {
final Class extends Object> objectClass = object.getClass();
final Collection propertyTagNames = classPropertyTagNamesMap.get(objectClass);
if (propertyTagNames == null) {
if (object instanceof List) {
final Collection list = (Collection)object;
if (list.isEmpty()) {
out.closeStartTag();
out.setElementHasContent();
} else {
final QName listElementTagName = tagNameListElementTagNameMap.get(tagName);
if (listElementTagName == null) {
for (final Object value : list) {
serialize(value);
}
} else {
for (final Object value : list) {
if (!startTag(listElementTagName)) {
writeXsiTypeAttribute(listElementTagName, value);
}
serializeObjectProperties(listElementTagName, value);
endTag(listElementTagName);
}
}
}
} else {
out.text(object);
}
} else {
for (final QName propertyTagName : propertyTagNames) {
String proptertyName = propertyTagName.getLocalPart();
if (proptertyName.length() > 1
&& Character.isLowerCase(proptertyName.charAt(1))) {
proptertyName = CaseConverter.toLowerFirstChar(proptertyName);
}
final Object value = JavaBeanUtil.getProperty(object, proptertyName);
if (writeNull || value != null) {
final Method method = getClassPropertyMethod(objectClass,
propertyTagName);
if (method == null) {
if (!startTag(propertyTagName)) {
writeXsiTypeAttribute(propertyTagName, value);
}
serializeObjectProperties(propertyTagName, value);
endTag(propertyTagName);
} else {
JavaBeanUtil.invokeMethod(method, this, value);
}
}
}
}
}
}
private boolean startTag(final QName tagName) {
if (writeNamespaces || writeFirstNamespace) {
out.startTag(tagName);
writeFirstNamespace = false;
} else {
out.startTag(null, tagName.getLocalPart());
}
final QName xsiTagName = tagNameXsiTagNameMap.get(tagName);
boolean hasXsi = false;
if (xsiTagName != null) {
out.xsiTypeAttribute(xsiTagName);
hasXsi = true;
}
final QName childTagName = tagNameChildTagNameMap.get(tagName);
if (childTagName != null) {
startTag(childTagName);
}
return hasXsi;
}
private void writeXsiTypeAttribute(final QName tagName,
final Class extends Object> objectClass) {
QName xsiTagName = classXsiTagNameMap.get(objectClass);
if (xsiTagName == null) {
if (xsiTypeTypeNames.contains(tagName)) {
xsiTagName = classTypeNameMap.get(objectClass);
if (xsiTagName == null) {
LOG.error("No xsi:type configuration for class " + objectClass);
}
}
}
if (xsiTagName != null) {
out.xsiTypeAttribute(xsiTagName);
}
}
private void writeXsiTypeAttribute(final QName tagName, final Object value) {
if (value != null) {
final Class> valueClass = value.getClass();
writeXsiTypeAttribute(tagName, valueClass);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy