⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scxmlparser.java

📁 java xml bean把xml解析成bean
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
     * @see ExternalContent
     */
    private static class ParseExternalContentRule extends NodeCreateRule {
        /**
         * Constructor.
         * @throws ParserConfigurationException A JAXP configuration error
         */
        ParseExternalContentRule()
        throws ParserConfigurationException {
            super();
        }
        /**
         * @see Rule#end(String, String)
         */
        public final void end(final String namespace, final String name) {
            Element bodyElement = (Element) getDigester().pop();
            NodeList childNodes = bodyElement.getChildNodes();
            List externalNodes = ((ExternalContent) getDigester().
                peek()).getExternalNodes();
            for (int i = 0; i < childNodes.getLength(); i++) {
                externalNodes.add(childNodes.item(i));
            }
        }
    }

    /**
     * Custom digestion rule for parsing bodies of &lt;data&gt; elements.
     */
    private static class ParseDataRule extends NodeCreateRule {

        /**
         * The PathResolver used to resolve the src attribute to the
         * SCXML document it points to.
         * @see PathResolver
         */
        private PathResolver pr;

        /**
         * The "src" attribute, retained to check if body content is legal.
         */
        private String src;

        /**
         * The "expr" attribute, retained to check if body content is legal.
         */
        private String expr;

        /**
         * The XML tree for this data, parse as a Node, obtained from
         * either the "src" or the "expr" attributes.
         */
        private Node attrNode;

        /**
         * Constructor.
         *
         * @param pr The <code>PathResolver</code>
         * @throws ParserConfigurationException A JAXP configuration error
         */
        ParseDataRule(final PathResolver pr)
        throws ParserConfigurationException {
            super();
            this.pr = pr;
        }

        /**
         * @see Rule#begin(String, String, Attributes)
         */
        public final void begin(final String namespace, final String name,
                final Attributes attributes) throws Exception {
            super.begin(namespace, name, attributes);
            src = attributes.getValue("src");
            expr = attributes.getValue("expr");
            if (!SCXMLHelper.isStringEmpty(src)) {
                String path = null;
                if (pr == null) {
                    path = src;
                } else {
                    path = pr.resolvePath(src);
                }
                try {
                    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.
                        newInstance();
                    DocumentBuilder db = dbFactory.newDocumentBuilder();
                    attrNode = db.parse(path);
                } catch (Throwable t) { // you read that correctly
                    org.apache.commons.logging.Log log = LogFactory.
                        getLog(SCXMLParser.class);
                    log.error(t.getMessage(), t);
                }
                return;
            }
        }

        /**
         * @see Rule#end(String, String)
         */
        public final void end(final String namespace, final String name) {
            Node bodyNode = (Node) getDigester().pop();
            Data data = ((Data) getDigester().peek());
            // Prefer "src" over "expr", "expr" over child nodes
            // "expr" can only be evaluated at execution time
            if (!SCXMLHelper.isStringEmpty(src)) {
                data.setNode(attrNode);
            } else  if (SCXMLHelper.isStringEmpty(expr)) {
                // both "src" and "expr" are empty
                data.setNode(bodyNode);
            }
        }
    }

    /**
     * Custom digestion rule for external sources, that is, the src attribute of
     * the &lt;state&gt; element.
     */
    private static class DigestSrcAttributeRule extends Rule {

        /**
         * The PathResolver used to resolve the src attribute to the
         * SCXML document it points to.
         * @see PathResolver
         */
        private PathResolver pr;

        /**
         * The root document.
         */
        private SCXML root;

        /**
         * The list of custom actions the parent document is capable of
         * processing (and hence, the child should be, by transitivity).
         * @see CustomAction
         */
        private List customActions;

        /**
         * Constructor.
         * @param pr The PathResolver
         * @param customActions The list of custom actions this digester needs
         *                      to be able to process
         *
         * @see PathResolver
         * @see CustomAction
         */
        DigestSrcAttributeRule(final List customActions,
                final PathResolver pr) {
            super();
            this.customActions = customActions;
            this.pr = pr;
        }

        /**
         * Constructor.
         * @param root The root document, if this one is src'ed in
         * @param pr The PathResolver
         * @param customActions The list of custom actions this digester needs
         *                      to be able to process
         *
         * @see PathResolver
         * @see CustomAction
         */
        DigestSrcAttributeRule(final SCXML root,
                final List customActions, final PathResolver pr) {
            super();
            this.root = root;
            this.customActions = customActions;
            this.pr = pr;
        }

        /**
         * @see Rule#begin(String, String, Attributes)
         */
        public final void begin(final String namespace, final String name,
                final Attributes attributes) throws ModelException {
            String src = attributes.getValue("src");
            if (SCXMLHelper.isStringEmpty(src)) {
                return;
            }

            // 1) Digest the external SCXML file
            Digester digester = getDigester();
            SCXML scxml = (SCXML) digester.peek(digester.getCount() - 1);
            SCXML parent = root;
            if (parent == null) {
                parent = scxml;
            }
            String path;
            PathResolver nextpr = null;
            if (pr == null) {
                path = src;
            } else {
                path = pr.resolvePath(src);
                nextpr = pr.getResolver(src);
            }
            String[] fragments = path.split("#", 2);
            String location = fragments[0];
            String fragment = null;
            if (fragments.length > 1) {
                fragment = fragments[1];
            }
            Digester externalSrcDigester;
            if (fragment != null) {
                // Cannot pull in all targets just yet, i.e. null parent
                externalSrcDigester = newInstance(null, nextpr,
                    customActions);
            } else {
                externalSrcDigester = newInstance(parent, nextpr,
                    customActions);
            }
            SCXML externalSCXML = null;
            try {
                externalSCXML = (SCXML) externalSrcDigester.parse(location);
            } catch (Exception e) {
                MessageFormat msgFormat =
                    new MessageFormat(ERR_STATE_SRC);
                String errMsg = msgFormat.format(new Object[] {
                    path
                });
                throw new ModelException(errMsg + " : " + e.getMessage(), e);
            }

            // 2) Adopt the children and datamodel
            if (externalSCXML == null) {
                return;
            }
            State s = (State) digester.peek();
            if (fragment == null) {
                // All targets pulled in since its not a src fragment
                Initial ini = new Initial();
                Transition t = new Transition();
                t.setNext(externalSCXML.getInitial());
                ini.setTransition(t);
                s.setInitial(ini);
                Map children = externalSCXML.getChildren();
                Iterator childIter = children.values().iterator();
                while (childIter.hasNext()) {
                    s.addChild((TransitionTarget) childIter.next());
                }
                s.setDatamodel(externalSCXML.getDatamodel());
            } else {
                // Need to pull in descendent targets
                Object source = externalSCXML.getTargets().get(fragment);
                if (source == null) {
                    MessageFormat msgFormat =
                        new MessageFormat(ERR_STATE_SRC_FRAGMENT);
                    String errMsg = msgFormat.format(new Object[] {
                        path
                    });
                    throw new ModelException(errMsg);
                }
                if (source instanceof State) {
                    State include = (State) source;
                    s.setOnEntry(include.getOnEntry());
                    s.setOnExit(include.getOnExit());
                    s.setDatamodel(include.getDatamodel());
                    List histories = include.getHistory();
                    for (int i = 0; i < histories.size(); i++) {
                        History h = (History) histories.get(i);
                        s.addHistory(h);
                        parent.addTarget(h);
                    }
                    Iterator childIter = include.getChildren().values().iterator();
                    while (childIter.hasNext()) {
                        TransitionTarget tt = (TransitionTarget) childIter.next();
                        s.addChild(tt);
                        parent.addTarget(tt);
                        addTargets(parent, tt);
                    }
                    s.setInvoke(include.getInvoke());
                    s.setFinal(include.isFinal());
                    if (include.getInitial() != null) {
                        s.setInitial(include.getInitial());
                    }
                    Iterator transIter = include.getTransitionsList().iterator();
                    while (transIter.hasNext()) {
                        s.addTransition((Transition) transIter.next());
                    }
                } else {
                    MessageFormat msgFormat =
                        new MessageFormat(ERR_STATE_SRC_FRAGMENT_TARGET);
                    String errMsg = msgFormat.format(new Object[] {
                        path
                    });
                    throw new ModelException(errMsg);
                }
            }
        }

        /**
         * Add all the nested targets from given target to given parent state machine.
         *
         * @param parent The state machine
         * @param tt The transition target to import
         */
        private static void addTargets(final SCXML parent, final TransitionTarget tt) {
            Iterator histIter = tt.getHistory().iterator();
            while (histIter.hasNext()) {
                History h = (History) histIter.next();
                parent.addTarget(h);
            }
            if (tt instanceof State) {
                Iterator childIter = ((State) tt).getChildren().values().iterator();
                while (childIter.hasNext()) {
                    TransitionTarget child = (TransitionTarget) childIter.next();
                    parent.addTarget(child);
                    addTargets(parent, child);
                }
            } else if (tt instanceof Parallel) {
                Iterator childIter = ((Parallel) tt).getChildren().iterator();
                while (childIter.hasNext()) {
                    TransitionTarget child = (TransitionTarget) childIter.next();
                    parent.addTarget(child);
                    addTargets(parent, child);
                }
            }
        }
    }

    /**
     * Custom digestion rule for setting PathResolver for runtime retrieval.
     */
    private static class SetPathResolverRule extends Rule {

        /**
         * The PathResolver to set

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -