📄 basemarkupserializer.java
字号:
int index; int saveIndent; // Print a CDATA section. The text is not escaped, but ']]>' // appearing in the code must be identified and dealt with. // The contents of a text node is considered space preserving. buffer = new StringBuffer( text.length() ); if ( ! state.inCData ) { buffer.append( "<![CDATA[" ); state.inCData = true; } index = text.indexOf( "]]>" ); while ( index >= 0 ) { buffer.append( text.substring( 0, index + 2 ) ).append( "]]><![CDATA[" ); text = text.substring( index + 2 ); index = text.indexOf( "]]>" ); } buffer.append( text ); saveIndent = _printer.getNextIndent(); _printer.setNextIndent( 0 ); printText( buffer.toString(), true, true ); _printer.setNextIndent( saveIndent ); } else { int saveIndent; if ( state.preserveSpace ) { // If preserving space then hold of indentation so no // excessive spaces are printed at line breaks, escape // the text content without replacing spaces and print // the text breaking only at line breaks. saveIndent = _printer.getNextIndent(); _printer.setNextIndent( 0 ); printText( text, true, state.unescaped ); _printer.setNextIndent( saveIndent ); } else { printText( text, false, state.unescaped ); } } } /** * Returns the suitable entity reference for this character value, * or null if no such entity exists. Calling this method with <tt>'&'</tt> * will return <tt>"&amp;"</tt>. * * @param ch Character value * @return Character entity name, or null */ protected abstract String getEntityRef( int ch ); /** * Called to serializee the DOM element. The element is serialized based on * the serializer's method (XML, HTML, XHTML). * * @param elem The element to serialize * @throws IOException An I/O exception occured while * serializing */ protected abstract void serializeElement( Element elem ) throws IOException; /** * Comments and PIs cannot be serialized before the root element, * because the root element serializes the document type, which * generally comes first. Instead such PIs and comments are * accumulated inside a vector and serialized by calling this * method. Will be called when the root element is serialized * and when the document finished serializing. * * @throws IOException An I/O exception occured while * serializing */ protected void serializePreRoot() throws IOException { int i; if ( _preRoot != null ) { for ( i = 0 ; i < _preRoot.size() ; ++i ) { printText( (String) _preRoot.elementAt( i ), true, true ); if ( _indenting ) _printer.breakLine(); } _preRoot.removeAllElements(); } } //---------------------------------------------// // Text pretty printing and formatting methods // //---------------------------------------------// /** * Called to print additional text with whitespace handling. * If spaces are preserved, the text is printed as if by calling * {@link #printText(String, boolean, boolean)} with a call to breakLine() * for each new line. If spaces are not preserved, the text is * broken at space boundaries if longer than the line width; * Multiple spaces are printed as such, but spaces at beginning * of line are removed. * * @param preserveSpace Space preserving flag * @param unescaped Print unescaped */ protected final void printText( char[] chars, int start, int length, boolean preserveSpace, boolean unescaped ) throws IOException { int index; char ch; if ( preserveSpace ) { // Preserving spaces: the text must print exactly as it is, // without breaking when spaces appear in the text and without // consolidating spaces. If a line terminator is used, a line // break will occur. while ( length-- > 0 ) { ch = chars[ start ]; ++start; if ( ch == '\n' || ch == '\r' || unescaped ) _printer.printText( ch ); else printEscaped( ch ); } } else { // Not preserving spaces: print one part at a time, and // use spaces between parts to break them into different // lines. Spaces at beginning of line will be stripped // by printing mechanism. Line terminator is treated // no different than other text part. while ( length-- > 0 ) { ch = chars[ start ]; ++start; if ( ch == ' ' || ch == '\f' || ch == '\t' || ch == '\n' || ch == '\r' ) _printer.printSpace(); else if ( unescaped ) _printer.printText( ch ); else printEscaped( ch ); } } } protected final void printText( String text, boolean preserveSpace, boolean unescaped ) throws IOException { int index; char ch; if ( preserveSpace ) { // Preserving spaces: the text must print exactly as it is, // without breaking when spaces appear in the text and without // consolidating spaces. If a line terminator is used, a line // break will occur. for ( index = 0 ; index < text.length() ; ++index ) { ch = text.charAt( index ); if ( ch == '\n' || ch == '\r' || unescaped ) _printer.printText( ch ); else printEscaped( ch ); } } else { // Not preserving spaces: print one part at a time, and // use spaces between parts to break them into different // lines. Spaces at beginning of line will be stripped // by printing mechanism. Line terminator is treated // no different than other text part. for ( index = 0 ; index < text.length() ; ++index ) { ch = text.charAt( index ); if ( ch == ' ' || ch == '\f' || ch == '\t' || ch == '\n' || ch == '\r' ) _printer.printSpace(); else if ( unescaped ) _printer.printText( ch ); else printEscaped( ch ); } } } /** * Print a document type public or system identifier URL. * Encapsulates the URL in double quotes, escapes non-printing * characters and print it equivalent to {@link #printText(char[], int, int, boolean, boolean)}. * * @param url The document type url to print */ protected void printDoctypeURL( String url ) throws IOException { int i; _printer.printText( '"' ); for( i = 0 ; i < url.length() ; ++i ) { if ( url.charAt( i ) == '"' || url.charAt( i ) < 0x20 || url.charAt( i ) > 0x7F ) { _printer.printText( '%' ); _printer.printText( Integer.toHexString( url.charAt( i ) ) ); } else _printer.printText( url.charAt( i ) ); } _printer.printText( '"' ); } protected void printEscaped( int ch ) throws IOException { String charRef; // If there is a suitable entity reference for this // character, print it. The list of available entity // references is almost but not identical between // XML and HTML. charRef = getEntityRef( ch ); if ( charRef != null ) { _printer.printText( '&' ); _printer.printText( charRef ); _printer.printText( ';' ); } else if ( ( ch >= ' ' && _encodingInfo.isPrintable(ch) && ch != 0xF7 ) || ch == '\n' || ch == '\r' || ch == '\t' ) { // If the character is not printable, print as character reference. // Non printables are below ASCII space but not tab or line // terminator, ASCII delete, or above a certain Unicode threshold. if (ch < 0x10000) { _printer.printText((char)ch ); } else { _printer.printText((char)(((ch-0x10000)>>10)+0xd800)); _printer.printText((char)(((ch-0x10000)&0x3ff)+0xdc00)); } } else { _printer.printText( "&#x" ); _printer.printText(Integer.toHexString(ch)); _printer.printText( ';' ); } } /** * Escapes a string so it may be printed as text content or attribute * value. Non printable characters are escaped using character references. * Where the format specifies a deault entity reference, that reference * is used (e.g. <tt>&lt;</tt>). * * @param source The string to escape */ protected void printEscaped( String source ) throws IOException { for ( int i = 0 ; i < source.length() ; ++i ) { int ch = source.charAt(i); if ((ch & 0xfc00) == 0xd800 && i+1 < source.length()) { int lowch = source.charAt(i+1); if ((lowch & 0xfc00) == 0xdc00) { ch = 0x10000 + ((ch-0xd800)<<10) + lowch-0xdc00; i++; } } printEscaped(ch); } } //--------------------------------// // Element state handling methods // //--------------------------------// /** * Return the state of the current element. * * @return Current element state */ protected ElementState getElementState() { return _elementStates[ _elementStateCount ]; } /** * Enter a new element state for the specified element. * Tag name and space preserving is specified, element * state is initially empty. * * @return Current element state, or null */ protected ElementState enterElementState( String namespaceURI, String localName, String rawName, boolean preserveSpace ) { ElementState state; if ( _elementStateCount + 1 == _elementStates.length ) { ElementState[] newStates; // Need to create a larger array of states. This does not happen // often, unless the document is really deep. newStates = new ElementState[ _elementStates.length + 10 ]; for ( int i = 0 ; i < _elementStates.length ; ++i ) newStates[ i ] = _elementStates[ i ]; for ( int i = _elementStates.length ; i < newStates.length ; ++i ) newStates[ i ] = new ElementState(); _elementStates = newStates; } ++_elementStateCount; state = _elementStates[ _elementStateCount ]; state.namespaceURI = namespaceURI; state.localName = localName; state.rawName = rawName; state.preserveSpace = preserveSpace; state.empty = true; state.afterElement = false; state.afterComment = false; state.doCData = state.inCData = false; state.unescaped = false; state.prefixes = _prefixes; _prefixes = null; return state; } /** * Leave the current element state and return to the * state of the parent element. If this was the root * element, return to the state of the document. * * @return Previous element state */ protected ElementState leaveElementState() { if ( _elementStateCount > 0 ) { /*Corrected by David Blondeau (blondeau@intalio.com)*/ _prefixes = null; //_prefixes = _elementStates[ _elementStateCount ].prefixes; -- _elementStateCount; return _elementStates[ _elementStateCount ]; } else throw new IllegalStateException( "Internal error: element state is zero" ); } /** * Returns true if in the state of the document. * Returns true before entering any element and after * leaving the root element. * * @return True if in the state of the document */ protected boolean isDocumentState() { return _elementStateCount == 0; } /** * Returns the namespace prefix for the specified URI. * If the URI has been mapped to a prefix, returns the * prefix, otherwise returns null. * * @param namespaceURI The namespace URI * @return The namespace prefix if known, or null */ protected String getPrefix( String namespaceURI ) { String prefix; if ( _prefixes != null ) { prefix = (String) _prefixes.get( namespaceURI ); if ( prefix != null ) return prefix; } if ( _elementStateCount == 0 ) return null; else { for ( int i = _elementStateCount ; i > 0 ; --i ) { if ( _elementStates[ i ].prefixes != null ) { prefix = (String) _elementStates[ i ].prefixes.get( namespaceURI ); if ( prefix != null ) return prefix; } } } return null; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -