On Fri, Dec 17, 2010 at 14:07, vmassol <platform-notifications(a)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(a)xwiki.org
http://lists.xwiki.org/mailman/listinfo/notifications
--
Thomas Mortagne