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