Inselraus: Anwendungen für FilterReader und FilterWriter
Unsere nächste Klasse bringt uns etwas näher an das HTML-Format heran. Wir wollen eine Klasse HTMLWriter entwerfen, die FilterWriter erweitert und Textausgaben in HTML konvertiert. In HTML werden Tags eingeführt, die vom Browser erkannt und besonders behandelt werden. Findet etwa der Browser im HTML-Text eine Zeile der Form <strong>Dick</strong>, so stellt er den Inhalt „Dick“ in fetter Schrift dar, da das <strong>-Element den Zeichensatz umstellt. Alle Tags werden in spitzen Klammern geschrieben. Daraus ergibt sich, dass HTML einige spezielle Zeichenfolgen (Entities genannt) verwendet. Wenn diese Zeichen auf der HTML-Seite dargestellt werden, muss dies durch spezielle Zeichensequenzen geschehen:
- < wird zu <
- > wird zu >
- & wird zu &
Kommen diese Zeichen im Quelltext vor, so muss unser HTMLWriter diese Zeichen durch die entsprechende Sequenz ersetzen. Andere Zeichen sollen nicht ersetzt werden.
Den Browsern ist die Struktur der Zeilen in einer HTML-Datei egal. Sie formatieren wiederum nach speziellen Tags. Zeilenvorschübe etwa werden mit <br/> eingeleitet. Unser HTMLWriter soll zwei leere Zeilen durch das Zeilenvorschub-Element <br/> markieren.
HTML-Dokument schreiben
Alle sauberen HTML-Dateien haben einen wohldefinierten Anfang und ein wohldefiniertes Ende. Das folgende kleine HTML-Dokument ist wohlgeformt und zeigt, was unser Programm später erzeugen soll:
Superkreativer Titel
Und eine Menge von Sonderzeichen: < und > und &
Zweite Zeile
Leerzeile
Keine Leerzeile danach
Der Titel der Seite sollte im Konstruktor übergeben werden können. Hier ist nun das Programm für den HTMLWriter:
package com.tutego.insel.io.stream;
import java.io.*;
class HTMLWriter extends FilterWriter {
private boolean newLine;
/**
* Creates a new filtered HTML writer with a title for the web page.
*
* @param out a Writer object to provide the underlying stream.
* @throws IOException if the header cannot be written
*/
public HTMLWriter( Writer out, String title ) throws IOException {
super( out );
out.write( "\n" );
out.write( "" + title + "\n\n" );
}
/**
* Creates a new filtered HTML writer with no title for the web page.
*
* @param out a Writer object to provide the underlying stream.
*/
public HTMLWriter( Writer out ) {
super( out );
}
/**
* Writes a single character.
*/
@Override
public void write( int c ) throws IOException {
switch ( c ) {
case '':
out.write( ">" );
newLine = false;
break;
case '&':
out.write( "&" );
newLine = false;
break;
case '\n':
if ( newLine ) {
out.write( "\n" );
newLine = false;
}
else
out.write( "\n" );
newLine = true;
break;
case '\r':
break; // ignore
default :
out.write( c );
newLine = false;
}
}
/**
* Writes a portion of an array of characters.
*
* @param cbuf Buffer of characters to be written
* @param off Offset from which to start reading characters
* @param len Number of characters to be written
* @exception IOException If an I/O error occurs
*/
@Override
public void write( char[] cbuf, int off, int len ) throws IOException {
for ( int i = off; i