Skip to content

Commit a4ca31f

Browse files
authored
XRENDERING-660: Get rid of the dependency on the xdom+xml syntax (#230)
* Pass the label via an XDOM instance instead of rendering/parsing to xdom+xml syntax. * Remove the dependency on the xdom+xml syntax as it isn't needed anymore. * Move the reference type detection into the XWikiReferenceTagHandler to simplify XHTMLXWikiGeneratorListener.
1 parent 15017cd commit a4ca31f

7 files changed

Lines changed: 127 additions & 144 deletions

File tree

xwiki-rendering-syntaxes/xwiki-rendering-syntax-xhtml/pom.xml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,6 @@
4444
<artifactId>xwiki-rendering-syntax-wikimodel</artifactId>
4545
<version>${project.version}</version>
4646
</dependency>
47-
<!-- Runtime dependency -->
48-
<!-- TODO: That's very bad and should be fixed by https://jira.xwiki.org/browse/XRENDERING-83 -->
49-
<dependency>
50-
<groupId>org.xwiki.rendering</groupId>
51-
<artifactId>xwiki-rendering-syntax-xdomxmlcurrent</artifactId>
52-
<version>${project.version}</version>
53-
</dependency>
5447
<!-- Test Dependencies -->
5548
<dependency>
5649
<groupId>org.xwiki.rendering</groupId>

xwiki-rendering-syntaxes/xwiki-rendering-syntax-xhtml/src/main/java/org/xwiki/rendering/internal/parser/xhtml/XHTMLParser.java

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,11 @@
4747
import org.xwiki.rendering.parser.ParseException;
4848
import org.xwiki.rendering.parser.ResourceReferenceParser;
4949
import org.xwiki.rendering.parser.StreamParser;
50-
import org.xwiki.rendering.renderer.PrintRendererFactory;
5150
import org.xwiki.rendering.syntax.Syntax;
5251
import org.xwiki.rendering.util.IdGenerator;
5352
import org.xwiki.rendering.wikimodel.IWikiParser;
5453
import org.xwiki.rendering.wikimodel.xhtml.XhtmlParser;
5554
import org.xwiki.rendering.wikimodel.xhtml.handler.TagHandler;
56-
import org.xwiki.rendering.wikimodel.xhtml.impl.TagStack;
5755
import org.xwiki.xml.XMLReaderFactory;
5856

5957
import static org.xwiki.rendering.internal.xhtml.XHTML10SyntaxProvider.XHTML_1_0;
@@ -69,20 +67,6 @@
6967
@Singleton
7068
public class XHTMLParser extends AbstractWikiModelParser
7169
{
72-
/**
73-
* The parser used for the link label parsing. For (x)html parsing, this will be an xwiki 2.0 parser, since it's
74-
* more convenient to pass link labels in xwiki syntax. See referred resource for more details.
75-
*
76-
* @see XWikiCommentHandler#handleLinkCommentStop(TagStack)
77-
*/
78-
@Inject
79-
@Named("xdom+xml/current")
80-
private StreamParser xmlParser;
81-
82-
@Inject
83-
@Named("xdom+xml/current")
84-
private PrintRendererFactory xmlRenderer;
85-
8670
/**
8771
* @see #getLinkReferenceParser()
8872
*/
@@ -127,7 +111,7 @@ public Syntax getSyntax()
127111
@Override
128112
public StreamParser getLinkLabelParser()
129113
{
130-
return this.xmlParser;
114+
return null;
131115
}
132116

133117
@Override
@@ -142,7 +126,7 @@ public IWikiParser createWikiModelParser() throws ParseException
142126
handlers.put("h4", handler);
143127
handlers.put("h5", handler);
144128
handlers.put("h6", handler);
145-
handlers.put("a", new XWikiReferenceTagHandler(this, this.xmlRenderer));
129+
handlers.put("a", new XWikiReferenceTagHandler(this));
146130
handlers.put("img", new XWikiImageTagHandler());
147131
handlers.put("span", new XWikiSpanTagHandler(this.componentManager, this));
148132
// Change the class value indicating that the division is an embedded document. We do this in order to be
@@ -153,8 +137,8 @@ public IWikiParser createWikiModelParser() throws ParseException
153137

154138
XhtmlParser parser = new XhtmlParser();
155139
parser.setExtraHandlers(handlers);
156-
parser.setCommentHandler(new XWikiCommentHandler(this.componentManager, this,
157-
this.xmlRenderer, this.xhtmlMarkerResourceReferenceParser));
140+
parser.setCommentHandler(
141+
new XWikiCommentHandler(this.componentManager, this, this.xhtmlMarkerResourceReferenceParser));
158142

159143
// Construct our own XML filter chain since we want to use our own Comment filter.
160144
try {

xwiki-rendering-syntaxes/xwiki-rendering-syntax-xhtml/src/main/java/org/xwiki/rendering/internal/parser/xhtml/wikimodel/XHTMLXWikiGeneratorListener.java

Lines changed: 21 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,14 @@
2020
package org.xwiki.rendering.internal.parser.xhtml.wikimodel;
2121

2222
import java.util.Map;
23-
import java.util.regex.Matcher;
24-
import java.util.regex.Pattern;
2523

2624
import org.apache.commons.lang3.tuple.Pair;
25+
import org.xwiki.rendering.block.Block;
2726
import org.xwiki.rendering.internal.parser.wikimodel.DefaultXWikiGeneratorListener;
27+
import org.xwiki.rendering.listener.InlineFilterListener;
2828
import org.xwiki.rendering.listener.Listener;
2929
import org.xwiki.rendering.listener.MetaData;
3030
import org.xwiki.rendering.listener.reference.ResourceReference;
31-
import org.xwiki.rendering.listener.reference.ResourceType;
3231
import org.xwiki.rendering.parser.ResourceReferenceParser;
3332
import org.xwiki.rendering.parser.StreamParser;
3433
import org.xwiki.rendering.renderer.PrintRendererFactory;
@@ -61,16 +60,6 @@ public class XHTMLXWikiGeneratorListener extends DefaultXWikiGeneratorListener
6160
*/
6261
public static final String METADATA_ATTRIBUTE_PREFIX = "data-xwiki-";
6362

64-
/**
65-
* URL matching pattern.
66-
*/
67-
private static final Pattern URL_SCHEME_PATTERN = Pattern.compile("[a-zA-Z0-9+.-]*://");
68-
69-
/**
70-
* Prefix for mailto-links.
71-
*/
72-
private static final String MAILTO_PREFIX = "mailto:";
73-
7463
private static final String CLASS_ATTRIBUTE = "class";
7564

7665
/**
@@ -93,32 +82,34 @@ public XHTMLXWikiGeneratorListener(StreamParser parser, Listener listener,
9382
@Override
9483
public void onReference(WikiReference reference)
9584
{
96-
// We need to handle 2 cases:
97-
// - when the passed reference is an instance of XWikiWikiReference, i.e. when a XHTML comment defining a XWiki
98-
// link has been specified and the XHTML parser has recognized it and thus is passing a typed reference to us.
99-
// - when the passed reference is not an instance of XWikiWikiReference which will happen if there's no special
100-
// XHTML comment defining a XWiki link. In this case, we need to figure out what how to consider the passed
101-
// reference.
85+
// We only support XWikiWikiReference as the XHTML parser never passes anything else to onReference.
10286

103-
ResourceReference resourceReference;
104-
boolean isFreeStanding;
10587
if (!(reference instanceof XWikiWikiReference)) {
106-
resourceReference = computeResourceReference(reference.getLink());
107-
isFreeStanding = false;
108-
} else {
109-
XWikiWikiReference xwikiReference = (XWikiWikiReference) reference;
110-
resourceReference = xwikiReference.getReference();
111-
isFreeStanding = xwikiReference.isFreeStanding();
112-
113-
flushFormat();
88+
throw new IllegalArgumentException("Expected XWikiWikiReference but got another type!");
11489
}
11590

91+
XWikiWikiReference xwikiReference = (XWikiWikiReference) reference;
92+
ResourceReference resourceReference = xwikiReference.getReference();
93+
boolean isFreeStanding = xwikiReference.isFreeStanding();
94+
Block labelXDOM = xwikiReference.getLabelXDOM();
95+
96+
flushFormat();
97+
11698
// Consider query string and anchor as ResourceReference parameters and the rest as generic parameters
11799
Pair<Map<String, String>, Map<String, String>> parameters =
118100
convertAndSeparateParameters(reference.getParameters());
119101

120102
resourceReference.setParameters(parameters.getLeft());
121-
onReference(resourceReference, reference.getLabel(), isFreeStanding, parameters.getRight(), false);
103+
104+
getListener().beginLink(resourceReference, isFreeStanding, parameters.getRight());
105+
106+
if (labelXDOM != null) {
107+
InlineFilterListener inlineFilterListener = new InlineFilterListener();
108+
inlineFilterListener.setWrappedListener(getListener());
109+
labelXDOM.traverse(inlineFilterListener);
110+
}
111+
112+
getListener().endLink(resourceReference, isFreeStanding, parameters.getRight());
122113
}
123114

124115
@Override
@@ -142,40 +133,6 @@ public void onImage(WikiReference reference)
142133
}
143134
}
144135

145-
/**
146-
* Recognize the passed reference and figure out what type of link it should be:
147-
* <ul>
148-
* <li>UC1: the reference points to a valid URL, we return a reference of type "url",
149-
* e.g. {@code http://server/path/reference#anchor}</li>
150-
* <li>UC2: the reference is a mailto: link, we return a reference of type "mailto",
151-
* e.g., {@code mailto:user@example.com}</li>
152-
* <li>UC3: the reference is not a valid URL, we return a reference of type "path",
153-
* e.g. {@code path/reference#anchor}</li>
154-
* </ul>
155-
*
156-
* @param rawReference the full reference (e.g. "/some/path/something#other")
157-
* @return the properly typed {@link ResourceReference} matching the use cases
158-
*/
159-
private ResourceReference computeResourceReference(String rawReference)
160-
{
161-
ResourceReference reference;
162-
163-
// Do we have a valid URL?
164-
Matcher matcher = URL_SCHEME_PATTERN.matcher(rawReference);
165-
if (matcher.lookingAt()) {
166-
// We have UC1
167-
reference = new ResourceReference(rawReference, ResourceType.URL);
168-
} else if (rawReference.startsWith(MAILTO_PREFIX)) {
169-
// We have UC2
170-
reference = new ResourceReference(rawReference.substring(MAILTO_PREFIX.length()), ResourceType.MAILTO);
171-
} else {
172-
// We have UC3
173-
reference = new ResourceReference(rawReference, ResourceType.PATH);
174-
}
175-
176-
return reference;
177-
}
178-
179136
static boolean isMetaDataElement(WikiParameters parameters)
180137
{
181138
return parameters.getParameter(CLASS_ATTRIBUTE) != null

xwiki-rendering-syntaxes/xwiki-rendering-syntax-xhtml/src/main/java/org/xwiki/rendering/internal/parser/xhtml/wikimodel/XWikiCommentHandler.java

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,13 @@
2525

2626
import org.xwiki.component.manager.ComponentLookupException;
2727
import org.xwiki.component.manager.ComponentManager;
28+
import org.xwiki.rendering.block.XDOM;
29+
import org.xwiki.rendering.internal.parser.XDOMGeneratorListener;
2830
import org.xwiki.rendering.internal.parser.wikimodel.XWikiGeneratorListener;
2931
import org.xwiki.rendering.internal.parser.xhtml.XHTMLParser;
3032
import org.xwiki.rendering.listener.MetaData;
3133
import org.xwiki.rendering.listener.reference.ResourceReference;
3234
import org.xwiki.rendering.parser.ResourceReferenceParser;
33-
import org.xwiki.rendering.renderer.PrintRenderer;
34-
import org.xwiki.rendering.renderer.PrintRendererFactory;
35-
import org.xwiki.rendering.renderer.printer.DefaultWikiPrinter;
3635
import org.xwiki.rendering.renderer.reference.link.URILabelGenerator;
3736
import org.xwiki.rendering.wikimodel.WikiParameter;
3837
import org.xwiki.rendering.wikimodel.WikiParameters;
@@ -62,8 +61,6 @@ public class XWikiCommentHandler extends CommentHandler implements XWikiWikiMode
6261
{
6362
private XHTMLParser parser;
6463

65-
private PrintRendererFactory xwikiSyntaxPrintRendererFactory;
66-
6764
private ComponentManager componentManager;
6865

6966
private ResourceReferenceParser xhtmlMarkerResourceReferenceParser;
@@ -80,12 +77,10 @@ public class XWikiCommentHandler extends CommentHandler implements XWikiWikiMode
8077
* http://code.google.com/p/wikimodel/issues/detail?id=87
8178
*/
8279
public XWikiCommentHandler(ComponentManager componentManager, XHTMLParser parser,
83-
PrintRendererFactory xwikiSyntaxPrintRendererFactory,
8480
ResourceReferenceParser xhtmlMarkerResourceReferenceParser)
8581
{
8682
this.componentManager = componentManager;
8783
this.parser = parser;
88-
this.xwikiSyntaxPrintRendererFactory = xwikiSyntaxPrintRendererFactory;
8984
this.xhtmlMarkerResourceReferenceParser = xhtmlMarkerResourceReferenceParser;
9085
}
9186

@@ -214,22 +209,15 @@ private void handleLinkCommentStart(String content, TagStack stack)
214209
// originally appears in the parsed source) and handle it specially in DefaultXWikiGeneratorListener, with the
215210
// parser passed as the first parameter in the DefaultXWikiGeneratorListener constructor.
216211
// Since we cannot get this label as it originally appeared in the HTML source ( we are doing a SAX-like
217-
// parsing), we should render the XDOM as HTML to get an HTML label.
218-
// Since any syntax would do it, as long as this renderer matches the corresponding
219-
// DefaultXWikiGeneratorListener
220-
// parser, we use an xwiki 2.1 renderer for it is less complex (no context needed to render xwiki 2.1, no url
221-
// resolution needed, no reference validity tests).
212+
// parsing), we directly parse it and instead pass the resulting XDOM via the XWikiWikiReference class.
222213
// see DefaultXWikiGeneratorListener#DefaultXWikiGeneratorListener(Parser, ResourceReferenceParser, ImageParser)
223214
// see WikiModelXHTMLParser#getLinkLabelParser()
224215
// see http://code.google.com/p/wikimodel/issues/detail?id=87
225216
// TODO: remove this workaround when wiki syntax in link labels will be supported by wikimodel
226-
DefaultWikiPrinter printer = new DefaultWikiPrinter();
227-
228-
PrintRenderer linkLabelRenderer = this.xwikiSyntaxPrintRendererFactory.createRenderer(printer);
229-
// Make sure to flush whatever the renderer implementation
230-
linkLabelRenderer.beginDocument(MetaData.EMPTY);
217+
XDOMGeneratorListener linkLabelListener = new XDOMGeneratorListener();
218+
linkLabelListener.beginDocument(MetaData.EMPTY);
231219

232-
XWikiGeneratorListener xwikiListener = this.parser.createXWikiGeneratorListener(linkLabelRenderer, null);
220+
XWikiGeneratorListener xwikiListener = this.parser.createXWikiGeneratorListener(linkLabelListener, null);
233221

234222
stack.pushStackParameter(LINK_LISTENER, xwikiListener);
235223

@@ -244,7 +232,7 @@ private void handleLinkCommentStop(TagStack stack)
244232
{
245233
XWikiGeneratorListener xwikiListener =
246234
(XWikiGeneratorListener) stack.popStackParameter(LINK_LISTENER);
247-
PrintRenderer linkLabelRenderer = (PrintRenderer) xwikiListener.getListener();
235+
XDOMGeneratorListener linkLabelRenderer = (XDOMGeneratorListener) xwikiListener.getListener();
248236

249237
// Make sure to flush whatever the renderer implementation
250238
linkLabelRenderer.endDocument(MetaData.EMPTY);
@@ -253,15 +241,15 @@ private void handleLinkCommentStop(TagStack stack)
253241

254242
ResourceReference linkReference = this.xhtmlMarkerResourceReferenceParser.parse(this.commentContentStack.pop());
255243
WikiParameters linkParams = WikiParameters.EMPTY;
256-
String label = null;
244+
XDOM label = null;
257245
if (!isFreeStandingLink) {
258-
label = linkLabelRenderer.getPrinter().toString();
246+
label = linkLabelRenderer.getXDOM();
259247

260248
// Add the Link reference parameters to the link parameters.
261249
linkParams = (WikiParameters) stack.getStackParameter(LINK_PARAMETERS);
262250
}
263251

264-
WikiReference wikiReference = new XWikiWikiReference(linkReference, label, linkParams, isFreeStandingLink);
252+
XWikiWikiReference wikiReference = new XWikiWikiReference(linkReference, label, linkParams, isFreeStandingLink);
265253
stack.getScannerContext().onReference(wikiReference);
266254

267255
stack.popStackParameter(IS_IN_LINK);

0 commit comments

Comments
 (0)