Source Code Cross Referenced for DTDParser.java in  » Swing-Library » abeille-forms-designer » org » netbeans » editor » ext » html » dtd » 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 » Swing Library » abeille forms designer » org.netbeans.editor.ext.html.dtd 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *                 Sun Public License Notice
0003:         *
0004:         * The contents of this file are subject to the Sun Public License
0005:         * Version 1.0 (the "License"). You may not use this file except in
0006:         * compliance with the License. A copy of the License is available at
0007:         * http://www.sun.com/
0008:         *
0009:         * The Original Code is NetBeans. The Initial Developer of the Original
0010:         * Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun
0011:         * Microsystems, Inc. All Rights Reserved.
0012:         */
0013:        package org.netbeans.editor.ext.html.dtd;
0014:
0015:        import java.io.IOException;
0016:        import java.io.PushbackReader;
0017:        import java.io.Reader;
0018:        import java.util.ArrayList;
0019:        import java.util.Arrays;
0020:        import java.util.Comparator;
0021:        import java.util.HashMap;
0022:        import java.util.HashSet;
0023:        import java.util.Iterator;
0024:        import java.util.List;
0025:        import java.util.Map;
0026:        import java.util.Set;
0027:        import java.util.SortedMap;
0028:        import java.util.TreeMap;
0029:        import java.util.TreeSet;
0030:
0031:        import org.netbeans.editor.ext.html.WeakHashSet;
0032:
0033:        /**
0034:         * !!! Includes !!!! String->DTD.Element
0035:         * 
0036:         * @author Petr Nejedly
0037:         * @version 0.2
0038:         */
0039:        class DTDParser extends Object {
0040:
0041:            // The provider used to provide the Readers for this DTD.
0042:            private ReaderProvider provider = null;
0043:
0044:            // Asks for Reader for given DTD.
0045:            private Reader getReader(String identifier, String fileName) {
0046:                if (provider == null)
0047:                    return null;
0048:                return provider.getReaderForIdentifier(identifier, fileName);
0049:            }
0050:
0051:            /**
0052:             * Weak set for holding already created strings, to not create more
0053:             * instances of the same string
0054:             */
0055:            private WeakHashSet stringCache = new WeakHashSet(131, 0.75f);
0056:
0057:            /** Weak set of attributes - helps sharing common attributes */
0058:            private WeakHashSet attributes = new WeakHashSet(23, 0.75f);
0059:
0060:            /** Weak set of models */
0061:            private WeakHashSet models = new WeakHashSet(131, 0.75f);
0062:
0063:            /** Weak set of Contents */
0064:            private WeakHashSet contents = new WeakHashSet(131, 0.75f);
0065:
0066:            /**
0067:             * Temporal storage of all ContentLeafs that needs to get their elements
0068:             * filled in at the end of parsing
0069:             */
0070:            Set leafs = new HashSet(131, 0.75f);
0071:
0072:            /**
0073:             * Map of all character references. Mapping is String name -> DTD.CharRef
0074:             * instance
0075:             */
0076:            private SortedMap charRefs = new TreeMap();
0077:
0078:            /**
0079:             * Map holding partially completed instances of Element. Mapping is String
0080:             * name -> DTD.Element instance
0081:             */
0082:            private SortedMap elementMap = new TreeMap();
0083:
0084:            /**
0085:             * Map holding entities during creation of DTD. Mapping is String name ->
0086:             * String content. This map should not be used for direct put(..), because
0087:             * entities are defined by first declaration and can not be overriden.
0088:             */
0089:            private Map entityMap = new HashMap();
0090:
0091:            public DTD createDTD(ReaderProvider provider, String identifier,
0092:                    String fileName) throws WrongDTDException {
0093:                this .provider = provider;
0094:
0095:                Reader reader = getReader(identifier, fileName);
0096:                if (reader == null)
0097:                    throw new WrongDTDException(
0098:                            "Can't open Reader for public identifier "
0099:                                    + identifier);
0100:                try {
0101:                    parseDTD(new PushbackReader(reader, 1024 * 128));
0102:                } catch (IOException e) {
0103:                    throw new WrongDTDException("IOException during parsing: "
0104:                            + e.getMessage());
0105:                }
0106:
0107:                // fixup includes and excludes of all elements
0108:                for (Iterator it = elementMap.values().iterator(); it.hasNext();) {
0109:                    DTD.Element elem = (DTD.Element) it.next();
0110:                    ContentModelImpl cm = (ContentModelImpl) elem
0111:                            .getContentModel();
0112:
0113:                    Set newIncs = new HashSet();
0114:                    for (Iterator incIter = cm.included.iterator(); incIter
0115:                            .hasNext();) {
0116:                        Object oldElem;
0117:                        Object subElem = oldElem = incIter.next();
0118:                        if (subElem instanceof  String) {
0119:                            subElem = elementMap.get(((String) subElem)
0120:                                    .toUpperCase());
0121:                        }
0122:                        if (subElem == null) {
0123:                            throw new WrongDTDException("'" + oldElem
0124:                                    + "' element referenced from "
0125:                                    + elem.getName()
0126:                                    + " not found throughout the DTD.");
0127:                        }
0128:                        newIncs.add(subElem);
0129:                    }
0130:                    cm.included = newIncs;
0131:
0132:                    Set newExcs = new HashSet();
0133:                    for (Iterator excIter = cm.excluded.iterator(); excIter
0134:                            .hasNext();) {
0135:                        Object oldElem;
0136:                        Object subElem = oldElem = excIter.next();
0137:                        if (subElem instanceof  String) {
0138:                            subElem = elementMap.get(((String) subElem)
0139:                                    .toUpperCase());
0140:                        }
0141:                        if (subElem == null) {
0142:                            throw new WrongDTDException("'" + oldElem
0143:                                    + "' element referenced from "
0144:                                    + elem.getName()
0145:                                    + " not found throughout the DTD.");
0146:                        }
0147:                        newExcs.add(subElem);
0148:                    }
0149:                    cm.excluded = newExcs;
0150:                    cm.hashcode = cm.content.hashCode() + 2
0151:                            * cm.included.hashCode() + 3
0152:                            * cm.excluded.hashCode();
0153:                }
0154:
0155:                // fixup content leafs
0156:                for (Iterator it = leafs.iterator(); it.hasNext();) {
0157:                    ContentLeafImpl leaf = (ContentLeafImpl) it.next();
0158:                    leaf.elem = (DTD.Element) elementMap.get(leaf.elemName);
0159:                }
0160:
0161:                return new DTDImpl(identifier, elementMap, charRefs);
0162:            }
0163:
0164:            /**
0165:             * Method for adding new entities to their map. Obeys the rule that entity,
0166:             * once defined, can not be overriden
0167:             */
0168:            void addEntity(String name, String content) {
0169:                if (entityMap.get(name) == null)
0170:                    entityMap.put(name, content);
0171:            }
0172:
0173:            /**
0174:             * Method for adding new entities to their map. Obeys the rule that entity,
0175:             * once defined, can not be overriden
0176:             */
0177:            void addPublicEntity(String name, String identifier, String file)
0178:                    throws WrongDTDException {
0179:                if (entityMap.get(name) == null) {
0180:
0181:                    StringBuffer sb = new StringBuffer();
0182:                    char[] buffer = new char[16384];
0183:                    Reader r = getReader(identifier, file);
0184:                    try {
0185:                        int len;
0186:                        while ((len = r.read(buffer)) >= 0) {
0187:                            sb.append(buffer, 0, len);
0188:                        }
0189:                    } catch (IOException e) {
0190:                        throw new WrongDTDException(
0191:                                "Error reading included public entity " + name
0192:                                        + " - " + e.getMessage());
0193:                    }
0194:
0195:                    entityMap.put(name, sb.toString());
0196:                }
0197:            }
0198:
0199:            DTD.Value createValue(String name) {
0200:                return new ValueImpl((String) stringCache.put(name));
0201:            }
0202:
0203:            /** Creates new or lookups old ContentModel with given properites */
0204:            DTD.ContentModel createContentModel(DTD.Content content,
0205:                    Set included, Set excluded) {
0206:
0207:                DTD.ContentModel cm = new ContentModelImpl(content, included,
0208:                        excluded);
0209:                return (DTD.ContentModel) models.put(cm);
0210:            }
0211:
0212:            /** Creates new or lookups old ContentLeaf with given properites */
0213:            DTD.Content createContentLeaf(String name) {
0214:                DTD.Content c = new ContentLeafImpl(name);
0215:                c = (DTD.Content) contents.put(c);
0216:                leafs.add(c); // remember for final fixup
0217:                return c;
0218:            }
0219:
0220:            /** Creates new or lookups old ContentNode with given properites */
0221:            DTD.Content createContentNode(char type, DTD.Content subContent) {
0222:                return (DTD.Content) contents.put(new UnaryContentNodeImpl(
0223:                        type, subContent));
0224:            }
0225:
0226:            /** Creates new or lookups old ContentNode with given properites */
0227:            DTD.Content createContentNode(char type, DTD.Content[] subContent) {
0228:                return (DTD.Content) contents.put(new MultiContentNodeImpl(
0229:                        type, subContent));
0230:            }
0231:
0232:            DTD.Element createElement(String name, DTD.ContentModel cm,
0233:                    boolean optStart, boolean optEnd) {
0234:                DTD.Element retVal = new ElementImpl(name, cm, optStart,
0235:                        optEnd, new TreeMap());
0236:                return retVal;
0237:            }
0238:
0239:            /** Creates new or lookups old attribute with given properites */
0240:            DTD.Attribute createAttribute(String name, int type,
0241:                    String baseType, String typeHelper, String defaultMode,
0242:                    SortedMap values) {
0243:                DTD.Attribute attr = new AttributeImpl(name, type,
0244:                        (String) stringCache.put(baseType),
0245:                        (String) stringCache.put(typeHelper),
0246:                        (String) stringCache.put(defaultMode), values);
0247:                return (DTD.Attribute) attributes.put(attr);
0248:            }
0249:
0250:            /** Adds given instance of DTD.Attribute to Element named elemName */
0251:            void addAttrToElement(String elemName, DTD.Attribute attr)
0252:                    throws WrongDTDException {
0253:                ElementImpl elem = (ElementImpl) elementMap.get(elemName
0254:                        .toUpperCase());
0255:                if (elem == null)
0256:                    throw new WrongDTDException(
0257:                            "Attribute definition for unknown Element \""
0258:                                    + elemName + "\".");
0259:                elem.addAttribute(attr);
0260:            }
0261:
0262:            void createAddCharRef(String name, char value) {
0263:                DTD.CharRef ref = new CharRefImpl(name, value);
0264:                charRefs.put(name, ref);
0265:            }
0266:
0267:            private boolean isNameChar(char c) {
0268:                return Character.isLetterOrDigit(c) || c == '_' || c == '-'
0269:                        || c == '.' || c == ':';
0270:            }
0271:
0272:            /*----------------------------------------------------------------------------*/
0273:            /*----------------------------- Parsing routines ---------------------------- */
0274:            /*----------------------------------------------------------------------------*/
0275:            private static final int DTD_INIT = 0;
0276:            private static final int DTD_LT = 1; // after '<'
0277:            private static final int DTD_EXC = 2; // after "<!"
0278:            private static final int DTD_MINUS = 3; // after "<!-"
0279:            private static final int DTD_ACOMMENT = 4; // after comment was parsed,
0280:
0281:            // awaiting '>'
0282:
0283:            private void parseDTD(PushbackReader in) throws IOException,
0284:                    WrongDTDException {
0285:                int state = DTD_INIT;
0286:                for (;;) {
0287:                    int i = in.read();
0288:                    if (i == -1) {
0289:                        break;
0290:                    }
0291:                    switch (state) {
0292:                    case DTD_INIT:
0293:                        switch (i) {
0294:                        case '<':
0295:                            state = DTD_LT;
0296:                            break;
0297:                        case '%':
0298:                            parseEntityReference(in);
0299:                            break; // Stay in DTD_INIT
0300:                        }
0301:                        break;
0302:
0303:                    case DTD_LT:
0304:                        if (i != '!')
0305:                            throw new WrongDTDException("Unexpected char '"
0306:                                    + (char) i + "' after '<'");
0307:                        state = DTD_EXC;
0308:                        break;
0309:
0310:                    case DTD_EXC:
0311:                        switch (i) {
0312:                        case '-':
0313:                            state = DTD_MINUS;
0314:                            break;
0315:                        case '[':
0316:                            parseOptional(in);
0317:                            state = DTD_INIT;
0318:                            break;
0319:                        default:
0320:                            in.unread(i);
0321:                            parseMarkup(in);
0322:                            state = DTD_INIT;
0323:                            break;
0324:                        }
0325:                        break;
0326:
0327:                    case DTD_MINUS:
0328:                        if (i != '-')
0329:                            throw new WrongDTDException("Unexpected char '"
0330:                                    + (char) i + "' after \"<!-\"");
0331:                        parseComment(in);
0332:                        state = DTD_ACOMMENT;
0333:                        break;
0334:
0335:                    case DTD_ACOMMENT:
0336:                        if (i != '>')
0337:                            throw new WrongDTDException("Unexpected char '"
0338:                                    + (char) i + "' after comment");
0339:                        state = DTD_INIT;
0340:                        break;
0341:
0342:                    }
0343:                }
0344:                if (state != DTD_INIT)
0345:                    throw new WrongDTDException("Premature end of DTD"); // NOI18N
0346:            }
0347:
0348:            /**
0349:             * Parser that reads the markup type after <!. Recognizes ENTITY, ELEMENT
0350:             * and ATTLIST markup and forwards their processing to proper parser. It
0351:             * gets the control just after starting "<!" and releases after eating
0352:             * final '>'
0353:             */
0354:            private void parseMarkup(PushbackReader in) throws IOException,
0355:                    WrongDTDException {
0356:                StringBuffer sb = new StringBuffer();
0357:                for (;;) {
0358:                    int i = in.read();
0359:                    if (i == -1)
0360:                        throw new WrongDTDException("Premature end of DTD"); // NOI18N
0361:                    // EOF
0362:                    if (i == ' ')
0363:                        break;
0364:                    sb.append((char) i); // next char of name
0365:                }
0366:
0367:                String markup = sb.toString();
0368:
0369:                if ("ENTITY".equals(markup)) {
0370:                    parseEntityDefinition(in);
0371:                } else if ("ELEMENT".equals(markup)) {
0372:                    parseElement(in);
0373:                } else if ("ATTLIST".equals(markup)) {
0374:                    parseAttlist(in);
0375:                } else
0376:                    throw new WrongDTDException("Wrong DTD markup <!" + markup);
0377:            }
0378:
0379:            private static final int PED_INIT = 0;
0380:            private static final int PED_PERCENT = 1;
0381:            private static final int PED_CHAR = 2;
0382:            private static final int PED_NAME = 3;
0383:            private static final int PED_ANAME = 4;
0384:            private static final int PED_VAL = 5;
0385:            private static final int PED_TYPE = 6;
0386:            private static final int PED_AVAL = 7;
0387:            private static final int PED_AVAL_M = 8;
0388:            private static final int PED_ATYPE = 9;
0389:            private static final int PED_ID = 10;
0390:            private static final int PED_AID = 11;
0391:            private static final int PED_FILE = 12;
0392:            private static final int PED_AFILE = 13;
0393:            private static final int PED_AFILE_M = 14;
0394:            private static final int PED_ACHAR = 15;
0395:            private static final int PED_CH_TYPE = 16;
0396:            private static final int PED_CH_ATYPE = 17;
0397:            private static final int PED_CH_QUOT = 18;
0398:
0399:            /* TODO: Parsing fo character references */
0400:            private void parseEntityDefinition(PushbackReader in)
0401:                    throws IOException, WrongDTDException {
0402:                int state = PED_INIT;
0403:                StringBuffer name = new StringBuffer();
0404:                StringBuffer value = new StringBuffer();
0405:                StringBuffer type = new StringBuffer();
0406:                StringBuffer identifier = new StringBuffer();
0407:
0408:                for (;;) {
0409:                    int i = in.read();
0410:                    if (i == -1)
0411:                        throw new WrongDTDException("Premature end of DTD"); // NOI18N
0412:                    // EOF
0413:                    switch (state) {
0414:                    case PED_INIT:
0415:                        if (Character.isWhitespace((char) i))
0416:                            break;
0417:                        if (i == '%')
0418:                            state = PED_PERCENT;
0419:                        else {
0420:                            name.append((char) i);
0421:                            state = PED_CHAR;
0422:                        }
0423:                        break;
0424:
0425:                    case PED_PERCENT:
0426:                        if (Character.isWhitespace((char) i))
0427:                            break;
0428:                        name.append((char) i);
0429:                        state = PED_NAME;
0430:                        break;
0431:
0432:                    case PED_NAME:
0433:                        if (Character.isWhitespace((char) i)) {
0434:                            state = PED_ANAME;
0435:                        } else {
0436:                            name.append((char) i);
0437:                        }
0438:                        break;
0439:
0440:                    case PED_ANAME:
0441:                        if (Character.isWhitespace((char) i))
0442:                            break;
0443:                        if (i == '"')
0444:                            state = PED_VAL;
0445:                        else {
0446:                            in.unread(i);
0447:                            state = PED_TYPE;
0448:                        }
0449:                        break;
0450:
0451:                    case PED_VAL:
0452:                        if (i == '"') {
0453:                            addEntity(name.toString(), value.toString());
0454:                            state = PED_AVAL;
0455:                        } else {
0456:                            value.append((char) i);
0457:                        }
0458:                        break;
0459:
0460:                    case PED_AVAL:
0461:                        if (i == '>') {
0462:                            return;
0463:                        }
0464:                        if (i == '-')
0465:                            state = PED_AVAL_M;
0466:                        break;
0467:
0468:                    case PED_AVAL_M:
0469:                        if (i == '-')
0470:                            parseComment(in);
0471:                        state = PED_AVAL;
0472:                        break;
0473:
0474:                    case PED_TYPE:
0475:                        if (Character.isWhitespace((char) i)) {
0476:                            if (type.toString().equals("PUBLIC")) {
0477:                                state = PED_ATYPE;
0478:                            } else {
0479:                                throw new WrongDTDException(
0480:                                        "Unexpected entity type \"" + type
0481:                                                + "\".");
0482:                            }
0483:                        } else {
0484:                            type.append((char) i);
0485:                        }
0486:                        break;
0487:
0488:                    case PED_ATYPE:
0489:                        if (Character.isWhitespace((char) i))
0490:                            break;
0491:                        if (i == '"') {
0492:                            state = PED_ID;
0493:                            break;
0494:                        }
0495:                        throw new WrongDTDException("Unexpected char '"
0496:                                + (char) i + "' in PUBLIC entity.");
0497:
0498:                    case PED_ID:
0499:                        if (i == '"') {
0500:                            state = PED_AID;
0501:                        } else {
0502:                            identifier.append((char) i);
0503:                        }
0504:                        break;
0505:
0506:                    case PED_AID:
0507:                        if (Character.isWhitespace((char) i))
0508:                            break;
0509:                        if (i == '"') {
0510:                            state = PED_FILE;
0511:                            break;
0512:                        }
0513:                        if (i == '>') {
0514:                            addPublicEntity(name.toString(), identifier
0515:                                    .toString(), null);
0516:                            return;
0517:                        }
0518:                        throw new WrongDTDException("Unexpected char '"
0519:                                + (char) i + "' in PUBLIC entity.");
0520:
0521:                    case PED_FILE:
0522:                        if (i == '"') {
0523:                            state = PED_AFILE;
0524:                        } else {
0525:                            value.append((char) i);
0526:                        }
0527:                        break;
0528:
0529:                    case PED_AFILE:
0530:                        if (Character.isWhitespace((char) i))
0531:                            break;
0532:                        if (i == '-') {
0533:                            state = PED_AFILE_M;
0534:                            break;
0535:                        }
0536:                        if (i == '>') {
0537:                            addPublicEntity(name.toString(), identifier
0538:                                    .toString(), value.toString());
0539:                            return;
0540:                        }
0541:                        throw new WrongDTDException("Unexpected char '"
0542:                                + (char) i + "' in PUBLIC entity.");
0543:
0544:                    case PED_AFILE_M:
0545:                        if (i == '-') {
0546:                            parseComment(in);
0547:                            state = PED_FILE;
0548:                            break;
0549:                        }
0550:                        throw new WrongDTDException("Unexpected sequence \"-"
0551:                                + (char) i + "\" in in PUBLIC entity.");
0552:
0553:                    case PED_CHAR:
0554:                        if (Character.isWhitespace((char) i)) {
0555:                            state = PED_ACHAR;
0556:                        } else {
0557:                            name.append((char) i);
0558:                        }
0559:                        break;
0560:
0561:                    case PED_ACHAR:
0562:                        if (Character.isWhitespace((char) i))
0563:                            break;
0564:                        else {
0565:                            type.append((char) i);
0566:                            state = PED_CH_TYPE;
0567:                        }
0568:                        break;
0569:
0570:                    case PED_CH_TYPE:
0571:                        if (Character.isWhitespace((char) i)) {
0572:                            if (type.toString().equals("CDATA")) {
0573:                                state = PED_ATYPE;
0574:                                state = PED_CH_ATYPE;
0575:                            } else {
0576:                                throw new WrongDTDException(
0577:                                        "Unexpected entity type \"" + type
0578:                                                + "\".");
0579:                            }
0580:                        } else {
0581:                            type.append((char) i);
0582:                        }
0583:                        break;
0584:
0585:                    case PED_CH_ATYPE:
0586:                        if (Character.isWhitespace((char) i))
0587:                            break;
0588:                        else if (i == '"') {
0589:                            state = PED_CH_QUOT;
0590:                        } else {
0591:                            throw new WrongDTDException("Unexpected char '"
0592:                                    + (char) i + "' in entity.");
0593:                        }
0594:                        break;
0595:
0596:                    case PED_CH_QUOT:
0597:                        if (i == '"') {
0598:                            value.delete(0, 2);
0599:                            value.deleteCharAt(value.length() - 1);
0600:                            int code = Integer.parseInt(value.toString());
0601:                            createAddCharRef(name.toString(), (char) code);
0602:                            state = PED_AVAL;
0603:                        } else {
0604:                            value.append((char) i);
0605:                        }
0606:                    }
0607:
0608:                }
0609:            }
0610:
0611:            private static final int GR_INIT = 0;
0612:            private static final int GR_NAME = 1;
0613:            private static final int GR_ANAME = 2;
0614:
0615:            /**
0616:             * Parse group of names separated by '|' character and optional spaces
0617:             * 
0618:             * @return List of Strings containing names
0619:             */
0620:            private List parseGroup(PushbackReader in) throws IOException,
0621:                    WrongDTDException {
0622:                int state = GR_INIT;
0623:                StringBuffer name = new StringBuffer();
0624:                List list = new ArrayList();
0625:
0626:                for (;;) {
0627:                    int i = in.read();
0628:                    if (i == -1)
0629:                        throw new WrongDTDException("Premature end of DTD"); // NOI18N
0630:                    // EOF
0631:                    switch (state) {
0632:                    case GR_INIT:
0633:                        if (Character.isWhitespace((char) i))
0634:                            break;
0635:                        if (i == '%') {
0636:                            parseEntityReference(in);
0637:                        } else {
0638:                            name.append((char) i);
0639:                            state = GR_NAME;
0640:                        }
0641:                        break;
0642:
0643:                    case GR_NAME:
0644:                        if (isNameChar((char) i)) {
0645:                            name.append((char) i);
0646:                            break;
0647:                        }
0648:                        switch (i) {
0649:                        case ')':
0650:                            list.add(name.toString());
0651:                            return list;
0652:                        case '|':
0653:                            list.add(name.toString());
0654:                            name.setLength(0);
0655:                            state = GR_INIT;
0656:                            break;
0657:                        default:
0658:                            if (Character.isWhitespace((char) i)) {
0659:                                list.add(name.toString());
0660:                                name.setLength(0);
0661:                                state = GR_ANAME;
0662:                                break;
0663:                            } else {
0664:                                throw new WrongDTDException("Unexpected char '"
0665:                                        + (char) i + "' in group definition.");
0666:                            }
0667:                        }
0668:                        break;
0669:
0670:                    case GR_ANAME:
0671:                        if (Character.isWhitespace((char) i))
0672:                            break;
0673:                        switch (i) {
0674:                        case ')':
0675:                            return list;
0676:                        case '|':
0677:                            state = GR_INIT;
0678:                            break;
0679:                        default:
0680:                            throw new WrongDTDException("Unexpected char '"
0681:                                    + (char) i + "' in group definition.");
0682:                        }
0683:                        break;
0684:                    }
0685:                }
0686:
0687:            }
0688:
0689:            private static final int EL_INIT = 0;
0690:            private static final int EL_NAME = 1;
0691:            private static final int EL_ANAME = 2;
0692:            private static final int EL_ASTART = 3;
0693:            private static final int EL_ACONTENT = 4;
0694:            private static final int EL_PLUS = 5;
0695:            private static final int EL_MINUS = 6;
0696:
0697:            /**
0698:             * parse the whole element(s) definition including content model. Create
0699:             * corresponding instances of DTD.Element filled with proper informations.
0700:             * Make the same content models and their contents shared across the DTD
0701:             */
0702:            private void parseElement(PushbackReader in) throws IOException,
0703:                    WrongDTDException {
0704:                int state = EL_INIT;
0705:                StringBuffer name = new StringBuffer();
0706:                List list = null;
0707:                boolean optStart = false;
0708:                boolean optEnd = false;
0709:                DTD.Content content = null;
0710:                Set inSet = new HashSet();
0711:                Set exSet = new HashSet();
0712:
0713:                for (;;) {
0714:                    int i = in.read();
0715:                    if (i == -1)
0716:                        break;
0717:                    switch (state) {
0718:                    case EL_INIT:
0719:                        if (Character.isWhitespace((char) i))
0720:                            break;
0721:                        switch (i) {
0722:                        case '(':
0723:                            list = parseGroup(in);
0724:                            state = EL_ANAME;
0725:                            break;
0726:                        case '%':
0727:                            parseEntityReference(in);
0728:                            break; // Stay in EL_INIT
0729:                        default:
0730:                            name.append((char) i);
0731:                            state = EL_NAME;
0732:                            break;
0733:                        }
0734:                        break;
0735:
0736:                    case EL_NAME:
0737:                        if (Character.isWhitespace((char) i)) {
0738:                            state = EL_ANAME;
0739:                            list = new ArrayList();
0740:                            list.add(name.toString());
0741:                        } else {
0742:                            name.append((char) i);
0743:                        }
0744:                        break;
0745:
0746:                    case EL_ANAME:
0747:                        if (Character.isWhitespace((char) i))
0748:                            break;
0749:                        switch (i) {
0750:                        case 'O':
0751:                            optStart = true; // fall fhrough
0752:                        case '-':
0753:                            state = EL_ASTART;
0754:                            break;
0755:                        default:
0756:                            throw new WrongDTDException("Unexpected char '"
0757:                                    + (char) i
0758:                                    + "' in ELEMENT optStart definition.");
0759:                        }
0760:                        break;
0761:
0762:                    case EL_ASTART:
0763:                        if (Character.isWhitespace((char) i))
0764:                            break;
0765:                        switch (i) {
0766:                        case 'O':
0767:                            optEnd = true; // fall fhrough
0768:                        case '-':
0769:                            content = parseContent(in);
0770:                            state = EL_ACONTENT;
0771:                            break;
0772:                        default:
0773:                            throw new WrongDTDException("Unexpected char '"
0774:                                    + (char) i
0775:                                    + "' in ELEMENT optEnd definition.");
0776:                        }
0777:                        break;
0778:
0779:                    case EL_ACONTENT:
0780:                        if (Character.isWhitespace((char) i))
0781:                            break;
0782:                        switch (i) {
0783:                        case '+':
0784:                            state = EL_PLUS;
0785:                            break;
0786:                        case '-':
0787:                            state = EL_MINUS;
0788:                            break;
0789:                        case '>':
0790:                            DTD.ContentModel cm = createContentModel(content,
0791:                                    inSet, exSet);
0792:                            for (Iterator iter = list.iterator(); iter
0793:                                    .hasNext();) {
0794:                                String key = ((String) iter.next())
0795:                                        .toUpperCase();
0796:                                elementMap.put(key, createElement(key, cm,
0797:                                        optStart, optEnd));
0798:                            }
0799:                            return;
0800:                        default:
0801:                            throw new WrongDTDException("Unexpected char '"
0802:                                    + (char) i + "' in ELEMENT definition.");
0803:                        }
0804:                        break;
0805:
0806:                    case EL_PLUS:
0807:                        if (i == '(') {
0808:                            state = EL_ACONTENT;
0809:                            inSet.addAll(parseGroup(in));
0810:                        } else {
0811:                            throw new WrongDTDException("Unexpected char '"
0812:                                    + (char) i + "' in ELEMENT definition.");
0813:                        }
0814:                        break;
0815:
0816:                    case EL_MINUS:
0817:                        switch (i) {
0818:                        case '(':
0819:                            state = EL_ACONTENT;
0820:                            List l = parseGroup(in);
0821:                            exSet.addAll(l);
0822:                            break;
0823:                        case '-':
0824:                            state = EL_ACONTENT;
0825:                            parseComment(in);
0826:                            break;
0827:                        default:
0828:                            throw new WrongDTDException("Unexpected char '"
0829:                                    + (char) i + "' in ELEMENT definition.");
0830:                        }
0831:                        break;
0832:                    }
0833:                }
0834:
0835:                // XXX
0836:            }
0837:
0838:            private static final int CO_INIT = 0;
0839:            private static final int CO_NAME = 1;
0840:            private static final int CO_AMODEL = 2;
0841:            private static final int CO_AND = 3;
0842:            private static final int CO_OR = 4;
0843:            private static final int CO_SEQ = 5;
0844:            private static final int CO_AGROUP = 6;
0845:
0846:            /**
0847:             * This automata would parse content model definitions and return them as a
0848:             * Content instance of root of generated CM tree
0849:             */
0850:            private DTD.Content parseContent(PushbackReader in)
0851:                    throws IOException, WrongDTDException {
0852:                int state = EL_INIT;
0853:                StringBuffer name = new StringBuffer();
0854:                ArrayList list = null;
0855:                DTD.Content content = null;
0856:
0857:                for (;;) {
0858:                    int i = in.read();
0859:                    if (i == -1)
0860:                        break;
0861:                    switch (state) {
0862:                    case CO_INIT:
0863:                        if (Character.isWhitespace((char) i))
0864:                            break;
0865:                        switch (i) {
0866:                        case '%':
0867:                            parseEntityReference(in);
0868:                            break; // Stay in CO_INIT
0869:                        case '(':
0870:                            content = parseContent(in);
0871:                            state = CO_AMODEL;
0872:                            break;
0873:                        default:
0874:                            name.append((char) i);
0875:                            state = CO_NAME;
0876:                            break;
0877:                        }
0878:                        break;
0879:
0880:                    case CO_NAME:
0881:                        if (isNameChar((char) i)) {
0882:                            name.append((char) i);
0883:                        } else {
0884:                            switch (i) {
0885:                            case '?':
0886:                            case '+':
0887:                            case '*':
0888:                                DTD.Content leaf = createContentLeaf(name
0889:                                        .toString());
0890:                                return createContentNode((char) i, leaf);
0891:
0892:                            default:
0893:                                in.unread(i);
0894:                                return createContentLeaf(name.toString());
0895:                            }
0896:                        }
0897:                        break;
0898:
0899:                    case CO_AMODEL:
0900:                        if (Character.isWhitespace((char) i))
0901:                            break;
0902:                        switch (i) {
0903:                        case '&':
0904:                            list = new ArrayList();
0905:                            list.add(content);
0906:                            list.add(parseContent(in));
0907:                            state = CO_AND;
0908:                            break;
0909:                        case '|':
0910:                            list = new ArrayList();
0911:                            list.add(content);
0912:                            list.add(parseContent(in));
0913:                            state = CO_OR;
0914:                            break;
0915:                        case ',':
0916:                            list = new ArrayList();
0917:                            list.add(content);
0918:                            list.add(parseContent(in));
0919:                            state = CO_SEQ;
0920:                            break;
0921:                        case ')':
0922:                            state = CO_AGROUP;
0923:                            break;
0924:                        default:
0925:                            throw new WrongDTDException("Unexpected char '"
0926:                                    + (char) i
0927:                                    + "' in ELEMENT optEnd definition.");
0928:                        }
0929:                        break;
0930:
0931:                    case CO_AND:
0932:                        if (Character.isWhitespace((char) i))
0933:                            break;
0934:                        switch (i) {
0935:                        case '&':
0936:                            list.add(parseContent(in));
0937:                            break;
0938:                        case ')':
0939:                            content = createContentNode('&',
0940:                                    (DTD.Content[]) list
0941:                                            .toArray(new DTD.Content[0]));
0942:                            state = CO_AGROUP;
0943:                            break;
0944:                        default:
0945:                            throw new WrongDTDException("Unexpected char '"
0946:                                    + (char) i
0947:                                    + "' in ContentModel definition.");
0948:                        }
0949:                        break;
0950:
0951:                    case CO_OR:
0952:                        if (Character.isWhitespace((char) i))
0953:                            break;
0954:                        switch (i) {
0955:                        case '|':
0956:                            list.add(parseContent(in));
0957:                            break;
0958:                        case ')':
0959:                            content = createContentNode('|',
0960:                                    (DTD.Content[]) list
0961:                                            .toArray(new DTD.Content[0]));
0962:                            state = CO_AGROUP;
0963:                            break;
0964:                        default:
0965:                            throw new WrongDTDException("Unexpected char '"
0966:                                    + (char) i
0967:                                    + "' in ContentModel definition.");
0968:                        }
0969:                        break;
0970:
0971:                    case CO_SEQ:
0972:                        if (Character.isWhitespace((char) i))
0973:                            break;
0974:                        switch (i) {
0975:                        case ',':
0976:                            list.add(parseContent(in));
0977:                            break;
0978:                        case ')':
0979:                            content = createContentNode(',',
0980:                                    (DTD.Content[]) list
0981:                                            .toArray(new DTD.Content[0]));
0982:                            state = CO_AGROUP;
0983:                            break;
0984:                        default:
0985:                            throw new WrongDTDException("Unexpected char '"
0986:                                    + (char) i
0987:                                    + "' in ContentModel definition.");
0988:                        }
0989:                        break;
0990:
0991:                    case CO_AGROUP:
0992:                        if (Character.isWhitespace((char) i))
0993:                            return content;
0994:                        switch (i) {
0995:                        case '?':
0996:                        case '+':
0997:                        case '*':
0998:                            return createContentNode((char) i, content);
0999:                        default:
1000:                            in.unread(i);
1001:                            return content;
1002:                        }
1003:                    }
1004:                }
1005:
1006:                throw new WrongDTDException("Premature end of DTD"); // NOI18N EOF
1007:
1008:            }
1009:
1010:            private static final int ATT_INIT = 0;
1011:            private static final int ATT_NAME = 1;
1012:            private static final int ATT_ANAME = 2;
1013:            private static final int ATT_ANAME_M = 3;
1014:            private static final int ATT_VAR = 4;
1015:            private static final int ATT_AVAR = 5;
1016:            private static final int ATT_TYPE = 6;
1017:            private static final int ATT_ATYPE = 7;
1018:            private static final int ATT_MODE = 8;
1019:
1020:            private void parseAttlist(PushbackReader in) throws IOException,
1021:                    WrongDTDException {
1022:                int state = ATT_INIT;
1023:                StringBuffer name = new StringBuffer();
1024:                List list = null; // List of tag names for which are these attribs
1025:                StringBuffer attr = new StringBuffer(); // name of attribute
1026:                List values = null; // (list of possible values
1027:                StringBuffer type = new StringBuffer(); // OR the type of attribute )
1028:                String typeHelper = null; // AND name of entity
1029:                StringBuffer mode = new StringBuffer(); // default mode of this attrib
1030:                for (;;) {
1031:                    int i = in.read();
1032:                    if (i == -1)
1033:                        break;
1034:                    switch (state) {
1035:                    case ATT_INIT:
1036:                        if (Character.isWhitespace((char) i))
1037:                            break;
1038:                        switch (i) {
1039:                        case '%':
1040:                            parseEntityReference(in);
1041:                            break; // Stay in ATT_INIT
1042:                        case '(':
1043:                            list = parseGroup(in);
1044:                            state = ATT_ANAME;
1045:                            break;
1046:                        default:
1047:                            name.append((char) i);
1048:                            state = ATT_NAME;
1049:                            break;
1050:                        }
1051:                        break;
1052:
1053:                    case ATT_NAME:
1054:                        if (Character.isWhitespace((char) i)) {
1055:                            list = new ArrayList();
1056:                            list.add(name.toString());
1057:                            state = ATT_ANAME;
1058:                            break;
1059:                        }
1060:                        name.append((char) i);
1061:                        break;
1062:
1063:                    case ATT_ANAME:
1064:                        if (Character.isWhitespace((char) i))
1065:                            break;
1066:                        switch (i) {
1067:                        case '%':
1068:                            parseEntityReference(in);
1069:                            break; // Stay in ATT_ANAME
1070:                        case '-':
1071:                            state = ATT_ANAME_M;
1072:                            break;
1073:                        case '>':
1074:                            return;
1075:                        default:
1076:                            attr.append((char) i);
1077:                            state = ATT_VAR;
1078:                            break;
1079:                        }
1080:                        break;
1081:
1082:                    case ATT_ANAME_M:
1083:                        if (i == '-') {
1084:                            parseComment(in); // skip the comment
1085:                            state = ATT_ANAME;
1086:                        } else {
1087:                            throw new WrongDTDException("Unexpected char '"
1088:                                    + (char) i + "' in ATTLIST definition.");
1089:                        }
1090:                        break;
1091:
1092:                    case ATT_VAR:
1093:                        if (Character.isWhitespace((char) i)) {
1094:                            state = ATT_AVAR;
1095:                            break;
1096:                        }
1097:                        attr.append((char) i);
1098:                        break;
1099:
1100:                    case ATT_AVAR:
1101:                        if (Character.isWhitespace((char) i))
1102:                            break;
1103:                        switch (i) {
1104:                        case '%':
1105:                            typeHelper = parseEntityReference(in);
1106:                            break; // Stay in ATT_AVAR
1107:                        case '(':
1108:                            values = parseGroup(in);
1109:                            state = ATT_ATYPE;
1110:                            break;
1111:                        default:
1112:                            type.append((char) i);
1113:                            state = ATT_TYPE;
1114:                            break;
1115:                        }
1116:                        break;
1117:
1118:                    case ATT_TYPE:
1119:                        if (Character.isWhitespace((char) i)) {
1120:                            state = ATT_ATYPE;
1121:                            break;
1122:                        }
1123:                        type.append((char) i);
1124:                        break;
1125:
1126:                    case ATT_ATYPE:
1127:                        if (Character.isWhitespace((char) i))
1128:                            break;
1129:                        switch (i) {
1130:                        case '%':
1131:                            parseEntityReference(in);
1132:                            break; // Stay in ATT_ATYPE
1133:                        default:
1134:                            mode.append((char) i);
1135:                            state = ATT_MODE;
1136:                            break;
1137:                        }
1138:                        break;
1139:
1140:                    case ATT_MODE:
1141:                        if (Character.isWhitespace((char) i)) {
1142:                            // Create attr and add it to all tags
1143:                            DTD.Attribute a = null;
1144:
1145:                            if (values == null) { // HOTSPOT for internation of
1146:                                // strings!!!
1147:                                a = createAttribute(attr.toString(),
1148:                                        DTD.Attribute.TYPE_BASE, type
1149:                                                .toString(), typeHelper, mode
1150:                                                .toString(), null);
1151:                            } else if (values.size() == 1) {
1152:                                a = createAttribute(attr.toString(),
1153:                                        DTD.Attribute.TYPE_BOOLEAN, null,
1154:                                        typeHelper, mode.toString(), null);
1155:                            } else {
1156:                                SortedMap vals = new TreeMap();
1157:                                for (Iterator iter = values.iterator(); iter
1158:                                        .hasNext();) {
1159:                                    String valName = (String) iter.next();
1160:                                    vals.put(valName, createValue(valName));
1161:                                }
1162:                                a = createAttribute(attr.toString(),
1163:                                        DTD.Attribute.TYPE_SET, null,
1164:                                        typeHelper, mode.toString(), vals);
1165:                            }
1166:                            for (Iterator iter = list.iterator(); iter
1167:                                    .hasNext();) {
1168:                                addAttrToElement((String) iter.next(), a);
1169:                            }
1170:
1171:                            typeHelper = null;
1172:                            attr.setLength(0);
1173:                            type.setLength(0);
1174:                            mode.setLength(0);
1175:                            values = null;
1176:
1177:                            state = ATT_ANAME;
1178:                            break;
1179:                        }
1180:                        mode.append((char) i);
1181:                        break;
1182:                    }
1183:                }
1184:            }
1185:
1186:            private static final int OPT_INIT = 0;
1187:            private static final int OPT_PROCESS = 1;
1188:            private static final int OPT_APROCESS = 2;
1189:            private static final int OPT_CONTENT = 3;
1190:            private static final int OPT_BRAC1 = 4;
1191:            private static final int OPT_BRAC2 = 5;
1192:
1193:            /**
1194:             * Parser that takes care of conditional inclusion/exclusion of part of DTD.
1195:             * Gets the control just after "<!["
1196:             */
1197:            private void parseOptional(PushbackReader in) throws IOException,
1198:                    WrongDTDException {
1199:                int state = OPT_INIT;
1200:                StringBuffer process = new StringBuffer();
1201:                StringBuffer content = new StringBuffer();
1202:                boolean ignore = false;
1203:
1204:                for (;;) {
1205:                    int i = in.read();
1206:                    if (i == -1)
1207:                        break; // EOF
1208:                    switch (state) {
1209:                    case OPT_INIT:
1210:                        if (Character.isWhitespace((char) i))
1211:                            break;
1212:                        if (i == '%') {
1213:                            parseEntityReference(in);
1214:                            break;
1215:                        }
1216:                        process.append((char) i);
1217:                        state = OPT_PROCESS;
1218:                        break;
1219:
1220:                    case OPT_PROCESS:
1221:                        if (Character.isWhitespace((char) i)) {
1222:                            String s = process.toString();
1223:                            if ("IGNORE".equals(s))
1224:                                ignore = true;
1225:                            else if (!"INCLUDE".equals(s))
1226:                                throw new WrongDTDException(
1227:                                        "Unexpected processing instruction "
1228:                                                + s);
1229:                            state = OPT_APROCESS;
1230:                        } else {
1231:                            process.append((char) i);
1232:                        }
1233:                        break;
1234:
1235:                    case OPT_APROCESS:
1236:                        if (Character.isWhitespace((char) i))
1237:                            break;
1238:                        if (i == '[')
1239:                            state = OPT_CONTENT;
1240:                        else
1241:                            throw new WrongDTDException("Unexpected char '"
1242:                                    + (char) i + "' in processing instruction.");
1243:                        break;
1244:
1245:                    case OPT_CONTENT:
1246:                        if (i == ']')
1247:                            state = OPT_BRAC1;
1248:                        else
1249:                            content.append((char) i);
1250:                        break;
1251:
1252:                    case OPT_BRAC1:
1253:                        if (i == ']')
1254:                            state = OPT_BRAC2;
1255:                        else {
1256:                            content.append(']').append((char) i);
1257:                            state = OPT_CONTENT;
1258:                        }
1259:                        break;
1260:
1261:                    case OPT_BRAC2:
1262:                        if (Character.isWhitespace((char) i))
1263:                            break;
1264:                        if (i == '>') {
1265:                            if (!ignore)
1266:                                in.unread(content.toString().toCharArray());
1267:                            return;
1268:                        }
1269:                        throw new WrongDTDException("Unexpected char '"
1270:                                + (char) i + "' in processing instruction.");
1271:                    }
1272:                }
1273:
1274:            }
1275:
1276:            private static final int COMM_TEXT = 0; // anywhere in text
1277:            private static final int COMM_DASH = 1; // after '-'
1278:
1279:            /** Parser that eats everything until two consecutive dashes (inclusive) */
1280:            private void parseComment(PushbackReader in) throws IOException,
1281:                    WrongDTDException {
1282:                int state = COMM_TEXT;
1283:                for (;;) {
1284:                    int i = in.read();
1285:                    if (i == -1)
1286:                        break; // EOF
1287:                    switch (state) {
1288:                    case COMM_TEXT:
1289:                        if (i == '-')
1290:                            state = COMM_DASH;
1291:                        break;
1292:                    case COMM_DASH:
1293:                        if (i == '-')
1294:                            return; // finished eating comment
1295:                        state = COMM_TEXT;
1296:                        break;
1297:                    }
1298:                }
1299:                throw new WrongDTDException("Premature end of DTD"); // NOI18N
1300:            }
1301:
1302:            /**
1303:             * Parser that reads the name of entity reference and replace it with the
1304:             * content of that entity (using the pushback capability of input). It gets
1305:             * the control just after starting '%'
1306:             * 
1307:             * @returns the name of reference which was replaced.
1308:             */
1309:            private String parseEntityReference(PushbackReader in)
1310:                    throws IOException, WrongDTDException {
1311:                StringBuffer sb = new StringBuffer();
1312:                for (;;) {
1313:                    int i = in.read();
1314:                    if (i == -1)
1315:                        break; // EOF
1316:                    if (isNameChar((char) i)) {
1317:                        sb.append((char) i); // next char of name
1318:                    } else {
1319:                        String entValue = (String) entityMap.get(sb.toString()); // get
1320:                        // the
1321:                        // entity
1322:                        // content
1323:                        if (entValue == null)
1324:                            throw new WrongDTDException("No such entity: \""
1325:                                    + sb + "\"");
1326:
1327:                        if (i != ';')
1328:                            in.unread(i);
1329:                        in.unread(entValue.toCharArray()); // push it back to stream
1330:                        return sb.toString();
1331:                    }
1332:                }
1333:                throw new WrongDTDException("Premature end of DTD"); // NOI18N
1334:            }
1335:
1336:            public static class WrongDTDException extends Exception {
1337:                public WrongDTDException(String reason) {
1338:                    super (reason);
1339:                }
1340:            }
1341:
1342:            /*----------------------------------------------------------------------------*/
1343:            /*---------- Implementation of classes this factory uses as results ----------*/
1344:            /*----------------------------------------------------------------------------*/
1345:
1346:            /** Implementation of the DTD which this DTDcreator works as factory for. */
1347:            private static class DTDImpl implements  DTD {
1348:                private String id;
1349:                private SortedMap elements;
1350:                private SortedMap charRefs;
1351:
1352:                DTDImpl(String identifier, SortedMap elements,
1353:                        SortedMap charRefs) {
1354:                    this .id = identifier;
1355:                    this .elements = elements;
1356:                    this .charRefs = charRefs;
1357:                }
1358:
1359:                /** Identify this instance of DTD */
1360:                public String getIdentifier() {
1361:                    return id;
1362:                }
1363:
1364:                /** Get List of all Elements whose names starts with given prefix */
1365:                public List getElementList(String prefix) {
1366:                    List l = new ArrayList();
1367:                    prefix = prefix == null ? "" : prefix.toUpperCase();
1368:                    Iterator i = elements.tailMap(prefix).entrySet().iterator();
1369:
1370:                    while (i.hasNext()) {
1371:                        Map.Entry entry = (Map.Entry) i.next();
1372:                        if (((String) entry.getKey()).startsWith(prefix)) {
1373:                            l.add(entry.getValue());
1374:                        } else { // we're getting data from SortedSet, so when any
1375:                            break; // entry fails, all remaining entry would fail.
1376:                        }
1377:                    }
1378:
1379:                    return l;
1380:                }
1381:
1382:                /** Get the Element of given name. */
1383:                public DTD.Element getElement(String name) {
1384:                    return (DTD.Element) elements.get(name);
1385:                }
1386:
1387:                /** Get List of all CharRefs whose aliases starts with given prefix. */
1388:                public List getCharRefList(String prefix) {
1389:                    List l = new ArrayList();
1390:                    Iterator i = charRefs.tailMap(prefix).entrySet().iterator();
1391:
1392:                    while (i.hasNext()) {
1393:                        Map.Entry entry = (Map.Entry) i.next();
1394:                        if (((String) entry.getKey()).startsWith(prefix)) {
1395:                            l.add(entry.getValue());
1396:                        } else { // we're getting data from SortedSet, so when any
1397:                            break; // entry fails, all remaining entry would fail.
1398:                        }
1399:                    }
1400:
1401:                    return l;
1402:                }
1403:
1404:                /** Get the CharRef of given name */
1405:                public DTD.CharRef getCharRef(String name) {
1406:                    return (DTD.CharRef) charRefs.get(name);
1407:                }
1408:
1409:                public String toString() {
1410:                    return super .toString() + "[id=" + id + ", elements="
1411:                            + elements + ",charRefs=" + charRefs + "]"; // NOI18N
1412:                }
1413:            }
1414:
1415:            /** Implementation of Element used by this DTDcreator. */
1416:            private static class ElementImpl implements  DTD.Element {
1417:
1418:                private String name;
1419:                private DTD.ContentModel model;
1420:                private boolean optStart;
1421:                private boolean optEnd;
1422:                private SortedMap attributes; // these are sorted just by name
1423:                private DTD dtd;
1424:
1425:                ElementImpl(String name, DTD.ContentModel model,
1426:                        boolean optStart, boolean optEnd, SortedMap attributes) {
1427:                    this .name = name;
1428:                    this .model = model;
1429:                    this .optStart = optStart;
1430:                    this .optEnd = optEnd;
1431:                    this .attributes = attributes;
1432:                }
1433:
1434:                /** Get the name of this Element */
1435:                public String getName() {
1436:                    return name;
1437:                }
1438:
1439:                /** Shorthand to resolving if content model of this Element is EMPTY */
1440:                public boolean isEmpty() {
1441:                    if (optEnd && model.getContent() instanceof  DTD.ContentLeaf)
1442:                        return true;
1443:                    // && ((DTD.ContentLeaf)model.getContent()).getName().equals(
1444:                    // "EMPTY" ) ) return true;
1445:                    return false;
1446:                }
1447:
1448:                /** Tells if this Element has optional Start Tag. */
1449:                public boolean hasOptionalStart() {
1450:                    return optStart;
1451:                }
1452:
1453:                /** Tells if this Element has optional End Tag. */
1454:                public boolean hasOptionalEnd() {
1455:                    return optEnd;
1456:                }
1457:
1458:                /**
1459:                 * Get the List of Attributes of this Element, which starts with given
1460:                 * <CODE>prefix</CODE>.
1461:                 */
1462:                public List getAttributeList(String prefix) {
1463:                    TreeSet set = new TreeSet(new Comparator() {
1464:                        public int compare(Object o1, Object o2) {
1465:                            if (isRequired(o1) && !isRequired(o2))
1466:                                return -1;
1467:                            if (!isRequired(o1) && isRequired(o2))
1468:                                return 1;
1469:                            return ((DTD.Attribute) o1).getName().compareTo(
1470:                                    ((DTD.Attribute) o2).getName());
1471:                        }
1472:
1473:                        private final boolean isRequired(Object o) {
1474:                            return ((DTD.Attribute) o).getDefaultMode().equals(
1475:                                    DTD.Attribute.MODE_REQUIRED);
1476:                        }
1477:                    });
1478:                    prefix = prefix.toLowerCase();
1479:                    Iterator i = attributes.tailMap(prefix).entrySet()
1480:                            .iterator();
1481:
1482:                    while (i.hasNext()) {
1483:                        Map.Entry entry = (Map.Entry) i.next();
1484:                        if (((String) entry.getKey()).startsWith(prefix)) {
1485:                            set.add(entry.getValue());
1486:                        } else { // we're getting data from SortedSet, so when any
1487:                            break; // entry fails, all remaining entry would fail.
1488:                        }
1489:                    }
1490:                    return new ArrayList(set);
1491:                }
1492:
1493:                /** Get the Attribute of given name. */
1494:                public DTD.Attribute getAttribute(String name) {
1495:                    return (DTD.Attribute) attributes.get(name);
1496:                }
1497:
1498:                void addAttribute(DTD.Attribute attr) {
1499:                    attributes.put(attr.getName(), attr);
1500:                }
1501:
1502:                /** Get the content model of this Element */
1503:                public DTD.ContentModel getContentModel() {
1504:                    return model;
1505:                }
1506:
1507:                public String toString() {
1508:                    return super .toString() + "[" + name
1509:                            + (optStart ? " O" : " -")
1510:                            + (optEnd ? " O " : " - ") + model + " attribs="
1511:                            + attributes + "]"; // NOI18
1512:                }
1513:            }
1514:
1515:            /** */
1516:            public static class AttributeImpl implements  DTD.Attribute {
1517:
1518:                private String name;
1519:                private int type;
1520:                private String baseType;
1521:                private String typeHelper;
1522:                private String defaultMode;
1523:                private SortedMap values;
1524:                private int hashcode;
1525:
1526:                public AttributeImpl(String name, int type, String baseType,
1527:                        String typeHelper, String defaultMode, SortedMap values) {
1528:                    this .name = name;
1529:                    this .type = type;
1530:                    this .baseType = baseType;
1531:                    this .typeHelper = typeHelper;
1532:                    this .defaultMode = defaultMode;
1533:                    this .values = values;
1534:                    hashcode = name.hashCode() * (type + 1)
1535:                            * (baseType == null ? 1 : baseType.hashCode())
1536:                            + (typeHelper == null ? 1 : typeHelper.hashCode())
1537:                            + defaultMode.hashCode()
1538:                            + (values == null ? 1 : values.hashCode());
1539:                }
1540:
1541:                /** @return name of this attribute */
1542:                public String getName() {
1543:                    return name;
1544:                }
1545:
1546:                /** @return type of this attribute */
1547:                public int getType() {
1548:                    return type;
1549:                }
1550:
1551:                public String getBaseType() {
1552:                    return baseType;
1553:                }
1554:
1555:                /** The last entity name through which was this Attribute's type defined. */
1556:                public String getTypeHelper() {
1557:                    return typeHelper;
1558:                }
1559:
1560:                /** This method is used to obtain default value information. */
1561:                public String getDefaultMode() {
1562:                    return defaultMode;
1563:                }
1564:
1565:                /** Shorthand for determining if defaultMode is "#REQUIRED" */
1566:                public boolean isRequired() {
1567:                    return defaultMode.equals(MODE_REQUIRED);
1568:                }
1569:
1570:                /**
1571:                 * The way how to obtain possible values for TYPE_SET Attributes
1572:                 * 
1573:                 * @param prefix
1574:                 *            required prefix, or <CODE>null</CODE>, if all possible
1575:                 *            values are required.
1576:                 * @return List of Values starting with prefix, from this attribute if
1577:                 *         it is of TYPE_SET. For other types, it doesn't make a sense
1578:                 *         and returns null.
1579:                 */
1580:                public List getValueList(String prefix) {
1581:                    if (type != TYPE_SET)
1582:                        return null;
1583:
1584:                    if (prefix == null)
1585:                        prefix = "";
1586:                    else
1587:                        prefix = prefix.toLowerCase();
1588:
1589:                    List retVal = new ArrayList();
1590:                    Iterator i = values.tailMap(prefix).entrySet().iterator();
1591:
1592:                    while (i.hasNext()) {
1593:                        Map.Entry entry = (Map.Entry) i.next();
1594:                        if (((String) entry.getKey()).startsWith(prefix)) {
1595:                            retVal.add(entry.getValue());
1596:                        } else { // we're getting data from SortedSet, so when any
1597:                            break; // entry fails, all remaining entry would fail.
1598:                        }
1599:                    }
1600:                    return retVal;
1601:                }
1602:
1603:                /** Get the value of given name. */
1604:                public DTD.Value getValue(String name) {
1605:                    return (DTD.Value) values.get(name);
1606:                }
1607:
1608:                public String toString() {
1609:                    if (type == TYPE_SET) {
1610:                        return name + " " + values + "[" + typeHelper + "] "
1611:                                + defaultMode; // NOI18
1612:                    } else if (type == TYPE_BOOLEAN) {
1613:                        return name + " (" + name + ")[" + typeHelper + "] "
1614:                                + defaultMode; // NOI18
1615:                    } else {
1616:                        return name + " " + baseType + "[" + typeHelper + "] "
1617:                                + defaultMode; // NOI18
1618:                    }
1619:                }
1620:
1621:                public int hashCode() {
1622:                    return hashcode;
1623:                }
1624:
1625:                public boolean equals(Object obj) {
1626:                    if (!(obj instanceof  AttributeImpl))
1627:                        return false;
1628:                    AttributeImpl a = (AttributeImpl) obj;
1629:                    return (hashcode == a.hashcode
1630:                            && name.equals(a.name)
1631:                            && type == a.type
1632:                            && (baseType == a.baseType || baseType != null
1633:                                    && baseType.equals(a.baseType))
1634:                            && (typeHelper == a.typeHelper || typeHelper != null
1635:                                    && typeHelper.equals(a.typeHelper))
1636:                            && defaultMode.equals(a.defaultMode) && (values == a.values || values != null
1637:                            && values.equals(a.values)));
1638:                }
1639:            }
1640:
1641:            private static class ValueImpl implements  DTD.Value {
1642:                String name;
1643:
1644:                ValueImpl(String name) {
1645:                    this .name = name;
1646:                }
1647:
1648:                public String getName() {
1649:                    return name;
1650:                }
1651:
1652:                public boolean equals(Object obj) {
1653:                    if (!(obj instanceof  ValueImpl))
1654:                        return false;
1655:                    return name.equals(((ValueImpl) obj).name);
1656:                }
1657:
1658:                public int hashCode() {
1659:                    return name.hashCode();
1660:                }
1661:
1662:                public String toString() {
1663:                    return name;
1664:                }
1665:            }
1666:
1667:            private static class CharRefImpl implements  DTD.CharRef {
1668:                private String name;
1669:                private char value;
1670:
1671:                CharRefImpl(String name, char value) {
1672:                    this .name = name;
1673:                    this .value = value;
1674:                }
1675:
1676:                /** @return alias to this CharRef */
1677:                public String getName() {
1678:                    return name;
1679:                }
1680:
1681:                /** @return the character this alias is for */
1682:                public char getValue() {
1683:                    return value;
1684:                }
1685:
1686:                public String toString() {
1687:                    return name + "->'" + value + "'(&#" + (int) value + ";)";
1688:                }
1689:
1690:                public boolean equals(Object obj) {
1691:                    if (!(obj instanceof  CharRefImpl))
1692:                        return false;
1693:                    return name.equals(((CharRefImpl) obj).name)
1694:                            && value == ((CharRefImpl) obj).value;
1695:                }
1696:
1697:                public int hashCode() {
1698:                    return name.hashCode() * value;
1699:                }
1700:            }
1701:
1702:            /** The implementation of ContentModel. It is immutable */
1703:            private static class ContentModelImpl implements  DTD.ContentModel {
1704:                int hashcode;
1705:                DTD.Content content;
1706:                Set included;
1707:                Set excluded;
1708:
1709:                public ContentModelImpl(DTD.Content content, Set included,
1710:                        Set excluded) {
1711:                    this .content = content;
1712:                    this .included = included;
1713:                    this .excluded = excluded;
1714:                    hashcode = content.hashCode() + 2 * included.hashCode() + 3
1715:                            * excluded.hashCode();
1716:                }
1717:
1718:                /** @return the Content tree part of this model */
1719:                public DTD.Content getContent() {
1720:                    return content;
1721:                }
1722:
1723:                /** @return Set of Element names which are recursively included. */
1724:                public Set getIncludes() {
1725:                    return included;
1726:                }
1727:
1728:                /** @return Set of Element names which are recursively excluded. */
1729:                public Set getExcludes() {
1730:                    return excluded;
1731:                }
1732:
1733:                public String toString() {
1734:                    StringBuffer sb = new StringBuffer(content.toString());
1735:
1736:                    if (!included.isEmpty()) {
1737:                        sb.append(" +(");
1738:                        Iterator i = included.iterator();
1739:                        for (;;) {
1740:                            sb.append(((DTD.Element) i.next()).getName());
1741:                            if (i.hasNext())
1742:                                sb.append("|");
1743:                            else
1744:                                break;
1745:                        }
1746:                        sb.append(")");
1747:                    }
1748:
1749:                    if (!excluded.isEmpty()) {
1750:                        sb.append(" -(");
1751:                        Iterator i = excluded.iterator();
1752:                        for (;;) {
1753:                            sb.append(((DTD.Element) i.next()).getName());
1754:                            if (i.hasNext())
1755:                                sb.append("|");
1756:                            else
1757:                                break;
1758:                        }
1759:                        sb.append(")");
1760:                    }
1761:
1762:                    return sb.toString();
1763:                }
1764:
1765:                public boolean equals(Object obj) {
1766:                    if (!(obj instanceof  ContentModelImpl))
1767:                        return false;
1768:                    ContentModelImpl cmi = (ContentModelImpl) obj;
1769:                    return content.equals(cmi.content)
1770:                            && included.equals(cmi.included)
1771:                            && excluded.equals(cmi.excluded);
1772:                }
1773:
1774:                public int hashCode() {
1775:                    return hashcode;
1776:                }
1777:
1778:            }
1779:
1780:            /**
1781:             * ContentLeaf is leaf of content tree, matches just one Element name
1782:             * (String)
1783:             */
1784:            static class ContentLeafImpl implements  DTD.ContentLeaf {
1785:                String elemName;
1786:                DTD.Element elem;
1787:
1788:                public ContentLeafImpl(String name) {
1789:                    this .elemName = name;
1790:                }
1791:
1792:                /** get the name of leaf Element */
1793:                public String getName() {
1794:                    return elemName;
1795:                }
1796:
1797:                public DTD.Element getElement() {
1798:                    return elem;
1799:                }
1800:
1801:                public boolean equals(Object obj) {
1802:                    if (!(obj instanceof  ContentLeafImpl))
1803:                        return false;
1804:                    return elemName.equals(((ContentLeafImpl) obj).elemName);
1805:                }
1806:
1807:                public int hashCode() {
1808:                    return elemName.hashCode();
1809:                }
1810:
1811:                public String toString() {
1812:                    return elemName;
1813:                }
1814:
1815:                /** ContentLeaf can't be discarded as it hac no operation associated */
1816:                public boolean isDiscardable() {
1817:                    return false;
1818:                }
1819:
1820:                /**
1821:                 * ContentLeaf is either reduced to EMPTY_CONTENT or doesn't match at
1822:                 * all
1823:                 */
1824:                public DTD.Content reduce(String elementName) {
1825:                    if (elemName.equals(elementName))
1826:                        return EMPTY_CONTENT;
1827:                    return null;
1828:                }
1829:
1830:                public Set getPossibleElements() {
1831:                    Set s = new HashSet();
1832:                    s.add(elem);
1833:                    return s;
1834:                }
1835:            }
1836:
1837:            /** ContentNode is node of content tree */
1838:            private static class UnaryContentNodeImpl implements 
1839:                    DTD.ContentNode {
1840:                int hashcode;
1841:                char type;
1842:                DTD.Content content;
1843:
1844:                /* Constructor for unary ContentNodes */
1845:                public UnaryContentNodeImpl(char type, DTD.Content content) {
1846:                    // sanity check:
1847:                    if (type != '*' && type != '?' && type != '+') {
1848:                        throw new IllegalArgumentException(
1849:                                "Unknown unary content type '" + type + "'");
1850:                    }
1851:
1852:                    this .type = type;
1853:                    this .content = content;
1854:                    hashcode = type + content.hashCode();
1855:                }
1856:
1857:                /** This is node, always return false */
1858:                public boolean isLeaf() {
1859:                    return false;
1860:                }
1861:
1862:                /** Get the operator for this node */
1863:                public char getType() {
1864:                    return type;
1865:                }
1866:
1867:                /** Get the content of this node */
1868:                public DTD.Content[] getContent() {
1869:                    return new DTD.Content[] { content };
1870:                }
1871:
1872:                public boolean equals(Object obj) {
1873:                    if (!(obj instanceof  UnaryContentNodeImpl))
1874:                        return false;
1875:                    return type == ((UnaryContentNodeImpl) obj).type
1876:                            && content
1877:                                    .equals(((UnaryContentNodeImpl) obj).content);
1878:                }
1879:
1880:                public int hashCode() {
1881:                    return hashcode;
1882:                }
1883:
1884:                public String toString() {
1885:                    return content.toString() + type;
1886:                }
1887:
1888:                public boolean isDiscardable() {
1889:                    if (type == '*' || type == '?')
1890:                        return true;
1891:                    // The only remaining type, don't check: if( type == '+' )
1892:                    return content.isDiscardable();
1893:                }
1894:
1895:                public DTD.Content reduce(String elementName) {
1896:                    DTD.Content sub = content.reduce(elementName);
1897:                    if (sub == null)
1898:                        return null;
1899:                    if (sub == EMPTY_CONTENT) {
1900:                        if (type == '?')
1901:                            return EMPTY_CONTENT;
1902:                        if (type == '*')
1903:                            return this ;
1904:                        // '+' is the last one: if( type == '+' )
1905:                        // we fullfilled the '+' rule, remainder is '*'
1906:                        return new UnaryContentNodeImpl('*', content);
1907:                    }
1908:                    if (type == '?')
1909:                        return sub;
1910:                    DTD.Content second = (type == '*') ? this 
1911:                            : new UnaryContentNodeImpl('*', content);
1912:                    return new MultiContentNodeImpl(',', new DTD.Content[] {
1913:                            sub, second });
1914:                }
1915:
1916:                public Set getPossibleElements() {
1917:                    return content.getPossibleElements();
1918:                }
1919:
1920:            }
1921:
1922:            /** ContentNodeImpl is n-ary node of content tree */
1923:            private static class MultiContentNodeImpl implements 
1924:                    DTD.ContentNode {
1925:                int hashcode;
1926:                char type;
1927:                DTD.Content[] content;
1928:
1929:                /* Constructor for n-ary ContentNodes */
1930:                public MultiContentNodeImpl(char type, DTD.Content[] content) {
1931:                    // sanity check:
1932:                    if (type != '|' && type != '&' && type != ',') {
1933:                        throw new IllegalArgumentException(
1934:                                "Unknown n-ary content type '" + type + "'");
1935:                    }
1936:
1937:                    this .type = type;
1938:                    this .content = content;
1939:                    hashcode = type;
1940:                    for (int i = 0; i < content.length; i++) {
1941:                        hashcode += content[i].hashCode();
1942:                    }
1943:                }
1944:
1945:                /** This is node, always return false */
1946:                public boolean isLeaf() {
1947:                    return false;
1948:                }
1949:
1950:                /** Get the operator for this node */
1951:                public char getType() {
1952:                    return type;
1953:                }
1954:
1955:                /** Get the content of this node */
1956:                public DTD.Content[] getContent() {
1957:                    return content;
1958:                }
1959:
1960:                public boolean equals(Object obj) {
1961:                    if (!(obj instanceof  MultiContentNodeImpl))
1962:                        return false;
1963:                    return type == ((MultiContentNodeImpl) obj).type
1964:                            && Arrays.equals(content,
1965:                                    ((MultiContentNodeImpl) obj).content);
1966:                }
1967:
1968:                public String toString() {
1969:                    StringBuffer sb = new StringBuffer("(");
1970:                    for (int i = 0; i < content.length; i++) {
1971:                        sb.append(content[i].toString());
1972:                        if (i + 1 < content.length)
1973:                            sb.append(type);
1974:                    }
1975:                    sb.append(')');
1976:                    return sb.toString();
1977:                }
1978:
1979:                public int hashCode() {
1980:                    return hashcode;
1981:                }
1982:
1983:                public boolean isDiscardable() {
1984:                    if (type == '&' || type == ',') {
1985:                        for (int i = 0; i < content.length; i++) {
1986:                            if (!content[i].isDiscardable())
1987:                                return false;
1988:                        }
1989:                        return true;
1990:                    }
1991:                    // The only remaining type, don't check: if( type == '|' )
1992:                    for (int i = 0; i < content.length; i++) {
1993:                        if (content[i].isDiscardable())
1994:                            return true;
1995:                    }
1996:                    return false;
1997:                }
1998:
1999:                public DTD.Content reduce(String elementName) {
2000:
2001:                    if (type == '|') {
2002:                        for (int index = 0; index < content.length; index++) {
2003:                            DTD.Content sub = content[index]
2004:                                    .reduce(elementName);
2005:                            if (sub != null)
2006:                                return sub;
2007:                        }
2008:                        return null;
2009:                    } else if (type == ',') {
2010:                        // everything before index doesn't match and is discardable
2011:                        int index = 0;
2012:
2013:                        while (index < content.length) {
2014:                            DTD.Content sub = content[index]
2015:                                    .reduce(elementName);
2016:                            // element of sequence still don't match and isn't
2017:                            // discardable:
2018:                            if (sub == null && !content[index].isDiscardable())
2019:                                return null;
2020:
2021:                            // Element matches fully:
2022:                            if (sub == EMPTY_CONTENT) {
2023:                                int newLen = content.length - index - 1;
2024:                                if (newLen > 1) { // resulting sequence contains 2+
2025:                                    // elements
2026:                                    DTD.Content[] newSub = new DTD.Content[newLen];
2027:                                    System.arraycopy(content, index + 1,
2028:                                            newSub, 0, newLen);
2029:                                    return new MultiContentNodeImpl(',', newSub);
2030:                                } else { // resulting sequence is one-item only
2031:                                    return content[index + 1];
2032:                                }
2033:                            }
2034:
2035:                            // Element matches and is modified
2036:                            if (sub != null) {
2037:                                int newLen = content.length - index;
2038:                                if (newLen > 1) { // resulting sequence contains 2+
2039:                                    // elements
2040:                                    DTD.Content[] newSub = new DTD.Content[newLen];
2041:                                    System.arraycopy(content, index + 1,
2042:                                            newSub, 1, newLen - 1);
2043:                                    newSub[0] = sub;
2044:                                    return new MultiContentNodeImpl(',', newSub);
2045:                                } else { // resulting sequence is one modified item only
2046:                                    return sub;
2047:                                }
2048:                            }
2049:                            index++; // discard the first element and try again
2050:                        }
2051:
2052:                        return null; // Doesn't match at all
2053:                    } else { // only '&' remains: if( type == '&' ) {
2054:                        for (int index = 0; index < content.length; index++) {
2055:                            DTD.Content sub = content[index]
2056:                                    .reduce(elementName);
2057:                            if (sub == EMPTY_CONTENT) {
2058:                                int newLen = content.length - 1;
2059:                                if (newLen > 1) {
2060:                                    DTD.Content[] newSub = new DTD.Content[newLen];
2061:                                    System.arraycopy(content, 0, newSub, 0,
2062:                                            index);
2063:                                    if (index < newSub.length) {
2064:                                        System.arraycopy(content, index + 1,
2065:                                                newSub, index, newLen - index);
2066:                                    }
2067:                                    return new MultiContentNodeImpl('&', newSub);
2068:                                } else {
2069:                                    return content[1 - index];
2070:                                }
2071:                            }
2072:                            if (sub != null) {
2073:                                DTD.Content right;
2074:                                if (content.length > 1) {
2075:                                    int newLen = content.length - 1;
2076:                                    DTD.Content[] newSub = new DTD.Content[newLen];
2077:                                    System.arraycopy(content, 0, newSub, 0,
2078:                                            index);
2079:                                    if (index < newSub.length) {
2080:                                        System.arraycopy(content, index + 1,
2081:                                                newSub, index, newLen - index);
2082:                                    }
2083:                                    right = new MultiContentNodeImpl('&',
2084:                                            newSub);
2085:                                } else {
2086:                                    right = content[1 - index];
2087:                                }
2088:                                return new MultiContentNodeImpl(',',
2089:                                        new DTD.Content[] { sub, right });
2090:                            }
2091:                        }
2092:                        return null;
2093:
2094:                    }
2095:                }
2096:
2097:                public Set getPossibleElements() {
2098:                    Set retVal = new HashSet(11);
2099:
2100:                    if (type == '|' || type == '&') {
2101:                        for (int index = 0; index < content.length; index++)
2102:                            retVal.addAll(content[index].getPossibleElements());
2103:
2104:                    } else { // only ',' remains if( type == ',' ) {}
2105:                        int index = 0;
2106:                        while (index < content.length) {
2107:                            retVal.addAll(content[index].getPossibleElements());
2108:                            if (!content[index].isDiscardable())
2109:                                break;
2110:                            index++;
2111:                        }
2112:                    }
2113:                    return retVal;
2114:                }
2115:            }
2116:
2117:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.