Source Code Cross Referenced for XMLStreamWriterImpl.java in  » 6.0-JDK-Modules-com.sun » xml » com » sun » xml » internal » stream » writers » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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


0001:        /*
0002:         * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004:         *
0005:         * This code is free software; you can redistribute it and/or modify it
0006:         * under the terms of the GNU General Public License version 2 only, as
0007:         * published by the Free Software Foundation.  Sun designates this
0008:         * particular file as subject to the "Classpath" exception as provided
0009:         * by Sun in the LICENSE file that accompanied this code.
0010:         *
0011:         * This code is distributed in the hope that it will be useful, but WITHOUT
0012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014:         * version 2 for more details (a copy is included in the LICENSE file that
0015:         * accompanied this code).
0016:         *
0017:         * You should have received a copy of the GNU General Public License version
0018:         * 2 along with this work; if not, write to the Free Software Foundation,
0019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020:         *
0021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022:         * CA 95054 USA or visit www.sun.com if you need additional information or
0023:         * have any questions.
0024:         */
0025:
0026:        package com.sun.xml.internal.stream.writers;
0027:
0028:        import java.io.FileOutputStream;
0029:        import java.io.IOException;
0030:        import java.io.OutputStream;
0031:        import java.io.OutputStreamWriter;
0032:        import java.io.Writer;
0033:        import java.nio.charset.Charset;
0034:        import java.nio.charset.CharsetEncoder;
0035:        import java.util.AbstractMap;
0036:        import java.util.ArrayList;
0037:        import java.util.Iterator;
0038:        import java.util.Random;
0039:        import java.util.Vector;
0040:        import java.util.Set;
0041:        import java.util.Iterator;
0042:
0043:        import javax.xml.XMLConstants;
0044:        import javax.xml.namespace.NamespaceContext;
0045:        import javax.xml.stream.XMLOutputFactory;
0046:        import javax.xml.stream.XMLStreamException;
0047:        import javax.xml.stream.XMLStreamWriter;
0048:        import javax.xml.transform.stream.StreamResult;
0049:
0050:        import com.sun.org.apache.xerces.internal.impl.Constants;
0051:        import com.sun.org.apache.xerces.internal.impl.PropertyManager;
0052:        import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
0053:        import com.sun.org.apache.xerces.internal.util.SymbolTable;
0054:        import com.sun.org.apache.xerces.internal.xni.QName;
0055:
0056:        import com.sun.xml.internal.stream.util.ReadOnlyIterator;
0057:
0058:        /**
0059:         * This class implements a StAX XMLStreamWriter. It extends 
0060:         * <code>AbstractMap</code> in order to support a getter for 
0061:         * implementation-specific properties. For example, you can get 
0062:         * the underlying <code>OutputStream</code> by casting an instance 
0063:         * of this class to <code>Map</code> and calling 
0064:         * <code>getProperty(OUTPUTSTREAM_PROPERTY)</code>. 
0065:         *
0066:         * @author Neeraj Bajaj
0067:         * @author K.Venugopal
0068:         * @author Santiago.Pericas-Geertsen@sun.com
0069:         * @author Sunitha.Reddy@sun.com
0070:         */
0071:        public final class XMLStreamWriterImpl extends AbstractMap implements 
0072:                XMLStreamWriter {
0073:
0074:            public static final String START_COMMENT = "<!--";
0075:            public static final String END_COMMENT = "-->";
0076:            public static final String DEFAULT_ENCODING = " encoding=\"utf-8\"";
0077:            public static final String DEFAULT_XMLDECL = "<?xml version=\"1.0\" ?>";
0078:            public static final String DEFAULT_XML_VERSION = "1.0";
0079:            public static final char CLOSE_START_TAG = '>';
0080:            public static final char OPEN_START_TAG = '<';
0081:            public static final String OPEN_END_TAG = "</";
0082:            public static final char CLOSE_END_TAG = '>';
0083:            public static final String START_CDATA = "<![CDATA[";
0084:            public static final String END_CDATA = "]]>";
0085:            public static final String CLOSE_EMPTY_ELEMENT = "/>";
0086:            public static final String SPACE = " ";
0087:            public static final String UTF_8 = "UTF-8";
0088:
0089:            public static final String OUTPUTSTREAM_PROPERTY = "sjsxp-outputstream";
0090:
0091:            /**
0092:             * This flag can be used to turn escaping off for content. It does
0093:             * not apply to attribute content.
0094:             */
0095:            boolean fEscapeCharacters = true;
0096:
0097:            /**
0098:             * Flag for the value of repairNamespace property 
0099:             */
0100:            private boolean fIsRepairingNamespace = false;
0101:
0102:            /**
0103:             * Underlying Writer to which characters are written.
0104:             */
0105:            private Writer fWriter;
0106:
0107:            /**
0108:             * Underlying OutputStream to which <code>fWriter</code>
0109:             * writes to. May be null if unknown.
0110:             */
0111:            private OutputStream fOutputStream = null;
0112:
0113:            /**
0114:             * Collects attributes when the writer is in reparing mode.
0115:             */
0116:            private ArrayList fAttributeCache;
0117:
0118:            /**
0119:             * Collects namespace declarations when the writer is in reparing mode.
0120:             */
0121:            private ArrayList fNamespaceDecls;
0122:
0123:            /** 
0124:             * Namespace context encapsulating user specified context
0125:             * and context built by the writer  
0126:             */
0127:            private NamespaceContextImpl fNamespaceContext = null;
0128:
0129:            private NamespaceSupport fInternalNamespaceContext = null;
0130:
0131:            private Random fPrefixGen = null;
0132:
0133:            /** 
0134:             * Reference to PropertyManager 
0135:             */
0136:            private PropertyManager fPropertyManager = null;
0137:
0138:            /** 
0139:             * Flag to track if start tag is opened 
0140:             */
0141:            private boolean fStartTagOpened = false;
0142:
0143:            /**
0144:             * Boolean flag  to indicate, if instance can be reused 
0145:             */
0146:            private boolean fReuse;
0147:
0148:            private SymbolTable fSymbolTable = new SymbolTable();
0149:
0150:            private ElementStack fElementStack = new ElementStack(); //Change this .-Venu
0151:
0152:            final private String DEFAULT_PREFIX = fSymbolTable.addSymbol("");
0153:
0154:            private final ReadOnlyIterator fReadOnlyIterator = new ReadOnlyIterator();
0155:
0156:            /**
0157:             * In some cases, this charset encoder is used to determine if a char is
0158:             * encodable by underlying writer. For example, an 8-bit char from the
0159:             * extended ASCII set is not encodable by 7-bit ASCII encoder. Unencodable
0160:             * chars are escaped using XML numeric entities.
0161:             */
0162:            private CharsetEncoder fEncoder = null;
0163:
0164:            /**
0165:             * Creates a new instance of XMLStreamWriterImpl. Uses platform's default
0166:             * encoding.
0167:             *
0168:             * @param outputStream Underlying stream to write the bytes to
0169:             * @param props        Properties used by this writer
0170:             */
0171:            public XMLStreamWriterImpl(OutputStream outputStream,
0172:                    PropertyManager props) throws IOException {
0173:
0174:                // cannot call this(outputStream, null, props); for constructor,
0175:                // OutputStreamWriter charsetName cannot be null
0176:
0177:                // use default encoding
0178:                this (new OutputStreamWriter(outputStream), props);
0179:            }
0180:
0181:            /**
0182:             * Creates a new instance of XMLStreamWriterImpl.
0183:             *
0184:             * @param outputStream Underlying stream to write the bytes
0185:             * @param encoding     Encoding used to convert chars into bytes
0186:             * @param props        Properties used by this writer
0187:             */
0188:            public XMLStreamWriterImpl(OutputStream outputStream,
0189:                    String encoding, PropertyManager props)
0190:                    throws java.io.IOException {
0191:                this (new StreamResult(outputStream), encoding, props);
0192:            }
0193:
0194:            /**
0195:             * Creates a new instance of XMLStreamWriterImpl using a Writer.
0196:             *
0197:             * @param writer  Underlying writer to which chars are written
0198:             * @param props   Properties used by this writer
0199:             */
0200:            public XMLStreamWriterImpl(Writer writer, PropertyManager props)
0201:                    throws java.io.IOException {
0202:                this (new StreamResult(writer), null, props);
0203:            }
0204:
0205:            /**
0206:             * Creates a new instance of XMLStreamWriterImpl using a StreamResult.
0207:             * A StreamResult encasupates an OutputStream, a Writer or a SystemId.
0208:             *
0209:             * @param writer  Underlying writer to which chars are written
0210:             * @param props   Properties used by this writer
0211:             */
0212:            public XMLStreamWriterImpl(StreamResult sr, String encoding,
0213:                    PropertyManager props) throws java.io.IOException {
0214:                setOutput(sr, encoding);
0215:                fPropertyManager = props;
0216:                init();
0217:            }
0218:
0219:            /**
0220:             * Initialize an instance of this XMLStreamWriter. Allocate new instances
0221:             * for all the data structures. Set internal flags based on property values.
0222:             */
0223:            private void init() {
0224:                fReuse = false;
0225:                fNamespaceDecls = new ArrayList();
0226:                fPrefixGen = new Random();
0227:                fAttributeCache = new ArrayList();
0228:                fInternalNamespaceContext = new NamespaceSupport();
0229:                fNamespaceContext = new NamespaceContextImpl();
0230:                fNamespaceContext.internalContext = fInternalNamespaceContext;
0231:
0232:                // Set internal state based on property values
0233:                Boolean ob = (Boolean) fPropertyManager
0234:                        .getProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES);
0235:                fIsRepairingNamespace = ob.booleanValue();
0236:                ob = (Boolean) fPropertyManager
0237:                        .getProperty(Constants.ESCAPE_CHARACTERS);
0238:                setEscapeCharacters(ob.booleanValue());
0239:            }
0240:
0241:            /**
0242:             * Reset this instance so that it can be re-used. Do not read properties
0243:             * again. The method <code>setOutput(StreamResult, encoding)</code> must
0244:             * be called after this one.
0245:             */
0246:            public void reset() {
0247:                reset(false);
0248:            }
0249:
0250:            /**
0251:             * Reset this instance so that it can be re-used. Clears but does not
0252:             * re-allocate internal data structures.
0253:             *
0254:             * @param resetProperties Indicates if properties should be read again
0255:             */
0256:            void reset(boolean resetProperties) {
0257:                if (!fReuse) {
0258:                    throw new java.lang.IllegalStateException(
0259:                            "close() Must be called before calling reset()");
0260:                }
0261:
0262:                fReuse = false;
0263:                fNamespaceDecls.clear();
0264:                fAttributeCache.clear();
0265:
0266:                // reset Element/NamespaceContext stacks
0267:                fElementStack.clear();
0268:                fInternalNamespaceContext.reset();
0269:
0270:                fStartTagOpened = false;
0271:                fNamespaceContext.userContext = null;
0272:
0273:                if (resetProperties) {
0274:                    Boolean ob = (Boolean) fPropertyManager
0275:                            .getProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES);
0276:                    fIsRepairingNamespace = ob.booleanValue();
0277:                    ob = (Boolean) fPropertyManager
0278:                            .getProperty(Constants.ESCAPE_CHARACTERS);
0279:                    setEscapeCharacters(ob.booleanValue());
0280:                }
0281:            }
0282:
0283:            /**
0284:             * Use a StreamResult to initialize the output for this XMLStreamWriter. Check
0285:             * for OutputStream, Writer and then systemId, in that order.
0286:             *
0287:             * @param sr        StreamResult encapsulating output information
0288:             * @param encoding  Encoding to be used except when a Writer is available
0289:             */
0290:            public void setOutput(StreamResult sr, String encoding)
0291:                    throws IOException {
0292:
0293:                if (sr.getOutputStream() != null) {
0294:                    setOutputUsingStream(sr.getOutputStream(), encoding);
0295:                } else if (sr.getWriter() != null) {
0296:                    setOutputUsingWriter(sr.getWriter());
0297:                } else if (sr.getSystemId() != null) {
0298:                    setOutputUsingStream(
0299:                            new FileOutputStream(sr.getSystemId()), encoding);
0300:                }
0301:            }
0302:
0303:            private void setOutputUsingWriter(Writer writer) throws IOException {
0304:                fWriter = writer;
0305:
0306:                if (writer instanceof  OutputStreamWriter) {
0307:                    String charset = ((OutputStreamWriter) writer)
0308:                            .getEncoding();
0309:                    if (charset != null && !charset.equalsIgnoreCase("utf-8")) {
0310:                        fEncoder = Charset.forName(charset).newEncoder();
0311:                    }
0312:                }
0313:            }
0314:
0315:            /**
0316:             * Utility method to create a writer when passed an OutputStream. Make
0317:             * sure to wrap an <code>OutputStreamWriter</code> using an 
0318:             * <code>XMLWriter</code> for performance reasons.
0319:             *
0320:             * @param os        Underlying OutputStream
0321:             * @param encoding  Encoding used to convert chars into bytes
0322:             */
0323:            private void setOutputUsingStream(OutputStream os, String encoding)
0324:                    throws IOException {
0325:                fOutputStream = os;
0326:
0327:                if (encoding != null) {
0328:                    if (encoding.equalsIgnoreCase("utf-8")) {
0329:                        fWriter = new UTF8OutputStreamWriter(os);
0330:                    } else {
0331:                        fWriter = new XMLWriter(new OutputStreamWriter(os,
0332:                                encoding));
0333:                        fEncoder = Charset.forName(encoding).newEncoder();
0334:                    }
0335:                } else {
0336:                    encoding = System.getProperty("file.encoding");
0337:                    if (encoding != null && encoding.equalsIgnoreCase("utf-8")) {
0338:                        fWriter = new UTF8OutputStreamWriter(os);
0339:                    } else {
0340:                        fWriter = new XMLWriter(new OutputStreamWriter(os));
0341:                    }
0342:                }
0343:            }
0344:
0345:            /** Can this instance be reused
0346:             *
0347:             * @return boolean boolean value to indicate if this instance can be reused or not
0348:             */
0349:            public boolean canReuse() {
0350:                return fReuse;
0351:            }
0352:
0353:            public void setEscapeCharacters(boolean escape) {
0354:                fEscapeCharacters = escape;
0355:            }
0356:
0357:            public boolean getEscapeCharacters() {
0358:                return fEscapeCharacters;
0359:            }
0360:
0361:            /**
0362:             * Close this XMLStreamWriter by closing underlying writer.
0363:             */
0364:            public void close() throws XMLStreamException {
0365:                if (fWriter != null) {
0366:                    try {
0367:                        //fWriter.close();
0368:                        fWriter.flush();
0369:                    } catch (IOException e) {
0370:                        throw new XMLStreamException(e);
0371:                    }
0372:                }
0373:                fWriter = null;
0374:                fOutputStream = null;
0375:                fNamespaceDecls.clear();
0376:                fAttributeCache.clear();
0377:                fElementStack.clear();
0378:                fInternalNamespaceContext.reset();
0379:                fReuse = true;
0380:            }
0381:
0382:            /**
0383:             * Flush this XMLStreamWriter by flushin underlying writer.
0384:             */
0385:            public void flush() throws XMLStreamException {
0386:                try {
0387:                    fWriter.flush();
0388:                } catch (IOException e) {
0389:                    throw new XMLStreamException(e);
0390:                }
0391:            }
0392:
0393:            /**
0394:             * Return <code>NamespaceContext</code> being used by the writer.
0395:             *
0396:             * @return NamespaceContext
0397:             */
0398:            public NamespaceContext getNamespaceContext() {
0399:                return fNamespaceContext;
0400:            }
0401:
0402:            /**
0403:             * Return a prefix associated with specified uri, or null if the
0404:             * uri is unknown.
0405:             *
0406:             * @param  uri The namespace uri
0407:             * @throws XMLStreamException if uri specified is "" or null
0408:             */
0409:            public String getPrefix(String uri) throws XMLStreamException {
0410:                return fNamespaceContext.getPrefix(uri);
0411:            }
0412:
0413:            /**
0414:             * Returns value associated with the specified property name.
0415:             *
0416:             * @param  str Property name
0417:             * @throws IllegalArgumentException if the specified property is not supported
0418:             * @return value associated with the specified property.
0419:             */
0420:            public Object getProperty(String str)
0421:                    throws IllegalArgumentException {
0422:                if (str == null) {
0423:                    throw new NullPointerException();
0424:                }
0425:
0426:                if (!fPropertyManager.containsProperty(str)) {
0427:                    throw new IllegalArgumentException("Property '" + str
0428:                            + "' is not supported");
0429:                }
0430:
0431:                return fPropertyManager.getProperty(str);
0432:            }
0433:
0434:            /**
0435:             * Set the specified URI as default namespace in the current namespace context.
0436:             *
0437:             * @param uri Namespace URI
0438:             */
0439:            public void setDefaultNamespace(String uri)
0440:                    throws XMLStreamException {
0441:                if (uri != null) {
0442:                    uri = fSymbolTable.addSymbol(uri);
0443:                }
0444:
0445:                if (fIsRepairingNamespace) {
0446:                    if (isDefaultNamespace(uri)) {
0447:                        return;
0448:                    }
0449:
0450:                    QName qname = new QName();
0451:                    qname.setValues(DEFAULT_PREFIX, "xmlns", null, uri);
0452:                    fNamespaceDecls.add(qname);
0453:                } else {
0454:                    fInternalNamespaceContext
0455:                            .declarePrefix(DEFAULT_PREFIX, uri);
0456:                }
0457:            }
0458:
0459:            /**
0460:             * Sets the current <code>NamespaceContext</code> for prefix and uri bindings.
0461:             * This context becomes the root namespace context for writing and
0462:             * will replace the current root namespace context. Subsequent calls
0463:             * to setPrefix and setDefaultNamespace will bind namespaces using
0464:             * the context passed to the method as the root context for resolving
0465:             * namespaces. This method may only be called once at the start of the
0466:             * document. It does not cause the namespaces to be declared. If a
0467:             * namespace URI to prefix mapping is found in the namespace context
0468:             * it is treated as declared and the prefix may be used by the
0469:             * <code>XMLStreamWriter</code>.
0470:             *
0471:             * @param namespaceContext the namespace context to use for this writer, may not be null
0472:             * @throws XMLStreamException
0473:             */
0474:            public void setNamespaceContext(NamespaceContext namespaceContext)
0475:                    throws XMLStreamException {
0476:                fNamespaceContext.userContext = namespaceContext;
0477:            }
0478:
0479:            /**
0480:             * Sets the prefix the uri is bound to. This prefix is bound in the scope of
0481:             * the current START_ELEMENT / END_ELEMENT pair. If this method is called before
0482:             * a START_ELEMENT has been written the prefix is bound in the root scope.
0483:             *
0484:             * @param prefix
0485:             * @param uri
0486:             * @throws XMLStreamException
0487:             */
0488:            public void setPrefix(String prefix, String uri)
0489:                    throws XMLStreamException {
0490:
0491:                if (prefix == null) {
0492:                    throw new XMLStreamException("Prefix cannot be null");
0493:                }
0494:
0495:                if (uri == null) {
0496:                    throw new XMLStreamException("URI cannot be null");
0497:                }
0498:
0499:                prefix = fSymbolTable.addSymbol(prefix);
0500:                uri = fSymbolTable.addSymbol(uri);
0501:
0502:                if (fIsRepairingNamespace) {
0503:                    String tmpURI = fInternalNamespaceContext.getURI(prefix);
0504:
0505:                    if ((tmpURI != null) && (tmpURI == uri)) {
0506:                        return;
0507:                    }
0508:
0509:                    if (checkUserNamespaceContext(prefix, uri))
0510:                        return;
0511:                    QName qname = new QName();
0512:                    qname.setValues(prefix, XMLConstants.XMLNS_ATTRIBUTE, null,
0513:                            uri);
0514:                    fNamespaceDecls.add(qname);
0515:
0516:                    return;
0517:                }
0518:
0519:                fInternalNamespaceContext.declarePrefix(prefix, uri);
0520:            }
0521:
0522:            public void writeAttribute(String localName, String value)
0523:                    throws XMLStreamException {
0524:                try {
0525:                    if (!fStartTagOpened) {
0526:                        throw new XMLStreamException(
0527:                                "Attribute not associated with any element");
0528:                    }
0529:
0530:                    if (fIsRepairingNamespace) {
0531:                        Attribute attr = new Attribute(value); // Revisit:Dont create new one's. Reuse.-Venu
0532:                        attr.setValues(null, localName, null, null);
0533:                        fAttributeCache.add(attr);
0534:
0535:                        return;
0536:                    }
0537:
0538:                    fWriter.write(" ");
0539:                    fWriter.write(localName);
0540:                    fWriter.write("=\"");
0541:                    writeXMLContent(value, true, // true = escapeChars
0542:                            true); // true = escapeDoubleQuotes
0543:                    fWriter.write("\"");
0544:                } catch (IOException e) {
0545:                    throw new XMLStreamException(e);
0546:                }
0547:            }
0548:
0549:            public void writeAttribute(String namespaceURI, String localName,
0550:                    String value) throws XMLStreamException {
0551:                try {
0552:                    if (!fStartTagOpened) {
0553:                        throw new XMLStreamException(
0554:                                "Attribute not associated with any element");
0555:                    }
0556:
0557:                    if (namespaceURI == null) {
0558:                        throw new XMLStreamException(
0559:                                "NamespaceURI cannot be null");
0560:                    }
0561:
0562:                    namespaceURI = fSymbolTable.addSymbol(namespaceURI);
0563:
0564:                    String prefix = fInternalNamespaceContext
0565:                            .getPrefix(namespaceURI);
0566:
0567:                    if (!fIsRepairingNamespace) {
0568:                        if (prefix == null) {
0569:                            throw new XMLStreamException(
0570:                                    "Prefix cannot be null");
0571:                        }
0572:
0573:                        writeAttributeWithPrefix(prefix, localName, value);
0574:                    } else {
0575:                        Attribute attr = new Attribute(value);
0576:                        attr.setValues(null, localName, null, namespaceURI);
0577:                        fAttributeCache.add(attr);
0578:                    }
0579:                } catch (IOException e) {
0580:                    throw new XMLStreamException(e);
0581:                }
0582:            }
0583:
0584:            private void writeAttributeWithPrefix(String prefix,
0585:                    String localName, String value) throws IOException {
0586:                fWriter.write(SPACE);
0587:
0588:                if ((prefix != null)
0589:                        && (prefix != XMLConstants.DEFAULT_NS_PREFIX)) {
0590:                    fWriter.write(prefix);
0591:                    fWriter.write(":");
0592:                }
0593:
0594:                fWriter.write(localName);
0595:                fWriter.write("=\"");
0596:                writeXMLContent(value, true, // true = escapeChars
0597:                        true); // true = escapeDoubleQuotes
0598:                fWriter.write("\"");
0599:            }
0600:
0601:            public void writeAttribute(String prefix, String namespaceURI,
0602:                    String localName, String value) throws XMLStreamException {
0603:                try {
0604:                    if (!fStartTagOpened) {
0605:                        throw new XMLStreamException(
0606:                                "Attribute not associated with any element");
0607:                    }
0608:
0609:                    if (namespaceURI == null) {
0610:                        throw new XMLStreamException(
0611:                                "NamespaceURI cannot be null");
0612:                    }
0613:
0614:                    if (localName == null) {
0615:                        throw new XMLStreamException(
0616:                                "Local name cannot be null");
0617:                    }
0618:
0619:                    if (!fIsRepairingNamespace) {
0620:                        if (prefix == null || prefix.equals("")) {
0621:                            if (!namespaceURI.equals("")) {
0622:                                throw new XMLStreamException(
0623:                                        "prefix cannot be null or empty");
0624:                            } else {
0625:                                writeAttributeWithPrefix(null, localName, value);
0626:                                return;
0627:                            }
0628:                        }
0629:
0630:                        if (!prefix.equals(XMLConstants.XML_NS_PREFIX)
0631:                                || !namespaceURI
0632:                                        .equals(XMLConstants.XML_NS_URI)) {
0633:
0634:                            prefix = fSymbolTable.addSymbol(prefix);
0635:                            namespaceURI = fSymbolTable.addSymbol(namespaceURI);
0636:
0637:                            if (fInternalNamespaceContext
0638:                                    .containsPrefixInCurrentContext(prefix)) {
0639:
0640:                                String tmpURI = fInternalNamespaceContext
0641:                                        .getURI(prefix);
0642:
0643:                                if (tmpURI != null && tmpURI != namespaceURI) {
0644:                                    throw new XMLStreamException("Prefix "
0645:                                            + prefix + " is "
0646:                                            + "already bound to " + tmpURI
0647:                                            + ". Trying to rebind it to "
0648:                                            + namespaceURI + " is an error.");
0649:                                }
0650:                            }
0651:                            fInternalNamespaceContext.declarePrefix(prefix,
0652:                                    namespaceURI);
0653:                        }
0654:                        writeAttributeWithPrefix(prefix, localName, value);
0655:                    } else {
0656:                        if (prefix != null) {
0657:                            prefix = fSymbolTable.addSymbol(prefix);
0658:                        }
0659:
0660:                        namespaceURI = fSymbolTable.addSymbol(namespaceURI);
0661:
0662:                        Attribute attr = new Attribute(value);
0663:                        attr.setValues(prefix, localName, null, namespaceURI);
0664:                        fAttributeCache.add(attr);
0665:                    }
0666:                } catch (IOException e) {
0667:                    throw new XMLStreamException(e);
0668:                }
0669:            }
0670:
0671:            public void writeCData(String cdata) throws XMLStreamException {
0672:                try {
0673:                    if (cdata == null) {
0674:                        throw new XMLStreamException("cdata cannot be null");
0675:                    }
0676:
0677:                    if (fStartTagOpened) {
0678:                        closeStartTag();
0679:                    }
0680:
0681:                    fWriter.write(START_CDATA);
0682:                    fWriter.write(cdata);
0683:                    fWriter.write(END_CDATA);
0684:                } catch (IOException e) {
0685:                    throw new XMLStreamException(e);
0686:                }
0687:            }
0688:
0689:            public void writeCharacters(String data) throws XMLStreamException {
0690:                try {
0691:                    if (fStartTagOpened) {
0692:                        closeStartTag();
0693:                    }
0694:
0695:                    writeXMLContent(data);
0696:                } catch (IOException e) {
0697:                    throw new XMLStreamException(e);
0698:                }
0699:            }
0700:
0701:            public void writeCharacters(char[] data, int start, int len)
0702:                    throws XMLStreamException {
0703:                try {
0704:                    if (fStartTagOpened) {
0705:                        closeStartTag();
0706:                    }
0707:
0708:                    writeXMLContent(data, start, len, fEscapeCharacters);
0709:                } catch (IOException e) {
0710:                    throw new XMLStreamException(e);
0711:                }
0712:            }
0713:
0714:            public void writeComment(String comment) throws XMLStreamException {
0715:                try {
0716:                    if (fStartTagOpened) {
0717:                        closeStartTag();
0718:                    }
0719:
0720:                    fWriter.write(START_COMMENT);
0721:
0722:                    if (comment != null) {
0723:                        fWriter.write(comment);
0724:                    }
0725:
0726:                    fWriter.write(END_COMMENT);
0727:                } catch (IOException e) {
0728:                    throw new XMLStreamException(e);
0729:                }
0730:            }
0731:
0732:            public void writeDTD(String dtd) throws XMLStreamException {
0733:                try {
0734:                    if (fStartTagOpened) {
0735:                        closeStartTag();
0736:                    }
0737:
0738:                    fWriter.write(dtd);
0739:                } catch (IOException e) {
0740:                    throw new XMLStreamException(e);
0741:                }
0742:            }
0743:
0744:            /*
0745:             * Write default Namespace.
0746:             *
0747:             * If namespaceURI == null,
0748:             * then it is assumed to be equivilent to {@link XMLConstants.NULL_NS_URI},
0749:             * i.e. there is no Namespace.
0750:             *
0751:             * @param namespaceURI NamespaceURI to declare.
0752:             *
0753:             * @throws XMLStreamException
0754:             *
0755:             * @see <a href="http://www.w3.org/TR/REC-xml-names/#defaulting">
0756:             *   Namespaces in XML, 5.2 Namespace Defaulting</a>
0757:             */
0758:            public void writeDefaultNamespace(String namespaceURI)
0759:                    throws XMLStreamException {
0760:
0761:                // normalize namespaceURI
0762:                String namespaceURINormalized = null;
0763:                if (namespaceURI == null) {
0764:                    namespaceURINormalized = ""; // XMLConstants.NULL_NS_URI
0765:                } else {
0766:                    namespaceURINormalized = namespaceURI;
0767:                }
0768:
0769:                try {
0770:                    if (!fStartTagOpened) {
0771:                        throw new IllegalStateException(
0772:                                "Namespace Attribute not associated with any element");
0773:                    }
0774:
0775:                    if (fIsRepairingNamespace) {
0776:                        QName qname = new QName();
0777:                        qname.setValues(XMLConstants.DEFAULT_NS_PREFIX,
0778:                                XMLConstants.XMLNS_ATTRIBUTE, null,
0779:                                namespaceURINormalized);
0780:                        fNamespaceDecls.add(qname);
0781:
0782:                        return;
0783:                    }
0784:
0785:                    namespaceURINormalized = fSymbolTable
0786:                            .addSymbol(namespaceURINormalized);
0787:
0788:                    if (fInternalNamespaceContext
0789:                            .containsPrefixInCurrentContext("")) {
0790:
0791:                        String tmp = fInternalNamespaceContext.getURI("");
0792:
0793:                        if (tmp != null && tmp != namespaceURINormalized) {
0794:                            throw new XMLStreamException(
0795:                                    "xmlns has been already bound to " + tmp
0796:                                            + ". Rebinding it to "
0797:                                            + namespaceURINormalized
0798:                                            + " is an error");
0799:                        }
0800:                    }
0801:                    fInternalNamespaceContext.declarePrefix("",
0802:                            namespaceURINormalized);
0803:
0804:                    // use common namespace code with a prefix == null for xmlns="..."
0805:                    writenamespace(null, namespaceURINormalized);
0806:                } catch (IOException e) {
0807:                    throw new XMLStreamException(e);
0808:                }
0809:            }
0810:
0811:            public void writeEmptyElement(String localName)
0812:                    throws XMLStreamException {
0813:                try {
0814:                    if (fStartTagOpened) {
0815:                        closeStartTag();
0816:                    }
0817:
0818:                    openStartTag();
0819:                    fElementStack.push(null, localName, null, null, true);
0820:                    fInternalNamespaceContext.pushContext();
0821:
0822:                    if (!fIsRepairingNamespace) {
0823:                        fWriter.write(localName);
0824:                    }
0825:                } catch (IOException e) {
0826:                    throw new XMLStreamException(e);
0827:                }
0828:            }
0829:
0830:            public void writeEmptyElement(String namespaceURI, String localName)
0831:                    throws XMLStreamException {
0832:                if (namespaceURI == null) {
0833:                    throw new XMLStreamException("NamespaceURI cannot be null");
0834:                }
0835:
0836:                namespaceURI = fSymbolTable.addSymbol(namespaceURI);
0837:
0838:                String prefix = fNamespaceContext.getPrefix(namespaceURI);
0839:                writeEmptyElement(prefix, localName, namespaceURI);
0840:            }
0841:
0842:            public void writeEmptyElement(String prefix, String localName,
0843:                    String namespaceURI) throws XMLStreamException {
0844:                try {
0845:                    if (localName == null) {
0846:                        throw new XMLStreamException(
0847:                                "Local Name cannot be null");
0848:                    }
0849:
0850:                    if (namespaceURI == null) {
0851:                        throw new XMLStreamException(
0852:                                "NamespaceURI cannot be null");
0853:                    }
0854:
0855:                    if (prefix != null) {
0856:                        prefix = fSymbolTable.addSymbol(prefix);
0857:                    }
0858:
0859:                    namespaceURI = fSymbolTable.addSymbol(namespaceURI);
0860:
0861:                    if (fStartTagOpened) {
0862:                        closeStartTag();
0863:                    }
0864:
0865:                    openStartTag();
0866:
0867:                    fElementStack.push(prefix, localName, null, namespaceURI,
0868:                            true);
0869:                    fInternalNamespaceContext.pushContext();
0870:
0871:                    if (!fIsRepairingNamespace) {
0872:                        if (prefix == null) {
0873:                            throw new XMLStreamException("NamespaceURI "
0874:                                    + namespaceURI
0875:                                    + " has not been bound to any prefix");
0876:                        }
0877:                    } else {
0878:                        return;
0879:                    }
0880:
0881:                    if ((prefix != null)
0882:                            && (prefix != XMLConstants.DEFAULT_NS_PREFIX)) {
0883:                        fWriter.write(prefix);
0884:                        fWriter.write(":");
0885:                    }
0886:
0887:                    fWriter.write(localName);
0888:                } catch (IOException e) {
0889:                    throw new XMLStreamException(e);
0890:                }
0891:            }
0892:
0893:            public void writeEndDocument() throws XMLStreamException {
0894:                try {
0895:                    if (fStartTagOpened) {
0896:                        closeStartTag();
0897:                    }
0898:
0899:                    ElementState elem = null;
0900:
0901:                    while (!fElementStack.empty()) {
0902:                        elem = (ElementState) fElementStack.pop();
0903:                        fInternalNamespaceContext.popContext();
0904:
0905:                        if (elem.isEmpty) {
0906:                            //fWriter.write(CLOSE_EMPTY_ELEMENT);
0907:                        } else {
0908:                            fWriter.write(OPEN_END_TAG);
0909:
0910:                            if ((elem.prefix != null)
0911:                                    && !(elem.prefix).equals("")) {
0912:                                fWriter.write(elem.prefix);
0913:                                fWriter.write(":");
0914:                            }
0915:
0916:                            fWriter.write(elem.localpart);
0917:                            fWriter.write(CLOSE_END_TAG);
0918:                        }
0919:                    }
0920:                } catch (IOException e) {
0921:                    throw new XMLStreamException(e);
0922:                } catch (ArrayIndexOutOfBoundsException e) {
0923:                    throw new XMLStreamException("No more elements to write");
0924:                }
0925:            }
0926:
0927:            public void writeEndElement() throws XMLStreamException {
0928:                try {
0929:                    if (fStartTagOpened) {
0930:                        closeStartTag();
0931:                    }
0932:
0933:                    ElementState currentElement = (ElementState) fElementStack
0934:                            .pop();
0935:
0936:                    if (currentElement == null) {
0937:                        throw new XMLStreamException(
0938:                                "No element was found to write");
0939:                    }
0940:
0941:                    if (currentElement.isEmpty) {
0942:                        //fWriter.write(CLOSE_EMPTY_ELEMENT);
0943:                        return;
0944:                    }
0945:
0946:                    fWriter.write(OPEN_END_TAG);
0947:
0948:                    if ((currentElement.prefix != null)
0949:                            && !(currentElement.prefix).equals("")) {
0950:                        fWriter.write(currentElement.prefix);
0951:                        fWriter.write(":");
0952:                    }
0953:
0954:                    fWriter.write(currentElement.localpart);
0955:                    fWriter.write(CLOSE_END_TAG);
0956:                    fInternalNamespaceContext.popContext();
0957:                } catch (IOException e) {
0958:                    throw new XMLStreamException(e);
0959:                } catch (ArrayIndexOutOfBoundsException e) {
0960:                    throw new XMLStreamException(
0961:                            "No element was found to write: " + e.toString(), e);
0962:                }
0963:            }
0964:
0965:            public void writeEntityRef(String refName)
0966:                    throws XMLStreamException {
0967:                try {
0968:                    if (fStartTagOpened) {
0969:                        closeStartTag();
0970:                    }
0971:
0972:                    fWriter.write('&');
0973:                    fWriter.write(refName);
0974:                    fWriter.write(';');
0975:                } catch (IOException e) {
0976:                    throw new XMLStreamException(e);
0977:                }
0978:            }
0979:
0980:            /**
0981:             * Write a Namespace declaration.
0982:             *
0983:             * If namespaceURI == null,
0984:             * then it is assumed to be equivilent to {@link XMLConstants.NULL_NS_URI},
0985:             * i.e. there is no Namespace.
0986:             *
0987:             * @param prefix Prefix to bind.
0988:             * @param namespaceURI NamespaceURI to declare.
0989:             *
0990:             * @throws XMLStreamException
0991:             *
0992:             * @see <a href="http://www.w3.org/TR/REC-xml-names/#defaulting">
0993:             *   Namespaces in XML, 5.2 Namespace Defaulting</a>
0994:             */
0995:            public void writeNamespace(String prefix, String namespaceURI)
0996:                    throws XMLStreamException {
0997:
0998:                // normalize namespaceURI
0999:                String namespaceURINormalized = null;
1000:                if (namespaceURI == null) {
1001:                    namespaceURINormalized = ""; // XMLConstants.NULL_NS_URI
1002:                } else {
1003:                    namespaceURINormalized = namespaceURI;
1004:                }
1005:
1006:                try {
1007:                    QName qname = null;
1008:
1009:                    if (!fStartTagOpened) {
1010:                        throw new IllegalStateException(
1011:                                "Invalid state: start tag is not opened at writeNamespace("
1012:                                        + prefix + ", "
1013:                                        + namespaceURINormalized + ")");
1014:                    }
1015:
1016:                    // is this the default Namespace?
1017:                    if (prefix == null
1018:                            || prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)
1019:                            || prefix.equals(XMLConstants.XMLNS_ATTRIBUTE)) {
1020:                        writeDefaultNamespace(namespaceURINormalized);
1021:                        return;
1022:                    }
1023:
1024:                    if (prefix.equals(XMLConstants.XML_NS_PREFIX)
1025:                            && namespaceURINormalized
1026:                                    .equals(XMLConstants.XML_NS_URI))
1027:                        return;
1028:
1029:                    prefix = fSymbolTable.addSymbol(prefix);
1030:                    namespaceURINormalized = fSymbolTable
1031:                            .addSymbol(namespaceURINormalized);
1032:
1033:                    if (fIsRepairingNamespace) {
1034:                        String tmpURI = fInternalNamespaceContext
1035:                                .getURI(prefix);
1036:
1037:                        if ((tmpURI != null)
1038:                                && (tmpURI == namespaceURINormalized)) {
1039:                            return;
1040:                        }
1041:
1042:                        qname = new QName();
1043:                        qname.setValues(prefix, XMLConstants.XMLNS_ATTRIBUTE,
1044:                                null, namespaceURINormalized);
1045:                        fNamespaceDecls.add(qname);
1046:
1047:                        return;
1048:                    }
1049:
1050:                    if (fInternalNamespaceContext
1051:                            .containsPrefixInCurrentContext(prefix)) {
1052:
1053:                        String tmp = fInternalNamespaceContext.getURI(prefix);
1054:
1055:                        if (tmp != null && tmp != namespaceURINormalized) {
1056:
1057:                            throw new XMLStreamException("prefix " + prefix
1058:                                    + " has been already bound to " + tmp
1059:                                    + ". Rebinding it to "
1060:                                    + namespaceURINormalized + " is an error");
1061:                        }
1062:                    }
1063:
1064:                    fInternalNamespaceContext.declarePrefix(prefix,
1065:                            namespaceURINormalized);
1066:                    writenamespace(prefix, namespaceURINormalized);
1067:
1068:                } catch (IOException e) {
1069:                    throw new XMLStreamException(e);
1070:                }
1071:            }
1072:
1073:            private void writenamespace(String prefix, String namespaceURI)
1074:                    throws IOException {
1075:                fWriter.write(" xmlns");
1076:
1077:                if ((prefix != null)
1078:                        && (prefix != XMLConstants.DEFAULT_NS_PREFIX)) {
1079:                    fWriter.write(":");
1080:                    fWriter.write(prefix);
1081:                }
1082:
1083:                fWriter.write("=\"");
1084:                writeXMLContent(namespaceURI, true, // true = escapeChars
1085:                        true); // true = escapeDoubleQuotes
1086:                fWriter.write("\"");
1087:            }
1088:
1089:            public void writeProcessingInstruction(String target)
1090:                    throws XMLStreamException {
1091:                try {
1092:                    if (fStartTagOpened) {
1093:                        closeStartTag();
1094:                    }
1095:
1096:                    if (target != null) {
1097:                        fWriter.write("<?");
1098:                        fWriter.write(target);
1099:                        fWriter.write("?>");
1100:
1101:                        return;
1102:                    }
1103:                } catch (IOException e) {
1104:                    throw new XMLStreamException(e);
1105:                }
1106:
1107:                throw new XMLStreamException("PI target cannot be null");
1108:            }
1109:
1110:            /**
1111:             * @param target
1112:             * @param data
1113:             * @throws XMLStreamException
1114:             */
1115:            public void writeProcessingInstruction(String target, String data)
1116:                    throws XMLStreamException {
1117:                try {
1118:                    if (fStartTagOpened) {
1119:                        closeStartTag();
1120:                    }
1121:
1122:                    if ((target == null) || (data == null)) {
1123:                        throw new XMLStreamException("PI target cannot be null");
1124:                    }
1125:
1126:                    fWriter.write("<?");
1127:                    fWriter.write(target);
1128:                    fWriter.write(SPACE);
1129:                    fWriter.write(data);
1130:                    fWriter.write("?>");
1131:                } catch (IOException e) {
1132:                    throw new XMLStreamException(e);
1133:                }
1134:            }
1135:
1136:            /**
1137:             * @throws XMLStreamException
1138:             */
1139:            public void writeStartDocument() throws XMLStreamException {
1140:                try {
1141:                    fWriter.write(DEFAULT_XMLDECL);
1142:                } catch (IOException ex) {
1143:                    throw new XMLStreamException(ex);
1144:                }
1145:            }
1146:
1147:            /**
1148:             * @param version
1149:             * @throws XMLStreamException
1150:             */
1151:            public void writeStartDocument(String version)
1152:                    throws XMLStreamException {
1153:                try {
1154:                    if ((version == null) || version.equals("")) {
1155:                        writeStartDocument();
1156:
1157:                        return;
1158:                    }
1159:
1160:                    fWriter.write("<?xml version=\"");
1161:                    fWriter.write(version);
1162:                    fWriter.write("\"");
1163:
1164:                    //fWriter.write(DEFAULT_ENCODING);
1165:                    fWriter.write("?>");
1166:                } catch (IOException ex) {
1167:                    throw new XMLStreamException(ex);
1168:                }
1169:            }
1170:
1171:            /**
1172:             * @param encoding
1173:             * @param version
1174:             * @throws XMLStreamException
1175:             */
1176:            public void writeStartDocument(String encoding, String version)
1177:                    throws XMLStreamException {
1178:                //Revisit : What about standalone ?
1179:                try {
1180:                    if ((encoding == null) && (version == null)) {
1181:                        writeStartDocument();
1182:
1183:                        return;
1184:                    }
1185:
1186:                    if (encoding == null) {
1187:                        writeStartDocument(version);
1188:
1189:                        return;
1190:                    }
1191:
1192:                    String streamEncoding = null;
1193:                    if (fWriter instanceof  OutputStreamWriter) {
1194:                        streamEncoding = ((OutputStreamWriter) fWriter)
1195:                                .getEncoding();
1196:                    } else if (fWriter instanceof  UTF8OutputStreamWriter) {
1197:                        streamEncoding = ((UTF8OutputStreamWriter) fWriter)
1198:                                .getEncoding();
1199:                    } else if (fWriter instanceof  XMLWriter) {
1200:                        streamEncoding = ((OutputStreamWriter) ((XMLWriter) fWriter)
1201:                                .getWriter()).getEncoding();
1202:                    }
1203:
1204:                    if (streamEncoding != null
1205:                            && !streamEncoding.equalsIgnoreCase(encoding)) {
1206:                        // If the equality check failed, check for charset encoding aliases
1207:                        boolean foundAlias = false;
1208:                        Set aliases = Charset.forName(encoding).aliases();
1209:                        for (Iterator it = aliases.iterator(); !foundAlias
1210:                                && it.hasNext();) {
1211:                            if (streamEncoding.equalsIgnoreCase((String) it
1212:                                    .next())) {
1213:                                foundAlias = true;
1214:                            }
1215:                        }
1216:                        // If no alias matches the encoding name, then report error
1217:                        if (!foundAlias) {
1218:                            throw new XMLStreamException(
1219:                                    "Underlying stream encoding '"
1220:                                            + streamEncoding
1221:                                            + "' and input paramter for writeStartDocument() method '"
1222:                                            + encoding + "' do not match.");
1223:                        }
1224:                    }
1225:
1226:                    fWriter.write("<?xml version=\"");
1227:
1228:                    if ((version == null) || version.equals("")) {
1229:                        fWriter.write(DEFAULT_XML_VERSION);
1230:                    } else {
1231:                        fWriter.write(version);
1232:                    }
1233:
1234:                    if (!encoding.equals("")) {
1235:                        fWriter.write("\" encoding=\"");
1236:                        fWriter.write(encoding);
1237:                    }
1238:
1239:                    fWriter.write("\"?>");
1240:                } catch (IOException ex) {
1241:                    throw new XMLStreamException(ex);
1242:                }
1243:            }
1244:
1245:            /**
1246:             * @param localName
1247:             * @throws XMLStreamException
1248:             */
1249:            public void writeStartElement(String localName)
1250:                    throws XMLStreamException {
1251:                try {
1252:                    if (localName == null) {
1253:                        throw new XMLStreamException(
1254:                                "Local Name cannot be null");
1255:                    }
1256:
1257:                    if (fStartTagOpened) {
1258:                        closeStartTag();
1259:                    }
1260:
1261:                    openStartTag();
1262:                    fElementStack.push(null, localName, null, null, false);
1263:                    fInternalNamespaceContext.pushContext();
1264:
1265:                    if (fIsRepairingNamespace) {
1266:                        return;
1267:                    }
1268:
1269:                    fWriter.write(localName);
1270:                } catch (IOException ex) {
1271:                    throw new XMLStreamException(ex);
1272:                }
1273:            }
1274:
1275:            /**
1276:             * @param namespaceURI
1277:             * @param localName
1278:             * @throws XMLStreamException
1279:             */
1280:            public void writeStartElement(String namespaceURI, String localName)
1281:                    throws XMLStreamException {
1282:                if (localName == null) {
1283:                    throw new XMLStreamException("Local Name cannot be null");
1284:                }
1285:
1286:                if (namespaceURI == null) {
1287:                    throw new XMLStreamException("NamespaceURI cannot be null");
1288:                }
1289:
1290:                namespaceURI = fSymbolTable.addSymbol(namespaceURI);
1291:
1292:                String prefix = null;
1293:
1294:                if (!fIsRepairingNamespace) {
1295:                    prefix = fNamespaceContext.getPrefix(namespaceURI);
1296:
1297:                    if (prefix != null) {
1298:                        prefix = fSymbolTable.addSymbol(prefix);
1299:                    }
1300:                }
1301:
1302:                writeStartElement(prefix, localName, namespaceURI);
1303:            }
1304:
1305:            /**
1306:             * @param prefix
1307:             * @param localName
1308:             * @param namespaceURI
1309:             * @throws XMLStreamException
1310:             */
1311:            public void writeStartElement(String prefix, String localName,
1312:                    String namespaceURI) throws XMLStreamException {
1313:                try {
1314:                    if (localName == null) {
1315:                        throw new XMLStreamException(
1316:                                "Local Name cannot be null");
1317:                    }
1318:
1319:                    if (namespaceURI == null) {
1320:                        throw new XMLStreamException(
1321:                                "NamespaceURI cannot be null");
1322:                    }
1323:
1324:                    if (!fIsRepairingNamespace) {
1325:                        if (prefix == null) {
1326:                            throw new XMLStreamException(
1327:                                    "Prefix cannot be null");
1328:                        }
1329:                    }
1330:
1331:                    if (fStartTagOpened) {
1332:                        closeStartTag();
1333:                    }
1334:
1335:                    openStartTag();
1336:                    namespaceURI = fSymbolTable.addSymbol(namespaceURI);
1337:
1338:                    if (prefix != null) {
1339:                        prefix = fSymbolTable.addSymbol(prefix);
1340:                    }
1341:
1342:                    fElementStack.push(prefix, localName, null, namespaceURI,
1343:                            false);
1344:                    fInternalNamespaceContext.pushContext();
1345:
1346:                    String tmpPrefix = fNamespaceContext
1347:                            .getPrefix(namespaceURI);
1348:
1349:                    if ((prefix != null)
1350:                            && ((tmpPrefix == null) || !prefix
1351:                                    .equals(tmpPrefix))) {
1352:                        fInternalNamespaceContext.declarePrefix(prefix,
1353:                                namespaceURI);
1354:
1355:                    }
1356:
1357:                    if (fIsRepairingNamespace) {
1358:                        if ((prefix == null)
1359:                                || ((tmpPrefix != null) && prefix
1360:                                        .equals(tmpPrefix))) {
1361:                            return;
1362:                        }
1363:
1364:                        QName qname = new QName();
1365:                        qname.setValues(prefix, XMLConstants.XMLNS_ATTRIBUTE,
1366:                                null, namespaceURI);
1367:                        fNamespaceDecls.add(qname);
1368:
1369:                        return;
1370:                    }
1371:
1372:                    if ((prefix != null)
1373:                            && (prefix != XMLConstants.DEFAULT_NS_PREFIX)) {
1374:                        fWriter.write(prefix);
1375:                        fWriter.write(":");
1376:                    }
1377:
1378:                    fWriter.write(localName);
1379:
1380:                } catch (IOException ex) {
1381:                    throw new XMLStreamException(ex);
1382:                }
1383:            }
1384:
1385:            /**
1386:             * Writes XML content to underlying writer. Escapes characters unless
1387:             * escaping character feature is turned off.
1388:             */
1389:            private void writeXMLContent(char[] content, int start, int length,
1390:                    boolean escapeChars) throws IOException {
1391:                if (!escapeChars) {
1392:                    fWriter.write(content, start, length);
1393:
1394:                    return;
1395:                }
1396:
1397:                // Index of the next char to be written
1398:                int startWritePos = start;
1399:
1400:                final int end = start + length;
1401:
1402:                for (int index = start; index < end; index++) {
1403:                    char ch = content[index];
1404:
1405:                    if (fEncoder != null && !fEncoder.canEncode(ch)) {
1406:                        fWriter.write(content, startWritePos, index
1407:                                - startWritePos);
1408:
1409:                        // Escape this char as underlying encoder cannot handle it
1410:                        fWriter.write("&#x");
1411:                        fWriter.write(Integer.toHexString(ch));
1412:                        fWriter.write(';');
1413:                        startWritePos = index + 1;
1414:                        continue;
1415:                    }
1416:
1417:                    switch (ch) {
1418:                    case '<':
1419:                        fWriter.write(content, startWritePos, index
1420:                                - startWritePos);
1421:                        fWriter.write("&lt;");
1422:                        startWritePos = index + 1;
1423:
1424:                        break;
1425:
1426:                    case '&':
1427:                        fWriter.write(content, startWritePos, index
1428:                                - startWritePos);
1429:                        fWriter.write("&amp;");
1430:                        startWritePos = index + 1;
1431:
1432:                        break;
1433:
1434:                    case '>':
1435:                        fWriter.write(content, startWritePos, index
1436:                                - startWritePos);
1437:                        fWriter.write("&gt;");
1438:                        startWritePos = index + 1;
1439:
1440:                        break;
1441:                    }
1442:                }
1443:
1444:                // Write any pending data
1445:                fWriter.write(content, startWritePos, end - startWritePos);
1446:            }
1447:
1448:            private void writeXMLContent(String content) throws IOException {
1449:                if ((content != null) && (content.length() > 0)) {
1450:                    writeXMLContent(content, fEscapeCharacters, // boolean = escapeChars
1451:                            false); // false = escapeDoubleQuotes
1452:                }
1453:            }
1454:
1455:            /**
1456:             * Writes XML content to underlying writer. Escapes characters unless
1457:             * escaping character feature is turned off.
1458:             */
1459:            private void writeXMLContent(String content, boolean escapeChars,
1460:                    boolean escapeDoubleQuotes) throws IOException {
1461:
1462:                if (!escapeChars) {
1463:                    fWriter.write(content);
1464:
1465:                    return;
1466:                }
1467:
1468:                // Index of the next char to be written
1469:                int startWritePos = 0;
1470:
1471:                final int end = content.length();
1472:
1473:                for (int index = 0; index < end; index++) {
1474:                    char ch = content.charAt(index);
1475:
1476:                    if (fEncoder != null && !fEncoder.canEncode(ch)) {
1477:                        fWriter.write(content, startWritePos, index
1478:                                - startWritePos);
1479:
1480:                        // Escape this char as underlying encoder cannot handle it
1481:                        fWriter.write("&#x");
1482:                        fWriter.write(Integer.toHexString(ch));
1483:                        fWriter.write(';');
1484:                        startWritePos = index + 1;
1485:                        continue;
1486:                    }
1487:
1488:                    switch (ch) {
1489:                    case '<':
1490:                        fWriter.write(content, startWritePos, index
1491:                                - startWritePos);
1492:                        fWriter.write("&lt;");
1493:                        startWritePos = index + 1;
1494:
1495:                        break;
1496:
1497:                    case '&':
1498:                        fWriter.write(content, startWritePos, index
1499:                                - startWritePos);
1500:                        fWriter.write("&amp;");
1501:                        startWritePos = index + 1;
1502:
1503:                        break;
1504:
1505:                    case '>':
1506:                        fWriter.write(content, startWritePos, index
1507:                                - startWritePos);
1508:                        fWriter.write("&gt;");
1509:                        startWritePos = index + 1;
1510:
1511:                        break;
1512:
1513:                    case '"':
1514:                        fWriter.write(content, startWritePos, index
1515:                                - startWritePos);
1516:                        if (escapeDoubleQuotes) {
1517:                            fWriter.write("&quot;");
1518:                        } else {
1519:                            fWriter.write('"');
1520:                        }
1521:                        startWritePos = index + 1;
1522:
1523:                        break;
1524:                    }
1525:                }
1526:
1527:                // Write any pending data
1528:                fWriter.write(content, startWritePos, end - startWritePos);
1529:            }
1530:
1531:            /**
1532:             * marks close of start tag and writes the same into the writer.
1533:             */
1534:            private void closeStartTag() throws XMLStreamException {
1535:                try {
1536:                    ElementState currentElement = fElementStack.peek();
1537:
1538:                    if (fIsRepairingNamespace) {
1539:                        repair();
1540:                        correctPrefix(currentElement);
1541:
1542:                        if ((currentElement.prefix != null)
1543:                                && (currentElement.prefix != XMLConstants.DEFAULT_NS_PREFIX)) {
1544:                            fWriter.write(currentElement.prefix);
1545:                            fWriter.write(":");
1546:                        }
1547:
1548:                        fWriter.write(currentElement.localpart);
1549:
1550:                        int len = fNamespaceDecls.size();
1551:                        QName qname = null;
1552:
1553:                        for (int i = 0; i < len; i++) {
1554:                            qname = (QName) fNamespaceDecls.get(i);
1555:
1556:                            if (qname != null) {
1557:                                if (fInternalNamespaceContext.declarePrefix(
1558:                                        qname.prefix, qname.uri)) {
1559:                                    writenamespace(qname.prefix, qname.uri);
1560:                                }
1561:                            }
1562:                        }
1563:
1564:                        fNamespaceDecls.clear();
1565:
1566:                        Attribute attr = null;
1567:
1568:                        for (int j = 0; j < fAttributeCache.size(); j++) {
1569:                            attr = (Attribute) fAttributeCache.get(j);
1570:
1571:                            if ((attr.prefix != null) && (attr.uri != null)) {
1572:                                if (!attr.prefix.equals("")
1573:                                        && !attr.uri.equals("")) {
1574:                                    String tmp = fInternalNamespaceContext
1575:                                            .getPrefix(attr.uri);
1576:
1577:                                    if ((tmp == null) || (tmp != attr.prefix)) {
1578:                                        if (fInternalNamespaceContext
1579:                                                .declarePrefix(attr.prefix,
1580:                                                        attr.uri)) {
1581:                                            writenamespace(attr.prefix,
1582:                                                    attr.uri);
1583:                                        }
1584:                                    }
1585:                                }
1586:                            }
1587:
1588:                            writeAttributeWithPrefix(attr.prefix,
1589:                                    attr.localpart, attr.value);
1590:                        }
1591:
1592:                        fAttributeCache.clear();
1593:                    }
1594:
1595:                    if (currentElement.isEmpty) {
1596:                        fElementStack.pop();
1597:                        fInternalNamespaceContext.popContext();
1598:                        fWriter.write(CLOSE_EMPTY_ELEMENT);
1599:                    } else {
1600:                        fWriter.write(CLOSE_START_TAG);
1601:                    }
1602:
1603:                    fStartTagOpened = false;
1604:                } catch (IOException ex) {
1605:                    fStartTagOpened = false;
1606:                    throw new XMLStreamException(ex);
1607:                }
1608:            }
1609:
1610:            /**
1611:             * marks open of start tag and writes the same into the writer.
1612:             */
1613:            private void openStartTag() throws IOException {
1614:                fStartTagOpened = true;
1615:                fWriter.write(OPEN_START_TAG);
1616:            }
1617:
1618:            /**
1619:             *
1620:             * @param uri
1621:             * @return
1622:             */
1623:            private void correctPrefix(QName attr) {
1624:                String tmpPrefix = null;
1625:                String prefix;
1626:                String uri;
1627:                prefix = attr.prefix;
1628:                uri = attr.uri;
1629:
1630:                if (prefix == null || prefix.equals("")) {
1631:                    if (uri == null) {
1632:                        return;
1633:                    }
1634:
1635:                    if (prefix == XMLConstants.DEFAULT_NS_PREFIX
1636:                            && uri == XMLConstants.DEFAULT_NS_PREFIX)
1637:                        return;
1638:
1639:                    uri = fSymbolTable.addSymbol(uri);
1640:
1641:                    QName decl = null;
1642:
1643:                    for (int i = 0; i < fNamespaceDecls.size(); i++) {
1644:                        decl = (QName) fNamespaceDecls.get(i);
1645:
1646:                        if ((decl != null) && (decl.uri == attr.uri)) {
1647:                            attr.prefix = decl.prefix;
1648:
1649:                            return;
1650:                        }
1651:                    }
1652:
1653:                    tmpPrefix = fNamespaceContext.getPrefix(uri);
1654:
1655:                    if (tmpPrefix == XMLConstants.DEFAULT_NS_PREFIX) {
1656:                        return;
1657:                    }
1658:
1659:                    if (tmpPrefix == null) {
1660:                        StringBuffer genPrefix = new StringBuffer("zdef");
1661:
1662:                        for (int i = 0; i < 1; i++) {
1663:                            genPrefix.append(fPrefixGen.nextInt());
1664:                        }
1665:
1666:                        prefix = genPrefix.toString();
1667:                        prefix = fSymbolTable.addSymbol(prefix);
1668:                    } else {
1669:                        prefix = fSymbolTable.addSymbol(tmpPrefix);
1670:                    }
1671:
1672:                    if (tmpPrefix == null) {
1673:                        QName qname = new QName();
1674:                        qname.setValues(prefix, XMLConstants.XMLNS_ATTRIBUTE,
1675:                                null, uri);
1676:                        fNamespaceDecls.add(qname);
1677:                        fInternalNamespaceContext.declarePrefix(fSymbolTable
1678:                                .addSymbol(prefix), uri);
1679:                    }
1680:                }
1681:
1682:                attr.prefix = prefix;
1683:            }
1684:
1685:            /**
1686:             * @param uri
1687:             * @return
1688:             */
1689:            private boolean isDefaultNamespace(String uri) {
1690:                String defaultNamespace = fInternalNamespaceContext
1691:                        .getURI(DEFAULT_PREFIX);
1692:
1693:                if (uri == defaultNamespace) {
1694:                    return true;
1695:                }
1696:
1697:                return false;
1698:            }
1699:
1700:            /**
1701:             * @param prefix
1702:             * @param uri
1703:             * @return
1704:             */
1705:            private boolean checkUserNamespaceContext(String prefix, String uri) {
1706:                if (fNamespaceContext.userContext != null) {
1707:                    String tmpURI = fNamespaceContext.userContext
1708:                            .getNamespaceURI(prefix);
1709:
1710:                    if ((tmpURI != null) && tmpURI.equals(uri)) {
1711:                        return true;
1712:                    }
1713:                }
1714:
1715:                return false;
1716:            }
1717:
1718:            /**
1719:             * Correct's namespaces  as per requirements of isReparisingNamespace property.
1720:             */
1721:            protected void repair() {
1722:                Attribute attr = null;
1723:                Attribute attr2 = null;
1724:                ElementState currentElement = fElementStack.peek();
1725:                removeDuplicateDecls();
1726:
1727:                for (int i = 0; i < fAttributeCache.size(); i++) {
1728:                    attr = (Attribute) fAttributeCache.get(i);
1729:                    if ((attr.prefix != null && !attr.prefix.equals(""))
1730:                            || (attr.uri != null && !attr.uri.equals(""))) {
1731:                        correctPrefix(currentElement, attr);
1732:                    }
1733:                }
1734:
1735:                if (!isDeclared(currentElement)) {
1736:                    if ((currentElement.prefix != null)
1737:                            && (currentElement.uri != null)) {
1738:                        if ((!currentElement.prefix.equals(""))
1739:                                && (!currentElement.uri.equals(""))) {
1740:                            fNamespaceDecls.add(currentElement);
1741:                        }
1742:                    }
1743:                }
1744:
1745:                for (int i = 0; i < fAttributeCache.size(); i++) {
1746:                    attr = (Attribute) fAttributeCache.get(i);
1747:                    for (int j = i + 1; j < fAttributeCache.size(); j++) {
1748:                        attr2 = (Attribute) fAttributeCache.get(j);
1749:                        if (!"".equals(attr.prefix) && !"".equals(attr2.prefix)) {
1750:                            correctPrefix(attr, attr2);
1751:                        }
1752:                    }
1753:                }
1754:
1755:                repairNamespaceDecl(currentElement);
1756:
1757:                int i = 0;
1758:
1759:                for (i = 0; i < fAttributeCache.size(); i++) {
1760:                    attr = (Attribute) fAttributeCache.get(i);
1761:                    /* If 'attr' is an attribute and it is in no namespace(which means that prefix="", uri=""), attr's 
1762:                       namespace should not be redinded. See [http://www.w3.org/TR/REC-xml-names/#defaulting].
1763:                     */
1764:                    if (attr.prefix != null && attr.prefix.equals("")
1765:                            && attr.uri != null && attr.uri.equals("")) {
1766:                        repairNamespaceDecl(attr);
1767:                    }
1768:                }
1769:
1770:                QName qname = null;
1771:
1772:                for (i = 0; i < fNamespaceDecls.size(); i++) {
1773:                    qname = (QName) fNamespaceDecls.get(i);
1774:
1775:                    if (qname != null) {
1776:                        fInternalNamespaceContext.declarePrefix(qname.prefix,
1777:                                qname.uri);
1778:                    }
1779:                }
1780:
1781:                for (i = 0; i < fAttributeCache.size(); i++) {
1782:                    attr = (Attribute) fAttributeCache.get(i);
1783:                    correctPrefix(attr);
1784:                }
1785:            }
1786:
1787:            /*
1788:             *If element and/or attribute names in the same start or empty-element tag
1789:             *are bound to different namespace URIs and are using the same prefix then
1790:             *the element or the first occurring attribute retains the original prefix
1791:             *and the following attributes have their prefixes replaced with a new prefix
1792:             *that is bound to the namespace URIs of those attributes.
1793:             */
1794:            void correctPrefix(QName attr1, QName attr2) {
1795:                String tmpPrefix = null;
1796:                QName decl = null;
1797:                boolean done = false;
1798:
1799:                checkForNull(attr1);
1800:                checkForNull(attr2);
1801:
1802:                if (attr1.prefix.equals(attr2.prefix)
1803:                        && !(attr1.uri.equals(attr2.uri))) {
1804:
1805:                    tmpPrefix = fNamespaceContext.getPrefix(attr2.uri);
1806:
1807:                    if (tmpPrefix != null) {
1808:                        attr2.prefix = fSymbolTable.addSymbol(tmpPrefix);
1809:                    } else {
1810:                        decl = null;
1811:                        for (int n = 0; n < fNamespaceDecls.size(); n++) {
1812:                            decl = (QName) fNamespaceDecls.get(n);
1813:                            if (decl != null && (decl.uri == attr2.uri)) {
1814:                                attr2.prefix = decl.prefix;
1815:
1816:                                return;
1817:                            }
1818:                        }
1819:
1820:                        //No namespace mapping found , so declare prefix.
1821:                        StringBuffer genPrefix = new StringBuffer("zdef");
1822:
1823:                        for (int k = 0; k < 1; k++) {
1824:                            genPrefix.append(fPrefixGen.nextInt());
1825:                        }
1826:
1827:                        tmpPrefix = genPrefix.toString();
1828:                        tmpPrefix = fSymbolTable.addSymbol(tmpPrefix);
1829:                        attr2.prefix = tmpPrefix;
1830:
1831:                        QName qname = new QName();
1832:                        qname.setValues(tmpPrefix,
1833:                                XMLConstants.XMLNS_ATTRIBUTE, null, attr2.uri);
1834:                        fNamespaceDecls.add(qname);
1835:                    }
1836:                }
1837:            }
1838:
1839:            void checkForNull(QName attr) {
1840:                if (attr.prefix == null)
1841:                    attr.prefix = XMLConstants.DEFAULT_NS_PREFIX;
1842:                if (attr.uri == null)
1843:                    attr.uri = XMLConstants.DEFAULT_NS_PREFIX;
1844:            }
1845:
1846:            void removeDuplicateDecls() {
1847:                QName decl1, decl2;
1848:                for (int i = 0; i < fNamespaceDecls.size(); i++) {
1849:                    decl1 = (QName) fNamespaceDecls.get(i);
1850:                    if (decl1 != null) {
1851:                        for (int j = i + 1; j < fNamespaceDecls.size(); j++) {
1852:                            decl2 = (QName) fNamespaceDecls.get(j);
1853:                            // QName.equals relies on identity equality, so we can't use it,
1854:                            // because prefixes aren't interned
1855:                            if (decl2 != null
1856:                                    && decl1.prefix.equals(decl2.prefix)
1857:                                    && decl1.uri.equals(decl2.uri))
1858:                                fNamespaceDecls.remove(j);
1859:                        }
1860:                    }
1861:                }
1862:            }
1863:
1864:            /*
1865:             *If an element or attribute name is bound to a prefix and there is a namespace
1866:             *declaration that binds that prefix to a different URI then that namespace declaration
1867:             *is either removed if the correct mapping is inherited from the parent context of that element,
1868:             *or changed to the namespace URI of the element or attribute using that prefix.
1869:             *
1870:             */
1871:            void repairNamespaceDecl(QName attr) {
1872:                QName decl = null;
1873:                String tmpURI;
1874:
1875:                //check for null prefix.
1876:                for (int j = 0; j < fNamespaceDecls.size(); j++) {
1877:                    decl = (QName) fNamespaceDecls.get(j);
1878:
1879:                    if (decl != null) {
1880:                        if ((attr.prefix != null)
1881:                                && (attr.prefix.equals(decl.prefix) && !(attr.uri
1882:                                        .equals(decl.uri)))) {
1883:                            tmpURI = fNamespaceContext
1884:                                    .getNamespaceURI(attr.prefix);
1885:
1886:                            //see if you need to add to symbole table.
1887:                            if (tmpURI != null) {
1888:                                if (tmpURI.equals(attr.uri)) {
1889:                                    fNamespaceDecls.set(j, null);
1890:                                } else {
1891:                                    decl.uri = attr.uri;
1892:                                }
1893:                            }
1894:                        }
1895:                    }
1896:                }
1897:            }
1898:
1899:            boolean isDeclared(QName attr) {
1900:                QName decl = null;
1901:
1902:                for (int n = 0; n < fNamespaceDecls.size(); n++) {
1903:                    decl = (QName) fNamespaceDecls.get(n);
1904:
1905:                    if ((attr.prefix != null)
1906:                            && ((attr.prefix == decl.prefix) && (decl.uri == attr.uri))) {
1907:                        return true;
1908:                    }
1909:                }
1910:
1911:                if (attr.uri != null) {
1912:                    if (fNamespaceContext.getPrefix(attr.uri) != null) {
1913:                        return true;
1914:                    }
1915:                }
1916:
1917:                return false;
1918:            }
1919:
1920:            /*
1921:             * Start of Internal classes.
1922:             *
1923:             */
1924:            protected class ElementStack {
1925:                /** The stack data. */
1926:                protected ElementState[] fElements;
1927:
1928:                /** The size of the stack. */
1929:                protected short fDepth;
1930:
1931:                /** Default constructor. */
1932:                public ElementStack() {
1933:                    fElements = new ElementState[10];
1934:
1935:                    for (int i = 0; i < fElements.length; i++) {
1936:                        fElements[i] = new ElementState();
1937:                    }
1938:                }
1939:
1940:                /**
1941:                 * Pushes an element on the stack.
1942:                 * <p>
1943:                 * <strong>Note:</strong> The QName values are copied into the
1944:                 * stack. In other words, the caller does <em>not</em> orphan
1945:                 * the element to the stack. Also, the QName object returned
1946:                 * is <em>not</em> orphaned to the caller. It should be
1947:                 * considered read-only.
1948:                 *
1949:                 * @param element The element to push onto the stack.
1950:                 *
1951:                 * @return Returns the actual QName object that stores the
1952:                 */
1953:                public ElementState push(ElementState element) {
1954:                    if (fDepth == fElements.length) {
1955:                        ElementState[] array = new ElementState[fElements.length * 2];
1956:                        System.arraycopy(fElements, 0, array, 0, fDepth);
1957:                        fElements = array;
1958:
1959:                        for (int i = fDepth; i < fElements.length; i++) {
1960:                            fElements[i] = new ElementState();
1961:                        }
1962:                    }
1963:
1964:                    fElements[fDepth].setValues(element);
1965:
1966:                    return fElements[fDepth++];
1967:                }
1968:
1969:                /**
1970:                 *
1971:                 * @param prefix
1972:                 * @param localpart
1973:                 * @param rawname
1974:                 * @param uri
1975:                 * @param isEmpty
1976:                 * @return
1977:                 */
1978:                public ElementState push(String prefix, String localpart,
1979:                        String rawname, String uri, boolean isEmpty) {
1980:                    if (fDepth == fElements.length) {
1981:                        ElementState[] array = new ElementState[fElements.length * 2];
1982:                        System.arraycopy(fElements, 0, array, 0, fDepth);
1983:                        fElements = array;
1984:
1985:                        for (int i = fDepth; i < fElements.length; i++) {
1986:                            fElements[i] = new ElementState();
1987:                        }
1988:                    }
1989:
1990:                    fElements[fDepth].setValues(prefix, localpart, rawname,
1991:                            uri, isEmpty);
1992:
1993:                    return fElements[fDepth++];
1994:                }
1995:
1996:                /**
1997:                 * Pops an element off of the stack by setting the values of
1998:                 * the specified QName.
1999:                 * <p>
2000:                 * <strong>Note:</strong> The object returned is <em>not</em>
2001:                 * orphaned to the caller. Therefore, the caller should consider
2002:                 * the object to be read-only.
2003:                 */
2004:                public ElementState pop() {
2005:                    return fElements[--fDepth];
2006:                }
2007:
2008:                /** Clears the stack without throwing away existing QName objects. */
2009:                public void clear() {
2010:                    fDepth = 0;
2011:                }
2012:
2013:                /**
2014:                 * This function is as a result of optimization done for endElement --
2015:                 * we dont need to set the value for every end element we encouter.
2016:                 * For Well formedness checks we can have the same QName object that was pushed.
2017:                 * the values will be set only if application need to know about the endElement
2018:                 * -- neeraj.bajaj@sun.com
2019:                 */
2020:                public ElementState peek() {
2021:                    return fElements[fDepth - 1];
2022:                }
2023:
2024:                /**
2025:                 *
2026:                 * @return
2027:                 */
2028:                public boolean empty() {
2029:                    return (fDepth > 0) ? false : true;
2030:                }
2031:            }
2032:
2033:            /**
2034:             * Maintains element state . localName for now.
2035:             */
2036:            class ElementState extends QName {
2037:                public boolean isEmpty = false;
2038:
2039:                public ElementState() {
2040:                }
2041:
2042:                public ElementState(String prefix, String localpart,
2043:                        String rawname, String uri) {
2044:                    super (prefix, localpart, rawname, uri);
2045:                }
2046:
2047:                public void setValues(String prefix, String localpart,
2048:                        String rawname, String uri, boolean isEmpty) {
2049:                    super .setValues(prefix, localpart, rawname, uri);
2050:                    this .isEmpty = isEmpty;
2051:                }
2052:            }
2053:
2054:            /**
2055:             * Attributes
2056:             */
2057:            class Attribute extends QName {
2058:                String value;
2059:
2060:                Attribute(String value) {
2061:                    super ();
2062:                    this .value = value;
2063:                }
2064:            }
2065:
2066:            /**
2067:             * Implementation of NamespaceContext .
2068:             *
2069:             */
2070:            class NamespaceContextImpl implements  NamespaceContext {
2071:                //root namespace context set by user.
2072:                NamespaceContext userContext = null;
2073:
2074:                //context built by the writer.
2075:                NamespaceSupport internalContext = null;
2076:
2077:                public String getNamespaceURI(String prefix) {
2078:                    String uri = null;
2079:
2080:                    if (prefix != null) {
2081:                        prefix = fSymbolTable.addSymbol(prefix);
2082:                    }
2083:
2084:                    if (internalContext != null) {
2085:                        uri = internalContext.getURI(prefix);
2086:
2087:                        if (uri != null) {
2088:                            return uri;
2089:                        }
2090:                    }
2091:
2092:                    if (userContext != null) {
2093:                        uri = userContext.getNamespaceURI(prefix);
2094:
2095:                        return uri;
2096:                    }
2097:
2098:                    return null;
2099:                }
2100:
2101:                public String getPrefix(String uri) {
2102:                    String prefix = null;
2103:
2104:                    if (uri != null) {
2105:                        uri = fSymbolTable.addSymbol(uri);
2106:                    }
2107:
2108:                    if (internalContext != null) {
2109:                        prefix = internalContext.getPrefix(uri);
2110:
2111:                        if (prefix != null) {
2112:                            return prefix;
2113:                        }
2114:                    }
2115:
2116:                    if (userContext != null) {
2117:                        return userContext.getPrefix(uri);
2118:                    }
2119:
2120:                    return null;
2121:                }
2122:
2123:                public java.util.Iterator getPrefixes(String uri) {
2124:                    Vector prefixes = null;
2125:                    Iterator itr = null;
2126:
2127:                    if (uri != null) {
2128:                        uri = fSymbolTable.addSymbol(uri);
2129:                    }
2130:
2131:                    if (userContext != null) {
2132:                        itr = userContext.getPrefixes(uri);
2133:                    }
2134:
2135:                    if (internalContext != null) {
2136:                        prefixes = internalContext.getPrefixes(uri);
2137:                    }
2138:
2139:                    if ((prefixes == null) && (itr != null)) {
2140:                        return itr;
2141:                    } else if ((prefixes != null) && (itr == null)) {
2142:                        return new ReadOnlyIterator(prefixes.iterator());
2143:                    } else if ((prefixes != null) && (itr != null)) {
2144:                        String ob = null;
2145:
2146:                        while (itr.hasNext()) {
2147:                            ob = (String) itr.next();
2148:
2149:                            if (ob != null) {
2150:                                ob = fSymbolTable.addSymbol(ob);
2151:                            }
2152:
2153:                            if (!prefixes.contains(ob)) {
2154:                                prefixes.add(ob);
2155:                            }
2156:                        }
2157:
2158:                        return new ReadOnlyIterator(prefixes.iterator());
2159:                    }
2160:
2161:                    return fReadOnlyIterator;
2162:                }
2163:            }
2164:
2165:            // -- Map Interface --------------------------------------------------
2166:
2167:            public int size() {
2168:                return 1;
2169:            }
2170:
2171:            public boolean isEmpty() {
2172:                return false;
2173:            }
2174:
2175:            public boolean containsKey(Object key) {
2176:                return key.equals(OUTPUTSTREAM_PROPERTY);
2177:            }
2178:
2179:            /**
2180:             * Returns the value associated to an implementation-specific
2181:             * property. 
2182:             */
2183:            public Object get(Object key) {
2184:                if (key.equals(OUTPUTSTREAM_PROPERTY)) {
2185:                    return fOutputStream;
2186:                }
2187:                return null;
2188:            }
2189:
2190:            public java.util.Set entrySet() {
2191:                throw new UnsupportedOperationException();
2192:            }
2193:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.