Source Code Cross Referenced for NGCCRuntime.java in  » 6.0-JDK-Modules-com.sun » xml » com » sun » xml » internal » xsom » impl » parser » state » 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 » 6.0 JDK Modules com.sun » xml » com.sun.xml.internal.xsom.impl.parser.state 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004:         *
005:         * This code is free software; you can redistribute it and/or modify it
006:         * under the terms of the GNU General Public License version 2 only, as
007:         * published by the Free Software Foundation.  Sun designates this
008:         * particular file as subject to the "Classpath" exception as provided
009:         * by Sun in the LICENSE file that accompanied this code.
010:         *
011:         * This code is distributed in the hope that it will be useful, but WITHOUT
012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014:         * version 2 for more details (a copy is included in the LICENSE file that
015:         * accompanied this code).
016:         *
017:         * You should have received a copy of the GNU General Public License version
018:         * 2 along with this work; if not, write to the Free Software Foundation,
019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020:         *
021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022:         * CA 95054 USA or visit www.sun.com if you need additional information or
023:         * have any questions.
024:         */
025:
026:        package com.sun.xml.internal.xsom.impl.parser.state;
027:
028:        import java.text.MessageFormat;
029:        import java.util.ArrayList;
030:        import java.util.Stack;
031:        import java.util.StringTokenizer;
032:
033:        import org.xml.sax.Attributes;
034:        import org.xml.sax.ContentHandler;
035:        import org.xml.sax.Locator;
036:        import org.xml.sax.SAXException;
037:        import org.xml.sax.SAXParseException;
038:
039:        /**
040:         * Runtime Engine for RELAXNGCC execution.
041:         * 
042:         * This class has the following functionalities:
043:         * 
044:         * <ol>
045:         *  <li>Managing a stack of NGCCHandler objects and
046:         *      switching between them appropriately.
047:         * 
048:         *  <li>Keep track of all Attributes.
049:         * 
050:         *  <li>manage mapping between namespace URIs and prefixes.
051:         * 
052:         *  <li>TODO: provide support for interleaving.
053:         * 
054:         * @version $Id: NGCCRuntime.java,v 1.15 2002/09/29 02:55:48 okajima Exp $
055:         * @author Kohsuke Kawaguchi (kk@kohsuke.org)
056:         */
057:        public class NGCCRuntime implements  ContentHandler, NGCCEventSource {
058:
059:            public NGCCRuntime() {
060:                reset();
061:            }
062:
063:            /**
064:             * Sets the root handler, which will be used to parse the
065:             * root element.
066:             * <p>
067:             * This method can be called right after the object is created
068:             * or the reset method is called. You can't replace the root
069:             * handler while parsing is in progress.
070:             * <p>
071:             * Usually a generated class that corresponds to the &lt;start>
072:             * pattern will be used as the root handler, but any NGCCHandler
073:             * can be a root handler.
074:             * 
075:             * @exception IllegalStateException
076:             *      If this method is called but it doesn't satisfy the
077:             *      pre-condition stated above.
078:             */
079:            public void setRootHandler(NGCCHandler rootHandler) {
080:                if (currentHandler != null)
081:                    throw new IllegalStateException();
082:                currentHandler = rootHandler;
083:            }
084:
085:            /**
086:             * Cleans up all the data structure so that the object can be reused later.
087:             * Normally, applications do not need to call this method directly,
088:             * 
089:             * as the runtime resets itself after the endDocument method.
090:             */
091:            public void reset() {
092:                attStack.clear();
093:                currentAtts = null;
094:                currentHandler = null;
095:                indent = 0;
096:                locator = null;
097:                namespaces.clear();
098:                needIndent = true;
099:                redirect = null;
100:                redirectionDepth = 0;
101:                text = new StringBuffer();
102:
103:                // add a dummy attributes at the bottom as a "centinel."
104:                attStack.push(new AttributesImpl());
105:            }
106:
107:            // current content handler can be acccessed via set/getContentHandler.
108:
109:            private Locator locator;
110:
111:            public void setDocumentLocator(Locator _loc) {
112:                this .locator = _loc;
113:            }
114:
115:            /**
116:             * Gets the source location of the current event.
117:             * 
118:             * <p>
119:             * One can call this method from RelaxNGCC handlers to access
120:             * the line number information. Note that to 
121:             */
122:            public Locator getLocator() {
123:                return locator;
124:            }
125:
126:            /** stack of {@link Attributes}. */
127:            private final Stack attStack = new Stack();
128:            /** current attributes set. always equal to attStack.peek() */
129:            private AttributesImpl currentAtts;
130:
131:            /**
132:             * Attributes that belong to the current element.
133:             * <p>
134:             * It's generally not recommended for applications to use
135:             * this method. RelaxNGCC internally removes processed attributes,
136:             * so this doesn't correctly reflect all the attributes an element
137:             * carries.
138:             */
139:            public Attributes getCurrentAttributes() {
140:                return currentAtts;
141:            }
142:
143:            /** accumulated text. */
144:            private StringBuffer text = new StringBuffer();
145:
146:            /** The current NGCCHandler. Always equals to handlerStack.peek() */
147:            private NGCCEventReceiver currentHandler;
148:
149:            public int replace(NGCCEventReceiver o, NGCCEventReceiver n) {
150:                if (o != currentHandler)
151:                    throw new IllegalStateException(); // bug of RelaxNGCC
152:                currentHandler = n;
153:
154:                return 0; // we only have one thread.
155:            }
156:
157:            /**
158:             * Processes buffered text.
159:             * 
160:             * This method will be called by the start/endElement event to process
161:             * buffered text as a text event.
162:             * 
163:             * <p>
164:             * Whitespace handling is a tricky business. Consider the following
165:             * schema fragment:
166:             * 
167:             * <xmp>
168:             * <element name="foo">
169:             *   <choice>
170:             *     <element name="bar"><empty/></element>
171:             *     <text/>
172:             *   </choice>
173:             * </element>
174:             * </xmp>
175:             * 
176:             * Assume we hit the following instance:
177:             * <xmp>
178:             * <foo> <bar/></foo>
179:             * </xmp>
180:             * 
181:             * Then this first space needs to be ignored (for otherwise, we will
182:             * end up treating this space as the match to &lt;text/> and won't
183:             * be able to process &lt;bar>.)
184:             * 
185:             * Now assume the following instance:
186:             * <xmp>
187:             * <foo/>
188:             * </xmp>
189:             * 
190:             * This time, we need to treat this empty string as a text, for
191:             * otherwise we won't be able to accept this instance.
192:             * 
193:             * <p>
194:             * This is very difficult to solve in general, but one seemingly
195:             * easy solution is to use the type of next event. If a text is
196:             * followed by a start tag, it follows from the constraint on
197:             * RELAX NG that that text must be either whitespaces or a match
198:             * to &lt;text/>.
199:             * 
200:             * <p>
201:             * On the contrary, if a text is followed by a end tag, then it
202:             * cannot be whitespace unless the content model can accept empty,
203:             * in which case sending a text event will be harmlessly ignored
204:             * by the NGCCHandler.
205:             * 
206:             * <p>
207:             * Thus this method take one parameter, which controls the
208:             * behavior of this method.
209:             * 
210:             * <p>
211:             * TODO: according to the constraint of RELAX NG, if characters
212:             * follow an end tag, then they must be either whitespaces or
213:             * must match to &lt;text/>.
214:             * 
215:             * @param   possiblyWhitespace
216:             *      True if the buffered character can be ignorabale. False if
217:             *      it needs to be consumed.
218:             */
219:            private void processPendingText(boolean ignorable)
220:                    throws SAXException {
221:                if (ignorable && text.toString().trim().length() == 0)
222:                    ; // ignore. See the above javadoc comment for the description
223:                else
224:                    currentHandler.text(text.toString()); // otherwise consume this token
225:
226:                // truncate StringBuffer, but avoid excessive allocation.
227:                if (text.length() > 1024)
228:                    text = new StringBuffer();
229:                else
230:                    text.setLength(0);
231:            }
232:
233:            public void processList(String str) throws SAXException {
234:                StringTokenizer t = new StringTokenizer(str, " \t\r\n");
235:                while (t.hasMoreTokens())
236:                    currentHandler.text(t.nextToken());
237:            }
238:
239:            public void startElement(String uri, String localname,
240:                    String qname, Attributes atts) throws SAXException {
241:
242:                if (redirect != null) {
243:                    redirect.startElement(uri, localname, qname, atts);
244:                    redirectionDepth++;
245:                } else {
246:                    processPendingText(true);
247:                    //        System.out.println("startElement:"+localname+"->"+_attrStack.size());
248:                    currentHandler.enterElement(uri, localname, qname, atts);
249:                }
250:            }
251:
252:            /**
253:             * Called by the generated handler code when an enter element
254:             * event is consumed.
255:             * 
256:             * <p>
257:             * Pushes a new attribute set.
258:             * 
259:             * <p>
260:             * Note that attributes are NOT pushed at the startElement method,
261:             * because the processing of the enterElement event can trigger
262:             * other attribute events and etc.
263:             * <p>
264:             * This method will be called from one of handlers when it truely
265:             * consumes the enterElement event.
266:             */
267:            public void onEnterElementConsumed(String uri, String localName,
268:                    String qname, Attributes atts) throws SAXException {
269:                attStack.push(currentAtts = new AttributesImpl(atts));
270:                nsEffectiveStack.push(new Integer(nsEffectivePtr));
271:                nsEffectivePtr = namespaces.size();
272:            }
273:
274:            public void onLeaveElementConsumed(String uri, String localName,
275:                    String qname) throws SAXException {
276:                attStack.pop();
277:                if (attStack.isEmpty())
278:                    currentAtts = null;
279:                else
280:                    currentAtts = (AttributesImpl) attStack.peek();
281:                nsEffectivePtr = ((Integer) nsEffectiveStack.pop()).intValue();
282:            }
283:
284:            public void endElement(String uri, String localname, String qname)
285:                    throws SAXException {
286:
287:                if (redirect != null) {
288:                    redirect.endElement(uri, localname, qname);
289:                    redirectionDepth--;
290:
291:                    if (redirectionDepth != 0)
292:                        return;
293:
294:                    // finished redirection.
295:                    for (int i = 0; i < namespaces.size(); i += 2)
296:                        redirect.endPrefixMapping((String) namespaces.get(i));
297:                    redirect.endDocument();
298:
299:                    redirect = null;
300:                    // then process this element normally
301:                }
302:
303:                processPendingText(false);
304:
305:                currentHandler.leaveElement(uri, localname, qname);
306:                //        System.out.println("endElement:"+localname);
307:            }
308:
309:            public void characters(char[] ch, int start, int length)
310:                    throws SAXException {
311:                if (redirect != null)
312:                    redirect.characters(ch, start, length);
313:                else
314:                    text.append(ch, start, length);
315:            }
316:
317:            public void ignorableWhitespace(char[] ch, int start, int length)
318:                    throws SAXException {
319:                if (redirect != null)
320:                    redirect.ignorableWhitespace(ch, start, length);
321:                else
322:                    text.append(ch, start, length);
323:            }
324:
325:            public int getAttributeIndex(String uri, String localname) {
326:                return currentAtts.getIndex(uri, localname);
327:            }
328:
329:            public void consumeAttribute(int index) throws SAXException {
330:                final String uri = currentAtts.getURI(index);
331:                final String local = currentAtts.getLocalName(index);
332:                final String qname = currentAtts.getQName(index);
333:                final String value = currentAtts.getValue(index);
334:                currentAtts.removeAttribute(index);
335:
336:                currentHandler.enterAttribute(uri, local, qname);
337:                currentHandler.text(value);
338:                currentHandler.leaveAttribute(uri, local, qname);
339:            }
340:
341:            public void startPrefixMapping(String prefix, String uri)
342:                    throws SAXException {
343:                if (redirect != null)
344:                    redirect.startPrefixMapping(prefix, uri);
345:                else {
346:                    namespaces.add(prefix);
347:                    namespaces.add(uri);
348:                }
349:            }
350:
351:            public void endPrefixMapping(String prefix) throws SAXException {
352:                if (redirect != null)
353:                    redirect.endPrefixMapping(prefix);
354:                else {
355:                    namespaces.remove(namespaces.size() - 1);
356:                    namespaces.remove(namespaces.size() - 1);
357:                }
358:            }
359:
360:            public void skippedEntity(String name) throws SAXException {
361:                if (redirect != null)
362:                    redirect.skippedEntity(name);
363:            }
364:
365:            public void processingInstruction(String target, String data)
366:                    throws SAXException {
367:                if (redirect != null)
368:                    redirect.processingInstruction(target, data);
369:            }
370:
371:            /** Impossible token. This value can never be a valid XML name. */
372:            static final String IMPOSSIBLE = "\u0000";
373:
374:            public void endDocument() throws SAXException {
375:                // consume the special "end document" token so that all the handlers
376:                // currently at the stack will revert to their respective parents.
377:                //
378:                // this is necessary to handle a grammar like
379:                // <start><ref name="X"/></start>
380:                // <define name="X">
381:                //   <element name="root"><empty/></element>
382:                // </define>
383:                //
384:                // With this grammar, when the endElement event is consumed, two handlers
385:                // are on the stack (because a child object won't revert to its parent
386:                // unless it sees a next event.)
387:
388:                // pass around an "impossible" token.
389:                currentHandler.leaveElement(IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE);
390:
391:                reset();
392:            }
393:
394:            public void startDocument() {
395:            }
396:
397:            //
398:            //
399:            // event dispatching methods
400:            //
401:            //
402:
403:            public void sendEnterAttribute(int threadId, String uri,
404:                    String local, String qname) throws SAXException {
405:
406:                currentHandler.enterAttribute(uri, local, qname);
407:            }
408:
409:            public void sendEnterElement(int threadId, String uri,
410:                    String local, String qname, Attributes atts)
411:                    throws SAXException {
412:
413:                currentHandler.enterElement(uri, local, qname, atts);
414:            }
415:
416:            public void sendLeaveAttribute(int threadId, String uri,
417:                    String local, String qname) throws SAXException {
418:
419:                currentHandler.leaveAttribute(uri, local, qname);
420:            }
421:
422:            public void sendLeaveElement(int threadId, String uri,
423:                    String local, String qname) throws SAXException {
424:
425:                currentHandler.leaveElement(uri, local, qname);
426:            }
427:
428:            public void sendText(int threadId, String value)
429:                    throws SAXException {
430:                currentHandler.text(value);
431:            }
432:
433:            //
434:            //
435:            // redirection of SAX2 events.
436:            //
437:            //
438:            /** When redirecting a sub-tree, this value will be non-null. */
439:            private ContentHandler redirect = null;
440:
441:            /**
442:             * Counts the depth of the elements when we are re-directing
443:             * a sub-tree to another ContentHandler.
444:             */
445:            private int redirectionDepth = 0;
446:
447:            /**
448:             * This method can be called only from the enterElement handler.
449:             * The sub-tree rooted at the new element will be redirected
450:             * to the specified ContentHandler.
451:             * 
452:             * <p>
453:             * Currently active NGCCHandler will only receive the leaveElement
454:             * event of the newly started element.
455:             * 
456:             * @param   uri,local,qname
457:             *      Parameters passed to the enter element event. Used to
458:             *      simulate the startElement event for the new ContentHandler.
459:             */
460:            public void redirectSubtree(ContentHandler child, String uri,
461:                    String local, String qname) throws SAXException {
462:
463:                redirect = child;
464:                redirect.setDocumentLocator(locator);
465:                redirect.startDocument();
466:
467:                // TODO: when a prefix is re-bound to something else,
468:                // the following code is potentially dangerous. It should be
469:                // modified to report active bindings only.
470:                for (int i = 0; i < namespaces.size(); i += 2)
471:                    redirect.startPrefixMapping((String) namespaces.get(i),
472:                            (String) namespaces.get(i + 1));
473:
474:                redirect.startElement(uri, local, qname, currentAtts);
475:                redirectionDepth = 1;
476:            }
477:
478:            //
479:            //
480:            // validation context implementation
481:            //
482:            //
483:            /** in-scope namespace mapping.
484:             * namespaces[2n  ] := prefix
485:             * namespaces[2n+1] := namespace URI */
486:            private final ArrayList namespaces = new ArrayList();
487:            /**
488:             * Index on the namespaces array, which points to
489:             * the top of the effective bindings. Because of the
490:             * timing difference between the startPrefixMapping method
491:             * and the execution of the corresponding actions,
492:             * this value can be different from <code>namespaces.size()</code>.
493:             * <p>
494:             * For example, consider the following schema:
495:             * <pre><xmp>
496:             *  <oneOrMore>
497:             *   <element name="foo"><empty/></element>
498:             *  </oneOrMore>
499:             *  code fragment X
500:             *  <element name="bob"/>
501:             * </xmp></pre>
502:             * Code fragment X is executed after we see a startElement event,
503:             * but at this time the namespaces variable already include new
504:             * namespace bindings declared on "bob".
505:             */
506:            private int nsEffectivePtr = 0;
507:
508:            /**
509:             * Stack to preserve old nsEffectivePtr values.
510:             */
511:            private final Stack nsEffectiveStack = new Stack();
512:
513:            public String resolveNamespacePrefix(String prefix) {
514:                for (int i = nsEffectivePtr - 2; i >= 0; i -= 2)
515:                    if (namespaces.get(i).equals(prefix))
516:                        return (String) namespaces.get(i + 1);
517:
518:                // no binding was found.
519:                if (prefix.equals(""))
520:                    return ""; // return the default no-namespace
521:                if (prefix.equals("xml")) // pre-defined xml prefix
522:                    return "http://www.w3.org/XML/1998/namespace";
523:                else
524:                    return null; // prefix undefined
525:            }
526:
527:            // error reporting
528:            protected void unexpectedX(String token) throws SAXException {
529:                throw new SAXParseException(MessageFormat.format(
530:                        "Unexpected {0} appears at line {1} column {2}",
531:                        new Object[] { token,
532:                                new Integer(getLocator().getLineNumber()),
533:                                new Integer(getLocator().getColumnNumber()) }),
534:                        getLocator());
535:            }
536:
537:            //
538:            //
539:            // trace functions
540:            //
541:            //
542:            private int indent = 0;
543:            private boolean needIndent = true;
544:
545:            private void printIndent() {
546:                for (int i = 0; i < indent; i++)
547:                    System.out.print("  ");
548:            }
549:
550:            public void trace(String s) {
551:                if (needIndent) {
552:                    needIndent = false;
553:                    printIndent();
554:                }
555:                System.out.print(s);
556:            }
557:
558:            public void traceln(String s) {
559:                trace(s);
560:                trace("\n");
561:                needIndent = true;
562:            }
563:        }
w__w_w._j_av__a2_s._c___om_ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.