com.googlecode.mjorm.XmlObjectDescriptorParser Maven / Gradle / Ivy
package com.googlecode.mjorm;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.bson.types.ObjectId;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import com.googlecode.mjorm.convert.JavaType;
/**
* Parses XML Object descriptor files and returns
* {@link ObjectDescriptor}s contained within the file.
*/
public class XmlObjectDescriptorParser {
private XPath xpath;
private DocumentBuilder builder;
/**
* Adds the given document configuration.
* @param file the {@link File}
* @throws IOException on error
* @throws ParserConfigurationException on error
* @throws SAXException on error
* @throws XPathExpressionException on error
* @return a {@link List} of {@link ObjectDescriptor}s
* @throws ClassNotFoundException on error
*/
public List parseDocument(File file)
throws IOException,
ParserConfigurationException,
SAXException,
XPathExpressionException,
ClassNotFoundException {
return parseDocument(new FileInputStream(file));
}
/**
* Adds the given document configuration.
* @param inputStream the {@link InputStream}
* @throws IOException on error
* @throws ParserConfigurationException on error
* @throws SAXException on error
* @throws XPathExpressionException on error
* @return a {@link List} of {@link ObjectDescriptor}s
* @throws ClassNotFoundException on error
*/
public List parseDocument(InputStream inputStream)
throws IOException,
ParserConfigurationException,
SAXException,
XPathExpressionException,
ClassNotFoundException {
if (builder==null) {
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
}
return parseDocument(builder.parse(inputStream));
}
/**
* Adds the given document configuration.
* @param doc the document
* @throws XPathExpressionException on error
* @throws ClassNotFoundException on error
* @return a {@link List} of {@link ObjectDescriptor}s
*/
public List parseDocument(Document doc)
throws XPathExpressionException,
ClassNotFoundException {
if (xpath==null) {
xpath = XPathFactory.newInstance().newXPath();
}
// create return list
List ret = new ArrayList();
// get descriptor elements
NodeList descriptorEls = (NodeList)xpath.evaluate(
"/descriptors/object", doc, XPathConstants.NODESET);
// loop through each element
for (int i=0; i descriptors)
throws XPathExpressionException,
ClassNotFoundException {
// create a descriptor
ObjectDescriptor descriptor = new ObjectDescriptor();
// get descriptor properties
Class> objClass = Class.forName(descriptorEl.getAttribute("class"));
String discriminatorName = descriptorEl.hasAttribute("discriminator-name")
? descriptorEl.getAttribute("discriminator-name") : null;
String discriminatorType = descriptorEl.hasAttribute("discriminator-type")
? descriptorEl.getAttribute("discriminator-type") : null;
// populate the descriptor
descriptor.setType(objClass);
descriptor.setDiscriminatorName(discriminatorName);
descriptor.setDiscriminatorType(discriminatorType);
// get properties
NodeList propertyEls = (NodeList)xpath.evaluate(
"./property", descriptorEl, XPathConstants.NODESET);
boolean foundIdentifier = false;
for (int i=0; i valueGenerator = null;
if (propertyEl.hasAttribute("auto")) {
propIsAutoGen = true;
String value = propertyEl.getAttribute("auto");
if (value.toLowerCase().trim().equals("true")) {
valueGenerator = ObjectIdValueGenerator.INSTANCE;
storageType = ObjectId.class;
} else {
try {
valueGenerator = ValueGenerator.class.cast(
Class.forName(value).newInstance());
} catch(Exception e) {
throw new IllegalArgumentException(
"Unable to create ValueGenerator for "+value, e);
}
}
}
// get property field
String propField = propertyEl.hasAttribute("field")
? propertyEl.getAttribute("field") : null;
if (propField==null && propertyEl.hasAttribute("column")) { // backwards compatibility
propField = propertyEl.getAttribute("column");
}
if (propField==null) {
propField = propIsIdentifier ? "_id" : propName;
}
// find the getter and setter.
Method propSetter = ReflectionUtil.findSetter(objClass, propName);
Method propGetter = ReflectionUtil.findGetter(objClass, propName);
if (propGetter==null || propSetter==null) {
throw new IllegalArgumentException(
"Unable to find getter or setter named "+propName+" for: "+objClass);
}
// make sure we have the type and get
// the generic type if there is one
if (propIsIdentifier && !foundIdentifier) {
foundIdentifier = true;
} else if (propIsIdentifier && foundIdentifier) {
throw new IllegalArgumentException(
"Two identifiers found for: "+objClass);
}
// get parameter types
NodeList parameterTypeEls = (NodeList)xpath.evaluate(
"./type-param", propertyEl, XPathConstants.NODESET);
Class>[] genericParameterTypes = new Class>[parameterTypeEls.getLength()];
for (int k=0; k hints = new HashMap();
for (int k=0; k