Author: ltheussl Date: Fri Sep 14 00:14:49 2007 New Revision: 575567 URL: http://svn.apache.org/viewvc?rev=575567&view=rev Log: Factor out aggregate sink into a separate class. Fix link/anchor handling between different source documents, for this we need to pass the name of the source document into the sink.
Added: maven/sandbox/trunk/doxia/doxia-module-fo/src/main/java/org/apache/maven/doxia/module/fo/FoAggregateSink.java (with props) Modified: maven/sandbox/trunk/doxia/doxia-module-fo/src/main/java/org/apache/maven/doxia/module/fo/FoSink.java maven/sandbox/trunk/doxia/doxia-module-fo/src/test/java/org/apache/maven/doxia/module/fo/FoSinkTest.java Added: maven/sandbox/trunk/doxia/doxia-module-fo/src/main/java/org/apache/maven/doxia/module/fo/FoAggregateSink.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/doxia/doxia-module-fo/src/main/java/org/apache/maven/doxia/module/fo/FoAggregateSink.java?rev=575567&view=auto ============================================================================== --- maven/sandbox/trunk/doxia/doxia-module-fo/src/main/java/org/apache/maven/doxia/module/fo/FoAggregateSink.java (added) +++ maven/sandbox/trunk/doxia/doxia-module-fo/src/main/java/org/apache/maven/doxia/module/fo/FoAggregateSink.java Fri Sep 14 00:14:49 2007 @@ -0,0 +1,356 @@ +package org.apache.maven.doxia.module.fo; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.io.Writer; + +import org.apache.maven.doxia.util.HtmlTools; + +/** + * A Doxia Sink that produces an aggregated FO model. + */ +public class FoAggregateSink extends FoSink +{ + + /** Counts the current chapter level. */ + private int chapter = 0; + + /** A name for the current document. */ + private String docName; + + /** In fragment mode, some text has to be ignored (title...). */ + private boolean ignoreText; + + /** + * Constructor. + * + * @param writer The writer for writing the result. + */ + public FoAggregateSink( Writer writer ) + { + super( writer ); + } + + // TODO page headers, page numbering + // TODO add FOP compliance mode? + + /** [EMAIL PROTECTED] */ + public void head() + { + ignoreText = true; + } + + /** [EMAIL PROTECTED] */ + public void head_() + { + ignoreText = false; + newline(); + } + + /** [EMAIL PROTECTED] */ + public void title() + { + // ignored + } + + /** [EMAIL PROTECTED] */ + public void title_() + { + // ignored + } + + /** [EMAIL PROTECTED] */ + public void author() + { + // ignored + } + + /** [EMAIL PROTECTED] */ + public void author_() + { + // ignored + } + + /** [EMAIL PROTECTED] */ + public void date() + { + // ignored + } + + /** [EMAIL PROTECTED] */ + public void date_() + { + // ignored + } + + /** [EMAIL PROTECTED] */ + public void body() + { + startPageSequence(); + + chapter++; + + if ( docName == null ) + { + // TODO: log.warn( "No document root specified, local links might not be resolved correctly!" ) + } + else { + writeStartTag( "block", "id", docName ); + } + + } + + /** [EMAIL PROTECTED] */ + public void body_() + { + newline(); + writeEndTag( "block" ); + writeEndTag( "flow" ); + writeEndTag( "page-sequence" ); + + // reset document name + docName = null; + } + + /** + * Sets the name for the current document. This should allow anchors to be resolved uniquely. + * + * @param name the name for the current document. + */ + public void setDocumentName( String name ) + { + this.docName = name; + + // prepend "./" and strip extension + if ( !docName.startsWith( "./" ) ) + { + this.docName = "./" + docName; + } + + if ( docName.indexOf( ".", 2 ) != -1) + { + this.docName = docName.substring( 0, docName.indexOf( ".", 2 ) ); + } + } + + // ----------------------------------------------------------------------- + // + // ----------------------------------------------------------------------- + + + + /** [EMAIL PROTECTED] */ + public void anchor( String name ) + { + String anchor = "#" + name; + + if ( docName != null ) + { + anchor = docName + anchor; + } + + writeStartTag( "inline", "id", anchor ); + } + + + /** [EMAIL PROTECTED] */ + public void link( String name ) + { + if ( name.startsWith( "http", 0 ) || name.startsWith( "mailto", 0 ) + || name.startsWith( "ftp", 0 ) ) + { + // external links + writeStartTag( "basic-link", "external-destination", HtmlTools.escapeHTML( name ) ); + writeStartTag( "inline", "href.external" ); + } + else if ( name.startsWith( "./", 0 ) || name.startsWith( "../", 0 ) ) + { + // internal non-local (ie anchor is not in the same source document) links + // TODO: link to another document, construct relative path + + String anchor = name; + + int dot = anchor.indexOf( ".", 2 ); + + if ( dot != -1) + { + int hash = anchor.indexOf( "#", dot ); + + if ( hash != -1 ) + { + int dot2 = anchor.indexOf( ".", hash ); + + if ( dot2 != -1) + { + anchor = anchor.substring( 0, dot ) + anchor.substring( hash, dot2 ); + } + else + { + anchor = anchor.substring( 0, dot ) + anchor.substring( hash, anchor.length() ); + } + } + else + { + anchor = anchor.substring( 0, dot ); + } + } + + writeStartTag( "basic-link", "internal-destination", HtmlTools.escapeHTML( anchor ) ); + writeStartTag( "inline", "href.internal" ); + } + else + { + // internal local (ie anchor is in the same source document) links + String anchor = "#" + name; + + if ( docName != null ) + { + anchor = docName + anchor; + } + + writeStartTag( "basic-link", "internal-destination", HtmlTools.escapeHTML( anchor ) ); + writeStartTag( "inline", "href.internal" ); + } + } + + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + /** + * Writes a start tag, prepending EOL. + * + * @param tag The tag name. + * @param attributeId An id identifying the attribute set. + */ + protected void writeStartTag( String tag, String attributeId ) + { + if ( !ignoreText ) + { + super.writeStartTag( tag, attributeId ); + } + } + + /** + * Writes a start tag, prepending EOL. + * + * @param tag The tag name. + * @param id An id to add. + * @param name The name (value) of the id. + */ + protected void writeStartTag( String tag, String id, String name ) + { + if ( !ignoreText ) + { + super.writeStartTag( tag, id, name ); + } + } + + /** + * Writes an end tag, appending EOL. + * + * @param tag The tag name. + */ + protected void writeEndTag( String tag ) + { + if ( !ignoreText ) + { + super.writeEndTag( tag ); + } + } + + /** + * Writes a simple tag, appending EOL. + * + * @param tag The tag name. + * @param attributeId An id identifying the attribute set. + */ + protected void writeEmptyTag( String tag, String attributeId ) + { + if ( !ignoreText ) + { + super.writeEmptyTag( tag, attributeId ); + } + } + + /** + * Writes a text, swallowing any exceptions. + * + * @param text The text to write. + */ + protected void write( String text ) + { + if ( !ignoreText ) + { + super.write( text ); + } + } + + /** + * Writes a text, appending EOL. + * + * @param text The text to write. + */ + protected void writeln( String text ) + { + if ( !ignoreText ) + { + super.writeln( text ); + } + } + + /** + * Writes content, escaping special characters. + * + * @param text The text to write. + */ + protected void content( String text ) + { + if ( !ignoreText ) + { + super.content( text ); + } + } + + /** Writes EOL. */ + protected void newline() + { + if ( !ignoreText ) + { + super.newline(); + } + } + + /** Starts a page sequence. */ + protected void startPageSequence() + { + if ( chapter == 0 ) + { + super.startPageSequence( "0" ); + } + else + { + super.startPageSequence( "auto" ); + } + } + + +} Propchange: maven/sandbox/trunk/doxia/doxia-module-fo/src/main/java/org/apache/maven/doxia/module/fo/FoAggregateSink.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/sandbox/trunk/doxia/doxia-module-fo/src/main/java/org/apache/maven/doxia/module/fo/FoAggregateSink.java ------------------------------------------------------------------------------ svn:keywords = "Author Date Id Revision" Modified: maven/sandbox/trunk/doxia/doxia-module-fo/src/main/java/org/apache/maven/doxia/module/fo/FoSink.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/doxia/doxia-module-fo/src/main/java/org/apache/maven/doxia/module/fo/FoSink.java?rev=575567&r1=575566&r2=575567&view=diff ============================================================================== --- maven/sandbox/trunk/doxia/doxia-module-fo/src/main/java/org/apache/maven/doxia/module/fo/FoSink.java (original) +++ maven/sandbox/trunk/doxia/doxia-module-fo/src/main/java/org/apache/maven/doxia/module/fo/FoSink.java Fri Sep 14 00:14:49 2007 @@ -45,9 +45,6 @@ /** Used to get attributes for a given FO element. */ private final FoConfiguration config; - /** Counts the current chapter level. */ - private int chapter = 0; - /** Counts the current section level. */ private int section = 0; @@ -69,12 +66,6 @@ /** Verbatim flag. */ private boolean verbatim; - /** Flag that indicates if the document to be written is only a fragment. */ - private boolean fragmentDocument; - - /** In fragment mode, some text has to be ignored (title...). */ - private boolean ignoreText; - /** * Constructor. * @@ -82,20 +73,8 @@ */ public FoSink( Writer writer ) { - this( writer, false ); - } - - /** - * Constructor. - * - * @param writer The writer for writing the result. - * @param fragment Indicates if the document is only a fragment. - */ - public FoSink( Writer writer, boolean fragment ) - { this.out = writer; this.config = new FoConfiguration(); - this.fragmentDocument = fragment; } /** @@ -114,13 +93,8 @@ /** [EMAIL PROTECTED] */ public void head() { - if ( fragmentDocument ) - { - return; - } - beginDocument(); - startPageSequence(); + startPageSequence( "0" ); } /** [EMAIL PROTECTED] */ @@ -132,93 +106,52 @@ /** [EMAIL PROTECTED] */ public void title() { - if ( fragmentDocument ) - { - ignoreText = true; - } - else - { - writeStartTag( "block", "doc.header.title" ); - } + writeStartTag( "block", "doc.header.title" ); } /** [EMAIL PROTECTED] */ public void title_() { - ignoreText = false; - if ( !fragmentDocument ) - { - writeEndTag( "block" ); - } + writeEndTag( "block" ); } /** [EMAIL PROTECTED] */ public void author() { - if ( fragmentDocument ) - { - ignoreText = true; - } - else - { - writeStartTag( "block", "doc.header.author" ); - } + writeStartTag( "block", "doc.header.author" ); } /** [EMAIL PROTECTED] */ public void author_() { - ignoreText = false; - if ( !fragmentDocument ) - { - writeEndTag( "block" ); - } + writeEndTag( "block" ); } /** [EMAIL PROTECTED] */ public void date() { - if ( fragmentDocument ) - { - ignoreText = true; - } - else - { - writeStartTag( "block", "doc.header.date" ); - } + writeStartTag( "block", "doc.header.date" ); } /** [EMAIL PROTECTED] */ public void date_() { - ignoreText = false; - if ( !fragmentDocument ) - { - writeEndTag( "block" ); - } + writeEndTag( "block" ); } /** [EMAIL PROTECTED] */ public void body() { - if ( fragmentDocument ) - { - startPageSequence(); - } - - chapter++; + // noop } /** [EMAIL PROTECTED] */ public void body_() { - newline(); - writeEndTag( "flow" ); - writeEndTag( "page-sequence" ); - if ( !fragmentDocument ) - { - endDocument(); - } + newline(); + writeEndTag( "flow" ); + writeEndTag( "page-sequence" ); + endDocument(); } // ----------------------------------------------------------------------- @@ -798,15 +731,7 @@ /** [EMAIL PROTECTED] */ public void anchor( String name ) { - String anchor = name; - - if ( fragmentDocument ) - { - anchor = anchor + String.valueOf( chapter ) + "." + String.valueOf( section ) - + "." + String.valueOf( subsection ) + "." + String.valueOf( subsubsection ); - } - - writeStartTag( "inline", "id", anchor ); + writeStartTag( "inline", "id", name ); } /** [EMAIL PROTECTED] */ @@ -818,14 +743,6 @@ /** [EMAIL PROTECTED] */ public void link( String name ) { - String anchor = name; - - if ( fragmentDocument ) - { - anchor = anchor + String.valueOf( chapter ) + "." + String.valueOf( section ) - + "." + String.valueOf( subsection ) + "." + String.valueOf( subsubsection ); - } - if ( name.startsWith( "http", 0 ) || name.startsWith( "mailto", 0 ) || name.startsWith( "ftp", 0 ) ) { @@ -840,7 +757,7 @@ else { // TODO: aggregate mode: link to another document, construct relative path - writeStartTag( "basic-link", "internal-destination", anchor ); + writeStartTag( "basic-link", "internal-destination", name ); writeStartTag( "inline", "href.internal" ); } } @@ -855,65 +772,44 @@ /** [EMAIL PROTECTED] */ public void italic() { - if ( !ignoreText ) - { - writeStartTag( "inline", "italic" ); - } + writeStartTag( "inline", "italic" ); } /** [EMAIL PROTECTED] */ public void italic_() { - if ( !ignoreText ) - { - writeEndTag( "inline" ); - } + writeEndTag( "inline" ); } /** [EMAIL PROTECTED] */ public void bold() { - if ( !ignoreText ) - { - writeStartTag( "inline", "bold" ); - } + writeStartTag( "inline", "bold" ); } /** [EMAIL PROTECTED] */ public void bold_() { - if ( !ignoreText ) - { - writeEndTag( "inline" ); - } + writeEndTag( "inline" ); } /** [EMAIL PROTECTED] */ public void monospaced() { - if ( !ignoreText ) - { - writeStartTag( "inline", "monospace" ); - } + writeStartTag( "inline", "monospace" ); } /** [EMAIL PROTECTED] */ public void monospaced_() { - if ( !ignoreText ) - { - writeEndTag( "inline" ); - } + writeEndTag( "inline" ); } /** [EMAIL PROTECTED] */ public void lineBreak() { - if ( !ignoreText ) - { - newline(); + newline(); writeEmptyTag( "block", null ); - } } /** [EMAIL PROTECTED] */ @@ -925,19 +821,13 @@ /** [EMAIL PROTECTED] */ public void text( String text ) { - if ( !ignoreText ) - { - content( text ); - } + content( text ); } /** [EMAIL PROTECTED] */ public void rawText( String text ) { - if ( !ignoreText ) - { - write( text ); - } + write( text ); } /** [EMAIL PROTECTED] */ @@ -1016,7 +906,7 @@ * @param tag The tag name. * @param attributeId An id identifying the attribute set. */ - private void writeStartTag( String tag, String attributeId ) + protected void writeStartTag( String tag, String attributeId ) { String attribs = config.getAttributeSet( attributeId ); newline(); @@ -1030,7 +920,7 @@ * @param id An id to add. * @param name The name (value) of the id. */ - private void writeStartTag( String tag, String id, String name ) + protected void writeStartTag( String tag, String id, String name ) { newline(); write( "<fo:" + tag + " " + id + "=\"" + name + "\">" ); @@ -1041,7 +931,7 @@ * * @param tag The tag name. */ - private void writeEndTag( String tag ) + protected void writeEndTag( String tag ) { writeln( "</fo:" + tag + ">" ); } @@ -1052,7 +942,7 @@ * @param tag The tag name. * @param attributeId An id identifying the attribute set. */ - private void writeEmptyTag( String tag, String attributeId ) + protected void writeEmptyTag( String tag, String attributeId ) { String attribs = config.getAttributeSet( attributeId ); writeln( "<fo:" + tag + attribs + "/>" ); @@ -1063,7 +953,7 @@ * * @param text The text to write. */ - private void write( String text ) + protected void write( String text ) { try { @@ -1080,7 +970,7 @@ * * @param text The text to write. */ - private void writeln( String text ) + protected void writeln( String text ) { write( text ); newline(); @@ -1091,13 +981,13 @@ * * @param text The text to write. */ - private void content( String text ) + protected void content( String text ) { write( escaped( text, verbatim ) ); } /** Writes EOL. */ - private void newline() + protected void newline() { write( EOL ); } @@ -1157,19 +1047,10 @@ } /** Starts a page sequence. */ - private void startPageSequence() + protected void startPageSequence( String initPageNumber ) { - if ( chapter == 0 ) - { - writeln( "<fo:page-sequence initial-page-number=\"1\" master-reference=\"body\">" ); - } - else - { - writeln( "<fo:page-sequence initial-page-number=\"auto\" master-reference=\"body\">" ); - } - + writeln( "<fo:page-sequence initial-page-number=\"" + initPageNumber + "\" master-reference=\"body\">" ); writeln( "<fo:flow flow-name=\"xsl-region-body\">" ); } - } Modified: maven/sandbox/trunk/doxia/doxia-module-fo/src/test/java/org/apache/maven/doxia/module/fo/FoSinkTest.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/doxia/doxia-module-fo/src/test/java/org/apache/maven/doxia/module/fo/FoSinkTest.java?rev=575567&r1=575566&r2=575567&view=diff ============================================================================== --- maven/sandbox/trunk/doxia/doxia-module-fo/src/test/java/org/apache/maven/doxia/module/fo/FoSinkTest.java (original) +++ maven/sandbox/trunk/doxia/doxia-module-fo/src/test/java/org/apache/maven/doxia/module/fo/FoSinkTest.java Fri Sep 14 00:14:49 2007 @@ -59,11 +59,17 @@ */ public void testAggregateMode() throws Exception { - FoSink fosink = new FoSink( getTestWriter( "aggregate" ), true ); + FoAggregateSink fosink = new FoAggregateSink( getTestWriter( "aggregate" ) ); + fosink.beginDocument(); + + fosink.setDocumentName( "doc1" ); SinkTestDocument.generate( fosink ); + // re-use the same source + fosink.setDocumentName( "doc2" ); SinkTestDocument.generate( fosink ); + fosink.endDocument(); // then generate PDF