
com.talanlabs.taskmanager.engine.configuration.xml.XMLTaskManagerConfigurationBuilder Maven / Gradle / Ivy
The newest version!
package com.talanlabs.taskmanager.engine.configuration.xml;
import com.talanlabs.taskmanager.engine.configuration.TaskManagerConfigurationBuilder;
import com.talanlabs.taskmanager.engine.configuration.registry.ITaskDefinitionRegistry;
import com.talanlabs.taskmanager.engine.configuration.registry.ITaskObjectManagerRegistry;
import com.talanlabs.taskmanager.engine.configuration.registry.TaskDefinitionRegistryBuilder;
import com.talanlabs.taskmanager.engine.configuration.registry.TaskObjectManagerRegistryBuilder;
import com.talanlabs.taskmanager.engine.graph.StatusGraphsBuilder;
import com.talanlabs.taskmanager.engine.manager.ITaskObjectManager;
import com.talanlabs.taskmanager.engine.manager.TaskObjectManagerBuilder;
import com.talanlabs.taskmanager.engine.taskdefinition.TaskDefinitionBuilder;
import com.talanlabs.taskmanager.engine.taskservice.ITaskService;
import com.talanlabs.taskmanager.model.ITaskObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class XMLTaskManagerConfigurationBuilder {
private TaskManagerConfigurationBuilder taskManagerConfigurationBuilder;
private Map, ITypeHandler> typeHandlerMap;
private XMLTaskManagerConfigurationBuilder(InputStream is) throws XMLParseException {
super();
this.taskManagerConfigurationBuilder = TaskManagerConfigurationBuilder.newBuilder();
parseXML(is);
}
public static TaskManagerConfigurationBuilder newBuilder(InputStream is) throws XMLParseException {
return new XMLTaskManagerConfigurationBuilder(is).taskManagerConfigurationBuilder;
}
private void parseXML(InputStream is) throws XMLParseException {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
Document document;
try {
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
document = documentBuilder.parse(is);
} catch (ParserConfigurationException e) {
throw new XMLParseException("Not create DocumentBuilder", e);
} catch (SAXException e) {
throw new XMLParseException("Not parse document", e);
} catch (IOException e) {
throw new XMLParseException("Not read inputStream", e);
}
Element root = document.getDocumentElement();
typeHandlerMap = parseTypeHandlers(getFirstElement(root, "type-handlers"));
taskManagerConfigurationBuilder.taskObjectManagerRegistry(parseGraphDefinitions(getFirstElement(root, "graph-definitions")));
taskManagerConfigurationBuilder.taskDefinitionRegistry(parseTaskDefinitions(getFirstElement(root, "task-definitions")));
}
private Map, ITypeHandler> parseTypeHandlers(Element typeHandlersElement) throws XMLParseException {
Map, ITypeHandler> res = new HashMap<>();
if (typeHandlersElement != null) {
for (Element typeHandlerElement : getElements(typeHandlersElement, "type-handler")) {
Class> type = stringToClass(typeHandlerElement.getAttribute("type"));
if (type == null) {
throw new XMLParseException("type-handler type must not null", null);
}
ITypeHandler> typeHandler = createInstance(ITypeHandler.class, typeHandlerElement.getAttribute("handler-class"));
if (typeHandler == null) {
throw new XMLParseException("type-handler handler-class must not null", null);
}
res.put(type, typeHandler);
}
}
return res;
}
private ITaskDefinitionRegistry parseTaskDefinitions(Element taskDefinitionsElement) throws XMLParseException {
TaskDefinitionRegistryBuilder taskDefinitionRegistryBuilder = TaskDefinitionRegistryBuilder.newBuilder();
if (taskDefinitionsElement != null) {
for (Element taskDefinitionElement : getElements(taskDefinitionsElement, "task-definition")) {
String taskId = taskDefinitionElement.getAttribute("task-id");
if (StringUtils.isBlank(taskId)) {
throw new XMLParseException("task-id must not empty", null);
}
Class> taskClass = stringToClass(taskDefinitionElement.getAttribute("task-class"));
if (taskClass == null) {
throw new XMLParseException("task-class must not empty", null);
}
if (!ITaskService.class.isAssignableFrom(taskClass)) {
throw new XMLParseException("task-class " + taskClass + " not inherit class=" + ITaskService.class, null);
}
List, String>> parameterStrings = getParameterStrings(taskDefinitionElement);
int nbParameter = parameterStrings.size();
List> constructors = getConstructors(taskClass, parameterStrings);
if (constructors.isEmpty()) {
throw new XMLParseException("task-class " + taskClass + " not found contructor for " + parameterStrings.size() + " parameter(s)", null);
}
if (constructors.size() > 1) {
throw new XMLParseException("task-class " + taskClass + " found multi contructors for " + parameterStrings.size() + " parameter(s) (" + constructors.size() + ")", null);
}
Constructor> constructor = constructors.get(0);
Class>[] parameterTypes = constructor.getParameterTypes();
Object[] parameters = new Object[nbParameter];
for (int i = 0; i < nbParameter; i++) {
String valueString = parameterStrings.get(i).getRight();
Class> parameterType = parameterTypes[i];
parameters[i] = convertStringTo(valueString, parameterType);
}
ITaskService taskService;
try {
taskService = (ITaskService) constructor.newInstance(parameters);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
throw new XMLParseException("task-class " + taskClass + " fail to created new instance", e);
}
taskDefinitionRegistryBuilder.addTaskDefinition(TaskDefinitionBuilder.newBuilder(taskId, taskService).build());
}
}
return taskDefinitionRegistryBuilder.build();
}
private List, String>> getParameterStrings(Element taskDefinitionElement) throws XMLParseException {
List, String>> res = new ArrayList<>();
List parameterElements = getElements(taskDefinitionElement, "parameter");
for (Element parameterElement : parameterElements) {
res.add(Pair.of(stringToClass(parameterElement.getAttribute("type")), parameterElement.getTextContent()));
}
return res;
}
private List> getConstructors(Class> taskClass, List, String>> parameterStrings) {
List> res = new ArrayList<>();
int nb = parameterStrings.size();
for (Constructor> constructor : taskClass.getConstructors()) {
if (constructor.getParameterCount() == nb) {
Class>[] parameterTypes = constructor.getParameterTypes();
boolean ok = true;
int i = 0;
while (i < nb && ok) {
Pair, String> parameterString = parameterStrings.get(i);
Class> type = parameterString.getLeft();
Class> clazz = parameterTypes[i];
if (type != null && !type.equals(clazz)) {
ok = false;
}
i++;
}
if (ok) {
res.add(constructor);
}
}
}
return res;
}
private ITaskObjectManagerRegistry parseGraphDefinitions(Element graphDefinitionsElement) throws XMLParseException {
TaskObjectManagerRegistryBuilder taskObjectManagerRegistryBuilder = TaskObjectManagerRegistryBuilder.newBuilder();
if (graphDefinitionsElement != null) {
TaskObjectManagerRegistryBuilder.IInstanceToClass instanceToClass = createInstance(TaskObjectManagerRegistryBuilder.IInstanceToClass.class,
graphDefinitionsElement.getAttribute("instance-to-class"));
if (instanceToClass != null) {
taskObjectManagerRegistryBuilder.instanceToClass(instanceToClass);
}
for (Element graphDefinitionElement : getElements(graphDefinitionsElement, "graph-definition")) {
taskObjectManagerRegistryBuilder.addTaskObjectManager(parseGraphDefinition(graphDefinitionElement));
}
}
return taskObjectManagerRegistryBuilder.build();
}
private ITaskObjectManager parseGraphDefinition(Element graphDefinitionElement) throws XMLParseException {
Class> statusClass = stringToClass(graphDefinitionElement.getAttribute("status-class"));
if (statusClass == null) {
statusClass = String.class;
}
String objectClassString = graphDefinitionElement.getAttribute("object-class");
Class> objectClass = stringToClass(objectClassString);
if (objectClass == null) {
throw new XMLParseException("object-class must not null", null);
}
if (!ITaskObject.class.isAssignableFrom(objectClass)) {
throw new XMLParseException("object-class must implements ITaskObject class=" + objectClassString, null);
}
TaskObjectManagerBuilder taskObjectManagerBuilder = TaskObjectManagerBuilder.newBuilder((Class extends ITaskObject>) objectClass);
TaskObjectManagerBuilder.IGetStatus, ?> getStatus = createInstance(TaskObjectManagerBuilder.IGetStatus.class, graphDefinitionElement.getAttribute("get-status-class"));
taskObjectManagerBuilder.initialStatus(getStatus);
Element initStateElement = getFirstElement(graphDefinitionElement, "init-state");
if (initStateElement != null) {
Object initStatut = convertStringTo(initStateElement.getAttribute("init-statut"), statusClass);
StatusGraphsBuilder
© 2015 - 2025 Weber Informatics LLC | Privacy Policy