Source Code Cross Referenced for EmitterImpl.java in  » Scripting » jruby » org » jvyamlb » 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 » Scripting » jruby » org.jvyamlb 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /***** BEGIN LICENSE BLOCK *****
0002:         * Version: CPL 1.0/GPL 2.0/LGPL 2.1
0003:         *
0004:         * The contents of this file are subject to the Common Public
0005:         * License Version 1.0 (the "License"); you may not use this file
0006:         * except in compliance with the License. You may obtain a copy of
0007:         * the License at http://www.eclipse.org/legal/cpl-v10.html
0008:         *
0009:         * Software distributed under the License is distributed on an "AS
0010:         * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
0011:         * implied. See the License for the specific language governing
0012:         * rights and limitations under the License.
0013:         *
0014:         * Copyright (C) 2007 Ola Bini <ola@ologix.com>
0015:         * 
0016:         * Alternatively, the contents of this file may be used under the terms of
0017:         * either of the GNU General Public License Version 2 or later (the "GPL"),
0018:         * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
0019:         * in which case the provisions of the GPL or the LGPL are applicable instead
0020:         * of those above. If you wish to allow use of your version of this file only
0021:         * under the terms of either the GPL or the LGPL, and not to allow others to
0022:         * use your version of this file under the terms of the CPL, indicate your
0023:         * decision by deleting the provisions above and replace them with the notice
0024:         * and other provisions required by the GPL or the LGPL. If you do not delete
0025:         * the provisions above, a recipient may use your version of this file under
0026:         * the terms of any one of the CPL, the GPL or the LGPL.
0027:         ***** END LICENSE BLOCK *****/package org.jvyamlb;
0028:
0029:        import java.io.IOException;
0030:        import java.io.OutputStream;
0031:        import java.io.BufferedInputStream;
0032:        import java.io.FileInputStream;
0033:
0034:        import java.util.HashMap;
0035:        import java.util.List;
0036:        import java.util.Map;
0037:        import java.util.ArrayList;
0038:        import java.util.Iterator;
0039:        import java.util.Set;
0040:        import java.util.TreeSet;
0041:
0042:        import java.util.regex.Pattern;
0043:
0044:        import org.jvyamlb.events.Event;
0045:        import org.jvyamlb.events.StreamStartEvent;
0046:        import org.jvyamlb.events.StreamEndEvent;
0047:        import org.jvyamlb.events.DocumentStartEvent;
0048:        import org.jvyamlb.events.DocumentEndEvent;
0049:        import org.jvyamlb.events.CollectionStartEvent;
0050:        import org.jvyamlb.events.CollectionEndEvent;
0051:        import org.jvyamlb.events.MappingStartEvent;
0052:        import org.jvyamlb.events.SequenceStartEvent;
0053:        import org.jvyamlb.events.MappingEndEvent;
0054:        import org.jvyamlb.events.SequenceEndEvent;
0055:        import org.jvyamlb.events.AliasEvent;
0056:        import org.jvyamlb.events.ScalarEvent;
0057:        import org.jvyamlb.events.NodeEvent;
0058:
0059:        import org.jruby.util.ByteList;
0060:
0061:        /**
0062:         * @author <a href="mailto:ola.bini@ki.se">Ola Bini</a>
0063:         */
0064:        public class EmitterImpl implements  Emitter {
0065:            private static class ScalarAnalysis {
0066:                public ByteList scalar;
0067:                public boolean empty;
0068:                public boolean multiline;
0069:                public boolean allowFlowPlain;
0070:                public boolean allowBlockPlain;
0071:                public boolean allowSingleQuoted;
0072:                public boolean allowDoubleQuoted;
0073:                public boolean allowBlock;
0074:
0075:                public ScalarAnalysis(final ByteList scalar,
0076:                        final boolean empty, final boolean multiline,
0077:                        final boolean allowFlowPlain,
0078:                        final boolean allowBlockPlain,
0079:                        final boolean allowSingleQuoted,
0080:                        final boolean allowDoubleQuoted,
0081:                        final boolean allowBlock) {
0082:                    this .scalar = scalar;
0083:                    this .empty = empty;
0084:                    this .multiline = multiline;
0085:                    this .allowFlowPlain = allowFlowPlain;
0086:                    this .allowBlockPlain = allowBlockPlain;
0087:                    this .allowSingleQuoted = allowSingleQuoted;
0088:                    this .allowDoubleQuoted = allowDoubleQuoted;
0089:                    this .allowBlock = allowBlock;
0090:                }
0091:            }
0092:
0093:            private static interface EmitterState {
0094:                void expect(final EmitterEnvironment env) throws IOException;
0095:            }
0096:
0097:            private static final int STREAM_START = 0;
0098:            private static final int FIRST_DOCUMENT_START = 1;
0099:            private static final int DOCUMENT_ROOT = 2;
0100:            private static final int NOTHING = 3;
0101:            private static final int DOCUMENT_START = 4;
0102:            private static final int DOCUMENT_END = 5;
0103:            private static final int FIRST_FLOW_SEQUENCE_ITEM = 6;
0104:            private static final int FLOW_SEQUENCE_ITEM = 7;
0105:            private static final int FIRST_FLOW_MAPPING_KEY = 8;
0106:            private static final int FLOW_MAPPING_SIMPLE_VALUE = 9;
0107:            private static final int FLOW_MAPPING_VALUE = 10;
0108:            private static final int FLOW_MAPPING_KEY = 11;
0109:            private static final int BLOCK_SEQUENCE_ITEM = 12;
0110:            private static final int FIRST_BLOCK_MAPPING_KEY = 13;
0111:            private static final int BLOCK_MAPPING_SIMPLE_VALUE = 14;
0112:            private static final int BLOCK_MAPPING_VALUE = 15;
0113:            private static final int BLOCK_MAPPING_KEY = 16;
0114:            private static final int FIRST_BLOCK_SEQUENCE_ITEM = 17;
0115:
0116:            private static final EmitterState[] STATES = new EmitterState[18];
0117:            static {
0118:                STATES[STREAM_START] = new EmitterState() {
0119:                    public void expect(final EmitterEnvironment env) {
0120:                        env.expectStreamStart();
0121:                    }
0122:                };
0123:                STATES[FIRST_DOCUMENT_START] = new EmitterState() {
0124:                    public void expect(final EmitterEnvironment env)
0125:                            throws IOException {
0126:                        env.expectDocumentStart(true);
0127:                    }
0128:                };
0129:                STATES[DOCUMENT_ROOT] = new EmitterState() {
0130:                    public void expect(final EmitterEnvironment env)
0131:                            throws IOException {
0132:                        env.expectDocumentRoot();
0133:                    }
0134:                };
0135:                STATES[NOTHING] = new EmitterState() {
0136:                    public void expect(final EmitterEnvironment env) {
0137:                        env.expectNothing();
0138:                    }
0139:                };
0140:                STATES[DOCUMENT_START] = new EmitterState() {
0141:                    public void expect(final EmitterEnvironment env)
0142:                            throws IOException {
0143:                        env.expectDocumentStart(false);
0144:                    }
0145:                };
0146:                STATES[DOCUMENT_END] = new EmitterState() {
0147:                    public void expect(final EmitterEnvironment env)
0148:                            throws IOException {
0149:                        env.expectDocumentEnd();
0150:                    }
0151:                };
0152:                STATES[FIRST_FLOW_SEQUENCE_ITEM] = new EmitterState() {
0153:                    public void expect(final EmitterEnvironment env)
0154:                            throws IOException {
0155:                        env.expectFirstFlowSequenceItem();
0156:                    }
0157:                };
0158:                STATES[FLOW_SEQUENCE_ITEM] = new EmitterState() {
0159:                    public void expect(final EmitterEnvironment env)
0160:                            throws IOException {
0161:                        env.expectFlowSequenceItem();
0162:                    }
0163:                };
0164:                STATES[FIRST_FLOW_MAPPING_KEY] = new EmitterState() {
0165:                    public void expect(final EmitterEnvironment env)
0166:                            throws IOException {
0167:                        env.expectFirstFlowMappingKey();
0168:                    }
0169:                };
0170:                STATES[FLOW_MAPPING_SIMPLE_VALUE] = new EmitterState() {
0171:                    public void expect(final EmitterEnvironment env)
0172:                            throws IOException {
0173:                        env.expectFlowMappingSimpleValue();
0174:                    }
0175:                };
0176:                STATES[FLOW_MAPPING_VALUE] = new EmitterState() {
0177:                    public void expect(final EmitterEnvironment env)
0178:                            throws IOException {
0179:                        env.expectFlowMappingValue();
0180:                    }
0181:                };
0182:                STATES[FLOW_MAPPING_KEY] = new EmitterState() {
0183:                    public void expect(final EmitterEnvironment env)
0184:                            throws IOException {
0185:                        env.expectFlowMappingKey();
0186:                    }
0187:                };
0188:                STATES[BLOCK_SEQUENCE_ITEM] = new EmitterState() {
0189:                    public void expect(final EmitterEnvironment env)
0190:                            throws IOException {
0191:                        env.expectBlockSequenceItem(false);
0192:                    }
0193:                };
0194:                STATES[FIRST_BLOCK_MAPPING_KEY] = new EmitterState() {
0195:                    public void expect(final EmitterEnvironment env)
0196:                            throws IOException {
0197:                        env.expectFirstBlockMappingKey();
0198:                    }
0199:                };
0200:                STATES[BLOCK_MAPPING_SIMPLE_VALUE] = new EmitterState() {
0201:                    public void expect(final EmitterEnvironment env)
0202:                            throws IOException {
0203:                        env.expectBlockMappingSimpleValue();
0204:                    }
0205:                };
0206:                STATES[BLOCK_MAPPING_VALUE] = new EmitterState() {
0207:                    public void expect(final EmitterEnvironment env)
0208:                            throws IOException {
0209:                        env.expectBlockMappingValue();
0210:                    }
0211:                };
0212:                STATES[BLOCK_MAPPING_KEY] = new EmitterState() {
0213:                    public void expect(final EmitterEnvironment env)
0214:                            throws IOException {
0215:                        env.expectBlockMappingKey(false);
0216:                    }
0217:                };
0218:                STATES[FIRST_BLOCK_SEQUENCE_ITEM] = new EmitterState() {
0219:                    public void expect(final EmitterEnvironment env)
0220:                            throws IOException {
0221:                        env.expectBlockSequenceItem(true);
0222:                    }
0223:                };
0224:            }
0225:
0226:            private final static Map DEFAULT_TAG_PREFIXES_1_0;
0227:            private final static Map DEFAULT_TAG_PREFIXES_1_1;
0228:            static {
0229:                final Map defInit0 = new HashMap();
0230:                defInit0.put("tag:yaml.org,2002:", "!");
0231:                DEFAULT_TAG_PREFIXES_1_0 = java.util.Collections
0232:                        .unmodifiableMap(defInit0);
0233:                final Map defInit = new HashMap();
0234:                defInit.put("!", "!");
0235:                defInit.put("tag:yaml.org,2002:", "!!");
0236:                DEFAULT_TAG_PREFIXES_1_1 = java.util.Collections
0237:                        .unmodifiableMap(defInit);
0238:            }
0239:
0240:            private OutputStream stream;
0241:            private YAMLConfig options;
0242:            private EmitterEnvironment env;
0243:
0244:            public EmitterImpl(final OutputStream stream, final YAMLConfig opts) {
0245:                this .stream = stream;
0246:                this .options = opts;
0247:                this .env = new EmitterEnvironment();
0248:                this .env.emitter = this ;
0249:                this .env.canonical = this .options.canonical();
0250:                final int propIndent = this .options.indent();
0251:                if (propIndent >= 2 && propIndent < 10) {
0252:                    this .env.bestIndent = propIndent;
0253:                }
0254:                final int propWidth = this .options.bestWidth();
0255:                if (propWidth != 0 && propWidth > (this .env.bestIndent * 2)) {
0256:                    this .env.bestWidth = propWidth;
0257:                }
0258:            }
0259:
0260:            public YAMLConfig getOptions() {
0261:                return options;
0262:            }
0263:
0264:            public void emit(final Event event) throws IOException {
0265:                this .env.events.add(event);
0266:                while (!this .env.needMoreEvents()) {
0267:                    this .env.event = (Event) this .env.events.remove(0);
0268:                    STATES[this .env.state].expect(env);
0269:                    this .env.event = null;
0270:                }
0271:            }
0272:
0273:            private static class EmitterEnvironment {
0274:                public List states = new ArrayList();
0275:                public int state = STREAM_START;
0276:                public List events = new ArrayList();
0277:                public Event event;
0278:                public int flowLevel = 0;
0279:                public List indents = new ArrayList();
0280:                public int indent = -1;
0281:                public boolean rootContext = false;
0282:                public boolean sequenceContext = false;
0283:                public boolean mappingContext = false;
0284:                public boolean simpleKeyContext = false;
0285:
0286:                public int line = 0;
0287:                public int column = 0;
0288:                public boolean whitespace = true;
0289:                public boolean indentation = true;
0290:
0291:                public boolean canonical = false;
0292:                public int bestIndent = 2;
0293:                public int bestWidth = 80;
0294:
0295:                public ByteList bestLinebreak = ByteList.create("\n");
0296:
0297:                public Map tagPrefixes;
0298:
0299:                public String preparedAnchor;
0300:                public String preparedTag;
0301:
0302:                public ScalarAnalysis analysis;
0303:                public char style = 0;
0304:
0305:                public EmitterImpl emitter;
0306:
0307:                public boolean isVersion10 = false;
0308:
0309:                public boolean needMoreEvents() {
0310:                    if (events.isEmpty()) {
0311:                        return true;
0312:                    }
0313:                    event = (Event) events.get(0);
0314:                    if (event instanceof  DocumentStartEvent) {
0315:                        return needEvents(1);
0316:                    } else if (event instanceof  SequenceStartEvent) {
0317:                        return needEvents(2);
0318:                    } else if (event instanceof  MappingStartEvent) {
0319:                        return needEvents(3);
0320:                    } else {
0321:                        return false;
0322:                    }
0323:                }
0324:
0325:                private boolean needEvents(final int count) {
0326:                    int level = 0;
0327:                    final Iterator iter = events.iterator();
0328:                    iter.next();
0329:                    for (; iter.hasNext();) {
0330:                        final Object curr = iter.next();
0331:                        if (curr instanceof  DocumentStartEvent
0332:                                || curr instanceof  CollectionStartEvent) {
0333:                            level++;
0334:                        } else if (curr instanceof  DocumentEndEvent
0335:                                || curr instanceof  CollectionEndEvent) {
0336:                            level--;
0337:                        } else if (curr instanceof  StreamEndEvent) {
0338:                            level = -1;
0339:                        }
0340:                        if (level < 0) {
0341:                            return false;
0342:                        }
0343:                    }
0344:                    return events.size() < count + 1;
0345:                }
0346:
0347:                private void increaseIndent(final boolean flow,
0348:                        final boolean indentless) {
0349:                    indents.add(0, new Integer(indent));
0350:                    if (indent == -1) {
0351:                        if (flow) {
0352:                            indent = bestIndent;
0353:                        } else {
0354:                            indent = 0;
0355:                        }
0356:                    } else if (!indentless) {
0357:                        indent += bestIndent;
0358:                    }
0359:                }
0360:
0361:                public void expectStreamStart() {
0362:                    if (this .event instanceof  StreamStartEvent) {
0363:                        emitter.writeStreamStart();
0364:                        this .state = FIRST_DOCUMENT_START;
0365:                    } else {
0366:                        throw new EmitterException(
0367:                                "expected StreamStartEvent, but got "
0368:                                        + this .event);
0369:                    }
0370:                }
0371:
0372:                public void expectNothing() {
0373:                    throw new EmitterException("expecting nothing, but got "
0374:                            + this .event);
0375:                }
0376:
0377:                public void expectDocumentStart(final boolean first)
0378:                        throws IOException {
0379:                    if (event instanceof  DocumentStartEvent) {
0380:                        final DocumentStartEvent ev = (DocumentStartEvent) event;
0381:                        if (first) {
0382:                            if (null != ev.getVersion()) {
0383:                                emitter.writeVersionDirective(prepareVersion(ev
0384:                                        .getVersion()));
0385:                            }
0386:
0387:                            if ((null != ev.getVersion() && ev.getVersion()[1] == 0)
0388:                                    || emitter.getOptions().version().equals(
0389:                                            "1.0")) {
0390:                                isVersion10 = true;
0391:                                tagPrefixes = new HashMap(
0392:                                        DEFAULT_TAG_PREFIXES_1_0);
0393:                            } else {
0394:                                tagPrefixes = new HashMap(
0395:                                        DEFAULT_TAG_PREFIXES_1_1);
0396:                            }
0397:
0398:                            if (null != ev.getTags()) {
0399:                                final Set handles = new TreeSet();
0400:                                handles.addAll(ev.getTags().keySet());
0401:                                for (final Iterator iter = handles.iterator(); iter
0402:                                        .hasNext();) {
0403:                                    final String handle = (String) iter.next();
0404:                                    final String prefix = (String) ev.getTags()
0405:                                            .get(handle);
0406:                                    tagPrefixes.put(prefix, handle);
0407:                                    final String handleText = prepareTagHandle(handle);
0408:                                    final String prefixText = prepareTagPrefix(prefix);
0409:                                    emitter.writeTagDirective(handleText,
0410:                                            prefixText);
0411:                                }
0412:                            }
0413:                        }
0414:
0415:                        final boolean implicit = first && !ev.getExplicit()
0416:                                && !canonical && ev.getVersion() == null
0417:                                && ev.getTags() == null
0418:                                && !checkEmptyDocument();
0419:                        if (!implicit) {
0420:                            emitter.writeIndent();
0421:                            emitter.writeIndicator(ByteList.create("--- "),
0422:                                    true, true, false);
0423:                            if (canonical) {
0424:                                emitter.writeIndent();
0425:                            }
0426:                        }
0427:                        state = DOCUMENT_ROOT;
0428:                    } else if (event instanceof  StreamEndEvent) {
0429:                        emitter.writeStreamEnd();
0430:                        state = NOTHING;
0431:                    } else {
0432:                        throw new EmitterException(
0433:                                "expected DocumentStartEvent, but got " + event);
0434:                    }
0435:                }
0436:
0437:                public void expectDocumentRoot() throws IOException {
0438:                    states.add(0, new Integer(DOCUMENT_END));
0439:                    expectNode(true, false, false, false);
0440:                }
0441:
0442:                public void expectDocumentEnd() throws IOException {
0443:                    if (event instanceof  DocumentEndEvent) {
0444:                        emitter.writeIndent();
0445:                        if (((DocumentEndEvent) event).getExplicit()) {
0446:                            emitter.writeIndicator(ByteList.create("..."),
0447:                                    true, false, false);
0448:                            emitter.writeIndent();
0449:                        }
0450:                        emitter.flushStream();
0451:                        state = DOCUMENT_START;
0452:                    } else {
0453:                        throw new EmitterException(
0454:                                "expected DocumentEndEvent, but got " + event);
0455:                    }
0456:                }
0457:
0458:                public void expectFirstFlowSequenceItem() throws IOException {
0459:                    if (event instanceof  SequenceEndEvent) {
0460:                        indent = ((Integer) indents.remove(0)).intValue();
0461:                        flowLevel--;
0462:                        emitter.writeIndicator(ByteList.create("]"), false,
0463:                                false, false);
0464:                        state = ((Integer) states.remove(0)).intValue();
0465:                    } else {
0466:                        if (canonical || column > bestWidth) {
0467:                            emitter.writeIndent();
0468:                        }
0469:                        states.add(0, new Integer(FLOW_SEQUENCE_ITEM));
0470:                        expectNode(false, true, false, false);
0471:                    }
0472:                }
0473:
0474:                public void expectFlowSequenceItem() throws IOException {
0475:                    if (event instanceof  SequenceEndEvent) {
0476:                        indent = ((Integer) indents.remove(0)).intValue();
0477:                        flowLevel--;
0478:                        if (canonical) {
0479:                            emitter.writeIndicator(ByteList.create(","), false,
0480:                                    false, false);
0481:                            emitter.writeIndent();
0482:                        }
0483:                        emitter.writeIndicator(ByteList.create("]"), false,
0484:                                false, false);
0485:                        state = ((Integer) states.remove(0)).intValue();
0486:                    } else {
0487:                        emitter.writeIndicator(ByteList.create(","), false,
0488:                                false, false);
0489:                        if (canonical || column > bestWidth) {
0490:                            emitter.writeIndent();
0491:                        }
0492:                        states.add(0, new Integer(FLOW_SEQUENCE_ITEM));
0493:                        expectNode(false, true, false, false);
0494:                    }
0495:                }
0496:
0497:                public void expectFirstFlowMappingKey() throws IOException {
0498:                    if (event instanceof  MappingEndEvent) {
0499:                        indent = ((Integer) indents.remove(0)).intValue();
0500:                        flowLevel--;
0501:                        emitter.writeIndicator(ByteList.create("}"), false,
0502:                                false, false);
0503:                        state = ((Integer) states.remove(0)).intValue();
0504:                    } else {
0505:                        if (canonical || column > bestWidth) {
0506:                            emitter.writeIndent();
0507:                        }
0508:                        if (!canonical && checkSimpleKey()) {
0509:                            states.add(0,
0510:                                    new Integer(FLOW_MAPPING_SIMPLE_VALUE));
0511:                            expectNode(false, false, true, true);
0512:                        } else {
0513:                            emitter.writeIndicator(ByteList.create("?"), true,
0514:                                    false, false);
0515:                            states.add(0, new Integer(FLOW_MAPPING_VALUE));
0516:                            expectNode(false, false, true, false);
0517:                        }
0518:                    }
0519:                }
0520:
0521:                public void expectFlowMappingSimpleValue() throws IOException {
0522:                    emitter.writeIndicator(ByteList.create(": "), false, true,
0523:                            false);
0524:                    states.add(0, new Integer(FLOW_MAPPING_KEY));
0525:                    expectNode(false, false, true, false);
0526:                }
0527:
0528:                public void expectFlowMappingValue() throws IOException {
0529:                    if (canonical || column > bestWidth) {
0530:                        emitter.writeIndent();
0531:                    }
0532:                    emitter.writeIndicator(ByteList.create(": "), false, true,
0533:                            false);
0534:                    states.add(0, new Integer(FLOW_MAPPING_KEY));
0535:                    expectNode(false, false, true, false);
0536:                }
0537:
0538:                public void expectFlowMappingKey() throws IOException {
0539:                    if (event instanceof  MappingEndEvent) {
0540:                        indent = ((Integer) indents.remove(0)).intValue();
0541:                        flowLevel--;
0542:                        if (canonical) {
0543:                            emitter.writeIndicator(ByteList.create(","), false,
0544:                                    false, false);
0545:                            emitter.writeIndent();
0546:                        }
0547:                        emitter.writeIndicator(ByteList.create("}"), false,
0548:                                false, false);
0549:                        state = ((Integer) states.remove(0)).intValue();
0550:                    } else {
0551:                        emitter.writeIndicator(ByteList.create(","), false,
0552:                                false, false);
0553:                        if (canonical || column > bestWidth) {
0554:                            emitter.writeIndent();
0555:                        }
0556:                        if (!canonical && checkSimpleKey()) {
0557:                            states.add(0,
0558:                                    new Integer(FLOW_MAPPING_SIMPLE_VALUE));
0559:                            expectNode(false, false, true, true);
0560:                        } else {
0561:                            emitter.writeIndicator(ByteList.create("?"), true,
0562:                                    false, false);
0563:                            states.add(0, new Integer(FLOW_MAPPING_VALUE));
0564:                            expectNode(false, false, true, false);
0565:                        }
0566:                    }
0567:                }
0568:
0569:                public void expectBlockSequenceItem(final boolean first)
0570:                        throws IOException {
0571:                    if (!first && event instanceof  SequenceEndEvent) {
0572:                        indent = ((Integer) indents.remove(0)).intValue();
0573:                        state = ((Integer) states.remove(0)).intValue();
0574:                    } else {
0575:                        emitter.writeIndent();
0576:                        emitter.writeIndicator(ByteList.create("-"), true,
0577:                                false, true);
0578:                        states.add(0, new Integer(BLOCK_SEQUENCE_ITEM));
0579:                        expectNode(false, true, false, false);
0580:                    }
0581:                }
0582:
0583:                public void expectFirstBlockMappingKey() throws IOException {
0584:                    expectBlockMappingKey(true);
0585:                }
0586:
0587:                public void expectBlockMappingSimpleValue() throws IOException {
0588:                    emitter.writeIndicator(ByteList.create(": "), false, true,
0589:                            false);
0590:                    states.add(0, new Integer(BLOCK_MAPPING_KEY));
0591:                    expectNode(false, false, true, false);
0592:                }
0593:
0594:                public void expectBlockMappingValue() throws IOException {
0595:                    emitter.writeIndent();
0596:                    emitter.writeIndicator(ByteList.create(": "), true, true,
0597:                            true);
0598:                    states.add(0, new Integer(BLOCK_MAPPING_KEY));
0599:                    expectNode(false, false, true, false);
0600:                }
0601:
0602:                public void expectBlockMappingKey(final boolean first)
0603:                        throws IOException {
0604:                    if (!first && event instanceof  MappingEndEvent) {
0605:                        indent = ((Integer) indents.remove(0)).intValue();
0606:                        state = ((Integer) states.remove(0)).intValue();
0607:                    } else {
0608:                        emitter.writeIndent();
0609:                        if (checkSimpleKey()) {
0610:                            states.add(0, new Integer(
0611:                                    BLOCK_MAPPING_SIMPLE_VALUE));
0612:                            expectNode(false, false, true, true);
0613:                        } else {
0614:                            emitter.writeIndicator(ByteList.create("?"), true,
0615:                                    false, true);
0616:                            states.add(0, new Integer(BLOCK_MAPPING_VALUE));
0617:                            expectNode(false, false, true, false);
0618:                        }
0619:                    }
0620:                }
0621:
0622:                private void expectNode(final boolean root,
0623:                        final boolean sequence, final boolean mapping,
0624:                        final boolean simpleKey) throws IOException {
0625:                    rootContext = root;
0626:                    sequenceContext = sequence;
0627:                    mappingContext = mapping;
0628:                    simpleKeyContext = simpleKey;
0629:                    if (event instanceof  AliasEvent) {
0630:                        expectAlias();
0631:                    } else if (event instanceof  ScalarEvent
0632:                            || event instanceof  CollectionStartEvent) {
0633:                        processAnchor(ByteList.create("&"));
0634:                        processTag();
0635:                        if (event instanceof  ScalarEvent) {
0636:                            expectScalar();
0637:                        } else if (event instanceof  SequenceStartEvent) {
0638:                            if (flowLevel != 0
0639:                                    || canonical
0640:                                    || ((SequenceStartEvent) event)
0641:                                            .getFlowStyle()
0642:                                    || checkEmptySequence()) {
0643:                                expectFlowSequence();
0644:                            } else {
0645:                                expectBlockSequence();
0646:                            }
0647:                        } else if (event instanceof  MappingStartEvent) {
0648:                            if (flowLevel != 0
0649:                                    || canonical
0650:                                    || ((MappingStartEvent) event)
0651:                                            .getFlowStyle()
0652:                                    || checkEmptyMapping()) {
0653:                                expectFlowMapping();
0654:                            } else {
0655:                                expectBlockMapping();
0656:                            }
0657:                        }
0658:                    } else {
0659:                        throw new EmitterException(
0660:                                "expected NodeEvent, but got " + event);
0661:                    }
0662:                }
0663:
0664:                private void expectAlias() throws IOException {
0665:                    if (((NodeEvent) event).getAnchor() == null) {
0666:                        throw new EmitterException(
0667:                                "anchor is not specified for alias");
0668:                    }
0669:                    processAnchor(ByteList.create("*"));
0670:                    state = ((Integer) states.remove(0)).intValue();
0671:                }
0672:
0673:                private void expectScalar() throws IOException {
0674:                    increaseIndent(true, false);
0675:                    processScalar();
0676:                    indent = ((Integer) indents.remove(0)).intValue();
0677:                    state = ((Integer) states.remove(0)).intValue();
0678:                }
0679:
0680:                private void expectFlowSequence() throws IOException {
0681:                    emitter.writeIndicator(ByteList.create("["), true, true,
0682:                            false);
0683:                    flowLevel++;
0684:                    increaseIndent(true, false);
0685:                    state = FIRST_FLOW_SEQUENCE_ITEM;
0686:                }
0687:
0688:                private void expectBlockSequence() throws IOException {
0689:                    increaseIndent(false, mappingContext && !indentation);
0690:                    state = FIRST_BLOCK_SEQUENCE_ITEM;
0691:                }
0692:
0693:                private void expectFlowMapping() throws IOException {
0694:                    emitter.writeIndicator(ByteList.create("{"), true, true,
0695:                            false);
0696:                    flowLevel++;
0697:                    increaseIndent(true, false);
0698:                    state = FIRST_FLOW_MAPPING_KEY;
0699:                }
0700:
0701:                private void expectBlockMapping() throws IOException {
0702:                    increaseIndent(false, false);
0703:                    state = FIRST_BLOCK_MAPPING_KEY;
0704:                }
0705:
0706:                private boolean checkEmptySequence() {
0707:                    return event instanceof  SequenceStartEvent
0708:                            && !events.isEmpty()
0709:                            && events.get(0) instanceof  SequenceEndEvent;
0710:                }
0711:
0712:                private boolean checkEmptyMapping() {
0713:                    return event instanceof  MappingStartEvent
0714:                            && !events.isEmpty()
0715:                            && events.get(0) instanceof  MappingEndEvent;
0716:                }
0717:
0718:                private boolean checkEmptyDocument() {
0719:                    if (!(event instanceof  DocumentStartEvent)
0720:                            || events.isEmpty()) {
0721:                        return false;
0722:                    }
0723:                    final Event ev = (Event) events.get(0);
0724:                    return ev instanceof  ScalarEvent
0725:                            && ((ScalarEvent) ev).getAnchor() == null
0726:                            && ((ScalarEvent) ev).getTag() == null
0727:                            && ((ScalarEvent) ev).getImplicit() != null
0728:                            && ((ScalarEvent) ev).getValue().realSize == 0;
0729:                }
0730:
0731:                private boolean checkSimpleKey() {
0732:                    int length = 0;
0733:                    if (event instanceof  NodeEvent
0734:                            && null != ((NodeEvent) event).getAnchor()) {
0735:                        if (null == preparedAnchor) {
0736:                            preparedAnchor = prepareAnchor(((NodeEvent) event)
0737:                                    .getAnchor());
0738:                        }
0739:                        length += preparedAnchor.length();
0740:                    }
0741:                    String tag = null;
0742:                    if (event instanceof  ScalarEvent) {
0743:                        tag = ((ScalarEvent) event).getTag();
0744:                    } else if (event instanceof  CollectionStartEvent) {
0745:                        tag = ((CollectionStartEvent) event).getTag();
0746:                    }
0747:                    if (tag != null) {
0748:                        if (null == preparedTag) {
0749:                            preparedTag = emitter.prepareTag(tag);
0750:                        }
0751:                        length += preparedTag.length();
0752:                    }
0753:                    if (event instanceof  ScalarEvent) {
0754:                        if (null == analysis) {
0755:                            analysis = analyzeScalar(((ScalarEvent) event)
0756:                                    .getValue());
0757:                            length += analysis.scalar.length();
0758:                        }
0759:                    }
0760:
0761:                    return (length < 128 && (event instanceof  AliasEvent
0762:                            || (event instanceof  ScalarEvent && !analysis.multiline)
0763:                            || checkEmptySequence() || checkEmptyMapping()));
0764:                }
0765:
0766:                private void processAnchor(final ByteList indicator)
0767:                        throws IOException {
0768:                    final NodeEvent ev = (NodeEvent) event;
0769:                    if (null == ev.getAnchor()) {
0770:                        preparedAnchor = null;
0771:                        return;
0772:                    }
0773:                    if (null == preparedAnchor) {
0774:                        preparedAnchor = prepareAnchor(ev.getAnchor());
0775:                    }
0776:                    if (preparedAnchor != null && !"".equals(preparedAnchor)) {
0777:                        indicator.append(preparedAnchor.getBytes());
0778:                        if (ev instanceof  CollectionStartEvent) {
0779:                            indentation = true;
0780:                        }
0781:                        emitter.writeIndicator(indicator, true, false, true);
0782:                    }
0783:                    preparedAnchor = null;
0784:                }
0785:
0786:                private void processTag() throws IOException {
0787:                    String tag = null;
0788:                    if (event instanceof  ScalarEvent) {
0789:                        final ScalarEvent ev = (ScalarEvent) event;
0790:                        tag = ev.getTag();
0791:                        if (style == 0) {
0792:                            style = chooseScalarStyle();
0793:                        }
0794:                        if (((!canonical || tag == null) && ((0 == style && ev
0795:                                .getImplicit()[0]) || (0 != style && ev
0796:                                .getImplicit()[1])))) {
0797:                            preparedTag = null;
0798:                            return;
0799:                        }
0800:                        if (ev.getImplicit()[0] && null == tag) {
0801:                            tag = "!";
0802:                            preparedTag = null;
0803:                        }
0804:                    } else {
0805:                        final CollectionStartEvent ev = (CollectionStartEvent) event;
0806:                        tag = ev.getTag();
0807:                        if ((!canonical || tag == null) && ev.getImplicit()) {
0808:                            preparedTag = null;
0809:                            return;
0810:                        }
0811:                        indentation = true;
0812:                    }
0813:                    if (tag == null) {
0814:                        throw new EmitterException("tag is not specified");
0815:                    }
0816:                    if (null == preparedTag) {
0817:                        preparedTag = emitter.prepareTag(tag);
0818:                    }
0819:                    if (preparedTag != null && !"".equals(preparedTag)) {
0820:                        emitter.writeIndicator(ByteList.create(preparedTag),
0821:                                true, false, true);
0822:                    }
0823:                    preparedTag = null;
0824:                }
0825:
0826:                private char chooseScalarStyle() {
0827:                    final ScalarEvent ev = (ScalarEvent) event;
0828:
0829:                    if (null == analysis) {
0830:                        analysis = analyzeScalar(ev.getValue());
0831:                    }
0832:
0833:                    if (ev.getStyle() == '"'
0834:                            || this .canonical
0835:                            || (analysis.empty && ev.getTag().equals(
0836:                                    "tag:yaml.org,2002:str"))) {
0837:                        return '"';
0838:                    }
0839:
0840:                    //            if(ev.getStyle() == 0 && ev.getImplicit()[0]) {
0841:                    if (ev.getStyle() == 0) {
0842:                        if (!(simpleKeyContext && (analysis.empty || analysis.multiline))
0843:                                && ((flowLevel != 0 && analysis.allowFlowPlain) || (flowLevel == 0 && analysis.allowBlockPlain))) {
0844:                            return 0;
0845:                        }
0846:                    }
0847:                    if (ev.getStyle() == 0
0848:                            && ev.getImplicit()[0]
0849:                            && (!(simpleKeyContext && (analysis.empty || analysis.multiline)) && (flowLevel != 0
0850:                                    && analysis.allowFlowPlain || (flowLevel == 0 && analysis.allowBlockPlain)))) {
0851:                        return 0;
0852:                    }
0853:                    if ((ev.getStyle() == '|' || ev.getStyle() == '>')
0854:                            && flowLevel == 0 && analysis.allowBlock) {
0855:                        return '\'';
0856:                    }
0857:                    if ((ev.getStyle() == 0 || ev.getStyle() == '\'')
0858:                            && (analysis.allowSingleQuoted && !(simpleKeyContext && analysis.multiline))) {
0859:                        return '\'';
0860:                    }
0861:                    if (analysis.multiline
0862:                            && !FIRST_SPACE.matcher(ev.getValue()).find()) {
0863:                        return '|';
0864:                    }
0865:
0866:                    return '"';
0867:                }
0868:
0869:                private void processScalar() throws IOException {
0870:                    final ScalarEvent ev = (ScalarEvent) event;
0871:
0872:                    if (null == analysis) {
0873:                        analysis = analyzeScalar(ev.getValue());
0874:                    }
0875:                    if (0 == style) {
0876:                        style = chooseScalarStyle();
0877:                    }
0878:                    final boolean split = !simpleKeyContext;
0879:                    if (style == '"') {
0880:                        emitter.writeDoubleQuoted(analysis.scalar, split);
0881:                    } else if (style == '\'') {
0882:                        emitter.writeSingleQuoted(analysis.scalar, split);
0883:                    } else if (style == '>') {
0884:                        emitter.writeFolded(analysis.scalar);
0885:                    } else if (style == '|') {
0886:                        emitter.writeLiteral(analysis.scalar);
0887:                    } else {
0888:                        emitter.writePlain(analysis.scalar, split);
0889:                    }
0890:                    analysis = null;
0891:                    style = 0;
0892:                }
0893:            }
0894:
0895:            void writeStreamStart() {
0896:            }
0897:
0898:            void writeStreamEnd() throws IOException {
0899:                flushStream();
0900:            }
0901:
0902:            void writeIndicator(final ByteList indicator,
0903:                    final boolean needWhitespace, final boolean whitespace,
0904:                    final boolean indentation) throws IOException {
0905:                ByteList data = indicator;
0906:                if (!(env.whitespace || !needWhitespace)) {
0907:                    data.prepend((byte) ' ');
0908:                }
0909:                env.whitespace = whitespace;
0910:                env.indentation = env.indentation && indentation;
0911:                env.column += data.length();
0912:                stream.write(data.bytes, 0, data.realSize);
0913:            }
0914:
0915:            void writeIndent() throws IOException {
0916:                int indent = 0;
0917:                if (env.indent != -1) {
0918:                    indent = env.indent;
0919:                }
0920:
0921:                if (!env.indentation || env.column > indent
0922:                        || (env.column == indent && !env.whitespace)) {
0923:                    writeLineBreak(null);
0924:                }
0925:
0926:                if (env.column < indent) {
0927:                    env.whitespace = true;
0928:                    final ByteList data = new ByteList();
0929:                    for (int i = 0, j = (indent - env.column); i < j; i++) {
0930:                        data.append((byte) ' ');
0931:                    }
0932:                    env.column = indent;
0933:                    stream.write(data.bytes, 0, data.realSize);
0934:                }
0935:            }
0936:
0937:            void writeVersionDirective(final String version_text)
0938:                    throws IOException {
0939:                stream.write(("%YAML " + version_text).getBytes());
0940:                writeLineBreak(null);
0941:            }
0942:
0943:            void writeTagDirective(final String handle, final String prefix)
0944:                    throws IOException {
0945:                stream.write(("%TAG " + handle + " " + prefix).getBytes());
0946:                writeLineBreak(null);
0947:            }
0948:
0949:            void writeDoubleQuoted(final ByteList text, final boolean split)
0950:                    throws IOException {
0951:                writeIndicator(ByteList.create("\""), true, false, false);
0952:                int start = 0;
0953:                int ending = 0;
0954:                ByteList data = null;
0955:                while (ending <= text.length()) {
0956:                    char ch = 0;
0957:                    if (ending < text.length()) {
0958:                        ch = text.charAt(ending);
0959:                    }
0960:                    if (ch == 0 || "\"\\\u0085".indexOf(ch) != -1
0961:                            || !('\u0020' <= ch && ch <= '\u007E')) {
0962:                        if (start < ending) {
0963:                            data = (ByteList) text.subSequence(start, ending);
0964:                            env.column += data.length();
0965:                            stream.write(data.bytes, 0, data.realSize);
0966:                            start = ending;
0967:                        }
0968:                        if (ch != 0) {
0969:                            if (YAML.ESCAPE_REPLACEMENTS
0970:                                    .containsKey(new Character(ch))) {
0971:                                data = ByteList.create("\\"
0972:                                        + YAML.ESCAPE_REPLACEMENTS
0973:                                                .get(new Character(ch)));
0974:                            } else if (ch <= '\u00FF') {
0975:                                String str = Integer.toString(ch, 16);
0976:                                if (str.length() == 1) {
0977:                                    str = "0" + str;
0978:                                }
0979:                                data = ByteList.create("\\x" + str);
0980:                            }
0981:                            env.column += data.length();
0982:                            stream.write(data.bytes, 0, data.realSize);
0983:                            start = ending + 1;
0984:                        }
0985:                    }
0986:
0987:                    if ((0 < ending && ending < (text.length() - 1))
0988:                            && (ch == ' ' || start >= ending)
0989:                            && (env.column + (ending - start)) > env.bestWidth
0990:                            && split) {
0991:                        if (start < ending) {
0992:                            data = (ByteList) text.subSequence(start, ending);
0993:                            data.append(' ');
0994:                            data.append('\\');
0995:                        } else {
0996:                            data = ByteList.create("\\");
0997:                        }
0998:
0999:                        if (start < ending) {
1000:                            start = ending;
1001:                        }
1002:                        env.column += data.length();
1003:                        stream.write(data.bytes, 0, data.realSize);
1004:                        writeIndent();
1005:                        env.whitespace = false;
1006:                        env.indentation = false;
1007:
1008:                        if (ending < (text.length() + 1)
1009:                                && text.charAt(ending + 1) == ' ') {
1010:                            data = ByteList.create("\\");
1011:                            stream.write(data.bytes, 0, data.realSize);
1012:                        }
1013:                    }
1014:                    ending += 1;
1015:                }
1016:
1017:                writeIndicator(ByteList.create("\""), false, false, false);
1018:            }
1019:
1020:            void writeSingleQuoted(final ByteList text, final boolean split)
1021:                    throws IOException {
1022:                writeIndicator(ByteList.create("'"), true, false, false);
1023:                boolean spaces = false;
1024:                boolean breaks = false;
1025:                int start = 0, ending = 0;
1026:                char ceh = 0;
1027:                ByteList data = null;
1028:                while (ending <= text.length()) {
1029:                    ceh = 0;
1030:                    if (ending < text.length()) {
1031:                        ceh = text.charAt(ending);
1032:                    }
1033:                    if (spaces) {
1034:                        if (ceh == 0 || ceh != 32) {
1035:                            if (start + 1 == ending
1036:                                    && env.column > env.bestWidth && split
1037:                                    && start != 0 && ending != text.length()) {
1038:                                writeIndent();
1039:                            } else {
1040:                                data = (ByteList) text.subSequence(start,
1041:                                        ending);
1042:                                env.column += data.length();
1043:                                stream.write(data.bytes, 0, data.realSize);
1044:                            }
1045:                            start = ending;
1046:                        }
1047:                    } else if (breaks) {
1048:                        if (ceh == 0 || !('\n' == ceh || '\u0085' == ceh)) {
1049:                            data = (ByteList) text.subSequence(start, ending);
1050:                            for (int i = 0, j = data.length(); i < j; i++) {
1051:                                char cha = data.charAt(i);
1052:                                if ('\n' == cha) {
1053:                                    writeLineBreak(null);
1054:                                } else {
1055:                                    writeLineBreak(ByteList.create("" + cha));
1056:                                }
1057:                            }
1058:                            writeIndent();
1059:                            start = ending;
1060:                        }
1061:                    } else {
1062:                        if (ceh == 0 || !('\n' == ceh || '\u0085' == ceh)) {
1063:                            if (start < ending) {
1064:                                data = (ByteList) text.subSequence(start,
1065:                                        ending);
1066:                                env.column += data.length();
1067:                                stream.write(data.bytes, 0, data.realSize);
1068:                                start = ending;
1069:                            }
1070:                        }
1071:                    }
1072:                    if (ceh == '\'') {
1073:                        data = ByteList.create("''");
1074:                        env.column += 2;
1075:                        stream.write(data.bytes, 0, data.realSize);
1076:                        start = ending + 1;
1077:                    }
1078:                    if (ceh != 0) {
1079:                        spaces = ceh == ' ';
1080:                        breaks = ceh == '\n' || ceh == '\u0085';
1081:                    }
1082:                    ending++;
1083:                }
1084:                writeIndicator(ByteList.create("'"), false, false, false);
1085:            }
1086:
1087:            void writeFolded(final ByteList text) throws IOException {
1088:                String chomp = determineChomp(text);
1089:                writeIndicator(ByteList.create(">" + chomp), true, false, false);
1090:                writeIndent();
1091:                boolean leadingSpace = false;
1092:                boolean spaces = false;
1093:                boolean breaks = false;
1094:                int start = 0, ending = 0;
1095:                ByteList data = null;
1096:                while (ending <= text.length()) {
1097:                    char ceh = 0;
1098:                    if (ending < text.length()) {
1099:                        ceh = text.charAt(ending);
1100:                    }
1101:                    if (breaks) {
1102:                        if (ceh == 0 || !('\n' == ceh || '\u0085' == ceh)) {
1103:                            if (!leadingSpace && ceh != 0 && ceh != ' '
1104:                                    && text.charAt(start) == '\n') {
1105:                                writeLineBreak(null);
1106:                            }
1107:                            leadingSpace = ceh == ' ';
1108:                            data = (ByteList) text.subSequence(start, ending);
1109:                            for (int i = 0, j = data.length(); i < j; i++) {
1110:                                char cha = data.charAt(i);
1111:                                if ('\n' == cha) {
1112:                                    writeLineBreak(null);
1113:                                } else {
1114:                                    writeLineBreak(ByteList.create("" + cha));
1115:                                }
1116:                            }
1117:                            if (ceh != 0) {
1118:                                writeIndent();
1119:                            }
1120:                            start = ending;
1121:                        }
1122:                    } else if (spaces) {
1123:                        if (ceh != ' ') {
1124:                            if (start + 1 == ending
1125:                                    && env.column > env.bestWidth) {
1126:                                writeIndent();
1127:                            } else {
1128:                                data = (ByteList) text.subSequence(start,
1129:                                        ending);
1130:                                env.column += data.length();
1131:                                stream.write(data.bytes, 0, data.realSize);
1132:                            }
1133:                            start = ending;
1134:                        }
1135:                    } else {
1136:                        if (ceh == 0 || ' ' == ceh || '\n' == ceh
1137:                                || '\u0085' == ceh) {
1138:                            data = (ByteList) text.subSequence(start, ending);
1139:                            stream.write(data.bytes, 0, data.realSize);
1140:                            if (ceh == 0) {
1141:                                writeLineBreak(null);
1142:                            }
1143:                            start = ending;
1144:                        }
1145:                    }
1146:                    if (ceh != 0) {
1147:                        breaks = '\n' == ceh || '\u0085' == ceh;
1148:                        spaces = ceh == ' ';
1149:                    }
1150:                    ending++;
1151:                }
1152:            }
1153:
1154:            void writeLiteral(final ByteList text) throws IOException {
1155:                String chomp = determineChomp(text);
1156:                writeIndicator(ByteList.create("|" + chomp), true, false, false);
1157:                writeIndent();
1158:                boolean breaks = false;
1159:                int start = 0, ending = 0;
1160:                ByteList data = null;
1161:                while (ending <= text.length()) {
1162:                    char ceh = 0;
1163:                    if (ending < text.length()) {
1164:                        ceh = text.charAt(ending);
1165:                    }
1166:                    if (breaks) {
1167:                        if (ceh == 0 || !('\n' == ceh || '\u0085' == ceh)) {
1168:                            data = (ByteList) text.subSequence(start, ending);
1169:                            for (int i = 0, j = data.length(); i < j; i++) {
1170:                                char cha = data.charAt(i);
1171:                                if ('\n' == cha) {
1172:                                    writeLineBreak(null);
1173:                                } else {
1174:                                    writeLineBreak(ByteList.create("" + cha));
1175:                                }
1176:                            }
1177:                            if (ceh != 0) {
1178:                                writeIndent();
1179:                            }
1180:                            start = ending;
1181:                        }
1182:                    } else {
1183:                        if (ceh == 0 || '\n' == ceh || '\u0085' == ceh) {
1184:                            data = (ByteList) text.subSequence(start, ending);
1185:                            stream.write(data.bytes, 0, data.realSize);
1186:                            if (ceh == 0) {
1187:                                writeLineBreak(null);
1188:                            }
1189:                            start = ending;
1190:                        }
1191:                    }
1192:                    if (ceh != 0) {
1193:                        breaks = '\n' == ceh || '\u0085' == ceh;
1194:                    }
1195:                    ending++;
1196:                }
1197:            }
1198:
1199:            void writePlain(final ByteList text, final boolean split)
1200:                    throws IOException {
1201:                if (text == null || text.realSize == 0) {
1202:                    return;
1203:                }
1204:                ByteList data = null;
1205:                if (!env.whitespace) {
1206:                    env.column += 1;
1207:                    stream.write(32); // space
1208:                }
1209:                env.whitespace = false;
1210:                env.indentation = false;
1211:                boolean spaces = false, breaks = false;
1212:                int start = 0, ending = 0;
1213:                while (ending <= text.length()) {
1214:                    char ceh = 0;
1215:                    if (ending < text.length()) {
1216:                        ceh = (char) (text.bytes[text.begin + ending] & 0xFF);
1217:                    }
1218:                    if (spaces) {
1219:                        if (ceh != ' ') {
1220:                            if (start + 1 == ending
1221:                                    && env.column > env.bestWidth && split) {
1222:                                writeIndent();
1223:                                env.whitespace = false;
1224:                                env.indentation = false;
1225:                            } else {
1226:                                data = new ByteList(text, start, ending - start);
1227:                                env.column += data.length();
1228:                                stream.write(data.bytes, 0, data.realSize);
1229:                            }
1230:                            start = ending;
1231:                        }
1232:                    } else if (breaks) {
1233:                        if (ceh != '\n' && ceh != '\u0085') {
1234:                            if ((text.bytes[start] & 0xFF) == '\n') {
1235:                                writeLineBreak(null);
1236:                            }
1237:                            data = new ByteList(text, start, ending - start);
1238:                            for (int i = 0, j = data.length(); i < j; i++) {
1239:                                char cha = (char) (data.bytes[data.begin + i] & 0xFF);
1240:                                if ('\n' == cha) {
1241:                                    writeLineBreak(null);
1242:                                } else {
1243:                                    writeLineBreak(ByteList.create("" + cha));
1244:                                }
1245:                            }
1246:                            writeIndent();
1247:                            env.whitespace = false;
1248:                            env.indentation = false;
1249:                            start = ending;
1250:                        }
1251:                    } else {
1252:                        if (ceh == 0 || ' ' == ceh || '\n' == ceh
1253:                                || '\u0085' == ceh) {
1254:                            data = new ByteList(text, start, ending - start);
1255:                            env.column += data.length();
1256:                            stream.write(data.bytes, 0, data.realSize);
1257:                            start = ending;
1258:                        }
1259:                    }
1260:                    if (ceh != 0) {
1261:                        spaces = ceh == ' ';
1262:                        breaks = ceh == '\n' || ceh == '\u0085';
1263:                    }
1264:                    ending++;
1265:                }
1266:            }
1267:
1268:            void writeLineBreak(final ByteList data) throws IOException {
1269:                ByteList xdata = data;
1270:                if (xdata == null) {
1271:                    xdata = env.bestLinebreak;
1272:                }
1273:                env.whitespace = true;
1274:                env.indentation = true;
1275:                env.line++;
1276:                env.column = 0;
1277:                stream.write(xdata.bytes, 0, xdata.realSize);
1278:            }
1279:
1280:            void flushStream() throws IOException {
1281:                stream.flush();
1282:            }
1283:
1284:            static String prepareVersion(final int[] version) {
1285:                if (version[0] != 1) {
1286:                    throw new EmitterException("unsupported YAML version: "
1287:                            + version[0] + "." + version[1]);
1288:                }
1289:                return "" + version[0] + "." + version[1];
1290:            }
1291:
1292:            private final static Pattern HANDLE_FORMAT = Pattern
1293:                    .compile("^![-\\w]*!$");
1294:
1295:            static String prepareTagHandle(final String handle) {
1296:                if (handle == null || "".equals(handle)) {
1297:                    throw new EmitterException("tag handle must not be empty");
1298:                } else if (handle.charAt(0) != '!'
1299:                        || handle.charAt(handle.length() - 1) != '!') {
1300:                    throw new EmitterException(
1301:                            "tag handle must start and end with '!': " + handle);
1302:                } else if (!"!".equals(handle)
1303:                        && !HANDLE_FORMAT.matcher(handle).matches()) {
1304:                    throw new EmitterException(
1305:                            "invalid syntax for tag handle: " + handle);
1306:                }
1307:                return handle;
1308:            }
1309:
1310:            static String prepareTagPrefix(final String prefix) {
1311:                if (prefix == null || "".equals(prefix)) {
1312:                    throw new EmitterException("tag prefix must not be empty");
1313:                }
1314:                final StringBuffer chunks = new StringBuffer();
1315:                int start = 0, ending = 0;
1316:                if (prefix.charAt(0) == '!') {
1317:                    ending = 1;
1318:                }
1319:                while (ending < prefix.length()) {
1320:                    ending++;
1321:                }
1322:                if (start < ending) {
1323:                    chunks.append(prefix.substring(start, ending));
1324:                }
1325:                return chunks.toString();
1326:            }
1327:
1328:            private final static Pattern ANCHOR_FORMAT = Pattern
1329:                    .compile("^[-\\w]*$");
1330:
1331:            static String prepareAnchor(final String anchor) {
1332:                if (anchor == null || "".equals(anchor)) {
1333:                    throw new EmitterException("anchor must not be empty");
1334:                }
1335:                if (!ANCHOR_FORMAT.matcher(anchor).matches()) {
1336:                    throw new EmitterException("invalid syntax for anchor: "
1337:                            + anchor);
1338:                }
1339:                return anchor;
1340:            }
1341:
1342:            String prepareTag(final String tag) {
1343:                if (tag == null || "".equals(tag)) {
1344:                    throw new EmitterException("tag must not be empty");
1345:                }
1346:                if (tag.equals("!")) {
1347:                    return tag;
1348:                }
1349:                String handle = null;
1350:                String suffix = tag;
1351:                for (final Iterator iter = env.tagPrefixes.keySet().iterator(); iter
1352:                        .hasNext();) {
1353:                    String prefix = (String) iter.next();
1354:                    if (Pattern.matches("^" + prefix + ".+$", tag)
1355:                            && (prefix.equals("!") || prefix.length() < tag
1356:                                    .length())) {
1357:                        handle = (String) env.tagPrefixes.get(prefix);
1358:                        suffix = tag.substring(prefix.length());
1359:                    }
1360:                }
1361:                if (handle == null) {
1362:                    if (tag.startsWith("tag:") && tag.indexOf(':', 4) != -1) {
1363:                        int doti = tag.indexOf('.', 4);
1364:                        String first = tag.substring(4, doti);
1365:                        String rest = tag.substring(tag.indexOf(':', 4) + 1);
1366:                        handle = "!" + first + "/";
1367:                        suffix = rest;
1368:                    }
1369:                }
1370:
1371:                final StringBuffer chunks = new StringBuffer();
1372:                int start = 0, ending = 0;
1373:                while (ending < suffix.length()) {
1374:                    ending++;
1375:                }
1376:                if (start < ending) {
1377:                    chunks.append(suffix.substring(start, ending));
1378:                }
1379:                String suffixText = chunks.toString();
1380:                if (tag.charAt(0) == '!' && env.isVersion10) {
1381:                    return tag;
1382:                }
1383:                if (handle != null) {
1384:                    return handle + suffixText;
1385:                } else {
1386:                    return "!<" + suffixText + ">";
1387:                }
1388:            }
1389:
1390:            private final static Pattern DOC_INDIC = Pattern
1391:                    .compile("^(---|\\.\\.\\.)");
1392:            private final static Pattern FIRST_SPACE = Pattern
1393:                    .compile("(^|\n) ");
1394:            private final static String NULL_BL_T_LINEBR = "\0 \t\r\n\u0085";
1395:            private final static String SPECIAL_INDIC = "#,[]{}#&*!|>'\"%@`";
1396:            private final static String FLOW_INDIC = ",?[]{}";
1397:
1398:            static ScalarAnalysis analyzeScalar(final ByteList scalar) {
1399:                if (scalar == null || scalar.realSize == 0) {
1400:                    return new ScalarAnalysis(scalar, true, false, false, true,
1401:                            true, true, false);
1402:                }
1403:                boolean blockIndicators = false;
1404:                boolean flowIndicators = false;
1405:                boolean lineBreaks = false;
1406:                boolean specialCharacters = false;
1407:
1408:                // Whitespaces.
1409:                boolean inlineSpaces = false; // non-space space+ non-space
1410:                boolean inlineBreaks = false; // non-space break+ non-space
1411:                boolean leadingSpaces = false; // ^ space+ (non-space | $)
1412:                boolean leadingBreaks = false; // ^ break+ (non-space | $)
1413:                boolean trailingSpaces = false; // (^ | non-space) space+ $
1414:                boolean trailingBreaks = false; // (^ | non-space) break+ $
1415:                boolean inlineBreaksSpaces = false; // non-space break+ space+ non-space
1416:                boolean mixedBreaksSpaces = false; // anything else
1417:
1418:                if (DOC_INDIC.matcher(scalar).matches()) {
1419:                    blockIndicators = true;
1420:                    flowIndicators = true;
1421:                }
1422:
1423:                boolean preceededBySpace = true;
1424:                boolean followedBySpace = scalar.length() == 1
1425:                        || NULL_BL_T_LINEBR.indexOf(scalar.charAt(1)) != -1;
1426:
1427:                boolean spaces = false;
1428:                boolean breaks = false;
1429:                boolean mixed = false;
1430:                boolean leading = false;
1431:
1432:                int index = 0;
1433:
1434:                while (index < scalar.length()) {
1435:                    char ceh = scalar.charAt(index);
1436:                    if (index == 0) {
1437:                        if (SPECIAL_INDIC.indexOf(ceh) != -1) {
1438:                            flowIndicators = true;
1439:                            blockIndicators = true;
1440:                        }
1441:                        if (ceh == '?' || ceh == ':') {
1442:                            flowIndicators = true;
1443:                            if (followedBySpace) {
1444:                                blockIndicators = true;
1445:                            }
1446:                        }
1447:                        if (ceh == '-' && followedBySpace) {
1448:                            flowIndicators = true;
1449:                            blockIndicators = true;
1450:                        }
1451:                    } else {
1452:                        if (FLOW_INDIC.indexOf(ceh) != -1) {
1453:                            flowIndicators = true;
1454:                        }
1455:                        if (ceh == ':') {
1456:                            flowIndicators = true;
1457:                            if (followedBySpace) {
1458:                                blockIndicators = true;
1459:                            }
1460:                        }
1461:                        if (ceh == '#' && preceededBySpace) {
1462:                            flowIndicators = true;
1463:                            blockIndicators = true;
1464:                        }
1465:                    }
1466:                    if (ceh == '\n' || '\u0085' == ceh) {
1467:                        lineBreaks = true;
1468:                    }
1469:                    if (!(ceh == '\n' || ('\u0020' <= ceh && ceh <= '\u007E'))) {
1470:                        specialCharacters = true;
1471:
1472:                    }
1473:                    if (' ' == ceh || '\n' == ceh || '\u0085' == ceh) {
1474:                        if (spaces && breaks) {
1475:                            if (ceh != ' ') {
1476:                                mixed = true;
1477:                            }
1478:                        } else if (spaces) {
1479:                            if (ceh != ' ') {
1480:                                breaks = true;
1481:                                mixed = true;
1482:                            }
1483:                        } else if (breaks) {
1484:                            if (ceh == ' ') {
1485:                                spaces = true;
1486:                            }
1487:                        } else {
1488:                            leading = (index == 0);
1489:                            if (ceh == ' ') {
1490:                                spaces = true;
1491:                            } else {
1492:                                breaks = true;
1493:                            }
1494:                        }
1495:                    } else if (spaces || breaks) {
1496:                        if (leading) {
1497:                            if (spaces && breaks) {
1498:                                mixedBreaksSpaces = true;
1499:                            } else if (spaces) {
1500:                                leadingSpaces = true;
1501:                            } else if (breaks) {
1502:                                leadingBreaks = true;
1503:                            }
1504:                        } else {
1505:                            if (mixed) {
1506:                                mixedBreaksSpaces = true;
1507:                            } else if (spaces && breaks) {
1508:                                inlineBreaksSpaces = true;
1509:                            } else if (spaces) {
1510:                                inlineSpaces = true;
1511:                            } else if (breaks) {
1512:                                inlineBreaks = true;
1513:                            }
1514:                        }
1515:                        spaces = breaks = mixed = leading = false;
1516:                    }
1517:
1518:                    if ((spaces || breaks) && (index == scalar.length() - 1)) {
1519:                        if (spaces && breaks) {
1520:                            mixedBreaksSpaces = true;
1521:                        } else if (spaces) {
1522:                            trailingSpaces = true;
1523:                            if (leading) {
1524:                                leadingSpaces = true;
1525:                            }
1526:                        } else if (breaks) {
1527:                            trailingBreaks = true;
1528:                            if (leading) {
1529:                                leadingBreaks = true;
1530:                            }
1531:                        }
1532:                        spaces = breaks = mixed = leading = false;
1533:                    }
1534:                    index++;
1535:                    preceededBySpace = NULL_BL_T_LINEBR.indexOf(ceh) != -1;
1536:                    followedBySpace = index + 1 >= scalar.length()
1537:                            || NULL_BL_T_LINEBR.indexOf(scalar
1538:                                    .charAt(index + 1)) != -1;
1539:                }
1540:                boolean allowFlowPlain = true;
1541:                boolean allowBlockPlain = true;
1542:                boolean allowSingleQuoted = true;
1543:                boolean allowDoubleQuoted = true;
1544:                boolean allowBlock = true;
1545:
1546:                if (leadingSpaces || leadingBreaks || trailingSpaces) {
1547:                    allowFlowPlain = allowBlockPlain = allowBlock = false;
1548:                }
1549:
1550:                if (trailingBreaks) {
1551:                    allowFlowPlain = allowBlockPlain = false;
1552:                }
1553:
1554:                if (inlineBreaksSpaces) {
1555:                    allowFlowPlain = allowBlockPlain = allowSingleQuoted = false;
1556:                }
1557:
1558:                if (mixedBreaksSpaces || specialCharacters) {
1559:                    allowFlowPlain = allowBlockPlain = allowSingleQuoted = allowBlock = false;
1560:                }
1561:
1562:                if (inlineBreaks) {
1563:                    allowFlowPlain = allowBlockPlain = allowSingleQuoted = false;
1564:                }
1565:
1566:                if (trailingBreaks) {
1567:                    allowSingleQuoted = false;
1568:                }
1569:
1570:                if (lineBreaks) {
1571:                    allowFlowPlain = allowBlockPlain = false;
1572:                }
1573:
1574:                if (flowIndicators) {
1575:                    allowFlowPlain = false;
1576:                }
1577:
1578:                if (blockIndicators) {
1579:                    allowBlockPlain = false;
1580:                }
1581:
1582:                return new ScalarAnalysis(scalar, false, lineBreaks,
1583:                        allowFlowPlain, allowBlockPlain, allowSingleQuoted,
1584:                        allowDoubleQuoted, allowBlock);
1585:            }
1586:
1587:            static String determineChomp(final ByteList text) {
1588:                char ceh = ' ';
1589:                char ceh2 = ' ';
1590:                if (text.realSize > 0) {
1591:                    ceh = (char) (text.bytes[text.realSize - 1] & 0xFF);
1592:                    if (text.realSize > 1) {
1593:                        ceh2 = (char) (text.bytes[text.realSize - 2] & 0xFF);
1594:                    }
1595:                }
1596:                return (ceh == '\n' || ceh == '\u0085') ? ((ceh2 == '\n' || ceh2 == '\u0085') ? "+"
1597:                        : "")
1598:                        : "-";
1599:            }
1600:
1601:            public static void main(final String[] args) throws IOException {
1602:                final String filename = args[0]; // filename to test against
1603:                System.out.println("File contents:");
1604:                final BufferedInputStream read = new BufferedInputStream(
1605:                        new FileInputStream(filename));
1606:                int last = -1;
1607:                while ((last = read.read()) != -1) {
1608:                    System.out.print((char) last);
1609:                }
1610:                read.close();
1611:                System.out.println("--------------------------------");
1612:                final Emitter emitter = new EmitterImpl(System.out, YAML
1613:                        .config());
1614:                final Parser pars = new ParserImpl(new ScannerImpl(
1615:                        new FileInputStream(filename)));
1616:                for (final Iterator iter = pars.eachEvent(); iter.hasNext();) {
1617:                    emitter.emit((Event) iter.next());
1618:                }
1619:            }
1620:        }// EmitterImpl
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.