private static void readCustomAction()

in src/main/java/org/apache/commons/scxml2/io/SCXMLReader.java [1086:1169]


    private static void readCustomAction(final XMLStreamReader reader, final Configuration configuration,
                                         final CustomAction customAction, final Executable executable,
                                         final ActionsContainer parent)
            throws XMLStreamException, ModelException {

        // Instantiate custom action
        Object actionObject;
        final String className = customAction.getActionClass().getName();
        ClassLoader cl = configuration.customActionClassLoader;
        if (configuration.useContextClassLoaderForCustomActions) {
            cl = Thread.currentThread().getContextClassLoader();
        }
        if (cl == null) {
            cl = SCXMLReader.class.getClassLoader();
        }
        Class<?> clazz;
        try {
            clazz = cl.loadClass(className);
            actionObject = clazz.getConstructor().newInstance();
        } catch (final ClassNotFoundException cnfe) {
            throw new XMLStreamException("Cannot find custom action class:" + className, cnfe);
        } catch (final IllegalAccessException iae) {
            throw new XMLStreamException("Cannot access custom action class:" + className, iae);
        } catch (final ReflectiveOperationException ie) {
            throw new XMLStreamException("Cannot instantiate custom action class:" + className, ie);
        }
        if (!(actionObject instanceof Action)) {
            throw new IllegalArgumentException(ERR_CUSTOM_ACTION_TYPE + className);
        }

        // Set the attribute values as properties
        final Action action = (Action) actionObject;

        final CustomActionWrapper actionWrapper = new CustomActionWrapper();
        actionWrapper.setAction(action);
        actionWrapper.setPrefix(reader.getPrefix());
        actionWrapper.setLocalName(reader.getLocalName());
        final Map<String, String> namespaces = readNamespaces(reader);
        if (namespaces != null) {
            actionWrapper.getNamespaces().putAll(namespaces);
        }

        final Map<String, String> attributes = new HashMap<>();
        for (int i = 0; i < reader.getAttributeCount(); i++) {
            final String name = reader.getAttributeLocalName(i);
            final String qname = createQualifiedName(reader.getAttributePrefix(i), name);
            final String value = reader.getAttributeValue(i);
            attributes.put(qname, value);
            final String setter = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
            Method method;
            try {
                method = clazz.getMethod(setter, String.class);
                method.invoke(action, value);
            } catch (final NoSuchMethodException nsme) {
                logger.warn("No method: " + setter + "(String) found in custom action class: " + className+ " for "
                        + qname + "=\"" + value + "\". Attribute ignored");
            } catch (final InvocationTargetException ite) {
                throw new XMLStreamException("Exception calling method:" + setter + "(String) in custom action class:"
                        + className, ite);
            } catch (final IllegalAccessException iae) {
                throw new XMLStreamException("Cannot access method: " + setter +"(String) in custom action class: "
                        + className, iae);
            }
        }
        if (!attributes.isEmpty()) {
            actionWrapper.setAttributes(attributes);
        }

        // Add any body content if necessary
        if (action instanceof ParsedValueContainer) {
            readParsedValue(reader, configuration, (ParsedValueContainer)action, false);
        }
        else {
            skipToEndElement(reader);
        }

        // Wire in the action and add to parent
        actionWrapper.setParent(executable);
        if (parent != null) {
            parent.addAction(actionWrapper);
        } else {
            executable.addAction(actionWrapper);
        }
    }