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

📄 modelupdater.java

📁 java xml bean把xml解析成bean
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.scxml.io;

import java.text.MessageFormat;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

import org.apache.commons.logging.LogFactory;
import org.apache.commons.scxml.SCXMLHelper;
import org.apache.commons.scxml.model.History;
import org.apache.commons.scxml.model.Initial;
import org.apache.commons.scxml.model.Invoke;
import org.apache.commons.scxml.model.ModelException;
import org.apache.commons.scxml.model.Parallel;
import org.apache.commons.scxml.model.SCXML;
import org.apache.commons.scxml.model.State;
import org.apache.commons.scxml.model.Transition;
import org.apache.commons.scxml.model.TransitionTarget;

/**
 * The ModelUpdater provides the utility methods to check the Commons
 * SCXML model for inconsistencies, detect errors, and wire the Commons
 * SCXML model appropriately post document parsing by the digester to make
 * it executor ready.
 */
final class ModelUpdater {

    /*
     * Post-processing methods to make the SCXML object SCXMLExecutor ready.
     */
    /**
     * <p>Update the SCXML object model and make it SCXMLExecutor ready.
     * This is part of post-digester processing, and sets up the necessary
     * object references throughtout the SCXML object model for the parsed
     * document.</p>
     *
     * @param scxml The SCXML object (output from Digester)
     * @throws ModelException If the object model is flawed
     */
   static void updateSCXML(final SCXML scxml) throws ModelException {
       String initial = scxml.getInitial();
       //we have to use getTargets() here since the initialTarget can be
       //an indirect descendant
       TransitionTarget initialTarget = (TransitionTarget) scxml.getTargets().
           get(initial);
       if (initialTarget == null) {
           // Where do we, where do we go?
           logAndThrowModelError(ERR_SCXML_NO_INIT, new Object[] {
               initial });
       }
       scxml.setInitialTarget(initialTarget);
       Map targets = scxml.getTargets();
       Map children = scxml.getChildren();
       Iterator i = children.keySet().iterator();
       while (i.hasNext()) {
           TransitionTarget tt = (TransitionTarget) children.get(i.next());
           if (tt instanceof State) {
               updateState((State) tt, targets);
           } else {
               updateParallel((Parallel) tt, targets);
           }
       }
   }

    /**
      * Update this State object (part of post-digestion processing).
      * Also checks for any errors in the document.
      *
      * @param s The State object
      * @param targets The global Map of all transition targets
      * @throws ModelException If the object model is flawed
      */
    private static void updateState(final State s, final Map targets)
    throws ModelException {
        //initialize next / inital
        Initial ini = s.getInitial();
        Map c = s.getChildren();
        List initialStates = null;
        if (!c.isEmpty()) {
            if (ini == null) {
                logAndThrowModelError(ERR_STATE_NO_INIT,
                    new Object[] {getStateName(s)});
            }
            Transition initialTransition = ini.getTransition();
            updateTransition(initialTransition, targets);
            initialStates = initialTransition.getTargets();
            // we have to allow for an indirect descendant initial (targets)
            //check that initialState is a descendant of s
            if (initialStates.size() == 0) {
                logAndThrowModelError(ERR_STATE_BAD_INIT,
                    new Object[] {getStateName(s)});
            } else {
                for (int i = 0; i < initialStates.size(); i++) {
                    TransitionTarget initialState = (TransitionTarget)
                        initialStates.get(i);
                    if (!SCXMLHelper.isDescendant(initialState, s)) {
                        logAndThrowModelError(ERR_STATE_BAD_INIT,
                            new Object[] {getStateName(s)});
                    }
                }
            }
        }
        List histories = s.getHistory();
        Iterator histIter = histories.iterator();
        while (histIter.hasNext()) {
            if (s.isSimple()) {
                logAndThrowModelError(ERR_HISTORY_SIMPLE_STATE,
                    new Object[] {getStateName(s)});
            }
            History h = (History) histIter.next();
            Transition historyTransition = h.getTransition();
            if (historyTransition == null) {
                // try to assign initial as default
                if (initialStates != null && initialStates.size() > 0) {
                    for (int i = 0; i < initialStates.size(); i++) {
                        if (initialStates.get(i) instanceof History) {
                            logAndThrowModelError(ERR_HISTORY_BAD_DEFAULT,
                                new Object[] {h.getId(), getStateName(s)});
                        }
                    }
                    historyTransition = new Transition();
                    historyTransition.getTargets().addAll(initialStates);
                    h.setTransition(historyTransition);
                } else {
                    logAndThrowModelError(ERR_HISTORY_NO_DEFAULT,
                        new Object[] {h.getId(), getStateName(s)});
                }
            }
            updateTransition(historyTransition, targets);
            List historyStates = historyTransition.getTargets();
            if (historyStates.size() == 0) {
                logAndThrowModelError(ERR_STATE_NO_HIST,
                    new Object[] {getStateName(s)});
            }
            for (int i = 0; i < historyStates.size(); i++) {
                TransitionTarget historyState = (TransitionTarget)
                    historyStates.get(i);
                if (!h.isDeep()) {
                    if (!c.containsValue(historyState)) {
                        logAndThrowModelError(ERR_STATE_BAD_SHALLOW_HIST,
                            new Object[] {getStateName(s)});
                    }
                } else {
                    if (!SCXMLHelper.isDescendant(historyState, s)) {
                        logAndThrowModelError(ERR_STATE_BAD_DEEP_HIST,
                            new Object[] {getStateName(s)});
                    }
                }
            }
        }
        List t = s.getTransitionsList();
        for (int i = 0; i < t.size(); i++) {
            Transition trn = (Transition) t.get(i);
            updateTransition(trn, targets);
        }
        Parallel p = s.getParallel(); //TODO: Remove in v1.0
        Invoke inv = s.getInvoke();
        if ((inv != null && p != null)
                || (inv != null && !c.isEmpty())
                || (p != null && !c.isEmpty())) {
            logAndThrowModelError(ERR_STATE_BAD_CONTENTS,
                new Object[] {getStateName(s)});
        }
        if (p != null) {
            updateParallel(p, targets);
        } else if (inv != null) {
            String ttype = inv.getTargettype();
            if (ttype == null || ttype.trim().length() == 0) {
                logAndThrowModelError(ERR_INVOKE_NO_TARGETTYPE,
                    new Object[] {getStateName(s)});
            }
            String src = inv.getSrc();
            boolean noSrc = (src == null || src.trim().length() == 0);
            String srcexpr = inv.getSrcexpr();
            boolean noSrcexpr = (srcexpr == null
                                 || srcexpr.trim().length() == 0);
            if (noSrc && noSrcexpr) {
                logAndThrowModelError(ERR_INVOKE_NO_SRC,
                    new Object[] {getStateName(s)});
            }
            if (!noSrc && !noSrcexpr) {
                logAndThrowModelError(ERR_INVOKE_AMBIGUOUS_SRC,
                    new Object[] {getStateName(s)});
            }
        } else {
            Iterator j = c.keySet().iterator();
            while (j.hasNext()) {
                TransitionTarget tt = (TransitionTarget) c.get(j.next());
                if (tt instanceof State) {
                    updateState((State) tt, targets);
                } else if (tt instanceof Parallel) {
                    updateParallel((Parallel) tt, targets);
                }
            }
        }
    }

    /**
      * Update this Parallel object (part of post-digestion processing).
      *
      * @param p The Parallel object
      * @param targets The global Map of all transition targets
      * @throws ModelException If the object model is flawed
      */
    private static void updateParallel(final Parallel p, final Map targets)
    throws ModelException {
        Iterator i = p.getChildren().iterator();
        while (i.hasNext()) {
            updateState((State) i.next(), targets);

⌨️ 快捷键说明

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