com.espertech.esper.event.xml.SchemaUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of esper Show documentation
Show all versions of esper Show documentation
Complex event processing and event series analysis component
/*
***************************************************************************************
* Copyright (C) 2006 EsperTech, Inc. All rights reserved. *
* http://www.espertech.com/esper *
* http://www.espertech.com *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the GPL license *
* a copy of which has been included with this distribution in the license.txt file. *
***************************************************************************************
*/
package com.espertech.esper.event.xml;
import com.espertech.esper.client.EPException;
import com.espertech.esper.client.PropertyAccessException;
import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
import org.w3c.dom.*;
import javax.xml.namespace.QName;
import javax.xml.xpath.XPathConstants;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Array;
import java.util.HashMap;
import java.util.Map;
/**
* Utility class for querying schema information via Xerces implementation classes.
*
* @author pablo
*/
public class SchemaUtil {
private static Map typeMap;
static {
typeMap = new HashMap();
Object[][] types = new Object[][]{
{"nonPositiveInteger", Integer.class},
{"nonNegativeInteger", Integer.class},
{"negativeInteger", Integer.class},
{"positiveInteger", Integer.class},
{"long", Long.class},
{"unsignedLong", Long.class},
{"int", Integer.class},
{"unsignedInt", Integer.class},
{"decimal", Double.class},
{"integer", Integer.class},
{"float", Float.class},
{"double", Double.class},
{"string", String.class},
{"short", Short.class},
{"unsignedShort", Short.class},
{"byte", Byte.class},
{"unsignedByte", Byte.class},
{"boolean", Boolean.class},
{"dateTime", String.class},
{"date", String.class},
{"time", String.class}};
for (int i = 0; i < types.length; i++) {
typeMap.put(types[i][0].toString(), (Class) types[i][1]);
}
}
/**
* Returns the Class-type of the schema item.
*
* @param item to to determine type for
* @return type
*/
public static Class toReturnType(SchemaItem item) {
if (item instanceof SchemaItemAttribute) {
SchemaItemAttribute att = (SchemaItemAttribute) item;
return SchemaUtil.toReturnType(att.getXsSimpleType(), att.getTypeName(), null);
} else if (item instanceof SchemaElementSimple) {
SchemaElementSimple simple = (SchemaElementSimple) item;
Class returnType = SchemaUtil.toReturnType(simple.getXsSimpleType(), simple.getTypeName(), simple.getFractionDigits());
if (simple.isArray()) {
returnType = Array.newInstance(returnType, 0).getClass();
}
return returnType;
} else if (item instanceof SchemaElementComplex) {
SchemaElementComplex complex = (SchemaElementComplex) item;
if (complex.getOptionalSimpleType() != null) {
return SchemaUtil.toReturnType(complex.getOptionalSimpleType(), complex.getOptionalSimpleTypeName(), null);
}
if (complex.isArray()) {
return NodeList.class;
}
return Node.class;
} else {
throw new PropertyAccessException("Invalid schema return type:" + item);
}
}
/**
* Returns the type for a give short type and type name.
*
* @param xsType XSSimplyType type
* @param typeName type name in XML standard
* @param optionalFractionDigits fraction digits if any are defined
* @return equivalent native type
*/
public static Class toReturnType(short xsType, String typeName, Integer optionalFractionDigits) {
if (typeName != null) {
Class result = typeMap.get(typeName);
if (result != null) {
return result;
}
}
switch (xsType) {
case XSSimpleType.PRIMITIVE_BOOLEAN:
return Boolean.class;
case XSSimpleType.PRIMITIVE_STRING:
return String.class;
case XSSimpleType.PRIMITIVE_DECIMAL:
if ((optionalFractionDigits != null) && (optionalFractionDigits > 0)) {
return Double.class;
}
return Integer.class;
case XSSimpleType.PRIMITIVE_FLOAT:
return Float.class;
case XSSimpleType.PRIMITIVE_DOUBLE:
return Double.class;
default:
return String.class;
}
}
/**
* Returns the native type based on XPathConstants qname and an optional cast-to type, if provided.
*
* @param resultType qname
* @param optionalCastToType null or cast-to type
* @return return type
*/
public static Class toReturnType(QName resultType, Class optionalCastToType) {
if (optionalCastToType != null) {
return optionalCastToType;
}
if (resultType.equals(XPathConstants.NODESET))
return NodeList.class;
if (resultType.equals(XPathConstants.NODE))
return Node.class;
if (resultType.equals(XPathConstants.BOOLEAN))
return Boolean.class;
if (resultType.equals(XPathConstants.NUMBER))
return Double.class;
if (resultType.equals(XPathConstants.STRING))
return String.class;
return String.class;
}
/**
* Returns the XPathConstants type for a given Xerces type definition.
*
* @param type is the type
* @return XPathConstants type
*/
public static QName simpleTypeToQName(short type) {
switch (type) {
case XSSimpleType.PRIMITIVE_BOOLEAN:
return XPathConstants.BOOLEAN;
case XSSimpleType.PRIMITIVE_DOUBLE:
return XPathConstants.NUMBER;
case XSSimpleType.PRIMITIVE_STRING:
return XPathConstants.STRING;
case XSSimpleType.PRIMITIVE_DECIMAL:
return XPathConstants.NUMBER;
case XSSimpleType.PRIMITIVE_FLOAT:
return XPathConstants.NUMBER;
case XSSimpleType.PRIMITIVE_DATETIME:
return XPathConstants.STRING;
case XSSimpleType.PRIMITIVE_DATE:
return XPathConstants.STRING;
case XSSimpleType.PRIMITIVE_TIME:
return XPathConstants.STRING;
default:
throw new EPException("Unexpected schema simple type encountered '" + type + "'");
}
}
/**
* Returns the root element for a given schema given a root element name and namespace.
*
* @param schema is the schema to interrogate
* @param namespace is the namespace of the root element
* @param elementName is the name of the root element
* @return declaration of root element
*/
public static SchemaElementComplex findRootElement(SchemaModel schema, String namespace, String elementName) {
if ((namespace != null) && namespace.length() != 0) {
for (SchemaElementComplex complexElement : schema.getComponents()) {
if ((complexElement.getNamespace().equals(namespace)) && (complexElement.getName().equals(elementName))) {
return complexElement;
}
}
} else {
for (SchemaElementComplex complexElement : schema.getComponents()) {
if (complexElement.getName().equals(elementName)) {
return complexElement;
}
}
}
if (elementName.startsWith("//")) {
elementName = elementName.substring(2);
for (SchemaElementComplex complexElement : schema.getComponents()) {
SchemaElementComplex match = recursiveDeepMatch(complexElement, namespace, elementName);
if (match != null) {
return match;
}
}
}
String text = "Could not find root element declaration in schema for element name '" + elementName + '\'';
if (namespace != null) {
text = text + " in namespace '" + namespace + '\'';
}
throw new EPException(text);
}
private static SchemaElementComplex recursiveDeepMatch(SchemaElementComplex parent, String namespace, String elementName) {
if ((namespace != null) && namespace.length() != 0) {
for (SchemaElementComplex complexElement : parent.getChildren()) {
if ((complexElement.getNamespace().equals(namespace)) && (complexElement.getName().equals(elementName))) {
return complexElement;
}
}
} else {
for (SchemaElementComplex complexElement : parent.getChildren()) {
if (complexElement.getName().equals(elementName)) {
return complexElement;
}
}
}
for (SchemaElementComplex complexElement : parent.getChildren()) {
SchemaElementComplex found = recursiveDeepMatch(complexElement, namespace, elementName);
if (found != null) {
return found;
}
}
return null;
}
/**
* Finds an apropiate definition for the given property, starting at the * given definition.
* First look if the property es an attribute. If not, look at simple and then child element
* definitions.
*
* @param def the definition to start looking
* @param property the property to look for
* @return schema element or null if not found
*/
public static SchemaItem findPropertyMapping(SchemaElementComplex def, String property) {
for (SchemaItemAttribute attribute : def.getAttributes()) {
if (attribute.getName().equals(property)) {
return attribute;
}
}
for (SchemaElementSimple simple : def.getSimpleElements()) {
if (simple.getName().equals(property)) {
return simple;
}
}
for (SchemaElementComplex complex : def.getChildren()) {
if (complex.getName().equals(property)) {
return complex;
}
}
//property not found in schema
return null;
}
/**
* Serialize the given node.
*
* @param doc node to serialize
* @return serialized node string
*/
public static String serialize(Node doc) {
StringWriter writer = new StringWriter();
try {
serializeNode(doc, "", writer);
} catch (IOException e) {
throw new RuntimeException(e);
}
writer.flush();
return writer.toString();
}
private static void serializeNode(Node node, String
indentLevel, StringWriter writer) throws IOException {
switch (node.getNodeType()) {
case Node.DOCUMENT_NODE:
Document doc = (Document) node;
writer.write("\n");
NodeList nodes = node.getChildNodes();
if (nodes != null) {
for (int i = 0; i < nodes.getLength(); i++) {
serializeNode(nodes.item(i), "", writer);
}
}
break;
case Node.ELEMENT_NODE:
String name = node.getNodeName();
writer.write(indentLevel + "<" + name);
NamedNodeMap attributes = node.getAttributes();
for (int i = 0; i < attributes.getLength(); i++) {
Node current = attributes.item(i);
writer.write(" " + current.getNodeName() + "=\"");
print(current.getNodeValue(), writer);
writer.write("\"");
}
writer.write(">");
NodeList children = node.getChildNodes();
if (children != null) {
if ((children.item(0) != null) && (children.item(0).getNodeType() == Node.ELEMENT_NODE)) {
writer.write("\n");
}
for (int i = 0; i < children.getLength(); i++) {
serializeNode(children.item(i), indentLevel, writer);
}
if ((children.item(0) != null)
&& (children.item(children.getLength() - 1).getNodeType() == Node.ELEMENT_NODE)) {
writer.write(indentLevel);
}
}
writer.write("" + name + ">\n");
break;
case Node.TEXT_NODE:
print(node.getNodeValue(), writer);
break;
case Node.CDATA_SECTION_NODE:
writer.write("CDATA");
print(node.getNodeValue(), writer);
writer.write("");
break;
case Node.COMMENT_NODE:
writer.write(indentLevel + "\n");
break;
case Node.PROCESSING_INSTRUCTION_NODE:
writer.write("" + node.getNodeName() + " " + node.getNodeValue() + "?>\n");
break;
case Node.ENTITY_REFERENCE_NODE:
writer.write("&" + node.getNodeName() + ";");
break;
case Node.DOCUMENT_TYPE_NODE:
DocumentType docType = (DocumentType) node;
String publicId = docType.getPublicId();
String systemId = docType.getSystemId();
String internalSubset = docType.getInternalSubset();
writer.write("\n");
break;
default:
break;
}
}
private static void print(String s, Writer writer) throws IOException {
if (s == null) {
return;
}
for (int i = 0, len = s.length(); i < len; i++) {
char c = s.charAt(i);
switch (c) {
case '<':
writer.write("<");
break;
case '>':
writer.write(">");
break;
case '&':
writer.write("&");
break;
case '\r':
writer.write("
");
break;
default:
writer.write(c);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy