Source Code Cross Referenced for ModelUpdater.java in  » Library » Apache-commons-scxml-0.6-src » org » apache » commons » scxml » io » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Library » Apache commons scxml 0.6 src » org.apache.commons.scxml.io 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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.io;
018:
019:        import java.text.MessageFormat;
020:        import java.util.Iterator;
021:        import java.util.List;
022:        import java.util.Map;
023:
024:        import org.apache.commons.logging.LogFactory;
025:        import org.apache.commons.scxml.SCXMLHelper;
026:        import org.apache.commons.scxml.model.History;
027:        import org.apache.commons.scxml.model.Initial;
028:        import org.apache.commons.scxml.model.Invoke;
029:        import org.apache.commons.scxml.model.ModelException;
030:        import org.apache.commons.scxml.model.Parallel;
031:        import org.apache.commons.scxml.model.SCXML;
032:        import org.apache.commons.scxml.model.State;
033:        import org.apache.commons.scxml.model.Transition;
034:        import org.apache.commons.scxml.model.TransitionTarget;
035:
036:        /**
037:         * The ModelUpdater provides the utility methods to check the Commons
038:         * SCXML model for inconsistencies, detect errors, and wire the Commons
039:         * SCXML model appropriately post document parsing by the digester to make
040:         * it executor ready.
041:         */
042:        final class ModelUpdater {
043:
044:            /*
045:             * Post-processing methods to make the SCXML object SCXMLExecutor ready.
046:             */
047:            /**
048:             * <p>Update the SCXML object model and make it SCXMLExecutor ready.
049:             * This is part of post-digester processing, and sets up the necessary
050:             * object references throughtout the SCXML object model for the parsed
051:             * document.</p>
052:             *
053:             * @param scxml The SCXML object (output from Digester)
054:             * @throws ModelException If the object model is flawed
055:             */
056:            static void updateSCXML(final SCXML scxml) throws ModelException {
057:                // Watch case, slightly unfortunate naming ;-)
058:                String initialstate = scxml.getInitialstate();
059:                //we have to use getTargets() here since the initialState can be
060:                //an indirect descendant
061:                // Concern marked by one of the code reviewers: better type check,
062:                //            now ClassCastException happens for Parallel
063:                // Response: initial should be a State, for Parallel, it is implicit
064:                State initialState = (State) scxml.getTargets().get(
065:                        initialstate);
066:                if (initialState == null) {
067:                    // Where do we, where do we go?
068:                    logAndThrowModelError(ERR_SCXML_NO_INIT,
069:                            new Object[] { initialstate });
070:                }
071:                scxml.setInitialState(initialState);
072:                Map targets = scxml.getTargets();
073:                Map states = scxml.getStates();
074:                Iterator i = states.keySet().iterator();
075:                while (i.hasNext()) {
076:                    updateState((State) states.get(i.next()), targets);
077:                }
078:            }
079:
080:            /**
081:             * Update this State object (part of post-digestion processing).
082:             * Also checks for any errors in the document.
083:             *
084:             * @param s The State object
085:             * @param targets The global Map of all transition targets
086:             * @throws ModelException If the object model is flawed
087:             */
088:            private static void updateState(final State s, final Map targets)
089:                    throws ModelException {
090:                //ensure both onEntry and onExit have parent
091:                //could add next two lines as a Digester rule for OnEntry/OnExit
092:                s.getOnEntry().setParent(s);
093:                s.getOnExit().setParent(s);
094:                //initialize next / inital
095:                Initial ini = s.getInitial();
096:                Map c = s.getChildren();
097:                TransitionTarget initialState = null;
098:                if (!c.isEmpty()) {
099:                    if (ini == null) {
100:                        logAndThrowModelError(ERR_STATE_NO_INIT,
101:                                new Object[] { getStateName(s) });
102:                    }
103:                    Transition initialTransition = ini.getTransition();
104:                    updateTransition(initialTransition, targets);
105:                    initialState = initialTransition.getTarget();
106:                    // we have to allow for an indirect descendant initial (targets)
107:                    //check that initialState is a descendant of s
108:                    if (initialState == null
109:                            || !SCXMLHelper.isDescendant(initialState, s)) {
110:                        logAndThrowModelError(ERR_STATE_BAD_INIT,
111:                                new Object[] { getStateName(s) });
112:                    }
113:                }
114:                List histories = s.getHistory();
115:                Iterator histIter = histories.iterator();
116:                while (histIter.hasNext()) {
117:                    if (s.isSimple()) {
118:                        logAndThrowModelError(ERR_HISTORY_SIMPLE_STATE,
119:                                new Object[] { getStateName(s) });
120:                    }
121:                    History h = (History) histIter.next();
122:                    Transition historyTransition = h.getTransition();
123:                    if (historyTransition == null) {
124:                        // try to assign initial as default
125:                        if (initialState != null
126:                                && !(initialState instanceof  History)) {
127:                            historyTransition = new Transition();
128:                            historyTransition.setNext(initialState.getId());
129:                            historyTransition.setParent(h);
130:                            h.setTransition(historyTransition);
131:                        } else {
132:                            logAndThrowModelError(ERR_HISTORY_NO_DEFAULT,
133:                                    new Object[] { h.getId(), getStateName(s) });
134:                        }
135:                    }
136:                    updateTransition(historyTransition, targets);
137:                    State historyState = (State) historyTransition.getTarget();
138:                    if (historyState == null) {
139:                        logAndThrowModelError(ERR_STATE_NO_HIST,
140:                                new Object[] { getStateName(s) });
141:                    }
142:                    if (!h.isDeep()) {
143:                        if (!c.containsValue(historyState)) {
144:                            logAndThrowModelError(ERR_STATE_BAD_SHALLOW_HIST,
145:                                    new Object[] { getStateName(s) });
146:                        }
147:                    } else {
148:                        if (!SCXMLHelper.isDescendant(historyState, s)) {
149:                            logAndThrowModelError(ERR_STATE_BAD_DEEP_HIST,
150:                                    new Object[] { getStateName(s) });
151:                        }
152:                    }
153:                }
154:                Map t = s.getTransitions();
155:                Iterator i = t.keySet().iterator();
156:                while (i.hasNext()) {
157:                    Iterator j = ((List) t.get(i.next())).iterator();
158:                    while (j.hasNext()) {
159:                        Transition trn = (Transition) j.next();
160:                        //could add next two lines as a Digester rule for Transition
161:                        trn.setParent(s);
162:                        updateTransition(trn, targets);
163:                    }
164:                }
165:                Parallel p = s.getParallel();
166:                Invoke inv = s.getInvoke();
167:                if ((inv != null && p != null) || (inv != null && !c.isEmpty())
168:                        || (p != null && !c.isEmpty())) {
169:                    logAndThrowModelError(ERR_STATE_BAD_CONTENTS,
170:                            new Object[] { getStateName(s) });
171:                }
172:                if (p != null) {
173:                    updateParallel(p, targets);
174:                } else if (inv != null) {
175:                    String ttype = inv.getTargettype();
176:                    if (ttype == null || ttype.trim().length() == 0) {
177:                        logAndThrowModelError(ERR_INVOKE_NO_TARGETTYPE,
178:                                new Object[] { getStateName(s) });
179:                    }
180:                    String src = inv.getSrc();
181:                    boolean noSrc = (src == null || src.trim().length() == 0);
182:                    String srcexpr = inv.getSrcexpr();
183:                    boolean noSrcexpr = (srcexpr == null || srcexpr.trim()
184:                            .length() == 0);
185:                    if (noSrc && noSrcexpr) {
186:                        logAndThrowModelError(ERR_INVOKE_NO_SRC,
187:                                new Object[] { getStateName(s) });
188:                    }
189:                    if (!noSrc && !noSrcexpr) {
190:                        logAndThrowModelError(ERR_INVOKE_AMBIGUOUS_SRC,
191:                                new Object[] { getStateName(s) });
192:                    }
193:                } else {
194:                    Iterator j = c.keySet().iterator();
195:                    while (j.hasNext()) {
196:                        updateState((State) c.get(j.next()), targets);
197:                    }
198:                }
199:            }
200:
201:            /**
202:             * Update this Parallel object (part of post-digestion processing).
203:             *
204:             * @param p The Parallel object
205:             * @param targets The global Map of all transition targets
206:             * @throws ModelException If the object model is flawed
207:             */
208:            private static void updateParallel(final Parallel p,
209:                    final Map targets) throws ModelException {
210:                Iterator i = p.getStates().iterator();
211:                while (i.hasNext()) {
212:                    updateState((State) i.next(), targets);
213:                }
214:            }
215:
216:            /**
217:             * Update this Transition object (part of post-digestion processing).
218:             *
219:             * @param t The Transition object
220:             * @param targets The global Map of all transition targets
221:             * @throws ModelException If the object model is flawed
222:             */
223:            private static void updateTransition(final Transition t,
224:                    final Map targets) throws ModelException {
225:                String next = t.getNext();
226:                if (next == null) { // stay transition
227:                    return;
228:                }
229:                TransitionTarget tt = t.getTarget();
230:                if (tt == null) {
231:                    tt = (TransitionTarget) targets.get(next);
232:                    if (tt == null) {
233:                        logAndThrowModelError(ERR_TARGET_NOT_FOUND,
234:                                new Object[] { next });
235:                    }
236:                    t.setTarget(tt);
237:                }
238:            }
239:
240:            /**
241:             * Log an error discovered in post-digestion processing.
242:             *
243:             * @param errType The type of error
244:             * @param msgArgs The arguments for formatting the error message
245:             * @throws ModelException The model error, always thrown.
246:             */
247:            private static void logAndThrowModelError(final String errType,
248:                    final Object[] msgArgs) throws ModelException {
249:                MessageFormat msgFormat = new MessageFormat(errType);
250:                String errMsg = msgFormat.format(msgArgs);
251:                org.apache.commons.logging.Log log = LogFactory
252:                        .getLog(ModelUpdater.class);
253:                log.error(errMsg);
254:                throw new ModelException(errMsg);
255:            }
256:
257:            /**
258:             * Get state identifier for error message. This method is only
259:             * called to produce an appropriate log message in some error
260:             * conditions.
261:             *
262:             * @param state The <code>State</code> object
263:             * @return The state identifier for the error message
264:             */
265:            private static String getStateName(final State state) {
266:                String badState = "anonymous state";
267:                if (!SCXMLHelper.isStringEmpty(state.getId())) {
268:                    badState = "state with ID \"" + state.getId() + "\"";
269:                }
270:                return badState;
271:            }
272:
273:            /**
274:             * Discourage instantiation since this is a utility class.
275:             */
276:            private ModelUpdater() {
277:                super ();
278:            }
279:
280:            //// Error messages
281:            /**
282:             * Error message when SCXML document specifies an illegal initial state.
283:             */
284:            private static final String ERR_SCXML_NO_INIT = "No SCXML child state "
285:                    + "with ID \"{0}\" found; illegal initialstate for SCXML document";
286:
287:            /**
288:             * Error message when a state element specifies an initial state which
289:             * cannot be found.
290:             */
291:            private static final String ERR_STATE_NO_INIT = "No initial element "
292:                    + "available for {0}";
293:
294:            /**
295:             * Error message when a state element specifies an initial state which
296:             * is not a direct descendent.
297:             */
298:            private static final String ERR_STATE_BAD_INIT = "Initial state "
299:                    + "null or not a descendant of {0}";
300:
301:            /**
302:             * Error message when a state element contains anything other than
303:             * one &lt;parallel&gt;, one &lt;invoke&gt; or any number of
304:             * &lt;state&gt; children.
305:             */
306:            private static final String ERR_STATE_BAD_CONTENTS = "{0} should "
307:                    + "contain either one <parallel>, one <invoke> or any number of "
308:                    + "<state> children.";
309:
310:            /**
311:             * Error message when a referenced history state cannot be found.
312:             */
313:            private static final String ERR_STATE_NO_HIST = "Referenced history state"
314:                    + " null for {0}";
315:
316:            /**
317:             * Error message when a shallow history state is not a child state.
318:             */
319:            private static final String ERR_STATE_BAD_SHALLOW_HIST = "History state"
320:                    + " for shallow history is not child for {0}";
321:
322:            /**
323:             * Error message when a deep history state is not a descendent state.
324:             */
325:            private static final String ERR_STATE_BAD_DEEP_HIST = "History state"
326:                    + " for deep history is not descendant for {0}";
327:
328:            /**
329:             * Transition target is not a legal IDREF (not found).
330:             */
331:            private static final String ERR_TARGET_NOT_FOUND = "Transition target with ID \"{0}\" not found";
332:
333:            /**
334:             * Simple states should not contain a history.
335:             */
336:            private static final String ERR_HISTORY_SIMPLE_STATE = "Simple {0} contains history elements";
337:
338:            /**
339:             * History does not specify a default transition target.
340:             */
341:            private static final String ERR_HISTORY_NO_DEFAULT = "No default target specified for history with ID \"{0}\""
342:                    + " belonging to {1}";
343:
344:            /**
345:             * Error message when an &lt;invoke&gt; does not specify a "targettype"
346:             * attribute.
347:             */
348:            private static final String ERR_INVOKE_NO_TARGETTYPE = "{0} contains "
349:                    + "<invoke> with no \"targettype\" attribute specified.";
350:
351:            /**
352:             * Error message when an &lt;invoke&gt; does not specify a "src"
353:             * or a "srcexpr" attribute.
354:             */
355:            private static final String ERR_INVOKE_NO_SRC = "{0} contains "
356:                    + "<invoke> without a \"src\" or \"srcexpr\" attribute specified.";
357:
358:            /**
359:             * Error message when an &lt;invoke&gt; specifies both "src" and "srcexpr"
360:             * attributes.
361:             */
362:            private static final String ERR_INVOKE_AMBIGUOUS_SRC = "{0} contains "
363:                    + "<invoke> with both \"src\" and \"srcexpr\" attributes specified,"
364:                    + " must specify either one, but not both.";
365:
366:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.