Source Code Cross Referenced for JspxSerializer.java in  » IDE-Netbeans » visualweb.api.designer » org » netbeans » modules » visualweb » insync » markup » 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 » IDE Netbeans » visualweb.api.designer » org.netbeans.modules.visualweb.insync.markup 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:        // XXX FIXME now using xerces-2.8.0;
0042:        // SLIGHTLY MODIFIED COPY OF Xerces2's
0043:        //  xerces-2_6_0/src/org/apache/xml/serialize/XMLSerializer.java
0044:        // Modifications are marked with BEGIN/END RAVE MODIFICATIONS.
0045:        // Subclassing and modifying was not practical because of references
0046:        // to package private and class private fields and methods.
0047:        /*
0048:         * The Apache Software License, Version 1.1
0049:         *
0050:         *
0051:         * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
0052:         * reserved.
0053:         *
0054:         * Redistribution and use in source and binary forms, with or without
0055:         * modification, are permitted provided that the following conditions
0056:         * are met:
0057:         *
0058:         * 1. Redistributions of source code must retain the above copyright
0059:         *    notice, this list of conditions and the following disclaimer.
0060:         *
0061:         * 2. Redistributions in binary form must reproduce the above copyright
0062:         *    notice, this list of conditions and the following disclaimer in
0063:         *    the documentation and/or other materials provided with the
0064:         *    distribution.
0065:         *
0066:         * 3. The end-user documentation included with the redistribution,
0067:         *    if any, must include the following acknowledgment:
0068:         *       "This product includes software developed by the
0069:         *        Apache Software Foundation (http://www.apache.org/)."
0070:         *    Alternately, this acknowledgment may appear in the software itself,
0071:         *    if and wherever such third-party acknowledgments normally appear.
0072:         *
0073:         * 4. The names "Xerces" and "Apache Software Foundation" must
0074:         *    not be used to endorse or promote products derived from this
0075:         *    software without prior written permission. For written
0076:         *    permission, please contact apache@apache.org.
0077:         *
0078:         * 5. Products derived from this software may not be called "Apache",
0079:         *    nor may "Apache" appear in their name, without prior written
0080:         *    permission of the Apache Software Foundation.
0081:         *
0082:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0083:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0084:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0085:         * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
0086:         * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0087:         * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0088:         * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0089:         * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0090:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0091:         * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0092:         * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0093:         * SUCH DAMAGE.
0094:         * ====================================================================
0095:         *
0096:         * This software consists of voluntary contributions made by many
0097:         * individuals on behalf of the Apache Software Foundation and was
0098:         * originally based on software copyright (c) 1999, International
0099:         * Business Machines, Inc., http://www.apache.org.  For more
0100:         * information on the Apache Software Foundation, please see
0101:         * <http://www.apache.org/>.
0102:         */
0103:
0104:        // Sep 14, 2000:
0105:        //  Fixed problem with namespace handling. Contributed by
0106:        //  David Blondeau <blondeau@intalio.com>
0107:        // Sep 14, 2000:
0108:        //  Fixed serializer to report IO exception directly, instead at
0109:        //  the end of document processing.
0110:        //  Reported by Patrick Higgins <phiggins@transzap.com>
0111:        // Aug 21, 2000:
0112:        //  Fixed bug in startDocument not calling prepare.
0113:        //  Reported by Mikael Staldal <d96-mst-ingen-reklam@d.kth.se>
0114:        // Aug 21, 2000:
0115:        //  Added ability to omit DOCTYPE declaration.
0116:
0117:        // BEGIN RAVE MODIFICATIONS
0118:        //package org.apache.xml.serialize;
0119:        package org.netbeans.modules.visualweb.insync.markup;
0120:
0121:        import org.netbeans.modules.visualweb.designer.html.HtmlTag;
0122:        import org.apache.xml.serialize.*; // END RAVE MODIFICATIONS
0123:
0124:        import java.io.IOException;
0125:        import java.io.OutputStream;
0126:        import java.io.Writer;
0127:        import java.util.Enumeration;
0128:
0129:        import org.apache.xerces.dom.DOMMessageFormatter;
0130:        import org.apache.xerces.util.NamespaceSupport;
0131:        import org.apache.xerces.util.SymbolTable;
0132:        import org.apache.xerces.util.XMLChar;
0133:        import org.apache.xerces.util.XMLSymbols;
0134:        import org.apache.xerces.xni.NamespaceContext;
0135:        import org.w3c.dom.Attr;
0136:        import org.w3c.dom.DOMError;
0137:        import org.w3c.dom.Element;
0138:        import org.w3c.dom.NamedNodeMap;
0139:        import org.w3c.dom.Node;
0140:        import org.xml.sax.AttributeList;
0141:        import org.xml.sax.Attributes;
0142:        import org.xml.sax.SAXException;
0143:        import org.xml.sax.helpers.AttributesImpl;
0144:
0145:        /**
0146:         * Implements an XML serializer supporting both DOM and SAX pretty
0147:         * serializing. For usage instructions see {@link Serializer}.
0148:         * <p>
0149:         * If an output stream is used, the encoding is taken from the
0150:         * output format (defaults to <tt>UTF-8</tt>). If a writer is
0151:         * used, make sure the writer uses the same encoding (if applies)
0152:         * as specified in the output format.
0153:         * <p>
0154:         * The serializer supports both DOM and SAX. SAX serializing is done by firing
0155:         * SAX events and using the serializer as a document handler. DOM serializing is done
0156:         * by calling {@link #serialize(Document)} or by using DOM Level 3  
0157:         * {@link org.w3c.dom.ls.DOMSerializer} and
0158:         * serializing with {@link org.w3c.dom.ls.DOMSerializer#write},
0159:         * {@link org.w3c.dom.ls.DOMSerializer#writeToString}.
0160:         * <p>
0161:         * If an I/O exception occurs while serializing, the serializer
0162:         * will not throw an exception directly, but only throw it
0163:         * at the end of serializing (either DOM or SAX's {@link
0164:         * org.xml.sax.DocumentHandler#endDocument}.
0165:         * <p>
0166:         * For elements that are not specified as whitespace preserving,
0167:         * the serializer will potentially break long text lines at space
0168:         * boundaries, indent lines, and serialize elements on separate
0169:         * lines. Line terminators will be regarded as spaces, and
0170:         * spaces at beginning of line will be stripped.
0171:         * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
0172:         * @author <a href="mailto:rahul.srivastava@sun.com">Rahul Srivastava</a>
0173:         * @author Elena Litani IBM
0174:         * @version $Revision$ $Date$
0175:         * @see Serializer
0176:         */
0177:        // BEGIN RAVE MODIFICATIONS
0178:        /**
0179:         * Serialize a JSPX DOM.  Similar to org.apache.xerces.serialize.XMLSerializer
0180:         * but follows JSPX (and some XHTML) rules; in particular, it will not
0181:         * mimimize &lt;script&gt;&lt;/script&gt; into &lt;script/&gt;. Unlike
0182:         * XHTML however is does not mash attribute names into lowercase since for
0183:         * example the "contentType" attribute needs to have an uppercase T.
0184:         * <p>
0185:         * This code reuses the XMLSerializer code, but it has to duplicate a couple
0186:         * of methods since the ability to conditionally minimize elements was
0187:         * not available in the methods that were hardcoded to emit /&gt; at the end
0188:         * of empty elements. Some other methods that were referenced by these 
0189:         * duplicated methods but were private were also inlined.
0190:         */
0191:        //public class XMLSerializer
0192:        public class JspxSerializer
0193:        // END RAVE MODIFICATIONS
0194:                extends BaseMarkupSerializer {
0195:
0196:            // BEGIN RAVE MODIFICATIONS
0197:            /**
0198:             * Report whether the given tagName represents an XHTML element that
0199:             * can/must be minimized. For example, "br" should always be
0200:             * minimized, whereas "textarea" should never be.
0201:             * @param tagName the name of the tag to be checked. Should always
0202:             *  be lowercase.
0203:             * @return true iff the tag should be minimized.
0204:             */
0205:            public static boolean canMinimizeTag(String tagName) {
0206:                // From the XHTML spec, section C.2., "Empty Elements":
0207:                //    "Use the minimized tag syntax for empty
0208:                //    elements, e.g. <br />, as the alternative
0209:                //    syntax <br></br> allowed by XML gives
0210:                //    uncertain results in many existing user
0211:                //    agents.""
0212:                if (tagName == null) {
0213:                    return true;
0214:                }
0215:                if (tagName.indexOf(':') != -1) {
0216:                    return true;
0217:                }
0218:                // I would have like to use
0219:                //  return !org.apache.xml.serialize.HTMLdtd.isEmptyTag(tagName);
0220:                // for the following, but the above only works when the tags are
0221:                // in uppercase.
0222:                switch (tagName.charAt(0)) {
0223:                case 'a':
0224:                    return HtmlTag.AREA.name.equals(tagName);
0225:                case 'b':
0226:                    return HtmlTag.BR.name.equals(tagName)
0227:                            || HtmlTag.BASE.name.equals(tagName)
0228:                            || HtmlTag.BASEFONT.name.equals(tagName);
0229:                case 'c':
0230:                    return HtmlTag.COL.name.equals(tagName);
0231:                case 'f':
0232:                    return HtmlTag.FRAME.name.equals(tagName);
0233:                case 'h':
0234:                    return HtmlTag.HR.name.equals(tagName);
0235:                case 'i':
0236:                    return HtmlTag.IMG.name.equals(tagName)
0237:                            || HtmlTag.INPUT.name.equals(tagName)
0238:                            || HtmlTag.ISINDEX.name.equals(tagName);
0239:                case 'l':
0240:                    return HtmlTag.LINK.name.equals(tagName);
0241:                case 'm':
0242:                    return HtmlTag.META.name.equals(tagName);
0243:                case 'p':
0244:                    return HtmlTag.PARAM.name.equals(tagName);
0245:                default:
0246:                    return false;
0247:                }
0248:            }
0249:
0250:            // Copied from super (BaseMarkupSerializer) because it was package
0251:            // private there yet used here in the child class
0252:
0253:            /**
0254:             * Escapes chars
0255:             */
0256:            final void printHex(int ch) throws IOException {
0257:                _printer.printText("&#x");
0258:                _printer.printText(Integer.toHexString(ch));
0259:                _printer.printText(';');
0260:
0261:            }
0262:
0263:            // END RAVE MODIFICATIONS
0264:
0265:            //
0266:            // constants
0267:            //
0268:
0269:            protected static final boolean DEBUG = false;
0270:
0271:            // 
0272:            // data
0273:            //
0274:
0275:            // 
0276:            // DOM Level 3 implementation: variables intialized in DOMSerializerImpl
0277:            // 
0278:
0279:            /** stores namespaces in scope */
0280:            protected NamespaceSupport fNSBinder;
0281:
0282:            /** stores all namespace bindings on the current element */
0283:            protected NamespaceSupport fLocalNSBinder;
0284:
0285:            /** symbol table for serialization */
0286:            protected SymbolTable fSymbolTable;
0287:
0288:            protected final static String PREFIX = "NS";
0289:
0290:            /**
0291:             * Controls whether namespace fixup should be performed during
0292:             * the serialization. 
0293:             * NOTE: if this field is set to true the following 
0294:             * fields need to be initialized: fNSBinder, fLocalNSBinder, fSymbolTable, 
0295:             * XMLSymbols.EMPTY_STRING, fXmlSymbol, fXmlnsSymbol
0296:             */
0297:            protected boolean fNamespaces = false;
0298:
0299:            private boolean fPreserveSpace;
0300:
0301:            /**
0302:             * Constructs a new serializer. The serializer cannot be used without
0303:             * calling {@link #setOutputCharStream} or {@link #setOutputByteStream}
0304:             * first.
0305:             */
0306:            // BEGIN RAVE MODIFICATIONS -- renamed below from XMLSerializer to JspxSerializer
0307:            public JspxSerializer() {
0308:                super (new OutputFormat(Method.XML, null, false));
0309:            }
0310:
0311:            /**
0312:             * Constructs a new serializer. The serializer cannot be used without
0313:             * calling {@link #setOutputCharStream} or {@link #setOutputByteStream}
0314:             * first.
0315:             */
0316:            // BEGIN RAVE MODIFICATIONS -- renamed below from XMLSerializer to JspxSerializer
0317:            public JspxSerializer(OutputFormat format) {
0318:                super (format != null ? format : new OutputFormat(Method.XML,
0319:                        null, false));
0320:                _format.setMethod(Method.XML);
0321:            }
0322:
0323:            /**
0324:             * Constructs a new serializer that writes to the specified writer
0325:             * using the specified output format. If <tt>format</tt> is null,
0326:             * will use a default output format.
0327:             *
0328:             * @param writer The writer to use
0329:             * @param format The output format to use, null for the default
0330:             */
0331:            // BEGIN RAVE MODIFICATIONS -- renamed below from XMLSerializer to JspxSerializer
0332:            public JspxSerializer(Writer writer, OutputFormat format) {
0333:                super (format != null ? format : new OutputFormat(Method.XML,
0334:                        null, false));
0335:                _format.setMethod(Method.XML);
0336:                setOutputCharStream(writer);
0337:            }
0338:
0339:            /**
0340:             * Constructs a new serializer that writes to the specified output
0341:             * stream using the specified output format. If <tt>format</tt>
0342:             * is null, will use a default output format.
0343:             *
0344:             * @param output The output stream to use
0345:             * @param format The output format to use, null for the default
0346:             */
0347:            // BEGIN RAVE MODIFICATIONS -- renamed below from XMLSerializer to JspxSerializer
0348:            public JspxSerializer(OutputStream output, OutputFormat format) {
0349:                super (format != null ? format : new OutputFormat(Method.XML,
0350:                        null, false));
0351:                _format.setMethod(Method.XML);
0352:                setOutputByteStream(output);
0353:            }
0354:
0355:            public void setOutputFormat(OutputFormat format) {
0356:                super .setOutputFormat(format != null ? format
0357:                        : new OutputFormat(Method.XML, null, false));
0358:            }
0359:
0360:            /**
0361:             * This methods turns on namespace fixup algorithm during
0362:             * DOM serialization.
0363:             * @see org.w3c.dom.ls.DOMSerializer
0364:             * 
0365:             * @param namespaces
0366:             */
0367:            public void setNamespaces(boolean namespaces) {
0368:                fNamespaces = namespaces;
0369:                if (fNSBinder == null) {
0370:                    fNSBinder = new NamespaceSupport();
0371:                    fLocalNSBinder = new NamespaceSupport();
0372:                    fSymbolTable = new SymbolTable();
0373:                }
0374:            }
0375:
0376:            //-----------------------------------------//
0377:            // SAX content handler serializing methods //
0378:            //-----------------------------------------//
0379:
0380:            public void startElement(String namespaceURI, String localName,
0381:                    String rawName, Attributes attrs) throws SAXException {
0382:                int i;
0383:                boolean preserveSpace;
0384:                ElementState state;
0385:                String name;
0386:                String value;
0387:
0388:                if (DEBUG) {
0389:                    System.out.println("==>startElement(" + namespaceURI + ","
0390:                            + localName + "," + rawName + ")");
0391:                }
0392:
0393:                try {
0394:                    if (_printer == null) {
0395:                        String msg = DOMMessageFormatter.formatMessage(
0396:                                DOMMessageFormatter.SERIALIZER_DOMAIN,
0397:                                "NoWriterSupplied", null);
0398:                        throw new IllegalStateException(msg);
0399:                    }
0400:
0401:                    state = getElementState();
0402:                    if (isDocumentState()) {
0403:                        // If this is the root element handle it differently.
0404:                        // If the first root element in the document, serialize
0405:                        // the document's DOCTYPE. Space preserving defaults
0406:                        // to that of the output format.
0407:                        if (!_started)
0408:                            startDocument((localName == null || localName
0409:                                    .length() == 0) ? rawName : localName);
0410:                    } else {
0411:                        // For any other element, if first in parent, then
0412:                        // close parent's opening tag and use the parnet's
0413:                        // space preserving.
0414:                        if (state.empty)
0415:                            _printer.printText('>');
0416:                        // Must leave CData section first
0417:                        if (state.inCData) {
0418:                            _printer.printText("]]>");
0419:                            state.inCData = false;
0420:                        }
0421:                        // Indent this element on a new line if the first
0422:                        // content of the parent element or immediately
0423:                        // following an element or a comment
0424:                        if (_indenting
0425:                                && !state.preserveSpace
0426:                                && (state.empty || state.afterElement || state.afterComment))
0427:                            _printer.breakLine();
0428:                    }
0429:                    preserveSpace = state.preserveSpace;
0430:
0431:                    //We remove the namespaces from the attributes list so that they will
0432:                    //be in _prefixes
0433:                    attrs = extractNamespaces(attrs);
0434:
0435:                    // Do not change the current element state yet.
0436:                    // This only happens in endElement().
0437:                    if (rawName == null || rawName.length() == 0) {
0438:                        if (localName == null) {
0439:                            String msg = DOMMessageFormatter.formatMessage(
0440:                                    DOMMessageFormatter.SERIALIZER_DOMAIN,
0441:                                    "NoName", null);
0442:                            throw new SAXException(msg);
0443:                        }
0444:                        if (namespaceURI != null && !namespaceURI.equals("")) {
0445:                            String prefix;
0446:                            prefix = getPrefix(namespaceURI);
0447:                            if (prefix != null && prefix.length() > 0)
0448:                                rawName = prefix + ":" + localName;
0449:                            else
0450:                                rawName = localName;
0451:                        } else
0452:                            rawName = localName;
0453:                    }
0454:
0455:                    _printer.printText('<');
0456:                    _printer.printText(rawName);
0457:                    _printer.indent();
0458:
0459:                    // For each attribute print it's name and value as one part,
0460:                    // separated with a space so the element can be broken on
0461:                    // multiple lines.
0462:                    if (attrs != null) {
0463:                        for (i = 0; i < attrs.getLength(); ++i) {
0464:                            _printer.printSpace();
0465:
0466:                            name = attrs.getQName(i);
0467:                            if (name != null && name.length() == 0) {
0468:                                String prefix;
0469:                                String attrURI;
0470:
0471:                                name = attrs.getLocalName(i);
0472:                                attrURI = attrs.getURI(i);
0473:                                if ((attrURI != null && attrURI.length() != 0)
0474:                                        && (namespaceURI == null
0475:                                                || namespaceURI.length() == 0 || !attrURI
0476:                                                .equals(namespaceURI))) {
0477:                                    prefix = getPrefix(attrURI);
0478:                                    if (prefix != null && prefix.length() > 0)
0479:                                        name = prefix + ":" + name;
0480:                                }
0481:                            }
0482:
0483:                            value = attrs.getValue(i);
0484:                            if (value == null)
0485:                                value = "";
0486:                            _printer.printText(name);
0487:                            _printer.printText("=\"");
0488:                            printEscaped(value);
0489:                            _printer.printText('"');
0490:
0491:                            // If the attribute xml:space exists, determine whether
0492:                            // to preserve spaces in this and child nodes based on
0493:                            // its value.
0494:                            if (name.equals("xml:space")) {
0495:                                if (value.equals("preserve"))
0496:                                    preserveSpace = true;
0497:                                else
0498:                                    preserveSpace = _format.getPreserveSpace();
0499:                            }
0500:                        }
0501:                    }
0502:
0503:                    if (_prefixes != null) {
0504:                        Enumeration keys;
0505:
0506:                        keys = _prefixes.keys();
0507:                        while (keys.hasMoreElements()) {
0508:                            _printer.printSpace();
0509:                            value = (String) keys.nextElement();
0510:                            name = (String) _prefixes.get(value);
0511:                            if (name.length() == 0) {
0512:                                _printer.printText("xmlns=\"");
0513:                                printEscaped(value);
0514:                                _printer.printText('"');
0515:                            } else {
0516:                                _printer.printText("xmlns:");
0517:                                _printer.printText(name);
0518:                                _printer.printText("=\"");
0519:                                printEscaped(value);
0520:                                _printer.printText('"');
0521:                            }
0522:                        }
0523:                    }
0524:
0525:                    // Now it's time to enter a new element state
0526:                    // with the tag name and space preserving.
0527:                    // We still do not change the curent element state.
0528:                    state = enterElementState(namespaceURI, localName, rawName,
0529:                            preserveSpace);
0530:                    name = (localName == null || localName.length() == 0) ? rawName
0531:                            : namespaceURI + "^" + localName;
0532:                    state.doCData = _format.isCDataElement(name);
0533:                    state.unescaped = _format.isNonEscapingElement(name);
0534:                } catch (IOException except) {
0535:                    throw new SAXException(except);
0536:                }
0537:            }
0538:
0539:            public void endElement(String namespaceURI, String localName,
0540:                    String rawName) throws SAXException {
0541:                try {
0542:                    endElementIO(namespaceURI, localName, rawName);
0543:                } catch (IOException except) {
0544:                    throw new SAXException(except);
0545:                }
0546:            }
0547:
0548:            public void endElementIO(String namespaceURI, String localName,
0549:                    String rawName) throws IOException {
0550:                ElementState state;
0551:                if (DEBUG) {
0552:                    System.out.println("==>endElement: " + rawName);
0553:                }
0554:                // Works much like content() with additions for closing
0555:                // an element. Note the different checks for the closed
0556:                // element's state and the parent element's state.
0557:                _printer.unindent();
0558:                state = getElementState();
0559:                // BEGIN RAVE MODIFICATIONS
0560:                //if (state.empty) {
0561:                if (state.empty && canMinimizeTag(state.localName)) {
0562:                    // END RAVE MODIFICATIONS
0563:                    _printer.printText("/>");
0564:                } else {
0565:                    // Must leave CData section first
0566:                    if (state.inCData)
0567:                        _printer.printText("]]>");
0568:                    // This element is not empty and that last content was
0569:                    // another element, so print a line break before that
0570:                    // last element and this element's closing tag.
0571:                    if (_indenting && !state.preserveSpace
0572:                            && (state.afterElement || state.afterComment))
0573:                        _printer.breakLine();
0574:                    _printer.printText("</");
0575:                    _printer.printText(state.rawName);
0576:                    _printer.printText('>');
0577:                }
0578:                // Leave the element state and update that of the parent
0579:                // (if we're not root) to not empty and after element.
0580:                state = leaveElementState();
0581:                state.afterElement = true;
0582:                state.afterComment = false;
0583:                state.empty = false;
0584:                if (isDocumentState())
0585:                    _printer.flush();
0586:            }
0587:
0588:            //------------------------------------------//
0589:            // SAX document handler serializing methods //
0590:            //------------------------------------------//
0591:
0592:            public void startElement(String tagName, AttributeList attrs)
0593:                    throws SAXException {
0594:                int i;
0595:                boolean preserveSpace;
0596:                ElementState state;
0597:                String name;
0598:                String value;
0599:
0600:                if (DEBUG) {
0601:                    System.out.println("==>startElement(" + tagName + ")");
0602:                }
0603:
0604:                try {
0605:                    if (_printer == null) {
0606:                        String msg = DOMMessageFormatter.formatMessage(
0607:                                DOMMessageFormatter.SERIALIZER_DOMAIN,
0608:                                "NoWriterSupplied", null);
0609:                        throw new IllegalStateException(msg);
0610:                    }
0611:
0612:                    state = getElementState();
0613:                    if (isDocumentState()) {
0614:                        // If this is the root element handle it differently.
0615:                        // If the first root element in the document, serialize
0616:                        // the document's DOCTYPE. Space preserving defaults
0617:                        // to that of the output format.
0618:                        if (!_started)
0619:                            startDocument(tagName);
0620:                    } else {
0621:                        // For any other element, if first in parent, then
0622:                        // close parent's opening tag and use the parnet's
0623:                        // space preserving.
0624:                        if (state.empty)
0625:                            _printer.printText('>');
0626:                        // Must leave CData section first
0627:                        if (state.inCData) {
0628:                            _printer.printText("]]>");
0629:                            state.inCData = false;
0630:                        }
0631:                        // Indent this element on a new line if the first
0632:                        // content of the parent element or immediately
0633:                        // following an element.
0634:                        if (_indenting
0635:                                && !state.preserveSpace
0636:                                && (state.empty || state.afterElement || state.afterComment))
0637:                            _printer.breakLine();
0638:                    }
0639:                    preserveSpace = state.preserveSpace;
0640:
0641:                    // Do not change the current element state yet.
0642:                    // This only happens in endElement().
0643:
0644:                    _printer.printText('<');
0645:                    _printer.printText(tagName);
0646:                    _printer.indent();
0647:
0648:                    // For each attribute print it's name and value as one part,
0649:                    // separated with a space so the element can be broken on
0650:                    // multiple lines.
0651:                    if (attrs != null) {
0652:                        for (i = 0; i < attrs.getLength(); ++i) {
0653:                            _printer.printSpace();
0654:                            name = attrs.getName(i);
0655:                            value = attrs.getValue(i);
0656:                            if (value != null) {
0657:                                _printer.printText(name);
0658:                                _printer.printText("=\"");
0659:                                printEscaped(value);
0660:                                _printer.printText('"');
0661:                            }
0662:
0663:                            // If the attribute xml:space exists, determine whether
0664:                            // to preserve spaces in this and child nodes based on
0665:                            // its value.
0666:                            if (name.equals("xml:space")) {
0667:                                if (value.equals("preserve"))
0668:                                    preserveSpace = true;
0669:                                else
0670:                                    preserveSpace = _format.getPreserveSpace();
0671:                            }
0672:                        }
0673:                    }
0674:                    // Now it's time to enter a new element state
0675:                    // with the tag name and space preserving.
0676:                    // We still do not change the curent element state.
0677:                    state = enterElementState(null, null, tagName,
0678:                            preserveSpace);
0679:                    state.doCData = _format.isCDataElement(tagName);
0680:                    state.unescaped = _format.isNonEscapingElement(tagName);
0681:                } catch (IOException except) {
0682:                    throw new SAXException(except);
0683:                }
0684:
0685:            }
0686:
0687:            public void endElement(String tagName) throws SAXException {
0688:                endElement(null, null, tagName);
0689:            }
0690:
0691:            //------------------------------------------//
0692:            // Generic node serializing methods methods //
0693:            //------------------------------------------//
0694:
0695:            /**
0696:             * Called to serialize the document's DOCTYPE by the root element.
0697:             * The document type declaration must name the root element,
0698:             * but the root element is only known when that element is serialized,
0699:             * and not at the start of the document.
0700:             * <p>
0701:             * This method will check if it has not been called before ({@link #_started}),
0702:             * will serialize the document type declaration, and will serialize all
0703:             * pre-root comments and PIs that were accumulated in the document
0704:             * (see {@link #serializePreRoot}). Pre-root will be serialized even if
0705:             * this is not the first root element of the document.
0706:             */
0707:            protected void startDocument(String rootTagName) throws IOException {
0708:                int i;
0709:                String dtd;
0710:
0711:                dtd = _printer.leaveDTD();
0712:                if (!_started) {
0713:
0714:                    if (!_format.getOmitXMLDeclaration()) {
0715:                        StringBuffer buffer;
0716:
0717:                        // Serialize the document declaration appreaing at the head
0718:                        // of very XML document (unless asked not to).
0719:                        buffer = new StringBuffer("<?xml version=\"");
0720:                        if (_format.getVersion() != null)
0721:                            buffer.append(_format.getVersion());
0722:                        else
0723:                            buffer.append("1.0");
0724:                        buffer.append('"');
0725:                        String format_encoding = _format.getEncoding();
0726:                        if (format_encoding != null) {
0727:                            buffer.append(" encoding=\"");
0728:                            buffer.append(format_encoding);
0729:                            buffer.append('"');
0730:                        }
0731:                        if (_format.getStandalone() && _docTypeSystemId == null
0732:                                && _docTypePublicId == null)
0733:                            buffer.append(" standalone=\"yes\"");
0734:                        buffer.append("?>");
0735:                        _printer.printText(buffer);
0736:                        _printer.breakLine();
0737:                    }
0738:
0739:                    if (!_format.getOmitDocumentType()) {
0740:                        if (_docTypeSystemId != null) {
0741:                            // System identifier must be specified to print DOCTYPE.
0742:                            // If public identifier is specified print 'PUBLIC
0743:                            // <public> <system>', if not, print 'SYSTEM <system>'.
0744:                            _printer.printText("<!DOCTYPE ");
0745:                            _printer.printText(rootTagName);
0746:                            if (_docTypePublicId != null) {
0747:                                _printer.printText(" PUBLIC ");
0748:                                printDoctypeURL(_docTypePublicId);
0749:                                if (_indenting) {
0750:                                    _printer.breakLine();
0751:                                    for (i = 0; i < 18 + rootTagName.length(); ++i)
0752:                                        _printer.printText(" ");
0753:                                } else
0754:                                    _printer.printText(" ");
0755:                                printDoctypeURL(_docTypeSystemId);
0756:                            } else {
0757:                                _printer.printText(" SYSTEM ");
0758:                                printDoctypeURL(_docTypeSystemId);
0759:                            }
0760:
0761:                            // If we accumulated any DTD contents while printing.
0762:                            // this would be the place to print it.
0763:                            if (dtd != null && dtd.length() > 0) {
0764:                                _printer.printText(" [");
0765:                                printText(dtd, true, true);
0766:                                _printer.printText(']');
0767:                            }
0768:
0769:                            _printer.printText(">");
0770:                            _printer.breakLine();
0771:                        } else if (dtd != null && dtd.length() > 0) {
0772:                            _printer.printText("<!DOCTYPE ");
0773:                            _printer.printText(rootTagName);
0774:                            _printer.printText(" [");
0775:                            printText(dtd, true, true);
0776:                            _printer.printText("]>");
0777:                            _printer.breakLine();
0778:                        }
0779:                    }
0780:                }
0781:                _started = true;
0782:                // Always serialize these, even if not te first root element.
0783:                serializePreRoot();
0784:            }
0785:
0786:            /**
0787:             * Called to serialize a DOM element. Equivalent to calling {@link
0788:             * #startElement}, {@link #endElement} and serializing everything
0789:             * inbetween, but better optimized.
0790:             */
0791:            protected void serializeElement(Element elem) throws IOException {
0792:                Attr attr;
0793:                NamedNodeMap attrMap;
0794:                int i;
0795:                Node child;
0796:                ElementState state;
0797:                String name;
0798:                String value;
0799:                String tagName;
0800:
0801:                String prefix, localUri;
0802:                String uri;
0803:                if (fNamespaces) {
0804:                    // local binder stores namespace declaration
0805:                    // that has been printed out during namespace fixup of
0806:                    // the current element
0807:                    fLocalNSBinder.reset();
0808:
0809:                    // add new namespace context        
0810:                    fNSBinder.pushContext();
0811:                }
0812:
0813:                if (DEBUG) {
0814:                    System.out.println("==>startElement: " + elem.getNodeName()
0815:                            + " ns=" + elem.getNamespaceURI());
0816:                }
0817:                tagName = elem.getTagName();
0818:                state = getElementState();
0819:                if (isDocumentState()) {
0820:                    // If this is the root element handle it differently.
0821:                    // If the first root element in the document, serialize
0822:                    // the document's DOCTYPE. Space preserving defaults
0823:                    // to that of the output format.
0824:
0825:                    if (!_started) {
0826:                        startDocument(tagName);
0827:                    }
0828:                } else {
0829:                    // For any other element, if first in parent, then
0830:                    // close parent's opening tag and use the parent's
0831:                    // space preserving.
0832:                    if (state.empty)
0833:                        _printer.printText('>');
0834:                    // Must leave CData section first
0835:                    if (state.inCData) {
0836:                        _printer.printText("]]>");
0837:                        state.inCData = false;
0838:                    }
0839:                    // Indent this element on a new line if the first
0840:                    // content of the parent element or immediately
0841:                    // following an element.
0842:                    if (_indenting
0843:                            && !state.preserveSpace
0844:                            && (state.empty || state.afterElement || state.afterComment))
0845:                        _printer.breakLine();
0846:                }
0847:
0848:                // Do not change the current element state yet.
0849:                // This only happens in endElement().
0850:                fPreserveSpace = state.preserveSpace;
0851:
0852:                int length = 0;
0853:                attrMap = null;
0854:                // retrieve attributes 
0855:                if (elem.hasAttributes()) {
0856:                    attrMap = elem.getAttributes();
0857:                    length = attrMap.getLength();
0858:                }
0859:
0860:                if (!fNamespaces) { // no namespace fixup should be perform                    
0861:
0862:                    // serialize element name
0863:                    _printer.printText('<');
0864:                    _printer.printText(tagName);
0865:                    _printer.indent();
0866:
0867:                    // For each attribute print it's name and value as one part,
0868:                    // separated with a space so the element can be broken on
0869:                    // multiple lines.
0870:                    for (i = 0; i < length; ++i) {
0871:                        attr = (Attr) attrMap.item(i);
0872:                        name = attr.getName();
0873:                        value = attr.getValue();
0874:                        if (value == null)
0875:                            value = "";
0876:                        if (attr.getSpecified()) {
0877:                            _printer.printSpace();
0878:                            _printer.printText(name);
0879:                            _printer.printText("=\"");
0880:                            printEscaped(value);
0881:                            _printer.printText('"');
0882:                        }
0883:                        // If the attribute xml:space exists, determine whether
0884:                        // to preserve spaces in this and child nodes based on
0885:                        // its value.
0886:                        if (name.equals("xml:space")) {
0887:                            if (value.equals("preserve"))
0888:                                fPreserveSpace = true;
0889:                            else
0890:                                fPreserveSpace = _format.getPreserveSpace();
0891:                        }
0892:                    }
0893:                } else { // do namespace fixup
0894:
0895:                    // REVISIT: some optimization could probably be done to avoid traversing 
0896:                    //          attributes twice.
0897:                    //
0898:
0899:                    // ---------------------------------------
0900:                    // record all valid namespace declarations
0901:                    // before attempting to fix element's namespace
0902:                    // ---------------------------------------
0903:
0904:                    for (i = 0; i < length; i++) {
0905:
0906:                        attr = (Attr) attrMap.item(i);
0907:                        uri = attr.getNamespaceURI();
0908:                        // check if attribute is a namespace decl 
0909:                        if (uri != null
0910:                                && uri.equals(NamespaceContext.XMLNS_URI)) {
0911:
0912:                            value = attr.getNodeValue();
0913:                            if (value == null) {
0914:                                value = XMLSymbols.EMPTY_STRING;
0915:                            }
0916:
0917:                            if (value.equals(NamespaceContext.XMLNS_URI)) {
0918:                                if (fDOMErrorHandler != null) {
0919:                                    modifyDOMError(
0920:                                            "No prefix other than 'xmlns' can be bound to 'http://www.w3.org/2000/xmlns/' namespace name",
0921:                                            DOMError.SEVERITY_ERROR,
0922:                                            "RaveUnknownType", attr);
0923:                                    boolean continueProcess = fDOMErrorHandler
0924:                                            .handleError(fDOMError);
0925:                                    if (!continueProcess) {
0926:                                        // stop the namespace fixup and validation
0927:                                        throw new RuntimeException(
0928:                                                "Stopped at user request");
0929:                                    }
0930:                                }
0931:                            } else {
0932:                                prefix = attr.getPrefix();
0933:                                prefix = (prefix == null || prefix.length() == 0) ? XMLSymbols.EMPTY_STRING
0934:                                        : fSymbolTable.addSymbol(prefix);
0935:                                String localpart = fSymbolTable.addSymbol(attr
0936:                                        .getLocalName());
0937:                                if (prefix == XMLSymbols.PREFIX_XMLNS) { //xmlns:prefix
0938:                                    value = fSymbolTable.addSymbol(value);
0939:                                    // record valid decl
0940:                                    if (value.length() != 0) {
0941:                                        fNSBinder.declarePrefix(localpart,
0942:                                                value);
0943:                                    }
0944:                                    //                            else {
0945:                                    //                                // REVISIT: issue error on invalid declarations
0946:                                    //                                //          xmlns:foo = ""
0947:                                    //                            }
0948:                                    continue;
0949:                                } else { // xmlns
0950:                                    // empty prefix is always bound ("" or some string)
0951:
0952:                                    value = fSymbolTable.addSymbol(value);
0953:                                    fNSBinder.declarePrefix(
0954:                                            XMLSymbols.EMPTY_STRING, value);
0955:                                    continue;
0956:                                }
0957:                            } // end-else: valid declaration
0958:                        } // end-if: namespace declaration 
0959:                    } // end-for
0960:
0961:                    //-----------------------
0962:                    // get element uri/prefix
0963:                    //-----------------------
0964:                    uri = elem.getNamespaceURI();
0965:                    prefix = elem.getPrefix();
0966:
0967:                    //----------------------
0968:                    // output element name
0969:                    //----------------------
0970:                    // REVISIT: this could be removed if we always convert empty string to null
0971:                    //          for the namespaces.
0972:                    if ((uri != null && prefix != null) && uri.length() == 0
0973:                            && prefix.length() != 0) {
0974:                        // uri is an empty string and element has some prefix
0975:                        // the namespace alg later will fix up the namespace attributes
0976:                        // remove element prefix 
0977:                        prefix = null;
0978:                        _printer.printText('<');
0979:                        _printer.printText(elem.getLocalName());
0980:                        _printer.indent();
0981:                    } else {
0982:                        _printer.printText('<');
0983:                        _printer.printText(tagName);
0984:                        _printer.indent();
0985:                    }
0986:
0987:                    // ---------------------------------------------------------
0988:                    // Fix up namespaces for element: per DOM L3 
0989:                    // Need to consider the following cases:
0990:                    //
0991:                    // case 1: <foo:elem xmlns:ns1="myURI" xmlns="default"/> 
0992:                    // Assume "foo", "ns1" are declared on the parent. We should not miss 
0993:                    // redeclaration for both "ns1" and default namespace. To solve this 
0994:                    // we add a local binder that stores declaration only for current element.
0995:                    // This way we avoid outputing duplicate declarations for the same element
0996:                    // as well as we are not omitting redeclarations.
0997:                    //
0998:                    // case 2: <elem xmlns="" xmlns="default"/> 
0999:                    // We need to bind default namespace to empty string, to be able to 
1000:                    // omit duplicate declarations for the same element
1001:                    //
1002:                    // case 3: <xsl:stylesheet xmlns:xsl="http://xsl">
1003:                    // We create another element body bound to the "http://xsl" namespace
1004:                    // as well as namespace attribute rebounding xsl to another namespace.
1005:                    // <xsl:body xmlns:xsl="http://another">
1006:                    // Need to make sure that the new namespace decl value is changed to 
1007:                    // "http://xsl"
1008:                    //
1009:                    // ---------------------------------------------------------
1010:                    // check if prefix/namespace is correct for current element
1011:                    // ---------------------------------------------------------
1012:
1013:                    if (uri != null) { // Element has a namespace
1014:                        uri = fSymbolTable.addSymbol(uri);
1015:                        prefix = (prefix == null || prefix.length() == 0) ? XMLSymbols.EMPTY_STRING
1016:                                : fSymbolTable.addSymbol(prefix);
1017:                        if (fNSBinder.getURI(prefix) == uri) {
1018:                            // The xmlns:prefix=namespace or xmlns="default" was declared at parent.
1019:                            // The binder always stores mapping of empty prefix to "".
1020:                            // (NOTE: local binder does not store this kind of binding!)
1021:                            // Thus the case where element was declared with uri="" (with or without a prefix)
1022:                            // will be covered here.
1023:
1024:                        } else {
1025:                            // the prefix is either undeclared 
1026:                            // or
1027:                            // conflict: the prefix is bound to another URI
1028:                            printNamespaceAttr(prefix, uri);
1029:                            fLocalNSBinder.declarePrefix(prefix, uri);
1030:                            fNSBinder.declarePrefix(prefix, uri);
1031:                        }
1032:                    } else { // Element has no namespace
1033:                        if (elem.getLocalName() == null) {
1034:                            //  DOM Level 1 node!
1035:
1036:                            if (fDOMErrorHandler != null) {
1037:                                // REVISIT: MSG modify error message
1038:                                modifyDOMError("DOM Level 1 Node: "
1039:                                        + elem.getNodeName(),
1040:                                        DOMError.SEVERITY_ERROR,
1041:                                        "RaveUnknownType", elem);
1042:                                boolean continueProcess = fDOMErrorHandler
1043:                                        .handleError(fDOMError);
1044:                                // REVISIT: should we terminate upon request?
1045:                                if (!continueProcess) {
1046:                                    throw new RuntimeException(
1047:                                            "Process stoped at user request");
1048:                                }
1049:                            }
1050:                        } else { // uri=null and no colon (DOM L2 node)
1051:                            uri = fNSBinder.getURI(XMLSymbols.EMPTY_STRING);
1052:
1053:                            if (uri != null && uri.length() > 0) {
1054:                                // there is a default namespace decl that is bound to
1055:                                // non-zero length uri, output xmlns=""
1056:                                printNamespaceAttr(XMLSymbols.EMPTY_STRING,
1057:                                        XMLSymbols.EMPTY_STRING);
1058:                                fLocalNSBinder.declarePrefix(
1059:                                        XMLSymbols.EMPTY_STRING,
1060:                                        XMLSymbols.EMPTY_STRING);
1061:                                fNSBinder.declarePrefix(
1062:                                        XMLSymbols.EMPTY_STRING,
1063:                                        XMLSymbols.EMPTY_STRING);
1064:                            }
1065:                        }
1066:                    }
1067:
1068:                    // -----------------------------------------
1069:                    // Fix up namespaces for attributes: per DOM L3 
1070:                    // check if prefix/namespace is correct the attributes
1071:                    // -----------------------------------------
1072:
1073:                    for (i = 0; i < length; i++) {
1074:
1075:                        attr = (Attr) attrMap.item(i);
1076:                        value = attr.getValue();
1077:                        name = attr.getNodeName();
1078:
1079:                        uri = attr.getNamespaceURI();
1080:
1081:                        // Fix attribute that was declared with a prefix and namespace=""
1082:                        if (uri != null && uri.length() == 0) {
1083:                            uri = null;
1084:                            // we must remove prefix for this attribute
1085:                            name = attr.getLocalName();
1086:                        }
1087:
1088:                        if (DEBUG) {
1089:                            System.out.println("==>process attribute: "
1090:                                    + attr.getNodeName());
1091:                        }
1092:                        // make sure that value is never null.
1093:                        if (value == null) {
1094:                            value = XMLSymbols.EMPTY_STRING;
1095:                        }
1096:
1097:                        if (uri != null) { // attribute has namespace !=null
1098:                            prefix = attr.getPrefix();
1099:                            prefix = prefix == null ? XMLSymbols.EMPTY_STRING
1100:                                    : fSymbolTable.addSymbol(prefix);
1101:                            String localpart = fSymbolTable.addSymbol(attr
1102:                                    .getLocalName());
1103:
1104:                            // ---------------------------------------------------
1105:                            // print namespace declarations namespace declarations 
1106:                            // ---------------------------------------------------
1107:                            if (uri != null
1108:                                    && uri.equals(NamespaceContext.XMLNS_URI)) {
1109:                                // check if we need to output this declaration
1110:                                prefix = attr.getPrefix();
1111:                                prefix = (prefix == null || prefix.length() == 0) ? XMLSymbols.EMPTY_STRING
1112:                                        : fSymbolTable.addSymbol(prefix);
1113:                                localpart = fSymbolTable.addSymbol(attr
1114:                                        .getLocalName());
1115:                                if (prefix == XMLSymbols.PREFIX_XMLNS) { //xmlns:prefix
1116:                                    localUri = fLocalNSBinder.getURI(localpart); // local prefix mapping
1117:                                    value = fSymbolTable.addSymbol(value);
1118:                                    if (value.length() != 0) {
1119:                                        if (localUri == null) {
1120:                                            // declaration was not printed while fixing element namespace binding
1121:                                            printNamespaceAttr(localpart, value);
1122:                                            // case 4: <elem xmlns:xx="foo" xx:attr=""/>
1123:                                            // where attribute is bound to "bar". 
1124:                                            // If the xmlns:xx is output here first, later we should not
1125:                                            // redeclare "xx" prefix. Instead we would pick up different prefix
1126:                                            // for the attribute.
1127:                                            // final: <elem xmlns:xx="foo" NS1:attr="" xmlns:NS1="bar"/>
1128:                                            fLocalNSBinder.declarePrefix(
1129:                                                    localpart, value);
1130:                                        }
1131:                                    }
1132:                                    //                            else {
1133:                                    //                                // REVISIT: issue error on invalid declarations
1134:                                    //                                //          xmlns:foo = ""
1135:                                    //                            }
1136:                                    continue;
1137:                                } else { // xmlns
1138:                                    // empty prefix is always bound ("" or some string)
1139:
1140:                                    uri = fNSBinder
1141:                                            .getURI(XMLSymbols.EMPTY_STRING);
1142:                                    localUri = fLocalNSBinder
1143:                                            .getURI(XMLSymbols.EMPTY_STRING);
1144:                                    value = fSymbolTable.addSymbol(value);
1145:                                    if (localUri == null) {
1146:                                        // declaration was not printed while fixing element namespace binding
1147:                                        printNamespaceAttr(
1148:                                                XMLSymbols.EMPTY_STRING, value);
1149:                                        // case 4 does not apply here since attributes can't use
1150:                                        // default namespace
1151:                                    }
1152:                                    continue;
1153:                                }
1154:
1155:                            }
1156:                            uri = fSymbolTable.addSymbol(uri);
1157:
1158:                            // find if for this prefix a URI was already declared
1159:                            String declaredURI = fNSBinder.getURI(prefix);
1160:
1161:                            if (prefix == XMLSymbols.EMPTY_STRING
1162:                                    || declaredURI != uri) {
1163:                                // attribute has no prefix (default namespace decl does not apply to attributes) 
1164:                                // OR
1165:                                // attribute prefix is not declared
1166:                                // OR
1167:                                // conflict: attr URI does not match the prefix in scope
1168:
1169:                                name = attr.getNodeName();
1170:                                // Find if any prefix for attributes namespace URI is available
1171:                                // in the scope
1172:                                String declaredPrefix = fNSBinder
1173:                                        .getPrefix(uri);
1174:
1175:                                if (declaredPrefix != null
1176:                                        && declaredPrefix != XMLSymbols.EMPTY_STRING) {
1177:                                    // use the prefix that was found
1178:                                    prefix = declaredPrefix;
1179:                                    name = prefix + ":" + localpart;
1180:                                } else {
1181:                                    if (DEBUG) {
1182:                                        System.out
1183:                                                .println("==> cound not find prefix for the attribute: "
1184:                                                        + prefix);
1185:                                    }
1186:
1187:                                    if (prefix != XMLSymbols.EMPTY_STRING
1188:                                            && fLocalNSBinder.getURI(prefix) == null) {
1189:                                        // the current prefix is not null and it has no in scope declaration
1190:
1191:                                        // use this prefix
1192:                                    } else {
1193:                                        // find a prefix following the pattern "NS" +index (starting at 1)
1194:                                        // make sure this prefix is not declared in the current scope.
1195:                                        int counter = 1;
1196:                                        prefix = fSymbolTable.addSymbol(PREFIX
1197:                                                + counter++);
1198:                                        while (fLocalNSBinder.getURI(prefix) != null) {
1199:                                            prefix = fSymbolTable
1200:                                                    .addSymbol(PREFIX
1201:                                                            + counter++);
1202:                                        }
1203:                                        name = prefix + ":" + localpart;
1204:                                    }
1205:                                    // add declaration for the new prefix
1206:                                    printNamespaceAttr(prefix, uri);
1207:                                    value = fSymbolTable.addSymbol(value);
1208:                                    fLocalNSBinder.declarePrefix(prefix, value);
1209:                                    fNSBinder.declarePrefix(prefix, uri);
1210:                                }
1211:
1212:                                // change prefix for this attribute
1213:                            }
1214:
1215:                            printAttribute(name,
1216:                                    (value == null) ? XMLSymbols.EMPTY_STRING
1217:                                            : value, attr.getSpecified());
1218:                        } else { // attribute uri == null
1219:                            if (attr.getLocalName() == null) {
1220:                                if (fDOMErrorHandler != null) {
1221:                                    modifyDOMError("DOM Level 1 Node: " + name,
1222:                                            DOMError.SEVERITY_ERROR,
1223:                                            "RaveUnknownType", attr);
1224:                                    boolean continueProcess = fDOMErrorHandler
1225:                                            .handleError(fDOMError);
1226:                                    if (!continueProcess) {
1227:                                        // stop the namespace fixup and validation
1228:                                        throw new RuntimeException(
1229:                                                "Stopped at user request");
1230:                                    }
1231:                                }
1232:                                printAttribute(name, value, attr.getSpecified());
1233:                            } else { // uri=null and no colon
1234:
1235:                                // no fix up is needed: default namespace decl does not 
1236:                                // apply to attributes
1237:                                printAttribute(name, value, attr.getSpecified());
1238:                            }
1239:                        }
1240:                    } // end loop for attributes
1241:
1242:                }// end namespace fixup algorithm
1243:
1244:                // If element has children, then serialize them, otherwise
1245:                // serialize en empty tag.        
1246:                if (elem.hasChildNodes()) {
1247:                    // Enter an element state, and serialize the children
1248:                    // one by one. Finally, end the element.
1249:                    state = enterElementState(null, null, tagName,
1250:                            fPreserveSpace);
1251:                    state.doCData = _format.isCDataElement(tagName);
1252:                    state.unescaped = _format.isNonEscapingElement(tagName);
1253:                    child = elem.getFirstChild();
1254:                    while (child != null) {
1255:                        serializeNode(child);
1256:                        child = child.getNextSibling();
1257:                    }
1258:                    if (fNamespaces) {
1259:                        fNSBinder.popContext();
1260:                    }
1261:                    endElementIO(null, null, tagName);
1262:                } else {
1263:                    if (DEBUG) {
1264:                        System.out.println("==>endElement: "
1265:                                + elem.getNodeName());
1266:                    }
1267:                    if (fNamespaces) {
1268:                        fNSBinder.popContext();
1269:                    }
1270:                    _printer.unindent();
1271:                    // BEGIN RAVE MODIFICATIONS
1272:                    //_printer.printText( "/>" );
1273:                    if (canMinimizeTag(tagName)) {
1274:                        _printer.printText("/>");
1275:                    } else {
1276:                        _printer.printText("></");
1277:                        _printer.printText(tagName);
1278:                        _printer.printText('>');
1279:                    }
1280:                    // END RAVE MODIFICATIONS
1281:                    // After element but parent element is no longer empty.
1282:                    state.afterElement = true;
1283:                    state.afterComment = false;
1284:                    state.empty = false;
1285:                    if (isDocumentState())
1286:                        _printer.flush();
1287:                }
1288:            }
1289:
1290:            /**
1291:             * Serializes a namespace attribute with the given prefix and value for URI.
1292:             * In case prefix is empty will serialize default namespace declaration.
1293:             * 
1294:             * @param prefix
1295:             * @param uri
1296:             * @exception IOException
1297:             */
1298:
1299:            private void printNamespaceAttr(String prefix, String uri)
1300:                    throws IOException {
1301:                _printer.printSpace();
1302:                if (prefix == XMLSymbols.EMPTY_STRING) {
1303:                    if (DEBUG) {
1304:                        System.out.println("=>add xmlns=\"" + uri
1305:                                + "\" declaration");
1306:                    }
1307:                    _printer.printText(XMLSymbols.PREFIX_XMLNS);
1308:                } else {
1309:                    if (DEBUG) {
1310:                        System.out.println("=>add xmlns:" + prefix + "=\""
1311:                                + uri + "\" declaration");
1312:                    }
1313:                    _printer.printText("xmlns:" + prefix);
1314:                }
1315:                _printer.printText("=\"");
1316:                printEscaped(uri);
1317:                _printer.printText('"');
1318:            }
1319:
1320:            /**
1321:             * Prints attribute. 
1322:             * NOTE: xml:space attribute modifies output format
1323:             * 
1324:             * @param name
1325:             * @param value
1326:             * @param isSpecified
1327:             * @exception IOException
1328:             */
1329:            private void printAttribute(String name, String value,
1330:                    boolean isSpecified) throws IOException {
1331:
1332:                // XXX Rave needs to update the entire source, using new xerces version.
1333:                //        if (isSpecified || ((features & DOMSerializerImpl.DISCARDDEFAULT) != 0)) {
1334:                if (isSpecified || ((features & 0x1 << 6) != 0)) {
1335:                    _printer.printSpace();
1336:                    _printer.printText(name);
1337:                    _printer.printText("=\"");
1338:                    printEscaped(value);
1339:                    _printer.printText('"');
1340:                }
1341:
1342:                // If the attribute xml:space exists, determine whether
1343:                // to preserve spaces in this and child nodes based on
1344:                // its value.
1345:                if (name.equals("xml:space")) {
1346:                    if (value.equals("preserve"))
1347:                        fPreserveSpace = true;
1348:                    else
1349:                        fPreserveSpace = _format.getPreserveSpace();
1350:                }
1351:            }
1352:
1353:            protected String getEntityRef(int ch) {
1354:                // Encode special XML characters into the equivalent character references.
1355:                // These five are defined by default for all XML documents.
1356:                switch (ch) {
1357:                case '<':
1358:                    return "lt";
1359:                case '>':
1360:                    return "gt";
1361:                case '"':
1362:                    return "quot";
1363:                case '\'':
1364:                    return "apos";
1365:                case '&':
1366:                    return "amp";
1367:                }
1368:                return null;
1369:            }
1370:
1371:            /** Retrieve and remove the namespaces declarations from the list of attributes.
1372:             *
1373:             */
1374:            private Attributes extractNamespaces(Attributes attrs)
1375:                    throws SAXException {
1376:                AttributesImpl attrsOnly;
1377:                String rawName;
1378:                int i;
1379:                int length;
1380:
1381:                if (attrs == null) {
1382:                    return null;
1383:                }
1384:                length = attrs.getLength();
1385:                attrsOnly = new AttributesImpl(attrs);
1386:
1387:                for (i = length - 1; i >= 0; --i) {
1388:                    rawName = attrsOnly.getQName(i);
1389:
1390:                    //We have to exclude the namespaces declarations from the attributes
1391:                    //Append only when the feature http://xml.org/sax/features/namespace-prefixes"
1392:                    //is TRUE
1393:                    if (rawName.startsWith("xmlns")) {
1394:                        if (rawName.length() == 5) {
1395:                            startPrefixMapping("", attrs.getValue(i));
1396:                            attrsOnly.removeAttribute(i);
1397:                        } else if (rawName.charAt(5) == ':') {
1398:                            startPrefixMapping(rawName.substring(6), attrs
1399:                                    .getValue(i));
1400:                            attrsOnly.removeAttribute(i);
1401:                        }
1402:                    }
1403:                }
1404:                return attrsOnly;
1405:            }
1406:
1407:            //
1408:            // Printing attribute value
1409:            //
1410:            protected void printEscaped(String source) throws IOException {
1411:                int length = source.length();
1412:                for (int i = 0; i < length; ++i) {
1413:                    int ch = source.charAt(i);
1414:                    if (!XMLChar.isValid(ch)) {
1415:                        if (++i < length) {
1416:                            surrogates(ch, source.charAt(i));
1417:                        } else {
1418:                            fatalError("The character '" + (char) ch
1419:                                    + "' is an invalid XML character");
1420:                        }
1421:                        continue;
1422:                    }
1423:                    // escape NL, CR, TAB
1424:                    if (ch == '\n' || ch == '\r' || ch == '\t') {
1425:                        printHex(ch);
1426:                    } else if (ch == '<') {
1427:                        _printer.printText("&lt;");
1428:                    } else if (ch == '>') {
1429:                        _printer.printText("&gt;");
1430:                    } else if (ch == '&') {
1431:                        _printer.printText("&amp;");
1432:                    } else if (ch == '"') {
1433:                        _printer.printText("&quot;");
1434:                    } else if ((ch >= ' ' && _encodingInfo
1435:                            .isPrintable((char) ch))) {
1436:                        _printer.printText((char) ch);
1437:                    } else {
1438:                        printHex(ch);
1439:                    }
1440:                }
1441:            }
1442:
1443:            /** print text data */
1444:            protected void printXMLChar(int ch) throws IOException {
1445:                if (ch == '\r') {
1446:                    printHex(ch);
1447:                } else if (ch == '<') {
1448:                    _printer.printText("&lt;");
1449:                } else if (ch == '&') {
1450:                    _printer.printText("&amp;");
1451:                } else if (ch == '>') {
1452:                    // character sequence "]]>" can't appear in content, therefore
1453:                    // we should escape '>' 
1454:                    _printer.printText("&gt;");
1455:                } else if (ch == '\n' || ch == '\t'
1456:                        || (ch >= ' ' && _encodingInfo.isPrintable((char) ch))) {
1457:                    _printer.printText((char) ch);
1458:                } else {
1459:                    printHex(ch);
1460:                }
1461:            }
1462:
1463:            protected void printText(String text, boolean preserveSpace,
1464:                    boolean unescaped) throws IOException {
1465:                int index;
1466:                char ch;
1467:                int length = text.length();
1468:                if (preserveSpace) {
1469:                    // Preserving spaces: the text must print exactly as it is,
1470:                    // without breaking when spaces appear in the text and without
1471:                    // consolidating spaces. If a line terminator is used, a line
1472:                    // break will occur.
1473:                    for (index = 0; index < length; ++index) {
1474:                        ch = text.charAt(index);
1475:                        if (!XMLChar.isValid(ch)) {
1476:                            // check if it is surrogate
1477:                            if (++index < length) {
1478:                                surrogates(ch, text.charAt(index));
1479:                            } else {
1480:                                fatalError("The character '" + (char) ch
1481:                                        + "' is an invalid XML character");
1482:                            }
1483:                            continue;
1484:                        }
1485:                        if (unescaped) {
1486:                            _printer.printText(ch);
1487:                        } else
1488:                            printXMLChar(ch);
1489:                    }
1490:                } else {
1491:                    // Not preserving spaces: print one part at a time, and
1492:                    // use spaces between parts to break them into different
1493:                    // lines. Spaces at beginning of line will be stripped
1494:                    // by printing mechanism. Line terminator is treated
1495:                    // no different than other text part.
1496:                    for (index = 0; index < length; ++index) {
1497:                        ch = text.charAt(index);
1498:                        if (!XMLChar.isValid(ch)) {
1499:                            // check if it is surrogate
1500:                            if (++index < length) {
1501:                                surrogates(ch, text.charAt(index));
1502:                            } else {
1503:                                fatalError("The character '" + (char) ch
1504:                                        + "' is an invalid XML character");
1505:                            }
1506:                            continue;
1507:                        }
1508:
1509:                        if (unescaped)
1510:                            _printer.printText(ch);
1511:                        else
1512:                            printXMLChar(ch);
1513:                    }
1514:                }
1515:            }
1516:
1517:            protected void printText(char[] chars, int start, int length,
1518:                    boolean preserveSpace, boolean unescaped)
1519:                    throws IOException {
1520:                char ch;
1521:
1522:                if (preserveSpace) {
1523:                    // Preserving spaces: the text must print exactly as it is,
1524:                    // without breaking when spaces appear in the text and without
1525:                    // consolidating spaces. If a line terminator is used, a line
1526:                    // break will occur.
1527:                    while (length-- > 0) {
1528:                        ch = chars[start];
1529:                        ++start;
1530:                        if (!XMLChar.isValid(ch)) {
1531:                            // check if it is surrogate
1532:                            if (++start < length) {
1533:                                surrogates(ch, chars[start]);
1534:                            } else {
1535:                                fatalError("The character '" + (char) ch
1536:                                        + "' is an invalid XML character");
1537:                            }
1538:                            continue;
1539:                        }
1540:                        if (unescaped)
1541:                            _printer.printText(ch);
1542:                        else
1543:                            printXMLChar(ch);
1544:                    }
1545:                } else {
1546:                    // Not preserving spaces: print one part at a time, and
1547:                    // use spaces between parts to break them into different
1548:                    // lines. Spaces at beginning of line will be stripped
1549:                    // by printing mechanism. Line terminator is treated
1550:                    // no different than other text part.
1551:                    while (length-- > 0) {
1552:                        ch = chars[start];
1553:                        ++start;
1554:
1555:                        if (!XMLChar.isValid(ch)) {
1556:                            // check if it is surrogate
1557:                            if (++start < length) {
1558:                                surrogates(ch, chars[start]);
1559:                            } else {
1560:                                fatalError("The character '" + (char) ch
1561:                                        + "' is an invalid XML character");
1562:                            }
1563:                            continue;
1564:                        }
1565:                        if (unescaped)
1566:                            _printer.printText(ch);
1567:                        else
1568:                            printXMLChar(ch);
1569:                    }
1570:                }
1571:            }
1572:
1573:            /**
1574:             * DOM Level 3:
1575:             * Check a node to determine if it contains unbound namespace prefixes.
1576:             *
1577:             * @param node The node to check for unbound namespace prefices
1578:             */
1579:            protected void checkUnboundNamespacePrefixedNode(Node node)
1580:                    throws IOException {
1581:
1582:                if (fNamespaces) {
1583:
1584:                    if (DEBUG) {
1585:                        System.out.println("==>serializeNode("
1586:                                + node.getNodeName()
1587:                                + ") [Entity Reference - Namespaces on]");
1588:                        System.out.println("==>Declared Prefix Count: "
1589:                                + fNSBinder.getDeclaredPrefixCount());
1590:                        System.out.println("==>Node Name: "
1591:                                + node.getNodeName());
1592:                        System.out.println("==>First Child Node Name: "
1593:                                + node.getFirstChild().getNodeName());
1594:                        System.out.println("==>First Child Node Prefix: "
1595:                                + node.getFirstChild().getPrefix());
1596:                        System.out.println("==>First Child Node NamespaceURI: "
1597:                                + node.getFirstChild().getNamespaceURI());
1598:                    }
1599:
1600:                    Node child, next;
1601:                    for (child = node.getFirstChild(); child != null; child = next) {
1602:                        next = child.getNextSibling();
1603:                        if (DEBUG) {
1604:                            System.out.println("==>serializeNode("
1605:                                    + child.getNodeName() + ") [Child Node]");
1606:                            System.out.println("==>serializeNode("
1607:                                    + child.getPrefix()
1608:                                    + ") [Child Node Prefix]");
1609:                        }
1610:
1611:                        //If a NamespaceURI is not declared for the current
1612:                        //node's prefix, raise a fatal error.
1613:                        String prefix = child.getPrefix();
1614:                        if (fNSBinder.getURI(prefix) == null && prefix != null) {
1615:                            fatalError("The replacement text of the entity node '"
1616:                                    + node.getNodeName()
1617:                                    + "' contains an element node '"
1618:                                    + child.getNodeName()
1619:                                    + "' with an undeclared prefix '"
1620:                                    + prefix
1621:                                    + "'.");
1622:                        }
1623:
1624:                        if (child.getNodeType() == Node.ELEMENT_NODE) {
1625:
1626:                            NamedNodeMap attrs = child.getAttributes();
1627:
1628:                            for (int i = 0; i < attrs.getLength(); i++) {
1629:
1630:                                String attrPrefix = attrs.item(i).getPrefix();
1631:                                if (fNSBinder.getURI(attrPrefix) == null
1632:                                        && attrPrefix != null) {
1633:                                    fatalError("The replacement text of the entity node '"
1634:                                            + node.getNodeName()
1635:                                            + "' contains an element node '"
1636:                                            + child.getNodeName()
1637:                                            + "' with an attribute '"
1638:                                            + attrs.item(i).getNodeName()
1639:                                            + "' an undeclared prefix '"
1640:                                            + attrPrefix + "'.");
1641:                                }
1642:
1643:                            }
1644:
1645:                        }
1646:
1647:                        if (child.hasChildNodes()) {
1648:                            checkUnboundNamespacePrefixedNode(child);
1649:                        }
1650:                    }
1651:                }
1652:            }
1653:
1654:            public boolean reset() {
1655:                super .reset();
1656:                if (fNSBinder != null) {
1657:                    fNSBinder.reset();
1658:                    // during serialization always have a mapping to empty string
1659:                    // so we assume there is a declaration.
1660:                    fNSBinder.declarePrefix(XMLSymbols.EMPTY_STRING,
1661:                            XMLSymbols.EMPTY_STRING);
1662:                }
1663:                return true;
1664:            }
1665:
1666:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.