You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by kw...@apache.org on 2023/12/23 18:47:13 UTC
(maven-doxia) branch feature/sink-wrapper created (now 39b177c6)
This is an automated email from the ASF dual-hosted git repository.
kwin pushed a change to branch feature/sink-wrapper
in repository https://gitbox.apache.org/repos/asf/maven-doxia.git
at 39b177c6 [DOXIA-711] Introduce SinkWrapper and according SinkWrapperFactory
This branch includes the following new commits:
new 39b177c6 [DOXIA-711] Introduce SinkWrapper and according SinkWrapperFactory
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(maven-doxia) 01/01: [DOXIA-711] Introduce SinkWrapper and according SinkWrapperFactory
Posted by kw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
kwin pushed a commit to branch feature/sink-wrapper
in repository https://gitbox.apache.org/repos/asf/maven-doxia.git
commit 39b177c60d0dbf2b26c2591d8c5c34abc40d0ba4
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Sat Dec 23 19:47:07 2023 +0100
[DOXIA-711] Introduce SinkWrapper and according SinkWrapperFactory
Add a BufferingSinkProxyWrapper which buffers all calls on the
underlying sink until it is flushed.
---
.../apache/maven/doxia/parser/AbstractParser.java | 47 +-
.../maven/doxia/parser/AbstractXmlParser.java | 2 +-
.../doxia/parser/BufferingSinkProxyFactory.java | 112 +++
.../java/org/apache/maven/doxia/parser/Parser.java | 15 +
.../org/apache/maven/doxia/parser/SinkWrapper.java | 529 +++++++++++
.../maven/doxia/parser/SinkWrapperFactory.java | 43 +
.../maven/doxia/sink/impl/RandomAccessSink.java | 965 +--------------------
.../sink/impl/SinkWrapperFactoryComparator.java | 33 +
.../maven/doxia/parser/AbstractParserTest.java | 61 +-
.../apache/maven/doxia/module/apt/AptParser.java | 2 +-
.../apache/maven/doxia/module/fml/FmlParser.java | 2 +-
.../doxia/module/markdown/MarkdownParser.java | 2 +-
12 files changed, 850 insertions(+), 963 deletions(-)
diff --git a/doxia-core/src/main/java/org/apache/maven/doxia/parser/AbstractParser.java b/doxia-core/src/main/java/org/apache/maven/doxia/parser/AbstractParser.java
index 1e868135..0c28241a 100644
--- a/doxia-core/src/main/java/org/apache/maven/doxia/parser/AbstractParser.java
+++ b/doxia-core/src/main/java/org/apache/maven/doxia/parser/AbstractParser.java
@@ -25,6 +25,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.PriorityQueue;
import java.util.Properties;
import org.apache.maven.doxia.macro.Macro;
@@ -33,6 +36,7 @@ import org.apache.maven.doxia.macro.MacroRequest;
import org.apache.maven.doxia.macro.manager.MacroManager;
import org.apache.maven.doxia.macro.manager.MacroNotFoundException;
import org.apache.maven.doxia.sink.Sink;
+import org.apache.maven.doxia.sink.impl.SinkWrapperFactoryComparator;
/**
* An abstract base class that defines some convenience methods for parsers.
@@ -48,11 +52,18 @@ public abstract class AbstractParser implements Parser {
@Inject
private MacroManager macroManager;
+ @Inject
+ private Collection<SinkWrapperFactory> automaticallyRegisteredSinkWrapperFactories;
+
+ private final Collection<SinkWrapperFactory> manuallyRegisteredSinkWrapperFactories = new LinkedList<>();
+
/**
* Emit Doxia comment events when parsing comments?
*/
private boolean emitComments = true;
+ private boolean emitAnchors = false;
+
private static final String DOXIA_VERSION;
static {
@@ -171,7 +182,25 @@ public abstract class AbstractParser implements Parser {
}
/**
- * Set <code>secondParsing</code> to true, if we need a second parsing.
+ * Retrieves the sink pipeline built from all registered {@link SinkWrapperFactory} objects.
+ * For secondary parsers (i.e. ones with {@link #isSecondParsing()} returning {@code true} just the given original sink is returned.
+ * @param sink
+ * @return the Sink pipeline to be used
+ */
+ protected Sink getWrappedSink(Sink sink) {
+ // no wrapping for secondary parsing
+ if (secondParsing) {
+ return sink;
+ }
+ Sink currentSink = sink;
+ for (SinkWrapperFactory factory : getSinkWrapperFactories()) {
+ currentSink = factory.createWrapper(currentSink);
+ }
+ return currentSink;
+ }
+
+ /**
+ * Set <code>secondParsing</code> to true, if this represents a secondary parsing of the same source.
*
* @param second true for second parsing
*/
@@ -189,6 +218,22 @@ public abstract class AbstractParser implements Parser {
return secondParsing;
}
+ @Override
+ public void addSinkWrapperFactory(SinkWrapperFactory factory) {
+ manuallyRegisteredSinkWrapperFactories.add(factory);
+ }
+
+ @Override
+ public Collection<SinkWrapperFactory> getSinkWrapperFactories() {
+ PriorityQueue<SinkWrapperFactory> effectiveSinkWrapperFactories =
+ new PriorityQueue<>(new SinkWrapperFactoryComparator());
+ if (automaticallyRegisteredSinkWrapperFactories != null) {
+ effectiveSinkWrapperFactories.addAll(automaticallyRegisteredSinkWrapperFactories);
+ }
+ effectiveSinkWrapperFactories.addAll(manuallyRegisteredSinkWrapperFactories);
+ return effectiveSinkWrapperFactories;
+ }
+
/**
* Gets the current {@link MacroManager}.
*
diff --git a/doxia-core/src/main/java/org/apache/maven/doxia/parser/AbstractXmlParser.java b/doxia-core/src/main/java/org/apache/maven/doxia/parser/AbstractXmlParser.java
index b4cbbfaa..d0d143d6 100644
--- a/doxia-core/src/main/java/org/apache/maven/doxia/parser/AbstractXmlParser.java
+++ b/doxia-core/src/main/java/org/apache/maven/doxia/parser/AbstractXmlParser.java
@@ -131,7 +131,7 @@ public abstract class AbstractXmlParser extends AbstractParser implements XmlMar
// Note: do it after input is set, otherwise values are reset
initXmlParser(parser);
- parseXml(parser, sink);
+ parseXml(parser, getWrappedSink(sink));
} catch (XmlPullParserException ex) {
throw new ParseException("Error parsing the model", ex, ex.getLineNumber(), ex.getColumnNumber());
} catch (MacroExecutionException ex) {
diff --git a/doxia-core/src/main/java/org/apache/maven/doxia/parser/BufferingSinkProxyFactory.java b/doxia-core/src/main/java/org/apache/maven/doxia/parser/BufferingSinkProxyFactory.java
new file mode 100644
index 00000000..4112ad31
--- /dev/null
+++ b/doxia-core/src/main/java/org/apache/maven/doxia/parser/BufferingSinkProxyFactory.java
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+package org.apache.maven.doxia.parser;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.LinkedList;
+import java.util.Queue;
+
+import org.apache.maven.doxia.sink.Sink;
+
+/**
+ * Buffers all method calls on the wrapped Sink until the proxy sink's method {@link Sink#flush()} is called.
+ */
+public class BufferingSinkProxyFactory implements SinkWrapperFactory {
+
+ private static final class MethodWithArguments {
+ private final Method method;
+ private final Object[] args;
+
+ MethodWithArguments(Method method, Object[] args) {
+ super();
+ this.method = method;
+ this.args = args;
+ }
+
+ void invoke(Object object) {
+ try {
+ method.invoke(object, args);
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+ throw new IllegalStateException("Could not call buffered method " + method, e);
+ }
+ }
+ }
+
+ public interface BufferingSink extends Sink {
+ // just a marker interface
+ Sink getBufferedSink();
+ }
+
+ private static final class BufferingSinkProxy implements InvocationHandler {
+ private final Queue<MethodWithArguments> bufferedInvocations;
+ private final Sink delegate;
+ private static final Method FLUSH_METHOD;
+ private static final Method GET_BUFFERED_SINK_METHOD;
+
+ static {
+ try {
+ FLUSH_METHOD = Sink.class.getMethod("flush");
+ GET_BUFFERED_SINK_METHOD = BufferingSink.class.getMethod("getBufferedSink");
+ } catch (NoSuchMethodException | SecurityException e) {
+ throw new IllegalStateException("Could not find flush method in Sink!", e);
+ }
+ }
+
+ BufferingSinkProxy(Sink delegate) {
+ bufferedInvocations = new LinkedList<>();
+ this.delegate = delegate;
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ if (method.equals(FLUSH_METHOD)) {
+ bufferedInvocations.forEach(i -> i.invoke(delegate));
+ bufferedInvocations.clear();
+ } else if (method.equals(GET_BUFFERED_SINK_METHOD)) {
+ return delegate;
+ } else {
+ bufferedInvocations.add(new MethodWithArguments(method, args));
+ }
+ return null;
+ }
+ }
+
+ @Override
+ public Sink createWrapper(Sink delegate) {
+ BufferingSinkProxy proxy = new BufferingSinkProxy(delegate);
+ return (Sink) Proxy.newProxyInstance(
+ delegate.getClass().getClassLoader(), new Class<?>[] {BufferingSink.class}, proxy);
+ }
+
+ public static BufferingSink castAsBufferingSink(Sink sink) {
+ if (sink instanceof BufferingSink) {
+ return (BufferingSink) sink;
+ } else {
+ throw new IllegalArgumentException("The given sink is no BufferingSink but a " + sink.getClass());
+ }
+ }
+
+ @Override
+ public int getPriority() {
+ return 0;
+ }
+}
diff --git a/doxia-core/src/main/java/org/apache/maven/doxia/parser/Parser.java b/doxia-core/src/main/java/org/apache/maven/doxia/parser/Parser.java
index e09953ed..ea80bb8e 100644
--- a/doxia-core/src/main/java/org/apache/maven/doxia/parser/Parser.java
+++ b/doxia-core/src/main/java/org/apache/maven/doxia/parser/Parser.java
@@ -19,6 +19,7 @@
package org.apache.maven.doxia.parser;
import java.io.Reader;
+import java.util.Collection;
import org.apache.maven.doxia.sink.Sink;
@@ -83,4 +84,18 @@ public interface Parser {
* @return <code>true</code> (default value) if comment Doxia events are emitted
*/
boolean isEmitComments();
+
+ /**
+ * Registers a given {@link SinkWrapperFactory} with the parser used in subsequent calls of {@code parse(...)}
+ * @param factory the factory to create the sink wrapper
+ * @since 2.0.0
+ */
+ void addSinkWrapperFactory(SinkWrapperFactory factory);
+
+ /**
+ *
+ * @return all sink wrapper factories in the correct order (both registered automatically and manually)
+ * @since 2.0.0
+ */
+ Collection<SinkWrapperFactory> getSinkWrapperFactories();
}
diff --git a/doxia-core/src/main/java/org/apache/maven/doxia/parser/SinkWrapper.java b/doxia-core/src/main/java/org/apache/maven/doxia/parser/SinkWrapper.java
new file mode 100644
index 00000000..6d793e5f
--- /dev/null
+++ b/doxia-core/src/main/java/org/apache/maven/doxia/parser/SinkWrapper.java
@@ -0,0 +1,529 @@
+/*
+ * 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.
+ */
+package org.apache.maven.doxia.parser;
+
+import org.apache.maven.doxia.sink.Sink;
+import org.apache.maven.doxia.sink.SinkEventAttributes;
+import org.apache.maven.doxia.sink.impl.AbstractSink;
+
+/**
+ * By default a {@link SinkWrapper} just delegates each method to the wrapped sink's method.
+ * For certain sink methods a derived wrapper may modify the sink before/after or instead of calling the delegate's method.
+ * Sink wrappers can either be registered manually via {@link Parser#registerSinkWrapperFactory(int, SinkWrapperFactory)} or
+ * are automatically registered if provided as JSR330 component.
+ * In addition Sink wrappers can be used programmatically without an according factory.
+ * @since 2.0.0
+ */
+public class SinkWrapper extends AbstractSink {
+
+ private Sink delegate;
+
+ public SinkWrapper(Sink delegate) {
+ super();
+ this.delegate = delegate;
+ }
+
+ public Sink getWrappedSink() {
+ return delegate;
+ }
+
+ public void setWrappedSink(Sink sink) {
+ delegate = sink;
+ }
+
+ @Override
+ public void head(SinkEventAttributes attributes) {
+ delegate.head(attributes);
+ }
+
+ @Override
+ public void head_() {
+ delegate.head_();
+ }
+
+ @Override
+ public void title(SinkEventAttributes attributes) {
+ delegate.title(attributes);
+ }
+
+ @Override
+ public void title_() {
+ delegate.title_();
+ }
+
+ @Override
+ public void author(SinkEventAttributes attributes) {
+ delegate.author(attributes);
+ }
+
+ @Override
+ public void author_() {
+ delegate.author_();
+ }
+
+ @Override
+ public void date(SinkEventAttributes attributes) {
+ delegate.date(attributes);
+ }
+
+ @Override
+ public void date_() {
+ delegate.date_();
+ }
+
+ @Override
+ public void body(SinkEventAttributes attributes) {
+ delegate.body(attributes);
+ }
+
+ @Override
+ public void body_() {
+ delegate.body_();
+ }
+
+ @Override
+ public void article(SinkEventAttributes attributes) {
+ delegate.article(attributes);
+ }
+
+ @Override
+ public void article_() {
+ delegate.article_();
+ }
+
+ @Override
+ public void navigation(SinkEventAttributes attributes) {
+ delegate.navigation(attributes);
+ }
+
+ @Override
+ public void navigation_() {
+ delegate.navigation_();
+ }
+
+ @Override
+ public void sidebar(SinkEventAttributes attributes) {
+ delegate.sidebar(attributes);
+ }
+
+ @Override
+ public void sidebar_() {
+ delegate.sidebar_();
+ }
+
+ @Override
+ public void section(int level, SinkEventAttributes attributes) {
+ delegate.section(level, attributes);
+ }
+
+ @Override
+ public void section_(int level) {
+ delegate.section_(level);
+ }
+
+ @Override
+ public void sectionTitle(int level, SinkEventAttributes attributes) {
+ delegate.sectionTitle(level, attributes);
+ }
+
+ @Override
+ public void sectionTitle_(int level) {
+ delegate.sectionTitle_(level);
+ }
+
+ @Override
+ public void header(SinkEventAttributes attributes) {
+ delegate.header(attributes);
+ }
+
+ @Override
+ public void header_() {
+ delegate.header_();
+ }
+
+ @Override
+ public void content(SinkEventAttributes attributes) {
+ delegate.content(attributes);
+ }
+
+ @Override
+ public void content_() {
+ delegate.content_();
+ }
+
+ @Override
+ public void footer(SinkEventAttributes attributes) {
+ delegate.footer(attributes);
+ }
+
+ @Override
+ public void footer_() {
+ delegate.footer_();
+ }
+
+ @Override
+ public void list(SinkEventAttributes attributes) {
+ delegate.list(attributes);
+ }
+
+ @Override
+ public void list_() {
+ delegate.list_();
+ }
+
+ @Override
+ public void listItem(SinkEventAttributes attributes) {
+ delegate.listItem(attributes);
+ }
+
+ @Override
+ public void listItem_() {
+ delegate.listItem_();
+ }
+
+ @Override
+ public void numberedList(int numbering, SinkEventAttributes attributes) {
+ delegate.numberedList(numbering, attributes);
+ }
+
+ @Override
+ public void numberedList_() {
+ delegate.numberedList_();
+ }
+
+ @Override
+ public void numberedListItem(SinkEventAttributes attributes) {
+ delegate.numberedListItem(attributes);
+ }
+
+ @Override
+ public void numberedListItem_() {
+ delegate.numberedListItem_();
+ }
+
+ @Override
+ public void definitionList(SinkEventAttributes attributes) {
+ delegate.definitionList(attributes);
+ }
+
+ @Override
+ public void definitionList_() {
+ delegate.definitionList_();
+ }
+
+ @Override
+ public void definitionListItem(SinkEventAttributes attributes) {
+ delegate.definitionListItem(attributes);
+ }
+
+ @Override
+ public void definitionListItem_() {
+ delegate.definitionListItem_();
+ }
+
+ @Override
+ public void definition(SinkEventAttributes attributes) {
+ delegate.definition(attributes);
+ }
+
+ @Override
+ public void definition_() {
+ delegate.definition_();
+ }
+
+ @Override
+ public void definedTerm(SinkEventAttributes attributes) {
+ delegate.definedTerm(attributes);
+ }
+
+ @Override
+ public void definedTerm_() {
+ delegate.definedTerm_();
+ }
+
+ @Override
+ public void figure(SinkEventAttributes attributes) {
+ delegate.figure(attributes);
+ }
+
+ @Override
+ public void figure_() {
+ delegate.figure_();
+ }
+
+ @Override
+ public void figureCaption(SinkEventAttributes attributes) {
+ delegate.figureCaption(attributes);
+ }
+
+ @Override
+ public void figureCaption_() {
+ delegate.figureCaption_();
+ }
+
+ @Override
+ public void figureGraphics(String src, SinkEventAttributes attributes) {
+ delegate.figureGraphics(src, attributes);
+ }
+
+ @Override
+ public void table(SinkEventAttributes attributes) {
+ delegate.table(attributes);
+ }
+
+ @Override
+ public void table_() {
+ delegate.table_();
+ }
+
+ @Override
+ public void tableRows(int[] justification, boolean grid) {
+ delegate.tableRows(justification, grid);
+ }
+
+ @Override
+ public void tableRows_() {
+ delegate.tableRows_();
+ }
+
+ @Override
+ public void tableRow(SinkEventAttributes attributes) {
+ delegate.tableRow(attributes);
+ }
+
+ @Override
+ public void tableRow_() {
+ delegate.tableRow_();
+ }
+
+ @Override
+ public void tableCell(SinkEventAttributes attributes) {
+ delegate.tableCell(attributes);
+ }
+
+ @Override
+ public void tableCell_() {
+ delegate.tableCell_();
+ }
+
+ @Override
+ public void tableHeaderCell(SinkEventAttributes attributes) {
+ delegate.tableHeaderCell(attributes);
+ }
+
+ @Override
+ public void tableHeaderCell_() {
+ delegate.tableHeaderCell_();
+ }
+
+ @Override
+ public void tableCaption(SinkEventAttributes attributes) {
+ delegate.tableCaption(attributes);
+ }
+
+ @Override
+ public void tableCaption_() {
+ delegate.tableCaption_();
+ }
+
+ @Override
+ public void paragraph(SinkEventAttributes attributes) {
+ delegate.paragraph(attributes);
+ }
+
+ @Override
+ public void paragraph_() {
+ delegate.paragraph_();
+ }
+
+ @Override
+ public void data(String value, SinkEventAttributes attributes) {
+ delegate.data(value, attributes);
+ }
+
+ @Override
+ public void data_() {
+ delegate.data_();
+ }
+
+ @Override
+ public void time(String datetime, SinkEventAttributes attributes) {
+ delegate.time(datetime, attributes);
+ }
+
+ @Override
+ public void time_() {
+ delegate.time_();
+ }
+
+ @Override
+ public void address(SinkEventAttributes attributes) {
+ delegate.address(attributes);
+ }
+
+ @Override
+ public void address_() {
+ delegate.address_();
+ }
+
+ @Override
+ public void blockquote(SinkEventAttributes attributes) {
+ delegate.blockquote(attributes);
+ }
+
+ @Override
+ public void blockquote_() {
+ delegate.blockquote_();
+ }
+
+ @Override
+ public void division(SinkEventAttributes attributes) {
+ delegate.division(attributes);
+ }
+
+ @Override
+ public void division_() {
+ delegate.division_();
+ }
+
+ @Override
+ public void verbatim(SinkEventAttributes attributes) {
+ delegate.verbatim(attributes);
+ }
+
+ @Override
+ public void verbatim_() {
+ delegate.verbatim_();
+ }
+
+ @Override
+ public void horizontalRule(SinkEventAttributes attributes) {
+ delegate.horizontalRule(attributes);
+ }
+
+ @Override
+ public void pageBreak() {
+ delegate.pageBreak();
+ }
+
+ @Override
+ public void anchor(String name, SinkEventAttributes attributes) {
+ delegate.anchor(name, attributes);
+ }
+
+ @Override
+ public void anchor_() {
+ delegate.anchor_();
+ }
+
+ @Override
+ public void link(String name, SinkEventAttributes attributes) {
+ delegate.link(name, attributes);
+ }
+
+ @Override
+ public void link_() {
+ delegate.link_();
+ }
+
+ @Override
+ public void inline(SinkEventAttributes attributes) {
+ delegate.inline(attributes);
+ }
+
+ @Override
+ public void inline_() {
+ delegate.inline_();
+ }
+
+ @Override
+ public void italic() {
+ delegate.italic();
+ }
+
+ @Override
+ public void italic_() {
+ delegate.italic_();
+ }
+
+ @Override
+ public void bold() {
+ delegate.bold();
+ }
+
+ @Override
+ public void bold_() {
+ delegate.bold_();
+ }
+
+ @Override
+ public void monospaced() {
+ delegate.monospaced();
+ }
+
+ @Override
+ public void monospaced_() {
+ delegate.monospaced_();
+ }
+
+ @Override
+ public void lineBreak(SinkEventAttributes attributes) {
+ delegate.lineBreak(attributes);
+ }
+
+ @Override
+ public void lineBreakOpportunity(SinkEventAttributes attributes) {
+ delegate.lineBreakOpportunity(attributes);
+ }
+
+ @Override
+ public void nonBreakingSpace() {
+ delegate.nonBreakingSpace();
+ }
+
+ @Override
+ public void text(String text, SinkEventAttributes attributes) {
+ delegate.text(text, attributes);
+ }
+
+ @Override
+ public void rawText(String text) {
+ delegate.rawText(text);
+ }
+
+ @Override
+ public void comment(String comment) {
+ delegate.comment(comment);
+ }
+
+ @Override
+ public void unknown(String name, Object[] requiredParams, SinkEventAttributes attributes) {
+ delegate.unknown(name, requiredParams, attributes);
+ }
+
+ @Override
+ public void flush() {
+ delegate.flush();
+ }
+
+ @Override
+ public void close() {
+ delegate.close();
+ }
+}
diff --git a/doxia-core/src/main/java/org/apache/maven/doxia/parser/SinkWrapperFactory.java b/doxia-core/src/main/java/org/apache/maven/doxia/parser/SinkWrapperFactory.java
new file mode 100644
index 00000000..c6082c17
--- /dev/null
+++ b/doxia-core/src/main/java/org/apache/maven/doxia/parser/SinkWrapperFactory.java
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+package org.apache.maven.doxia.parser;
+
+import org.apache.maven.doxia.sink.Sink;
+
+/**
+ * A factory for a sink wrapping another sink.
+ * The delegate may either be the original sink or another wrapper.
+ * @since 2.0.0
+ */
+public interface SinkWrapperFactory {
+
+ /**
+ * By default all wrappers just delegate each method to the wrapped sink's method.
+ * For certain Sink methods the wrapper may modify the sink before/after or instead of calling the delegate's method.
+ * @param sink the delegate
+ * @return a new sink wrapping the given one
+ */
+ Sink createWrapper(Sink sink);
+
+ /**
+ * Determines the order of sink wrappers. The wrapper factory with the highest priority is called first.
+ * @return the priority of this factory
+ */
+ int getPriority();
+}
diff --git a/doxia-core/src/main/java/org/apache/maven/doxia/sink/impl/RandomAccessSink.java b/doxia-core/src/main/java/org/apache/maven/doxia/sink/impl/RandomAccessSink.java
index f35d030a..6de18e69 100644
--- a/doxia-core/src/main/java/org/apache/maven/doxia/sink/impl/RandomAccessSink.java
+++ b/doxia-core/src/main/java/org/apache/maven/doxia/sink/impl/RandomAccessSink.java
@@ -26,8 +26,8 @@ import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
+import org.apache.maven.doxia.parser.SinkWrapper;
import org.apache.maven.doxia.sink.Sink;
-import org.apache.maven.doxia.sink.SinkEventAttributes;
import org.apache.maven.doxia.sink.SinkFactory;
/**
@@ -39,7 +39,7 @@ import org.apache.maven.doxia.sink.SinkFactory;
* @author Robert Scholte
* @since 1.3
*/
-public class RandomAccessSink implements Sink {
+public class RandomAccessSink extends SinkWrapper {
private SinkFactory sinkFactory;
private String encoding;
@@ -62,10 +62,10 @@ public class RandomAccessSink implements Sink {
* @throws java.io.IOException if any.
*/
public RandomAccessSink(SinkFactory sinkFactory, OutputStream stream) throws IOException {
+ super(sinkFactory.createSink(stream));
this.sinkFactory = sinkFactory;
this.coreOutputStream = stream;
- this.currentSink = sinkFactory.createSink(stream);
- this.coreSink = this.currentSink;
+ this.coreSink = getWrappedSink();
}
/**
@@ -77,11 +77,11 @@ public class RandomAccessSink implements Sink {
* @throws java.io.IOException if any.
*/
public RandomAccessSink(SinkFactory sinkFactory, OutputStream stream, String encoding) throws IOException {
+ super(sinkFactory.createSink(stream, encoding));
this.sinkFactory = sinkFactory;
this.coreOutputStream = stream;
this.encoding = encoding;
- this.currentSink = sinkFactory.createSink(stream, encoding);
- this.coreSink = this.currentSink;
+ this.coreSink = getWrappedSink();
}
/**
@@ -93,10 +93,12 @@ public class RandomAccessSink implements Sink {
* @throws java.io.IOException if any.
*/
public RandomAccessSink(SinkFactory sinkFactory, File outputDirectory, String outputName) throws IOException {
+ super(null);
this.sinkFactory = sinkFactory;
this.coreOutputStream = new FileOutputStream(new File(outputDirectory, outputName));
this.currentSink = sinkFactory.createSink(coreOutputStream);
this.coreSink = this.currentSink;
+ setWrappedSink(currentSink);
}
/**
@@ -110,29 +112,13 @@ public class RandomAccessSink implements Sink {
*/
public RandomAccessSink(SinkFactory sinkFactory, File outputDirectory, String outputName, String encoding)
throws IOException {
+ super(null);
this.sinkFactory = sinkFactory;
this.coreOutputStream = new FileOutputStream(new File(outputDirectory, outputName));
this.encoding = encoding;
this.currentSink = sinkFactory.createSink(coreOutputStream, encoding);
this.coreSink = this.currentSink;
- }
-
- /** {@inheritDoc} */
- @Override
- public void address() {
- currentSink.address();
- }
-
- /** {@inheritDoc} */
- @Override
- public void address(SinkEventAttributes attributes) {
- currentSink.address(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void address_() {
- currentSink.address_();
+ setWrappedSink(currentSink);
}
/**
@@ -159,114 +145,13 @@ public class RandomAccessSink implements Sink {
}
sinks.add(subSink);
sinks.add(currentSink);
+ setWrappedSink(currentSink);
} catch (IOException e) {
// IOException can only be caused by our own ByteArrayOutputStream
}
return subSink;
}
- /** {@inheritDoc} */
- @Override
- public void anchor(String name) {
- currentSink.anchor(name);
- }
-
- /** {@inheritDoc} */
- @Override
- public void anchor(String name, SinkEventAttributes attributes) {
- currentSink.anchor(name, attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void anchor_() {
- currentSink.anchor_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void article() {
- currentSink.article();
- }
-
- /** {@inheritDoc} */
- @Override
- public void article(SinkEventAttributes attributes) {
- currentSink.article(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void article_() {
- currentSink.article_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void author() {
- currentSink.author();
- }
-
- /** {@inheritDoc} */
- @Override
- public void author(SinkEventAttributes attributes) {
- currentSink.author(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void author_() {
- currentSink.author_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void blockquote() {
- currentSink.blockquote();
- }
-
- /** {@inheritDoc} */
- @Override
- public void blockquote(SinkEventAttributes attributes) {
- currentSink.blockquote(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void blockquote_() {
- currentSink.blockquote_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void body() {
- currentSink.body();
- }
-
- /** {@inheritDoc} */
- @Override
- public void body(SinkEventAttributes attributes) {
- currentSink.body(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void body_() {
- currentSink.body_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void bold() {
- currentSink.bold();
- }
-
- /** {@inheritDoc} */
- @Override
- public void bold_() {
- currentSink.bold_();
- }
-
/**
* Close all sinks
*/
@@ -278,204 +163,6 @@ public class RandomAccessSink implements Sink {
coreSink.close();
}
- /** {@inheritDoc} */
- @Override
- public void comment(String comment) {
- currentSink.comment(comment);
- }
-
- /** {@inheritDoc} */
- @Override
- public void content() {
- currentSink.content();
- }
-
- /** {@inheritDoc} */
- @Override
- public void content(SinkEventAttributes attributes) {
- currentSink.content(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void content_() {
- currentSink.content_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void data(String value) {
- currentSink.data(value);
- }
-
- /** {@inheritDoc} */
- @Override
- public void data(String value, SinkEventAttributes attributes) {
- currentSink.data(value, attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void data_() {
- currentSink.data_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void date() {
- currentSink.date();
- }
-
- /** {@inheritDoc} */
- @Override
- public void date(SinkEventAttributes attributes) {
- currentSink.date(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void date_() {
- currentSink.date_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void definedTerm() {
- currentSink.definedTerm();
- }
-
- /** {@inheritDoc} */
- @Override
- public void definedTerm(SinkEventAttributes attributes) {
- currentSink.definedTerm(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void definedTerm_() {
- currentSink.definedTerm_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void definition() {
- currentSink.definition();
- }
-
- /** {@inheritDoc} */
- @Override
- public void definition(SinkEventAttributes attributes) {
- currentSink.definition(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void definitionList() {
- currentSink.definitionList();
- }
-
- /** {@inheritDoc} */
- @Override
- public void definitionList(SinkEventAttributes attributes) {
- currentSink.definitionList(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void definitionListItem() {
- currentSink.definitionListItem();
- }
-
- /** {@inheritDoc} */
- @Override
- public void definitionListItem(SinkEventAttributes attributes) {
- currentSink.definitionListItem(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void definitionListItem_() {
- currentSink.definitionListItem_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void definitionList_() {
- currentSink.definitionList_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void definition_() {
- currentSink.definition_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void division() {
- currentSink.division();
- }
-
- /** {@inheritDoc} */
- @Override
- public void division(SinkEventAttributes attributes) {
- currentSink.division(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void division_() {
- currentSink.division_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void figure() {
- currentSink.figure();
- }
-
- /** {@inheritDoc} */
- @Override
- public void figure(SinkEventAttributes attributes) {
- currentSink.figure(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void figureCaption() {
- currentSink.figureCaption();
- }
-
- /** {@inheritDoc} */
- @Override
- public void figureCaption(SinkEventAttributes attributes) {
- currentSink.figureCaption(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void figureCaption_() {
- currentSink.figureCaption_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void figureGraphics(String name) {
- currentSink.figureGraphics(name);
- }
-
- /** {@inheritDoc} */
- @Override
- public void figureGraphics(String src, SinkEventAttributes attributes) {
- currentSink.figureGraphics(src, attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void figure_() {
- currentSink.figure_();
- }
-
/**
* Flush all sinks
*/
@@ -495,634 +182,4 @@ public class RandomAccessSink implements Sink {
}
coreSink.flush();
}
-
- /** {@inheritDoc} */
- @Override
- public void footer() {
- currentSink.footer();
- }
-
- /** {@inheritDoc} */
- @Override
- public void footer(SinkEventAttributes attributes) {
- currentSink.footer(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void footer_() {
- currentSink.footer_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void head() {
- currentSink.head();
- }
-
- /** {@inheritDoc} */
- @Override
- public void head(SinkEventAttributes attributes) {
- currentSink.head(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void head_() {
- currentSink.head_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void header() {
- currentSink.header();
- }
-
- /** {@inheritDoc} */
- @Override
- public void header(SinkEventAttributes attributes) {
- currentSink.header(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void header_() {
- currentSink.header_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void horizontalRule() {
- currentSink.horizontalRule();
- }
-
- /** {@inheritDoc} */
- @Override
- public void horizontalRule(SinkEventAttributes attributes) {
- currentSink.horizontalRule(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void inline() {
- currentSink.inline();
- }
-
- /** {@inheritDoc} */
- @Override
- public void inline(SinkEventAttributes attributes) {
- currentSink.inline(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void inline_() {
- currentSink.inline_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void italic() {
- currentSink.italic();
- }
-
- /** {@inheritDoc} */
- @Override
- public void italic_() {
- currentSink.italic_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void lineBreak() {
- currentSink.lineBreak();
- }
-
- /** {@inheritDoc} */
- @Override
- public void lineBreak(SinkEventAttributes attributes) {
- currentSink.lineBreak(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void lineBreakOpportunity() {
- currentSink.lineBreakOpportunity();
- }
-
- /** {@inheritDoc} */
- @Override
- public void lineBreakOpportunity(SinkEventAttributes attributes) {
- currentSink.lineBreakOpportunity(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void link(String name) {
- currentSink.link(name);
- }
-
- /** {@inheritDoc} */
- @Override
- public void link(String name, SinkEventAttributes attributes) {
- currentSink.link(name, attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void link_() {
- currentSink.link_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void list() {
- currentSink.list();
- }
-
- /** {@inheritDoc} */
- @Override
- public void list(SinkEventAttributes attributes) {
- currentSink.list(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void listItem() {
- currentSink.listItem();
- }
-
- /** {@inheritDoc} */
- @Override
- public void listItem(SinkEventAttributes attributes) {
- currentSink.listItem(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void listItem_() {
- currentSink.listItem_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void list_() {
- currentSink.list_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void monospaced() {
- currentSink.monospaced();
- }
-
- /** {@inheritDoc} */
- @Override
- public void monospaced_() {
- currentSink.monospaced_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void navigation() {
- currentSink.navigation();
- }
-
- /** {@inheritDoc} */
- @Override
- public void navigation(SinkEventAttributes attributes) {
- currentSink.navigation(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void navigation_() {
- currentSink.navigation_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void nonBreakingSpace() {
- currentSink.nonBreakingSpace();
- }
-
- /** {@inheritDoc} */
- @Override
- public void numberedList(int numbering) {
- currentSink.numberedList(numbering);
- }
-
- /** {@inheritDoc} */
- @Override
- public void numberedList(int numbering, SinkEventAttributes attributes) {
- currentSink.numberedList(numbering, attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void numberedListItem() {
- currentSink.numberedListItem();
- }
-
- /** {@inheritDoc} */
- @Override
- public void numberedListItem(SinkEventAttributes attributes) {
- currentSink.numberedListItem(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void numberedListItem_() {
- currentSink.numberedListItem_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void numberedList_() {
- currentSink.numberedList_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void pageBreak() {
- currentSink.pageBreak();
- }
-
- /** {@inheritDoc} */
- @Override
- public void paragraph() {
- currentSink.paragraph();
- }
-
- /** {@inheritDoc} */
- @Override
- public void paragraph(SinkEventAttributes attributes) {
- currentSink.paragraph(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void paragraph_() {
- currentSink.paragraph_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void rawText(String text) {
- currentSink.rawText(text);
- }
-
- /** {@inheritDoc} */
- @Override
- public void section(int level, SinkEventAttributes attributes) {
- currentSink.section(level, attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void section1() {
- currentSink.section1();
- }
-
- /** {@inheritDoc} */
- @Override
- public void section1_() {
- currentSink.section1_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void section2() {
- currentSink.section2();
- }
-
- /** {@inheritDoc} */
- @Override
- public void section2_() {
- currentSink.section2_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void section3() {
- currentSink.section3();
- }
-
- /** {@inheritDoc} */
- @Override
- public void section3_() {
- currentSink.section3_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void section4() {
- currentSink.section4();
- }
-
- /** {@inheritDoc} */
- @Override
- public void section4_() {
- currentSink.section4_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void section5() {
- currentSink.section5();
- }
-
- /** {@inheritDoc} */
- @Override
- public void section5_() {
- currentSink.section5_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void sectionTitle() {
- currentSink.sectionTitle();
- }
-
- /** {@inheritDoc} */
- @Override
- public void sectionTitle(int level, SinkEventAttributes attributes) {
- currentSink.sectionTitle(level, attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void sectionTitle1() {
- currentSink.sectionTitle1();
- }
-
- /** {@inheritDoc} */
- @Override
- public void sectionTitle1_() {
- currentSink.sectionTitle1_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void sectionTitle2() {
- currentSink.sectionTitle2();
- }
-
- /** {@inheritDoc} */
- @Override
- public void sectionTitle2_() {
- currentSink.sectionTitle2_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void sectionTitle3() {
- currentSink.sectionTitle3();
- }
-
- /** {@inheritDoc} */
- @Override
- public void sectionTitle3_() {
- currentSink.sectionTitle3_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void sectionTitle4() {
- currentSink.sectionTitle4();
- }
-
- /** {@inheritDoc} */
- @Override
- public void sectionTitle4_() {
- currentSink.sectionTitle4_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void sectionTitle5() {
- currentSink.sectionTitle5();
- }
-
- /** {@inheritDoc} */
- @Override
- public void sectionTitle5_() {
- currentSink.sectionTitle5_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void sectionTitle_() {
- currentSink.sectionTitle_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void sectionTitle_(int level) {
- currentSink.sectionTitle_(level);
- }
-
- /** {@inheritDoc} */
- @Override
- public void section_(int level) {
- currentSink.section_(level);
- }
-
- /** {@inheritDoc} */
- @Override
- public void sidebar() {
- currentSink.sidebar();
- }
-
- /** {@inheritDoc} */
- @Override
- public void sidebar(SinkEventAttributes attributes) {
- currentSink.sidebar(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void sidebar_() {
- currentSink.sidebar_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void table() {
- currentSink.table();
- }
-
- /** {@inheritDoc} */
- @Override
- public void table(SinkEventAttributes attributes) {
- currentSink.table(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void tableCaption() {
- currentSink.tableCaption();
- }
-
- /** {@inheritDoc} */
- @Override
- public void tableCaption(SinkEventAttributes attributes) {
- currentSink.tableCaption(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void tableCaption_() {
- currentSink.tableCaption_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void tableCell() {
- currentSink.tableCell();
- }
-
- /** {@inheritDoc} */
- @Override
- public void tableCell(SinkEventAttributes attributes) {
- currentSink.tableCell(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void tableCell_() {
- currentSink.tableCell_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void tableHeaderCell() {
- currentSink.tableHeaderCell();
- }
-
- /** {@inheritDoc} */
- @Override
- public void tableHeaderCell(SinkEventAttributes attributes) {
- currentSink.tableHeaderCell(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void tableHeaderCell_() {
- currentSink.tableHeaderCell_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void tableRow() {
- currentSink.tableRow();
- }
-
- /** {@inheritDoc} */
- @Override
- public void tableRow(SinkEventAttributes attributes) {
- currentSink.tableRow(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void tableRow_() {
- currentSink.tableRow_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void tableRows() {
- currentSink.tableRows();
- }
-
- /** {@inheritDoc} */
- @Override
- public void tableRows(int[] justification, boolean grid) {
- currentSink.tableRows(justification, grid);
- }
-
- /** {@inheritDoc} */
- @Override
- public void tableRows_() {
- currentSink.tableRows_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void table_() {
- currentSink.table_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void text(String text) {
- currentSink.text(text);
- }
-
- /** {@inheritDoc} */
- @Override
- public void text(String text, SinkEventAttributes attributes) {
- currentSink.text(text, attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void time(String datetime) {
- currentSink.time(datetime);
- }
-
- /** {@inheritDoc} */
- @Override
- public void time(String datetime, SinkEventAttributes attributes) {
- currentSink.time(datetime, attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void time_() {
- currentSink.time_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void title() {
- currentSink.title();
- }
-
- /** {@inheritDoc} */
- @Override
- public void title(SinkEventAttributes attributes) {
- currentSink.title(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void title_() {
- currentSink.title_();
- }
-
- /** {@inheritDoc} */
- @Override
- public void unknown(String name, Object[] requiredParams, SinkEventAttributes attributes) {
- currentSink.unknown(name, requiredParams, attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void verbatim() {
- currentSink.verbatim();
- }
-
- /** {@inheritDoc} */
- @Override
- public void verbatim(SinkEventAttributes attributes) {
- currentSink.verbatim(attributes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void verbatim_() {
- currentSink.verbatim_();
- }
}
diff --git a/doxia-core/src/main/java/org/apache/maven/doxia/sink/impl/SinkWrapperFactoryComparator.java b/doxia-core/src/main/java/org/apache/maven/doxia/sink/impl/SinkWrapperFactoryComparator.java
new file mode 100644
index 00000000..c3c8149b
--- /dev/null
+++ b/doxia-core/src/main/java/org/apache/maven/doxia/sink/impl/SinkWrapperFactoryComparator.java
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+package org.apache.maven.doxia.sink.impl;
+
+import java.util.Comparator;
+
+import org.apache.maven.doxia.parser.SinkWrapperFactory;
+
+/** Sorts the given {@link SinkWrapperFactory}s so that the one with the highest rank comes first (i.e. order by descending ranking) */
+public class SinkWrapperFactoryComparator implements Comparator<SinkWrapperFactory> {
+
+ @Override
+ public int compare(SinkWrapperFactory o1, SinkWrapperFactory o2) {
+
+ return Integer.compare(o2.getPriority(), o1.getPriority());
+ }
+}
diff --git a/doxia-core/src/test/java/org/apache/maven/doxia/parser/AbstractParserTest.java b/doxia-core/src/test/java/org/apache/maven/doxia/parser/AbstractParserTest.java
index 5e1ffbd4..1db75f50 100644
--- a/doxia-core/src/test/java/org/apache/maven/doxia/parser/AbstractParserTest.java
+++ b/doxia-core/src/test/java/org/apache/maven/doxia/parser/AbstractParserTest.java
@@ -20,11 +20,13 @@ package org.apache.maven.doxia.parser;
import java.io.IOException;
import java.io.Reader;
+import java.io.StringWriter;
import java.io.Writer;
import java.util.Iterator;
import org.apache.maven.doxia.AbstractModuleTest;
import org.apache.maven.doxia.sink.Sink;
+import org.apache.maven.doxia.sink.SinkEventAttributes;
import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet;
import org.apache.maven.doxia.sink.impl.SinkEventElement;
import org.apache.maven.doxia.sink.impl.TextSink;
@@ -96,18 +98,69 @@ public abstract class AbstractParserTest extends AbstractModuleTest {
}
}
- protected static void assertSinkEquals(SinkEventElement element, String name, Object... args) {
+ @Test
+ public final void testSinkWrapper() throws ParseException, IOException {
+ Parser parser = createParser();
+
+ parser.addSinkWrapperFactory(new SinkWrapperFactory() {
+
+ @Override
+ public Sink createWrapper(Sink sink) {
+ return new SinkWrapper(sink) {
+
+ @Override
+ public void text(String text, SinkEventAttributes attributes) {
+ super.text("beforeWrapper1" + text + "afterWrapper1", attributes);
+ }
+ };
+ }
+
+ @Override
+ public int getPriority() {
+ return 0;
+ }
+ });
+
+ parser.addSinkWrapperFactory(new SinkWrapperFactory() {
+
+ @Override
+ public Sink createWrapper(Sink sink) {
+ return new SinkWrapper(sink) {
+ @Override
+ public void text(String text, SinkEventAttributes attributes) {
+ super.text("beforeWrapper2" + text + "afterWrapper2", attributes);
+ }
+ };
+ }
+
+ @Override
+ public int getPriority() {
+ return 1;
+ }
+ });
+ try (StringWriter writer = new StringWriter();
+ Reader reader = getTestReader("test", outputExtension())) {
+ Sink sink = new TextSink(writer);
+ parser.parse(reader, sink);
+
+ // assert order of sink wrappers
+ assertTrue(writer.toString().contains("beforeWrapper2beforeWrapper1"));
+ assertTrue(writer.toString().contains("afterWrapper1afterWrapper2"));
+ }
+ }
+
+ public static void assertSinkEquals(SinkEventElement element, String name, Object... args) {
Assertions.assertEquals(name, element.getName(), "Name of element doesn't match");
Assertions.assertArrayEquals(args, element.getArgs(), "Arguments don't match");
}
- protected static void assertSinkAttributeEquals(SinkEventElement element, String name, String attr, String value) {
+ public static void assertSinkAttributeEquals(SinkEventElement element, String name, String attr, String value) {
Assertions.assertEquals(name, element.getName());
SinkEventAttributeSet atts = (SinkEventAttributeSet) element.getArgs()[0];
Assertions.assertEquals(value, atts.getAttribute(attr));
}
- protected static void assertSinkEquals(Iterator<SinkEventElement> it, String... names) {
+ public static void assertSinkEquals(Iterator<SinkEventElement> it, String... names) {
StringBuilder expected = new StringBuilder();
StringBuilder actual = new StringBuilder();
@@ -122,7 +175,7 @@ public abstract class AbstractParserTest extends AbstractModuleTest {
Assertions.assertEquals(expected.toString(), actual.toString());
}
- protected static void assertSinkStartsWith(Iterator<SinkEventElement> it, String... names) {
+ public static void assertSinkStartsWith(Iterator<SinkEventElement> it, String... names) {
StringBuilder expected = new StringBuilder();
StringBuilder actual = new StringBuilder();
diff --git a/doxia-modules/doxia-module-apt/src/main/java/org/apache/maven/doxia/module/apt/AptParser.java b/doxia-modules/doxia-module-apt/src/main/java/org/apache/maven/doxia/module/apt/AptParser.java
index 36990f7a..1df6a41c 100644
--- a/doxia-modules/doxia-module-apt/src/main/java/org/apache/maven/doxia/module/apt/AptParser.java
+++ b/doxia-modules/doxia-module-apt/src/main/java/org/apache/maven/doxia/module/apt/AptParser.java
@@ -199,7 +199,7 @@ public class AptParser extends AbstractTextParser implements AptMarkup {
try {
this.source = new AptReaderSource(new StringReader(sourceContent), reference);
- this.sink = sink;
+ this.sink = getWrappedSink(sink);
blockFileName = null;
diff --git a/doxia-modules/doxia-module-fml/src/main/java/org/apache/maven/doxia/module/fml/FmlParser.java b/doxia-modules/doxia-module-fml/src/main/java/org/apache/maven/doxia/module/fml/FmlParser.java
index c1dd98cd..559d3f2a 100644
--- a/doxia-modules/doxia-module-fml/src/main/java/org/apache/maven/doxia/module/fml/FmlParser.java
+++ b/doxia-modules/doxia-module-fml/src/main/java/org/apache/maven/doxia/module/fml/FmlParser.java
@@ -105,7 +105,7 @@ public class FmlParser extends AbstractXmlParser implements FmlMarkup {
// this populates faqs
super.parse(tmp, sink, reference);
- writeFaqs(sink);
+ writeFaqs(getWrappedSink(sink));
} finally {
this.faqs = null;
this.sourceContent = null;
diff --git a/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownParser.java b/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownParser.java
index 610f4dc4..9c229ccf 100644
--- a/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownParser.java
+++ b/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownParser.java
@@ -172,7 +172,7 @@ public class MarkdownParser extends AbstractTextParser implements TextMarkup {
String html = toHtml(source);
// then HTML to Sink API
- parser.parse(html, sink);
+ parser.parse(html, getWrappedSink(sink));
} catch (IOException e) {
throw new ParseException("Failed reading Markdown source document", e);
}