workcraft/workcraft

View on GitHub
workcraft/WorkcraftCore/src/org/workcraft/dom/NodeFactory.java

Summary

Maintainability
A
30 mins
Test Coverage
package org.workcraft.dom;

import org.workcraft.annotations.VisualClass;
import org.workcraft.dom.math.MathConnection;
import org.workcraft.dom.math.MathNode;
import org.workcraft.dom.visual.VisualComponent;
import org.workcraft.dom.visual.connections.VisualConnection;
import org.workcraft.exceptions.NodeCreationException;
import org.workcraft.serialisation.reflection.ConstructorParametersMatcher;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class NodeFactory {

    public static VisualConnection createVisualConnection(MathConnection connection)
            throws NodeCreationException {

        // Find the corresponding visual class
        VisualClass vcat = connection.getClass().getAnnotation(VisualClass.class);

        // The component/connection does not define a visual representation
        if (vcat == null) {
            return null;
        }

        try {
            Class<?> visualClass = vcat.value();
            Constructor<?> ctor = visualClass.getConstructor();
            return (VisualConnection) ctor.newInstance();

        } catch (SecurityException | NoSuchMethodException | IllegalArgumentException |
                InstantiationException | IllegalAccessException | InvocationTargetException e) {
            throw new NodeCreationException(e);
        }
    }

    @SuppressWarnings("unchecked")
    public static <T extends Node> T createNode(Class<T> cls) throws NodeCreationException {
        try {
            Constructor<?> ctor = cls.getConstructor();
            return (T) ctor.newInstance();
        } catch (ClassCastException | SecurityException | NoSuchMethodException |
                IllegalArgumentException | InstantiationException |
                IllegalAccessException | InvocationTargetException e) {
            throw new NodeCreationException(e);
        }
    }

    public static VisualComponent createVisualComponent(MathNode component) throws NodeCreationException {
        return createVisualComponentInternal(component);
    }

    private static VisualComponent createVisualComponentInternal(MathNode component, Object... constructorParameters) throws NodeCreationException {
        // Find the corresponding visual class
        VisualClass annotation = component.getClass().getAnnotation(VisualClass.class);

        // The component/connection does not define a visual representation
        if (annotation == null) {
            return null;
        }
        try {
            Class<?> visualClass = annotation.value();

            Object[] args = new Object[constructorParameters.length + 1];
            args[0] = component;
            for (int i = 0; i < constructorParameters.length; i++) {
                args[i + 1] = constructorParameters[i];
            }
            Class<?>[] types = new Class<?>[args.length];
            for (int i = 0; i < args.length; i++) {
                types[i] = args[i].getClass();
            }
            Constructor<?> ctor = new ConstructorParametersMatcher().match(visualClass, types);
            return (VisualComponent) ctor.newInstance(args);

        } catch (SecurityException | NoSuchMethodException | IllegalArgumentException |
                InstantiationException | IllegalAccessException | InvocationTargetException e) {
            throw new NodeCreationException(e);
        }
    }

}