001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.scxml.env;
018    
019    import java.io.Serializable;
020    import java.util.Iterator;
021    import java.util.Map;
022    import java.util.Set;
023    
024    import org.apache.commons.logging.Log;
025    import org.apache.commons.logging.LogFactory;
026    import org.apache.commons.scxml.ErrorReporter;
027    import org.apache.commons.scxml.model.SCXML;
028    import org.apache.commons.scxml.model.State;
029    import org.apache.commons.scxml.model.TransitionTarget;
030    import org.apache.commons.scxml.semantics.ErrorConstants;
031    
032    /**
033     * Custom error reporter that log execution errors.
034     */
035    public class SimpleErrorReporter implements ErrorReporter, Serializable {
036    
037        /** Serial version UID. */
038        private static final long serialVersionUID = 1L;
039        /** Log. */
040        private Log log = LogFactory.getLog(getClass());
041    
042        /**
043         * Constructor.
044         */
045        public SimpleErrorReporter() {
046            super();
047        }
048    
049        /**
050         * @see ErrorReporter#onError(String, String, Object)
051         */
052        public void onError(final String errorCode, final String errDetail,
053                final Object errCtx) {
054            //Note: the if-then-else below is based on the actual usage
055            // (codebase search), it has to be kept up-to-date as the code changes
056            String errCode = errorCode.intern();
057            StringBuffer msg = new StringBuffer();
058            msg.append(errCode).append(" (");
059            msg.append(errDetail).append("): ");
060            if (errCode == ErrorConstants.NO_INITIAL) {
061                if (errCtx instanceof SCXML) {
062                    //determineInitialStates
063                    msg.append("<SCXML>");
064                } else if (errCtx instanceof State) {
065                    //determineInitialStates
066                    //determineTargetStates
067                    msg.append("State " + LogUtils.getTTPath((State) errCtx));
068                }
069            } else if (errCode == ErrorConstants.UNKNOWN_ACTION) {
070                //executeActionList
071                msg.append("Action: " + errCtx.getClass().getName());
072            } else if (errCode == ErrorConstants.ILLEGAL_CONFIG) {
073                //isLegalConfig
074                if (errCtx instanceof Map.Entry) {
075                    TransitionTarget tt = (TransitionTarget)
076                        (((Map.Entry) errCtx).getKey());
077                    Set vals = (Set) (((Map.Entry) errCtx).getValue());
078                    msg.append(LogUtils.getTTPath(tt) + " : [");
079                    for (Iterator i = vals.iterator(); i.hasNext();) {
080                        TransitionTarget tx = (TransitionTarget) i.next();
081                        msg.append(LogUtils.getTTPath(tx));
082                        if (i.hasNext()) {
083                            msg.append(", ");
084                        }
085                    }
086                    msg.append(']');
087                } else if (errCtx instanceof Set) {
088                    Set vals = (Set) errCtx;
089                    msg.append("<SCXML> : [");
090                    for (Iterator i = vals.iterator(); i.hasNext();) {
091                        TransitionTarget tx = (TransitionTarget) i.next();
092                        msg.append(LogUtils.getTTPath(tx));
093                        if (i.hasNext()) {
094                            msg.append(", ");
095                        }
096                    }
097                    msg.append(']');
098                }
099            }
100            if (log.isWarnEnabled()) {
101                log.warn(msg.toString());
102            }
103        }
104    
105    }
106