Re: [xwiki-devs] [xwiki-notifications] r33583 - in platform/core/trunk: . xwiki-bridge xwiki-bridge/src/main/java/org/xwiki/bridge xwiki-model/src/main/java/org/xwiki/model/internal/reference xwiki-model/src/main/resources/META-INF xwiki-model/src/test/java/org/x
On Fri, Dec 17, 2010 at 14:07, vmassol <platform-notifications@xwiki.org> wrote:
Author: vmassol Date: 2010-12-17 14:07:48 +0100 (Fri, 17 Dec 2010) New Revision: 33583
Added: platform/core/trunk/xwiki-model/src/main/java/org/xwiki/model/internal/reference/ExplicitStringAttachmentReferenceResolver.java platform/core/trunk/xwiki-model/src/test/java/org/xwiki/model/internal/reference/ExplicitStringAttachmentReferenceResolverTest.java platform/core/trunk/xwiki-rendering/xwiki-rendering-api/src/test/java/org/xwiki/rendering/transformation/ platform/core/trunk/xwiki-rendering/xwiki-rendering-api/src/test/java/org/xwiki/rendering/transformation/TransformationContextTest.java platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/java/org/xwiki/rendering/internal/macro/DefaultMacroContentParser.java platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/java/org/xwiki/rendering/internal/macro/MacroContentParser.java platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/test/java/org/xwiki/rendering/internal/transformation/macro/MacroTransformationContextTest.java Removed: platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/internal/macro/box/DefaultMacroContentParser.java platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/internal/macro/box/MacroContentParser.java Modified: platform/core/trunk/pom.xml platform/core/trunk/xwiki-bridge/pom.xml platform/core/trunk/xwiki-bridge/src/main/java/org/xwiki/bridge/DocumentModelBridge.java platform/core/trunk/xwiki-model/src/main/resources/META-INF/components.txt platform/core/trunk/xwiki-rendering/xwiki-rendering-api/src/main/java/org/xwiki/rendering/transformation/TransformationContext.java platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/internal/macro/box/DefaultBoxMacro.java platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/macro/box/AbstractBoxMacro.java platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/resources/META-INF/components.txt platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-include/src/main/java/org/xwiki/rendering/internal/macro/include/IncludeMacro.java platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-include/src/test/java/org/xwiki/rendering/internal/macro/IncludeMacroTest.java platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/java/org/xwiki/rendering/transformation/MacroTransformationContext.java platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/resources/META-INF/components.txt Log: XWIKI-5807: Add support for relative links/images in included documents
* First implementation. Current limitation: Doesn't work when links are generated by macros in the included document.
Modified: platform/core/trunk/pom.xml =================================================================== --- platform/core/trunk/pom.xml 2010-12-17 12:25:56 UTC (rev 33582) +++ platform/core/trunk/pom.xml 2010-12-17 13:07:48 UTC (rev 33583) @@ -192,6 +192,8 @@ <exclude>**/internal/**</exclude> <exclude>**/test/**</exclude> <!-- To be removed when we release 3.0 --> + <exclude>org/xwiki/bridge/DocumentModelBridge</exclude> + <exclude>org/xwiki/rendering/macro/box/AbstractBoxMacro</exclude> </excludes> </configuration> </plugin>
Modified: platform/core/trunk/xwiki-bridge/pom.xml =================================================================== --- platform/core/trunk/xwiki-bridge/pom.xml 2010-12-17 12:25:56 UTC (rev 33582) +++ platform/core/trunk/xwiki-bridge/pom.xml 2010-12-17 13:07:48 UTC (rev 33583) @@ -46,6 +46,11 @@ </dependency> <dependency> <groupId>org.xwiki.platform</groupId> + <artifactId>xwiki-core-rendering-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.xwiki.platform</groupId> <artifactId>xwiki-core-observation-local</artifactId>
Are you sure you need the implementation ? It should probably be xwiki-observation-api instead.
<version>${pom.version}</version> </dependency>
Modified: platform/core/trunk/xwiki-bridge/src/main/java/org/xwiki/bridge/DocumentModelBridge.java =================================================================== --- platform/core/trunk/xwiki-bridge/src/main/java/org/xwiki/bridge/DocumentModelBridge.java 2010-12-17 12:25:56 UTC (rev 33582) +++ platform/core/trunk/xwiki-bridge/src/main/java/org/xwiki/bridge/DocumentModelBridge.java 2010-12-17 13:07:48 UTC (rev 33583) @@ -20,6 +20,7 @@ package org.xwiki.bridge;
import org.xwiki.model.reference.DocumentReference; +import org.xwiki.rendering.syntax.Syntax;
/** * Exposes methods for accessing Documents. This is temporary until we remodel the Model classes and the Document @@ -78,19 +79,28 @@ /** * @return the Syntax id representing the syntax used for the current document. For example "xwiki/1.0" represents * the first version XWiki syntax while "xwiki/2.0" represents version 2.0 of the XWiki Syntax. + * @deprecated since 3.0M1 use {@link #getSyntax()} instead */ + @Deprecated String getSyntaxId(); - + /** + * @return the Syntax id representing the syntax used for the current document. For example "xwiki/1.0" represents + * the first version XWiki syntax while "xwiki/2.0" represents version 2.0 of the XWiki Syntax. + * @since 3.0M1 + */ + Syntax getSyntax(); + + /** * @return the page to which the document belongs to (eg "WebHome") - * @deprecated since 2.2M1 use {@link #getDocumentReference()} instead + * @deprecated since 2.2M1 use {@link #getDocumentReference()} instead */ @Deprecated String getPageName();
/** * @return the space to which the document belongs to (eg "Main") - * @deprecated since 2.2M1 use {@link #getDocumentReference()} instead + * @deprecated since 2.2M1 use {@link #getDocumentReference()} instead */ @Deprecated String getSpaceName();
Added: platform/core/trunk/xwiki-model/src/main/java/org/xwiki/model/internal/reference/ExplicitStringAttachmentReferenceResolver.java =================================================================== --- platform/core/trunk/xwiki-model/src/main/java/org/xwiki/model/internal/reference/ExplicitStringAttachmentReferenceResolver.java (rev 0) +++ platform/core/trunk/xwiki-model/src/main/java/org/xwiki/model/internal/reference/ExplicitStringAttachmentReferenceResolver.java 2010-12-17 13:07:48 UTC (rev 33583) @@ -0,0 +1,52 @@ +/* [...] + */ +package org.xwiki.model.internal.reference; + +import org.xwiki.component.annotation.Component; +import org.xwiki.component.annotation.Requirement; +import org.xwiki.model.EntityType; +import org.xwiki.model.reference.AttachmentReference; +import org.xwiki.model.reference.AttachmentReferenceResolver; +import org.xwiki.model.reference.EntityReferenceResolver; + +/** + * Specialized version of {@link org.xwiki.model.reference.EntityReferenceResolver} which can be considered a helper + * component to resolve {@link org.xwiki.model.reference.AttachmentReference} objects from their string representation. + * The behavior is the one defined in {@link org.xwiki.model.internal.reference.ExplicitStringEntityReferenceResolver}. + * + * @version $Id$ + * @since 3.0M1 + */ +@Component("explicit") +public class ExplicitStringAttachmentReferenceResolver implements AttachmentReferenceResolver<String> +{ + @Requirement("explicit") + private EntityReferenceResolver<String> entityReferenceResolver; + + /** + * {@inheritDoc} + * @see org.xwiki.model.reference.AttachmentReferenceResolver#resolve + */ + public AttachmentReference resolve(String attachmentReferenceRepresentation, Object... parameters) + { + return new AttachmentReference(this.entityReferenceResolver.resolve( + attachmentReferenceRepresentation, EntityType.ATTACHMENT, parameters)); + } +}
[..]
Added: platform/core/trunk/xwiki-model/src/test/java/org/xwiki/model/internal/reference/ExplicitStringAttachmentReferenceResolverTest.java =================================================================== --- platform/core/trunk/xwiki-model/src/test/java/org/xwiki/model/internal/reference/ExplicitStringAttachmentReferenceResolverTest.java (rev 0) +++ platform/core/trunk/xwiki-model/src/test/java/org/xwiki/model/internal/reference/ExplicitStringAttachmentReferenceResolverTest.java 2010-12-17 13:07:48 UTC (rev 33583) @@ -0,0 +1,58 @@ +/*
[...]
+ */ +package org.xwiki.model.internal.reference; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.xwiki.component.util.ReflectionUtils; +import org.xwiki.model.reference.AttachmentReference; +import org.xwiki.model.reference.AttachmentReferenceResolver; +import org.xwiki.model.reference.DocumentReference; +import org.xwiki.model.reference.DocumentReferenceResolver; + +/** + * Unit tests for {@link org.xwiki.model.internal.reference.ExplicitStringAttachmentReferenceResolver}. + * + * @version $Id$ + * @since 3.0M1 + */ +public class ExplicitStringAttachmentReferenceResolverTest +{ + private AttachmentReferenceResolver<String> resolver; + + @Before + public void setUp() throws Exception + { + this.resolver = new ExplicitStringAttachmentReferenceResolver(); + ReflectionUtils.setFieldValue(this.resolver, "entityReferenceResolver", + new ExplicitStringEntityReferenceResolver()); + } + + @Test + public void testResolveWithExplicitAttachmentReference() + { + DocumentReference documentReference = new DocumentReference("wiki", "space", "page"); + AttachmentReference reference = this.resolver.resolve("", new AttachmentReference("file", documentReference)); + + Assert.assertEquals("file", reference.getName()); + Assert.assertEquals(documentReference, reference.getDocumentReference()); + } +}
Modified: platform/core/trunk/xwiki-rendering/xwiki-rendering-api/src/main/java/org/xwiki/rendering/transformation/TransformationContext.java =================================================================== --- platform/core/trunk/xwiki-rendering/xwiki-rendering-api/src/main/java/org/xwiki/rendering/transformation/TransformationContext.java 2010-12-17 12:25:56 UTC (rev 33582) +++ platform/core/trunk/xwiki-rendering/xwiki-rendering-api/src/main/java/org/xwiki/rendering/transformation/TransformationContext.java 2010-12-17 13:07:48 UTC (rev 33583) @@ -28,7 +28,7 @@ * @version $Id$ * @since 2.4M1 */ -public class TransformationContext +public class TransformationContext implements Cloneable { /** * The complete {@link XDOM} of the content currently being transformed. @@ -117,4 +117,22 @@ { return syntax; } + + /** + * {@inheritDoc} + * @see Object#clone() + */ + @Override + public TransformationContext clone() + { + TransformationContext newContext; + try { + newContext = (TransformationContext) super.clone(); + } catch (CloneNotSupportedException e) { + // Should never happen + throw new RuntimeException("Failed to clone object", e); + } + + return newContext; + } }
Added: platform/core/trunk/xwiki-rendering/xwiki-rendering-api/src/test/java/org/xwiki/rendering/transformation/TransformationContextTest.java =================================================================== --- platform/core/trunk/xwiki-rendering/xwiki-rendering-api/src/test/java/org/xwiki/rendering/transformation/TransformationContextTest.java (rev 0) +++ platform/core/trunk/xwiki-rendering/xwiki-rendering-api/src/test/java/org/xwiki/rendering/transformation/TransformationContextTest.java 2010-12-17 13:07:48 UTC (rev 33583) @@ -0,0 +1,54 @@ +/* [...] + */ +package org.xwiki.rendering.transformation; + +import java.util.Arrays; + +import org.junit.Test; +import org.junit.Assert; +import org.xwiki.rendering.block.Block; +import org.xwiki.rendering.block.WordBlock; +import org.xwiki.rendering.block.XDOM; +import org.xwiki.rendering.syntax.Syntax; + +/** + * Unit tests for {@link TransformationContext}. + * + * @version $Id$ + * @since 3.0M1 + */ +public class TransformationContextTest +{ + @Test + public void testClone() + { + TransformationContext context = new TransformationContext(); + context.setId("id"); + context.setSyntax(Syntax.XWIKI_2_0); + XDOM xdom = new XDOM(Arrays.<Block>asList(new WordBlock("test"))); + context.setXDOM(xdom); + + TransformationContext newContext = context.clone(); + Assert.assertNotSame(context, newContext); + Assert.assertEquals("id", newContext.getId()); + Assert.assertEquals(Syntax.XWIKI_2_0, newContext.getSyntax()); + Assert.assertEquals(xdom, newContext.getXDOM()); + } +}
Modified: platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/internal/macro/box/DefaultBoxMacro.java =================================================================== --- platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/internal/macro/box/DefaultBoxMacro.java 2010-12-17 12:25:56 UTC (rev 33582) +++ platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/internal/macro/box/DefaultBoxMacro.java 2010-12-17 13:07:48 UTC (rev 33583) @@ -67,6 +67,7 @@ protected List<Block> parseContent(P parameters, String content, MacroTransformationContext context) throws MacroExecutionException { - return getMacroContentParser().parse(content, context.getSyntax(), context.isInline()); + // Don't execute transformations explicitly. They'll be executed on the generated content later on. + return getMacroContentParser().parse(content, context, false, context.isInline()); } }
Deleted: platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/internal/macro/box/DefaultMacroContentParser.java =================================================================== --- platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/internal/macro/box/DefaultMacroContentParser.java 2010-12-17 12:25:56 UTC (rev 33582) +++ platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/internal/macro/box/DefaultMacroContentParser.java 2010-12-17 13:07:48 UTC (rev 33583) @@ -1,88 +0,0 @@ -/* [...] - */ -package org.xwiki.rendering.internal.macro.box; - -import java.io.StringReader; -import java.util.List; - -import org.xwiki.component.annotation.Component; -import org.xwiki.component.annotation.Requirement; -import org.xwiki.component.manager.ComponentLookupException; -import org.xwiki.component.manager.ComponentManager; -import org.xwiki.rendering.block.Block; -import org.xwiki.rendering.macro.MacroExecutionException; -import org.xwiki.rendering.parser.Parser; -import org.xwiki.rendering.syntax.Syntax; -import org.xwiki.rendering.util.ParserUtils; - -/** - * Default implementation for {@link org.xwiki.rendering.internal.macro.box.MacroContentParser}. - * - * @version $Id$ - * @since 2.6RC1 - */ -@Component -public class DefaultMacroContentParser implements MacroContentParser -{ - /** - * Used to look up the syntax parser to use for parsing the content. - */ - @Requirement - private ComponentManager componentManager; - - /** - * Utility to remove the top level paragraph. - */ - private ParserUtils parserUtils = new ParserUtils(); - - /** - * {@inheritDoc} - * @see MacroContentParser#parse(String, org.xwiki.rendering.syntax.Syntax, boolean) - */ - public List<Block> parse(String content, Syntax syntax, boolean removeTopLevelParagraph) - throws MacroExecutionException - { - try { - List<Block> blocks = getSyntaxParser(syntax).parse(new StringReader(content)).getChildren(); - if (removeTopLevelParagraph) { - this.parserUtils.removeTopLevelParagraph(blocks); - } - return blocks; - } catch (Exception e) { - throw new MacroExecutionException("Failed to parse content [" + content + "]", e); - } - } - - /** - * Get the parser for the current syntax. - * - * @param syntax the current syntax of the title content - * @return the parser for the current syntax - * @throws org.xwiki.rendering.macro.MacroExecutionException Failed to find source parser. - */ - private Parser getSyntaxParser(Syntax syntax) throws MacroExecutionException - { - try { - return this.componentManager.lookup(Parser.class, syntax.toIdString()); - } catch (ComponentLookupException e) { - throw new MacroExecutionException("Failed to find source parser for syntax [" + syntax + "]", e); - } - } -}
Deleted: platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/internal/macro/box/MacroContentParser.java =================================================================== --- platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/internal/macro/box/MacroContentParser.java 2010-12-17 12:25:56 UTC (rev 33582) +++ platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/internal/macro/box/MacroContentParser.java 2010-12-17 13:07:48 UTC (rev 33583) @@ -1,49 +0,0 @@ -/* [...] - */ -package org.xwiki.rendering.internal.macro.box; - -import java.util.List; - -import org.xwiki.component.annotation.ComponentRole; -import org.xwiki.rendering.block.Block; -import org.xwiki.rendering.macro.MacroExecutionException; -import org.xwiki.rendering.syntax.Syntax; - -/** - * Parses content of a macro field (parameter, macro content) in a given syntax. - * - * @version $Id$ - * @since 2.6RC1 - */ -@ComponentRole -public interface MacroContentParser -{ - /** - * Parses content of a macro field (parameter, macro content) in a given syntax and optionally remove the top level - * paragraph. - * - * @param content the content to parse - * @param syntax the syntax in which the content is written in - * @param removeTopLevelParagraph whether the top level paragraph should be removed after parsing - * @return the result as a {@link org.xwiki.rendering.block.Block}s - * @throws MacroExecutionException in case of a parsing error - */ - List<Block> parse(String content, Syntax syntax, boolean removeTopLevelParagraph) throws MacroExecutionException; -}
Modified: platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/macro/box/AbstractBoxMacro.java =================================================================== --- platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/macro/box/AbstractBoxMacro.java 2010-12-17 12:25:56 UTC (rev 33582) +++ platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/macro/box/AbstractBoxMacro.java 2010-12-17 13:07:48 UTC (rev 33583) @@ -31,7 +31,7 @@ import org.xwiki.rendering.block.GroupBlock; import org.xwiki.rendering.block.ImageBlock; import org.xwiki.rendering.block.NewLineBlock; -import org.xwiki.rendering.internal.macro.box.MacroContentParser; +import org.xwiki.rendering.internal.macro.MacroContentParser; import org.xwiki.rendering.listener.Format; import org.xwiki.rendering.listener.reference.ResourceReference; import org.xwiki.rendering.listener.reference.ResourceType; @@ -137,7 +137,8 @@ } // we add the title, if there is one if (!StringUtils.isEmpty(titleParameter)) { - boxBlock.addChildren(this.contentParser.parse(titleParameter, context.getSyntax(), true)); + // Don't execute transformations explicitly. They'll be executed on the generated content later on. + boxBlock.addChildren(this.contentParser.parse(titleParameter, context, false, true)); } if (titleBlockList != null) { boxBlock.addChildren(titleBlockList);
Modified: platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/resources/META-INF/components.txt =================================================================== --- platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/resources/META-INF/components.txt 2010-12-17 12:25:56 UTC (rev 33582) +++ platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/resources/META-INF/components.txt 2010-12-17 13:07:48 UTC (rev 33583) @@ -1,2 +1 @@ -org.xwiki.rendering.internal.macro.box.DefaultBoxMacro -org.xwiki.rendering.internal.macro.box.DefaultMacroContentParser \ No newline at end of file +org.xwiki.rendering.internal.macro.box.DefaultBoxMacro \ No newline at end of file
Modified: platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-include/src/main/java/org/xwiki/rendering/internal/macro/include/IncludeMacro.java =================================================================== --- platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-include/src/main/java/org/xwiki/rendering/internal/macro/include/IncludeMacro.java 2010-12-17 12:25:56 UTC (rev 33582) +++ platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-include/src/main/java/org/xwiki/rendering/internal/macro/include/IncludeMacro.java 2010-12-17 13:07:48 UTC (rev 33583) @@ -19,35 +19,37 @@ */ package org.xwiki.rendering.internal.macro.include;
-import java.io.StringReader; import java.util.HashMap; import java.util.List; import java.util.Map;
import org.xwiki.bridge.DocumentAccessBridge; +import org.xwiki.bridge.DocumentModelBridge; import org.xwiki.component.annotation.Component; import org.xwiki.component.annotation.Requirement; import org.xwiki.component.manager.ComponentManager; import org.xwiki.context.Execution; import org.xwiki.context.ExecutionContext; import org.xwiki.context.ExecutionContextManager; +import org.xwiki.model.reference.AttachmentReferenceResolver; import org.xwiki.model.reference.DocumentReference; import org.xwiki.model.reference.DocumentReferenceResolver; +import org.xwiki.model.reference.EntityReference; import org.xwiki.model.reference.EntityReferenceSerializer; import org.xwiki.rendering.block.Block; +import org.xwiki.rendering.block.ImageBlock; import org.xwiki.rendering.block.LinkBlock; import org.xwiki.rendering.block.MacroMarkerBlock; import org.xwiki.rendering.block.XDOM; +import org.xwiki.rendering.internal.macro.MacroContentParser; import org.xwiki.rendering.listener.reference.ResourceReference; import org.xwiki.rendering.listener.reference.ResourceType; import org.xwiki.rendering.macro.AbstractMacro; import org.xwiki.rendering.macro.MacroExecutionException; import org.xwiki.rendering.macro.include.IncludeMacroParameters; import org.xwiki.rendering.macro.include.IncludeMacroParameters.Context; -import org.xwiki.rendering.parser.Parser; +import org.xwiki.rendering.syntax.Syntax; import org.xwiki.rendering.transformation.MacroTransformationContext; -import org.xwiki.rendering.transformation.Transformation; -import org.xwiki.rendering.transformation.TransformationContext;
/** * @version $Id$ @@ -86,14 +88,24 @@ private DocumentAccessBridge documentAccessBridge;
/** - * Used to transform relative document links into absolute references when including a document containing links. - * This is required otherwise the links will be resolved at render time in the context of the including document - * instead of in the context of the included document. + * Used to transform the passed document reference macro parameter to a typed {@link DocumentReference} object. */ @Requirement("current") private DocumentReferenceResolver<String> currentDocumentReferenceResolver;
/** + * Used to transform relative document links into absolute references relative to the included document. + */ + @Requirement("explicit") + private DocumentReferenceResolver<String> explicitDocumentReferenceResolver; + + /** + * Used to transform relative attachment links into absolute references relative to the included document. + */ + @Requirement("explicit") + private AttachmentReferenceResolver<String> explicitAttachmentReferenceResolver; + + /** * Used to serialize resolved document links into a string again since the Rendering API only manipulates Strings * (done voluntarily to be independent of any wiki engine and not draw XWiki-specific dependencies). */ @@ -101,6 +113,12 @@ private EntityReferenceSerializer<String> defaultEntityReferenceSerializer;
/** + * The parser used to parse included document content. + */ + @Requirement + private MacroContentParser contentParser; + + /** * Default constructor. */ public IncludeMacro() @@ -141,38 +159,39 @@ public List<Block> execute(IncludeMacroParameters parameters, String content, MacroTransformationContext context) throws MacroExecutionException { - String documentName = parameters.getDocument(); - if (documentName == null) { + // Step 1: Perform checks + if (parameters.getDocument() == null) { throw new MacroExecutionException( "You must specify a 'document' parameter pointing to the document to include."); }
- DocumentReference documentReference = resolve(context.getCurrentMacroBlock(), documentName); + DocumentReference includedReference = resolve(context.getCurrentMacroBlock(), parameters.getDocument());
if (context.getCurrentMacroBlock() != null) { - checkRecursiveInclusion(context.getCurrentMacroBlock(), documentReference); + checkRecursiveInclusion(context.getCurrentMacroBlock(), includedReference); }
- Context actualContext = parameters.getContext(); + if (!this.documentAccessBridge.isDocumentViewable(includedReference)) { + throw new MacroExecutionException("Current user doesn't have view rights on document [" + + this.defaultEntityReferenceSerializer.serialize(includedReference) + "]"); + }
- // Retrieve the included document's content - String includedContent; - String includedSyntax; + Context parametersContext = parameters.getContext(); + + // Step 2: Extract included document's content and syntax. + // TODO: use macro source information to resolve document reference based on the macro source instead + // of the context + DocumentModelBridge documentBridge; try { - if (this.documentAccessBridge.isDocumentViewable(documentReference)) { - // TODO: use macro source informations to resolve document reference besed on the macro source instead - // of the context - includedContent = this.documentAccessBridge.getDocumentContent(documentName); - includedSyntax = this.documentAccessBridge.getDocumentSyntaxId(documentName); - } else { - throw new MacroExecutionException("Current user doesn't have view rights on document [" + documentName - + "]"); - } + documentBridge = this.documentAccessBridge.getDocument(includedReference); } catch (Exception e) { - throw new MacroExecutionException("Failed to get content for Document [" + documentName + "]", e); + throw new MacroExecutionException("Failed to load Document [" + + this.defaultEntityReferenceSerializer.serialize(includedReference) + "]", e); } + String includedContent = documentBridge.getContent(); + Syntax includedSyntax = documentBridge.getSyntax();
- List<Block> result; + // Step 3: Parse and transform the included document's content.
// Check the value of the "context" parameter. // @@ -184,30 +203,68 @@ // if CONTEXT_CURRENT, then simply get the included page's content, parse it and return the resulting AST // (i.e. don't apply any transformations since we don't want any Macro to be executed at this stage since they // should be executed by the currently running Macro Transformation. - if (actualContext == Context.NEW) { - result = - executeWithNewContext(documentReference, includedContent, includedSyntax, context.getTransformation()); + List<Block> result; + MacroTransformationContext newContext = context.clone(); + newContext.setSyntax(includedSyntax); + if (parametersContext == Context.NEW) { + // Since the execution happens in a separate context use a different transformation id to ensure it's + // isolated (for ex this will ensure that the velocity macros defined in the included document cannot + // interfere with the macros in the including document). + newContext.setId(this.defaultEntityReferenceSerializer.serialize(includedReference)); + result = executeWithNewContext(includedReference, includedContent, newContext); } else { - result = executeWithCurrentContext(documentReference, includedContent, includedSyntax); + result = executeWithCurrentContext(includedReference, includedContent, newContext); }
- // We need to handle the case when there are relative links specified in the content of the included document. - // These link references need to be resolved against the document being included and not the including document. - // TODO: When http://jira.xwiki.org/jira/browse/XWIKI-4802 is implemented it should be possible remove this - // code portion and instead perform the resolution at render time, using context information. - XDOM xdom = new XDOM(result); + // Step 4: Modify relative references. + resolveRelativeReferences(result, includedReference); + + return result; + } + + /** + * We need to handle the case when there are relative links specified in the content of the included document. + * These link references need to be resolved against the document being included and not the including document. + * TODO: When http://jira.xwiki.org/jira/browse/XWIKI-4802 is implemented it should be possible remove this + * code portion and instead perform the resolution at render time, using context information. + * + * @param includedReference reference to the included document + */ + private void resolveRelativeReferences(List<Block> blocks, DocumentReference includedReference) + { + XDOM xdom = new XDOM(blocks); + + // Resolve links for (LinkBlock block : xdom.getChildrenByType(LinkBlock.class, true)) { - ResourceReference reference = block.getReference(); - if (reference.getType().equals(ResourceType.DOCUMENT)) { - // It's a link to a document, make the reference absolute - String resolvedReference = - this.defaultEntityReferenceSerializer.serialize(this.currentDocumentReferenceResolver.resolve( - reference.getReference())); - reference.setReference(resolvedReference); + ResourceReference resourceReference = block.getReference(); + // Make reference absolute for links to document and attachments. + if (resourceReference.getType().equals(ResourceType.DOCUMENT) + || resourceReference.getType().equals(ResourceType.ATTACHMENT)) + { + EntityReference entityReference; + if (resourceReference.getType().equals(ResourceType.DOCUMENT)) { + entityReference = this.explicitDocumentReferenceResolver.resolve(resourceReference.getReference(), + includedReference); + } else { + entityReference = this.explicitAttachmentReferenceResolver.resolve(resourceReference.getReference(), + includedReference); + } + String resolvedReference = this.defaultEntityReferenceSerializer.serialize(entityReference); + resourceReference.setReference(resolvedReference); } }
- return result; + // Resolve images + for (ImageBlock block : xdom.getChildrenByType(ImageBlock.class, true)) { + ResourceReference resourceReference = block.getReference(); + // Make reference absolute for images in documents + if (resourceReference.getType().equals(ResourceType.ATTACHMENT)) { + String resolvedReference = this.defaultEntityReferenceSerializer.serialize( + this.explicitAttachmentReferenceResolver.resolve(resourceReference.getReference(), + includedReference)); + resourceReference.setReference(resolvedReference); + } + } }
/** @@ -274,13 +331,12 @@ * * @param includedDocumentReference the name of the document to include. * @param includedContent the content of the document to include. - * @param includedSyntax the syntax identifier of the provided content. - * @param transformation the macro transformation. + * @param macroContext the transformation context to use to parse/transform the content * @return the result of parsing and transformation of the document to include. * @throws MacroExecutionException error when parsing content. */ private List<Block> executeWithNewContext(DocumentReference includedDocumentReference, String includedContent, - String includedSyntax, Transformation transformation) throws MacroExecutionException + MacroTransformationContext macroContext) throws MacroExecutionException { List<Block> result;
@@ -293,8 +349,7 @@ Map<String, Object> backupObjects = new HashMap<String, Object>(); try { this.documentAccessBridge.pushDocumentInContext(backupObjects, includedDocumentReference); - result = - generateIncludedPageDOM(includedDocumentReference, includedContent, includedSyntax, transformation); + result = generateIncludedPageDOM(includedDocumentReference, includedContent, macroContext, true); } finally { this.documentAccessBridge.popDocumentFromContext(backupObjects); } @@ -315,14 +370,14 @@ * * @param includedDocumentReference the name of the document to include. * @param includedContent the content of the document to include. - * @param includedSyntax the syntax identifier of the provided content. + * @param macroContext the transformation context to use to parse the content * @return the result of parsing and transformation of the document to include. * @throws MacroExecutionException error when parsing content. */ private List<Block> executeWithCurrentContext(DocumentReference includedDocumentReference, String includedContent, - String includedSyntax) throws MacroExecutionException + MacroTransformationContext macroContext) throws MacroExecutionException { - return generateIncludedPageDOM(includedDocumentReference, includedContent, includedSyntax, null); + return generateIncludedPageDOM(includedDocumentReference, includedContent, macroContext, false); }
/** @@ -330,30 +385,26 @@ * * @param includedDocumentReference the name of the document to include. * @param includedContent the content of the document to include. - * @param includedSyntax the syntax identifier of the provided content. - * @param transformation the macro transformation. + * @param macroContext the transformation context to use to parse/transform the content + * @param transform if true then execute transformations * @return the result of parsing and transformation of the document to include. * @throws MacroExecutionException error when parsing content. */ private List<Block> generateIncludedPageDOM(DocumentReference includedDocumentReference, String includedContent, - String includedSyntax, Transformation transformation) throws MacroExecutionException + MacroTransformationContext macroContext, boolean transform) throws MacroExecutionException { - XDOM includedDom; + List<Block> result; try { - Parser parser = this.componentManager.lookup(Parser.class, includedSyntax); - includedDom = parser.parse(new StringReader(includedContent));
// Only run Macro transformation when the context is a new one as otherwise we need the macros in the // included page to be added to the list of macros on the including page so that they're all sorted // and executed in the right order. Note that this works only because the Include macro has the highest // execution priority and is thus executed first. - if (transformation != null) { - transformation.transform(includedDom, new TransformationContext(includedDom, parser.getSyntax())); - } + result = this.contentParser.parse(includedContent, macroContext, transform, false); } catch (Exception e) { throw new MacroExecutionException("Failed to parse included page [" + includedDocumentReference + "]", e); }
- return includedDom.getChildren(); + return result; } }
Modified: platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-include/src/test/java/org/xwiki/rendering/internal/macro/IncludeMacroTest.java =================================================================== --- platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-include/src/test/java/org/xwiki/rendering/internal/macro/IncludeMacroTest.java 2010-12-17 12:25:56 UTC (rev 33582) +++ platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-include/src/test/java/org/xwiki/rendering/internal/macro/IncludeMacroTest.java 2010-12-17 13:07:48 UTC (rev 33583) @@ -28,6 +28,8 @@
import org.jmock.Expectations; import org.junit.Test; +import org.xwiki.bridge.DocumentModelBridge; +import org.xwiki.model.reference.AttachmentReference; import org.xwiki.model.reference.DocumentReference; import org.xwiki.rendering.block.Block; import org.xwiki.rendering.block.MacroBlock; @@ -73,77 +75,35 @@ }
@Test - public void testIncludeMacroWithNewContext() throws Exception + public void testIncludeMacroWithNewContextShowsVelocityMacrosAreIsolated() throws Exception { String expected = "beginDocument\n" - + "beginMacroMarkerStandalone [velocity] [] [$myvar]\n" + + "beginMacroMarkerStandalone [velocity] [] [#testmacro]\n" + "beginParagraph\n" - + "onWord [hello]\n" + + "onSpecialSymbol [#]\n" + + "onWord [testmacro]\n" + "endParagraph\n" - + "endMacroMarkerStandalone [velocity] [] [$myvar]\n" + + "endMacroMarkerStandalone [velocity] [] [#testmacro]\n" + "endDocument";
- // Since it's not in the same context, we verify that a Velocity variable set in the including page is not - // seen in the included page. - VelocityManager velocityManager = getComponentManager().lookup(VelocityManager.class); - StringWriter writer = new StringWriter(); - velocityManager.getVelocityEngine().evaluate(velocityManager.getVelocityContext(), writer, "template", - "#set ($myvar = 'hello')"); + // We verify that a Velocity macro set in the including page is not seen in the included page. + List<Block> blocks = runIncludeMacroWithPreVelocity(Context.NEW, "#macro(testmacro)#end", + "{{velocity}}#testmacro{{/velocity}}");
- getMockery().checking(new Expectations() {{ - oneOf(mockSetup.bridge).isDocumentViewable(with(any(DocumentReference.class))); will(returnValue(true)); - oneOf(mockSetup.bridge).getDocumentContent(with(any(String.class))); - will(returnValue("{{velocity}}$myvar{{/velocity}}")); - oneOf(mockSetup.bridge).getDocumentSyntaxId(with(any(String.class))); - will(returnValue(Syntax.XWIKI_2_0.toIdString())); - oneOf(mockSetup.bridge).pushDocumentInContext(with(any(Map.class)), with(any(DocumentReference.class))); - oneOf(mockSetup.bridge).popDocumentFromContext(with(any(Map.class))); - oneOf(mockSetup.documentReferenceResolver).resolve("wiki:Space.Page"); - will(returnValue(new DocumentReference("wiki", "Space", "Page"))); - }}); - this.includeMacro.setDocumentAccessBridge(this.mockSetup.bridge); - - IncludeMacroParameters parameters = new IncludeMacroParameters(); - parameters.setDocument("wiki:Space.Page"); - parameters.setContext(Context.NEW); - - // Create a Macro transformation context with the Macro transformation object defined so that the include - // macro can transform included page which is using a new context. - MacroTransformation macroTransformation = - (MacroTransformation) getComponentManager().lookup(Transformation.class, "macro"); - MacroTransformationContext context = new MacroTransformationContext(); - context.setTransformation(macroTransformation); - - List<Block> blocks = this.includeMacro.execute(parameters, null, context); - assertBlocks(expected, blocks, this.rendererFactory); }
@Test - public void testIncludeMacroWithCurrentContext() throws Exception + public void testIncludeMacroWithCurrentContextShowsVelocityMacrosAreShared() throws Exception { String expected = "beginDocument\n" - + "onMacroStandalone [someMacro] []\n" + + "onMacroStandalone [velocity] [] [#testmacro]\n" + "endDocument";
- getMockery().checking(new Expectations() {{ - oneOf(mockSetup.bridge).isDocumentViewable(with(any(DocumentReference.class))); will(returnValue(true)); - oneOf(mockSetup.bridge).getDocumentContent(with(any(String.class))); - will(returnValue("{{someMacro/}}")); - oneOf(mockSetup.bridge).getDocumentSyntaxId(with(any(String.class))); - will(returnValue(Syntax.XWIKI_2_0.toIdString())); - oneOf(mockSetup.documentReferenceResolver).resolve("wiki:Space.Page"); - will(returnValue(new DocumentReference("wiki", "Space", "Page"))); - }}); - - this.includeMacro.setDocumentAccessBridge(mockSetup.bridge); + // We verify that a Velocity macro set in the including page is seen in the included page. + List<Block> blocks = runIncludeMacroWithPreVelocity(Context.CURRENT, "#macro(testmacro)#end", + "{{velocity}}#testmacro{{/velocity}}");
- IncludeMacroParameters parameters = new IncludeMacroParameters(); - parameters.setDocument("wiki:Space.Page"); - parameters.setContext(Context.CURRENT); - - List<Block> blocks = this.includeMacro.execute(parameters, null, new MacroTransformationContext()); - assertBlocks(expected, blocks, this.rendererFactory); }
@@ -165,27 +125,30 @@ * Verify that relative links are made absolute in the XDOM returned by the Include macro. */ @Test - public void testIncludeMacroWhenIncludingDocumentWithRelativeLinks() throws Exception + public void testIncludeMacroWhenIncludingDocumentWithRelativeReferences() throws Exception { String expected = "beginDocument\n" + "beginParagraph\n" - + "beginLink [Typed = [false] Type = [doc] Reference = [wiki:space.page]] [false]\n" - + "endLink [Typed = [false] Type = [doc] Reference = [wiki:space.page]] [false]\n" + + "beginLink [Typed = [false] Type = [doc] Reference = [includedWiki:includedSpace.page]] [false]\n" + + "endLink [Typed = [false] Type = [doc] Reference = [includedWiki:includedSpace.page]] [false]\n" + + "onSpace\n" + + "beginLink [Typed = [true] Type = [attach] " + + "Reference = [includedWiki:includedSpace.includedPage@test.png]] [false]\n" + + "endLink [Typed = [true] Type = [attach] " + + "Reference = [includedWiki:includedSpace.includedPage@test.png]] [false]\n" + + "onSpace\n" + + "onImage [Typed = [false] Type = [attach] " + + "Reference = [includedWiki:includedSpace.includedPage@test.png]] [true]\n" + "endParagraph\n" + "endDocument";
+ setUpDocumentMock("includedWiki:includedSpace.includedPage", + new DocumentReference("includedWiki", "includedSpace", "includedPage"), + "[[page]] [[attach:test.png]] image:test.png"); getMockery().checking(new Expectations() {{ oneOf(mockSetup.bridge).isDocumentViewable(with(any(DocumentReference.class))); will(returnValue(true)); - oneOf(mockSetup.bridge).getDocumentContent("includedWiki:includedSpace.includedPage"); - will(returnValue("[[page]]")); - oneOf(mockSetup.bridge).getDocumentSyntaxId(with(any(String.class))); - will(returnValue(Syntax.XWIKI_2_0.toIdString())); oneOf(mockSetup.bridge).pushDocumentInContext(with(any(Map.class)), with(any(DocumentReference.class))); oneOf(mockSetup.bridge).popDocumentFromContext(with(any(Map.class))); - oneOf(mockSetup.documentReferenceResolver).resolve("page"); - will(returnValue(new DocumentReference("wiki", "space", "page"))); - oneOf(mockSetup.documentReferenceResolver).resolve("includedWiki:includedSpace.includedPage"); - will(returnValue(new DocumentReference("includedWiki", "includedSpace", "includedPage"))); }});
IncludeMacroParameters parameters = new IncludeMacroParameters(); @@ -201,32 +164,84 @@ public void testIncludeMacroWithRecursiveInclude() throws Exception { getMockery().checking(new Expectations() {{ - oneOf(mockSetup.documentReferenceResolver).resolve("wiki:Space.Page"); - will(returnValue(new DocumentReference("wiki", "Space", "Page"))); - oneOf(mockSetup.documentReferenceResolver).resolve("Space.Page"); - will(returnValue(new DocumentReference("wiki", "Space", "Page"))); + allowing(mockSetup.documentReferenceResolver).resolve("wiki:space.page"); + will(returnValue(new DocumentReference("wiki", "space", "page"))); + allowing(mockSetup.documentReferenceResolver).resolve("space.page"); + will(returnValue(new DocumentReference("wiki", "space", "page"))); }}); - + this.includeMacro.setDocumentAccessBridge(mockSetup.bridge);
- MacroBlock includeMacro = new MacroBlock("include", Collections.singletonMap("document", "wiki:Space.Page"), false); - new MacroMarkerBlock("include", Collections.singletonMap("document", "Space.Page"), Collections.<Block>singletonList(includeMacro), false); + MacroBlock includeMacro = + new MacroBlock("include", Collections.singletonMap("document", "wiki:space.page"), false); + new MacroMarkerBlock("include", Collections.singletonMap("document", "space.page"), + Collections.<Block>singletonList(includeMacro), false); MacroTransformationContext context = new MacroTransformationContext(); context.setCurrentMacroBlock(includeMacro);
IncludeMacroParameters parameters = new IncludeMacroParameters(); - parameters.setDocument("wiki:Space.Page"); + parameters.setDocument("wiki:space.page"); parameters.setContext(Context.CURRENT);
- List<Block> blocks; try { - blocks = this.includeMacro.execute(parameters, null, context); - - Assert.fail("The include macro did not checked the recusive inclusion"); + this.includeMacro.execute(parameters, null, context); + Assert.fail("The include macro hasn't checked the recursive inclusion"); } catch (MacroExecutionException expected) { if (!expected.getMessage().startsWith("Found recursive inclusion")) { throw expected; } } } + + private void setUpDocumentMock(final String resolve, final DocumentReference reference, final String content) + throws Exception + { + final DocumentModelBridge mockDocument = getMockery().mock(DocumentModelBridge.class, resolve); + getMockery().checking(new Expectations() {{ + allowing(mockSetup.documentReferenceResolver).resolve(resolve); + will(returnValue(reference)); + allowing(mockSetup.bridge).getDocument(reference); will(returnValue(mockDocument)); + allowing(mockDocument).getSyntax(); will(returnValue(Syntax.XWIKI_2_0)); + allowing(mockDocument).getContent(); will(returnValue(content)); + }}); + } + + private List<Block> runIncludeMacroWithPreVelocity(Context context, String velocity, String includedContent) + throws Exception + { + VelocityManager velocityManager = getComponentManager().lookup(VelocityManager.class); + StringWriter writer = new StringWriter(); + velocityManager.getVelocityEngine().evaluate(velocityManager.getVelocityContext(), writer, "templateId", + velocity); + + return runIncludeMacro(context, includedContent); + } + + private List<Block> runIncludeMacro(final Context context, String includedContent) throws Exception + { + setUpDocumentMock("wiki:space.page", new DocumentReference("wiki", "space", "page"), includedContent); + getMockery().checking(new Expectations() {{ + allowing(mockSetup.bridge).isDocumentViewable(with(any(DocumentReference.class))); will(returnValue(true)); + // Verify that push/pop are called when context is NEW + if (context == Context.NEW) { + oneOf(mockSetup.bridge).pushDocumentInContext(with(any(Map.class)), with(any(DocumentReference.class))); + oneOf(mockSetup.bridge).popDocumentFromContext(with(any(Map.class))); + } + }}); + this.includeMacro.setDocumentAccessBridge(this.mockSetup.bridge); + + IncludeMacroParameters parameters = new IncludeMacroParameters(); + parameters.setDocument("wiki:space.page"); + parameters.setContext(context); + + // Create a Macro transformation context with the Macro transformation object defined so that the include + // macro can transform included page which is using a new context. + MacroTransformation macroTransformation = + (MacroTransformation) getComponentManager().lookup(Transformation.class, "macro"); + MacroTransformationContext macroContext = new MacroTransformationContext(); + macroContext.setId("templateId"); + macroContext.setTransformation(macroTransformation); + + return this.includeMacro.execute(parameters, null, macroContext); + } }
Copied: platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/java/org/xwiki/rendering/internal/macro/DefaultMacroContentParser.java (from rev 33541, platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/internal/macro/box/DefaultMacroContentParser.java) =================================================================== --- platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/java/org/xwiki/rendering/internal/macro/DefaultMacroContentParser.java (rev 0) +++ platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/java/org/xwiki/rendering/internal/macro/DefaultMacroContentParser.java 2010-12-17 13:07:48 UTC (rev 33583) @@ -0,0 +1,105 @@ +/* [...] + */ +package org.xwiki.rendering.internal.macro; + +import java.io.StringReader; +import java.util.List; + +import org.xwiki.component.annotation.Component; +import org.xwiki.component.annotation.Requirement; +import org.xwiki.component.manager.ComponentLookupException; +import org.xwiki.component.manager.ComponentManager; +import org.xwiki.rendering.block.Block; +import org.xwiki.rendering.block.XDOM; +import org.xwiki.rendering.macro.MacroExecutionException; +import org.xwiki.rendering.parser.Parser; +import org.xwiki.rendering.syntax.Syntax; +import org.xwiki.rendering.transformation.MacroTransformationContext; +import org.xwiki.rendering.transformation.TransformationContext; +import org.xwiki.rendering.util.ParserUtils; + +/** + * Default implementation for {@link org.xwiki.rendering.internal.macro.MacroContentParser}. + * + * @version $Id$ + * @since 3.0M1 + */ +@Component +public class DefaultMacroContentParser implements MacroContentParser +{ + /** + * Used to look up the syntax parser to use for parsing the content. + */ + @Requirement + private ComponentManager componentManager; + + /** + * Utility to remove the top level paragraph. + */ + private ParserUtils parserUtils = new ParserUtils(); + + /** + * {@inheritDoc} + * @see MacroContentParser#parse(String, MacroTransformationContext, boolean, boolean) + */ + public List<Block> parse(String content, MacroTransformationContext macroContext, boolean transform, + boolean removeTopLevelParagraph) throws MacroExecutionException + { + try { + List<Block> blocks = getSyntaxParser(macroContext.getSyntax()).parse( + new StringReader(content)).getChildren(); + + if (transform && macroContext.getTransformation() != null) { + XDOM xdom = new XDOM(blocks); + TransformationContext txContext = new TransformationContext(xdom, macroContext.getSyntax()); + txContext.setId(macroContext.getId()); + try { + macroContext.getTransformation().transform(xdom, txContext); + } catch (Exception e) { + throw new MacroExecutionException("Failed to perform transformation", e); + } + blocks = xdom.getChildren(); + } + + if (removeTopLevelParagraph) { + this.parserUtils.removeTopLevelParagraph(blocks); + } + return blocks; + } catch (Exception e) { + throw new MacroExecutionException("Failed to parse content [" + content + "]", e); + } + } + + /** + * Get the parser for the current syntax. + * + * @param syntax the current syntax of the title content + * @return the parser for the current syntax + * @throws org.xwiki.rendering.macro.MacroExecutionException Failed to find source parser. + */ + private Parser getSyntaxParser(Syntax syntax) throws MacroExecutionException + { + try { + return this.componentManager.lookup(Parser.class, syntax.toIdString()); + } catch (ComponentLookupException e) { + throw new MacroExecutionException("Failed to find source parser for syntax [" + syntax + "]", e); + } + } +}
Copied: platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/java/org/xwiki/rendering/internal/macro/MacroContentParser.java (from rev 33541, platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/internal/macro/box/MacroContentParser.java) =================================================================== --- platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/java/org/xwiki/rendering/internal/macro/MacroContentParser.java (rev 0) +++ platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/java/org/xwiki/rendering/internal/macro/MacroContentParser.java 2010-12-17 13:07:48 UTC (rev 33583) @@ -0,0 +1,51 @@ +/* + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.xwiki.rendering.internal.macro; + +import java.util.List; + +import org.xwiki.component.annotation.ComponentRole; +import org.xwiki.rendering.block.Block; +import org.xwiki.rendering.macro.MacroExecutionException; +import org.xwiki.rendering.transformation.MacroTransformationContext; + +/** + * Parses content of a macro field (parameter, macro content) in a given syntax. + * + * @version $Id$ + * @since 3.0M1 + */ +@ComponentRole +public interface MacroContentParser +{ + /** + * Parses content of a macro field (parameter, macro content) in a given syntax and optionally remove the top level + * paragraph. + * + * @param content the content to parse + * @param macroContext the executing Macro context (from which to get the current syntax, etc) + * @param transform if true then executes transformations + * @param removeTopLevelParagraph whether the top level paragraph should be removed after parsing + * @return the result as a {@link org.xwiki.rendering.block.Block}s + * @throws MacroExecutionException in case of a parsing error + */ + List<Block> parse(String content, MacroTransformationContext macroContext, boolean transform, + boolean removeTopLevelParagraph) throws MacroExecutionException; +}
Modified: platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/java/org/xwiki/rendering/transformation/MacroTransformationContext.java =================================================================== --- platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/java/org/xwiki/rendering/transformation/MacroTransformationContext.java 2010-12-17 12:25:56 UTC (rev 33582) +++ platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/java/org/xwiki/rendering/transformation/MacroTransformationContext.java 2010-12-17 13:07:48 UTC (rev 33583) @@ -29,7 +29,7 @@ * * @version $Id$ */ -public class MacroTransformationContext +public class MacroTransformationContext implements Cloneable { /** * The context of the transformation process. @@ -181,4 +181,24 @@ { this.transformationContext.setId(id); } + + /** + * {@inheritDoc} + * @see Object#clone() + */ + @Override + public MacroTransformationContext clone() + { + MacroTransformationContext newContext; + try { + newContext = (MacroTransformationContext) super.clone(); + } catch (CloneNotSupportedException e) { + // Should never happen + throw new RuntimeException("Failed to clone object", e); + } + + newContext.transformationContext = getTransformationContext().clone(); + + return newContext; + } }
Modified: platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/resources/META-INF/components.txt =================================================================== --- platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/resources/META-INF/components.txt 2010-12-17 12:25:56 UTC (rev 33582) +++ platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/resources/META-INF/components.txt 2010-12-17 13:07:48 UTC (rev 33583) @@ -2,5 +2,6 @@ org.xwiki.rendering.internal.macro.DefaultMacroCategoryManager org.xwiki.rendering.internal.macro.DefaultMacroIdFactory org.xwiki.rendering.internal.macro.ResourceReferenceConverter +org.xwiki.rendering.internal.macro.DefaultMacroContentParser org.xwiki.rendering.internal.transformation.macro.MacroTransformation org.xwiki.rendering.internal.transformation.macro.DefaultMacroTransformationConfiguration
Added: platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/test/java/org/xwiki/rendering/internal/transformation/macro/MacroTransformationContextTest.java =================================================================== --- platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/test/java/org/xwiki/rendering/internal/transformation/macro/MacroTransformationContextTest.java (rev 0) +++ platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/test/java/org/xwiki/rendering/internal/transformation/macro/MacroTransformationContextTest.java 2010-12-17 13:07:48 UTC (rev 33583) @@ -0,0 +1,92 @@ +/* [...] + */ +package org.xwiki.rendering.internal.transformation.macro; + +import java.util.Arrays; +import java.util.Collections; + +import org.junit.Assert; +import org.junit.Test; +import org.xwiki.rendering.block.Block; +import org.xwiki.rendering.block.MacroBlock; +import org.xwiki.rendering.block.WordBlock; +import org.xwiki.rendering.block.XDOM; +import org.xwiki.rendering.syntax.Syntax; +import org.xwiki.rendering.transformation.MacroTransformationContext; +import org.xwiki.rendering.transformation.Transformation; +import org.xwiki.rendering.transformation.TransformationContext; +import org.xwiki.rendering.transformation.TransformationException; + +/** + * Unit tests for {@link MacroTransformationContext}. + * + * @version $Id$ + * @since 3.0M1 + */ +public class MacroTransformationContextTest +{ + @Test + public void testClone() + { + MacroTransformationContext context = new MacroTransformationContext(); + context.setId("id"); + context.setInline(true); + context.setSyntax(Syntax.XWIKI_2_0); + + XDOM xdom = new XDOM(Arrays.<Block>asList(new WordBlock("test1"))); + context.setXDOM(xdom); + + MacroBlock macroBlock = new MacroBlock("testmacro", Collections.<String, String>emptyMap(), null, false); + context.setCurrentMacroBlock(macroBlock); + + Transformation transformation = new Transformation() + { + public int getPriority() + { + throw new RuntimeException("dummy"); + } + + public void transform(XDOM dom, Syntax syntax) throws TransformationException + { + throw new RuntimeException("dummy"); + } + + public void transform(Block block, TransformationContext context) throws TransformationException + { + throw new RuntimeException("dummy"); + } + + public int compareTo(Transformation transformation) + { + throw new RuntimeException("dummy"); + } + }; + context.setTransformation(transformation); + + MacroTransformationContext newContext = context.clone(); + Assert.assertNotSame(context, newContext); + Assert.assertEquals("id", newContext.getId()); + Assert.assertEquals(true, newContext.isInline()); + Assert.assertEquals(Syntax.XWIKI_2_0, newContext.getSyntax()); + Assert.assertEquals(xdom, newContext.getXDOM()); + Assert.assertEquals(macroBlock, newContext.getCurrentMacroBlock()); + Assert.assertEquals(transformation, newContext.getTransformation()); + } +}
_______________________________________________ notifications mailing list notifications@xwiki.org http://lists.xwiki.org/mailman/listinfo/notifications
-- Thomas Mortagne
On Dec 17, 2010, at 2:37 PM, Thomas Mortagne wrote:
On Fri, Dec 17, 2010 at 14:07, vmassol <platform-notifications@xwiki.org> wrote:
Author: vmassol Date: 2010-12-17 14:07:48 +0100 (Fri, 17 Dec 2010) New Revision: 33583
Added: platform/core/trunk/xwiki-model/src/main/java/org/xwiki/model/internal/reference/ExplicitStringAttachmentReferenceResolver.java platform/core/trunk/xwiki-model/src/test/java/org/xwiki/model/internal/reference/ExplicitStringAttachmentReferenceResolverTest.java platform/core/trunk/xwiki-rendering/xwiki-rendering-api/src/test/java/org/xwiki/rendering/transformation/ platform/core/trunk/xwiki-rendering/xwiki-rendering-api/src/test/java/org/xwiki/rendering/transformation/TransformationContextTest.java platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/java/org/xwiki/rendering/internal/macro/DefaultMacroContentParser.java platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/java/org/xwiki/rendering/internal/macro/MacroContentParser.java platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/test/java/org/xwiki/rendering/internal/transformation/macro/MacroTransformationContextTest.java Removed: platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/internal/macro/box/DefaultMacroContentParser.java platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/internal/macro/box/MacroContentParser.java Modified: platform/core/trunk/pom.xml platform/core/trunk/xwiki-bridge/pom.xml platform/core/trunk/xwiki-bridge/src/main/java/org/xwiki/bridge/DocumentModelBridge.java platform/core/trunk/xwiki-model/src/main/resources/META-INF/components.txt platform/core/trunk/xwiki-rendering/xwiki-rendering-api/src/main/java/org/xwiki/rendering/transformation/TransformationContext.java platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/internal/macro/box/DefaultBoxMacro.java platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/java/org/xwiki/rendering/macro/box/AbstractBoxMacro.java platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-box/src/main/resources/META-INF/components.txt platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-include/src/main/java/org/xwiki/rendering/internal/macro/include/IncludeMacro.java platform/core/trunk/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-include/src/test/java/org/xwiki/rendering/internal/macro/IncludeMacroTest.java platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/java/org/xwiki/rendering/transformation/MacroTransformationContext.java platform/core/trunk/xwiki-rendering/xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/resources/META-INF/components.txt Log: XWIKI-5807: Add support for relative links/images in included documents
* First implementation. Current limitation: Doesn't work when links are generated by macros in the included document.
Modified: platform/core/trunk/pom.xml =================================================================== --- platform/core/trunk/pom.xml 2010-12-17 12:25:56 UTC (rev 33582) +++ platform/core/trunk/pom.xml 2010-12-17 13:07:48 UTC (rev 33583) @@ -192,6 +192,8 @@ <exclude>**/internal/**</exclude> <exclude>**/test/**</exclude> <!-- To be removed when we release 3.0 --> + <exclude>org/xwiki/bridge/DocumentModelBridge</exclude> + <exclude>org/xwiki/rendering/macro/box/AbstractBoxMacro</exclude> </excludes> </configuration> </plugin>
Modified: platform/core/trunk/xwiki-bridge/pom.xml =================================================================== --- platform/core/trunk/xwiki-bridge/pom.xml 2010-12-17 12:25:56 UTC (rev 33582) +++ platform/core/trunk/xwiki-bridge/pom.xml 2010-12-17 13:07:48 UTC (rev 33583) @@ -46,6 +46,11 @@ </dependency> <dependency> <groupId>org.xwiki.platform</groupId> + <artifactId>xwiki-core-rendering-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.xwiki.platform</groupId> <artifactId>xwiki-core-observation-local</artifactId>
Are you sure you need the implementation ? It should probably be xwiki-observation-api instead.
Fixed, thanks (note that it was there before my commit). -Vincent [snip]
participants (2)
-
Thomas Mortagne -
Vincent Massol