com.buschmais.xo.impl.bootstrap.XOUnitFactory Maven / Gradle / Ivy
The newest version!
package com.buschmais.xo.impl.bootstrap;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.*;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import com.buschmais.xo.api.ConcurrencyMode;
import com.buschmais.xo.api.Transaction;
import com.buschmais.xo.api.ValidationMode;
import com.buschmais.xo.api.XOException;
import com.buschmais.xo.api.bootstrap.XOUnit;
import com.buschmais.xo.impl.schema.v1.*;
import com.buschmais.xo.spi.bootstrap.XODatastoreProvider;
import com.buschmais.xo.spi.reflection.ClassHelper;
import org.xml.sax.SAXException;
public class XOUnitFactory {
private static final XOUnitFactory instance = new XOUnitFactory();
private final JAXBContext xoContext;
private final Schema xoXsd;
private XOUnitFactory() {
try {
xoContext = JAXBContext.newInstance(ObjectFactory.class);
SchemaFactory xsdFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
xoXsd = xsdFactory.newSchema(new StreamSource(XOUnitFactory.class.getResourceAsStream("/META-INF/xsd/xo-1.0.xsd")));
} catch (JAXBException e) {
throw new XOException("Cannot create JAXBContext for reading xo.xml descriptors.", e);
} catch (SAXException e) {
throw new XOException("Cannot create Schema for validation of xo.xml descriptors.", e);
}
}
public static XOUnitFactory getInstance() {
return instance;
}
public List getXOUnits(URL url) throws IOException {
Xo xo = readXODescriptor(url, xoXsd);
return getXOUnits(xo);
}
private Xo readXODescriptor(URL url, Schema xoXsd) throws IOException {
try (InputStream is = url.openStream()) {
try {
Unmarshaller unmarshaller = xoContext.createUnmarshaller();
XOUnitValidationHandler validationHandler = new XOUnitValidationHandler();
unmarshaller.setSchema(xoXsd);
unmarshaller.setEventHandler(validationHandler);
Xo xoXmlContent = unmarshaller.unmarshal(new StreamSource(is), Xo.class)
.getValue();
if (validationHandler.isValid()) {
return xoXmlContent;
} else {
throw new XOException("Invalid xo.xml descriptor detected: " + validationHandler.getValidationMessages());
}
} catch (JAXBException e) {
throw new XOException("Cannot create JAXB unmarshaller for reading xo.xml descriptors.", e);
}
}
}
private List getXOUnits(Xo xo) {
List xoUnits = new LinkedList<>();
for (XOUnitType xoUnitType : xo.getXoUnit()) {
String name = xoUnitType.getName();
String description = xoUnitType.getDescription();
String urlName = xoUnitType.getUrl();
URI uri;
try {
uri = new URI(urlName);
} catch (URISyntaxException e) {
throw new XOException("Cannot convert '" + urlName + "' to url.", e);
}
String providerName = xoUnitType.getProvider();
Class extends XODatastoreProvider> provider = ClassHelper.getType(providerName);
Set> types = new HashSet<>();
for (String typeName : xoUnitType.getTypes()
.getType()) {
types.add(ClassHelper.getType(typeName));
}
List> instanceListeners = new ArrayList<>();
InstanceListenersType instanceListenersType = xoUnitType.getInstanceListeners();
if (instanceListenersType != null) {
for (String instanceListenerName : instanceListenersType.getInstanceListener()) {
instanceListeners.add(ClassHelper.getType(instanceListenerName));
}
}
ValidationMode validationMode = getValidationMode(xoUnitType.getValidationMode());
ConcurrencyMode concurrencyMode = getConcurrencyMode(xoUnitType.getConcurrencyMode());
Transaction.TransactionAttribute defaultTransactionAttribute = getTransactionAttribute(xoUnitType.getDefaultTransactionAttribute());
Properties properties = new Properties();
PropertiesType propertiesType = xoUnitType.getProperties();
if (propertiesType != null) {
for (PropertyType propertyType : propertiesType.getProperty()) {
properties.setProperty(propertyType.getName(), propertyType.getValue());
}
}
XOUnit xoUnit = XOUnit.builder()
.name(name)
.description(description)
.uri(uri)
.provider(provider)
.types(types)
.instanceListeners(instanceListeners)
.validationMode(validationMode)
.concurrencyMode(concurrencyMode)
.defaultTransactionAttribute(defaultTransactionAttribute)
.properties(properties)
.build();
xoUnits.add(xoUnit);
}
return xoUnits;
}
private ConcurrencyMode getConcurrencyMode(ConcurrencyModeType concurrencyModeType) {
if (concurrencyModeType == null) {
return ConcurrencyMode.SINGLETHREADED;
}
switch (concurrencyModeType) {
case SINGLETHREADED:
return ConcurrencyMode.SINGLETHREADED;
case MULTITHREADED:
return ConcurrencyMode.MULTITHREADED;
default:
throw new XOException("Unknown concurrency mode type " + concurrencyModeType);
}
}
private ValidationMode getValidationMode(ValidationModeType validationModeType) {
if (validationModeType == null) {
return ValidationMode.AUTO;
}
switch (validationModeType) {
case NONE:
return ValidationMode.NONE;
case AUTO:
return ValidationMode.AUTO;
default:
throw new XOException("Unknown validation mode type " + validationModeType);
}
}
private Transaction.TransactionAttribute getTransactionAttribute(TransactionAttributeType defaultTransactionAttributeType) {
if (defaultTransactionAttributeType == null) {
return Transaction.TransactionAttribute.NONE;
}
switch (defaultTransactionAttributeType) {
case NONE:
return Transaction.TransactionAttribute.NONE;
case MANDATORY:
return Transaction.TransactionAttribute.MANDATORY;
case REQUIRES:
return Transaction.TransactionAttribute.REQUIRES;
default:
throw new XOException("Unknown transaction attribute type " + defaultTransactionAttributeType);
}
}
}