Search in sources :

Example 11 with MacroTransformationContext

use of org.xwiki.rendering.transformation.MacroTransformationContext in project xwiki-platform by xwiki.

the class ContextMacro method execute.

@Override
public List<Block> execute(ContextMacroParameters parameters, String content, MacroTransformationContext context) throws MacroExecutionException {
    if (parameters.getDocument() == null) {
        throw new MacroExecutionException("You must specify a 'document' parameter pointing to the document to " + "set in the context as the current document.");
    }
    DocumentReference referencedDocReference = this.macroDocumentReferenceResolver.resolve(parameters.getDocument(), context.getCurrentMacroBlock());
    boolean currentContextHasProgrammingRights = this.documentAccessBridge.hasProgrammingRights();
    List<Block> result;
    try {
        Map<String, Object> backupObjects = new HashMap<>();
        try {
            this.documentAccessBridge.pushDocumentInContext(backupObjects, referencedDocReference);
            // error since it would be a security breach otherwise.
            if (this.documentAccessBridge.hasProgrammingRights() && !currentContextHasProgrammingRights) {
                throw new MacroExecutionException("Current document must have programming rights since the " + "context document provided [" + parameters.getDocument() + "] has programming rights.");
            }
            MetaData metadata = new MetaData();
            metadata.addMetaData(MetaData.SOURCE, parameters.getDocument());
            metadata.addMetaData(MetaData.BASE, parameters.getDocument());
            XDOM xdom = this.contentParser.parse(content, context, false, metadata, false);
            // Configure the  Transformation Context depending on the mode asked.
            if (parameters.getTransformationContext() == TransformationContextMode.DOCUMENT || parameters.getTransformationContext() == TransformationContextMode.TRANSFORMATIONS) {
                // Apply the transformations but with a Transformation Context having the XDOM of the passed
                // document so that macros execute on the passed document's XDOM (e.g. the TOC macro will generate
                // the toc for the passed document instead of the current document).
                DocumentModelBridge referencedDoc = this.documentAccessBridge.getTranslatedDocumentInstance(referencedDocReference);
                XDOM referencedXDOM = referencedDoc.getXDOM();
                if (parameters.getTransformationContext() == TransformationContextMode.TRANSFORMATIONS) {
                    // Get the XDOM from the referenced doc but with Transformations applied so that all macro are
                    // executed and contribute XDOM elements.
                    // IMPORTANT: This can be dangerous since it means executing macros, and thus also script macros
                    // defined in the referenced document. To be used with caution.
                    TransformationContext referencedTxContext = new TransformationContext(referencedXDOM, referencedDoc.getSyntax());
                    this.transformationManager.performTransformations(referencedXDOM, referencedTxContext);
                }
                // Now execute transformation on the context macro content but with the referenced XDOM in the
                // Transformation context!
                TransformationContext txContext = new TransformationContext(referencedXDOM, referencedDoc.getSyntax());
                this.transformationManager.performTransformations(xdom, txContext);
            }
            // Keep metadata so that the result stay associated to context properties when inserted in the parent
            // XDOM
            result = Arrays.asList((Block) new MetaDataBlock(xdom.getChildren(), xdom.getMetaData()));
        } finally {
            this.documentAccessBridge.popDocumentFromContext(backupObjects);
        }
    } catch (Exception e) {
        if (e instanceof MacroExecutionException) {
            throw (MacroExecutionException) e;
        } else {
            throw new MacroExecutionException(String.format("Failed to render page in the context of [%s]", referencedDocReference), e);
        }
    }
    return result;
}
Also used : XDOM(org.xwiki.rendering.block.XDOM) HashMap(java.util.HashMap) TransformationContext(org.xwiki.rendering.transformation.TransformationContext) MacroTransformationContext(org.xwiki.rendering.transformation.MacroTransformationContext) MacroExecutionException(org.xwiki.rendering.macro.MacroExecutionException) DocumentModelBridge(org.xwiki.bridge.DocumentModelBridge) MetaData(org.xwiki.rendering.listener.MetaData) MacroExecutionException(org.xwiki.rendering.macro.MacroExecutionException) Block(org.xwiki.rendering.block.Block) MetaDataBlock(org.xwiki.rendering.block.MetaDataBlock) DocumentReference(org.xwiki.model.reference.DocumentReference) MetaDataBlock(org.xwiki.rendering.block.MetaDataBlock)

Example 12 with MacroTransformationContext

use of org.xwiki.rendering.transformation.MacroTransformationContext in project xwiki-platform by xwiki.

the class ContextMacroTest method executeWithReferencedDocumentHavingProgrammingRightsButNotTheCallingDocument.

@Test
public void executeWithReferencedDocumentHavingProgrammingRightsButNotTheCallingDocument() throws Exception {
    MacroTransformationContext macroContext = new MacroTransformationContext();
    MacroBlock macroBlock = new MacroBlock("context", Collections.emptyMap(), false);
    macroContext.setCurrentMacroBlock(macroBlock);
    DocumentReferenceResolver<String> resolver = this.mocker.getInstance(DocumentReferenceResolver.TYPE_STRING, "macro");
    when(resolver.resolve("wiki:space.page", macroBlock)).thenReturn(new DocumentReference("wiki", "space", "page"));
    DocumentAccessBridge dab = this.mocker.getInstance(DocumentAccessBridge.class);
    when(dab.hasProgrammingRights()).thenReturn(false).thenReturn(true);
    ContextMacroParameters parameters = new ContextMacroParameters();
    parameters.setDocument("wiki:space.page");
    try {
        this.mocker.getComponentUnderTest().execute(parameters, "", macroContext);
        fail("Should have thrown an exception");
    } catch (MacroExecutionException expected) {
        assertEquals("Current document must have programming rights since the context document provided [" + "wiki:space.page] has programming rights.", expected.getMessage());
    }
}
Also used : MacroTransformationContext(org.xwiki.rendering.transformation.MacroTransformationContext) DocumentAccessBridge(org.xwiki.bridge.DocumentAccessBridge) MacroExecutionException(org.xwiki.rendering.macro.MacroExecutionException) ContextMacroParameters(org.xwiki.rendering.macro.context.ContextMacroParameters) DocumentReference(org.xwiki.model.reference.DocumentReference) MacroBlock(org.xwiki.rendering.block.MacroBlock) Test(org.junit.Test)

Example 13 with MacroTransformationContext

use of org.xwiki.rendering.transformation.MacroTransformationContext in project xwiki-platform by xwiki.

the class ContextMacroTest method executeWithRelativeDocumentReferenceParameter.

@Test
public void executeWithRelativeDocumentReferenceParameter() throws Exception {
    MacroBlock macroBlock = new MacroBlock("context", Collections.<String, String>emptyMap(), false);
    MacroTransformationContext macroContext = new MacroTransformationContext();
    macroContext.setSyntax(Syntax.XWIKI_2_0);
    macroContext.setCurrentMacroBlock(macroBlock);
    DocumentReferenceResolver<String> resolver = this.mocker.getInstance(DocumentReferenceResolver.TYPE_STRING, "macro");
    DocumentReference referencedDocumentReference = new DocumentReference("basewiki", "basespace", "page");
    when(resolver.resolve("page", macroBlock)).thenReturn(referencedDocumentReference);
    DocumentAccessBridge dab = this.mocker.getInstance(DocumentAccessBridge.class);
    DocumentModelBridge dmb = mock(DocumentModelBridge.class);
    when(dab.getTranslatedDocumentInstance(referencedDocumentReference)).thenReturn(dmb);
    MacroContentParser parser = this.mocker.getInstance(MacroContentParser.class);
    when(parser.parse(eq(""), same(macroContext), eq(false), any(MetaData.class), eq(false))).thenReturn(new XDOM(Collections.emptyList()));
    ContextMacroParameters parameters = new ContextMacroParameters();
    parameters.setDocument("page");
    this.mocker.getComponentUnderTest().execute(parameters, "", macroContext);
}
Also used : XDOM(org.xwiki.rendering.block.XDOM) DocumentModelBridge(org.xwiki.bridge.DocumentModelBridge) MacroContentParser(org.xwiki.rendering.macro.MacroContentParser) MetaData(org.xwiki.rendering.listener.MetaData) MacroTransformationContext(org.xwiki.rendering.transformation.MacroTransformationContext) DocumentAccessBridge(org.xwiki.bridge.DocumentAccessBridge) ContextMacroParameters(org.xwiki.rendering.macro.context.ContextMacroParameters) DocumentReference(org.xwiki.model.reference.DocumentReference) MacroBlock(org.xwiki.rendering.block.MacroBlock) Test(org.junit.Test)

Example 14 with MacroTransformationContext

use of org.xwiki.rendering.transformation.MacroTransformationContext in project xwiki-platform by xwiki.

the class CacheMacroTest method executeWithDifferentTimeToLive.

@Test
public void executeWithDifferentTimeToLive() throws Exception {
    CacheMacroParameters params = new CacheMacroParameters();
    MacroTransformationContext context = createMacroTransformationContext();
    params.setId("id");
    params.setMaxEntries(10);
    params.setTimeToLive(100);
    List<Block> result1 = this.cacheMacro.execute(params, "content1", context);
    // Execute a second time with different content but with different time to live param. This means another
    // cache will be used and thus the first cached content won't be returned.
    params.setTimeToLive(200);
    List<Block> result2 = this.cacheMacro.execute(params, "content2", context);
    assertFalse(result2.equals(result1));
}
Also used : CacheMacroParameters(org.xwiki.rendering.macro.cache.CacheMacroParameters) MacroTransformationContext(org.xwiki.rendering.transformation.MacroTransformationContext) Block(org.xwiki.rendering.block.Block) Test(org.junit.Test)

Example 15 with MacroTransformationContext

use of org.xwiki.rendering.transformation.MacroTransformationContext in project xwiki-platform by xwiki.

the class CacheMacroTest method createMacroTransformationContext.

private MacroTransformationContext createMacroTransformationContext() throws Exception {
    MacroTransformation macroTransformation = getComponentManager().getInstance(Transformation.class, "macro");
    MacroTransformationContext context = new MacroTransformationContext();
    context.setTransformation(macroTransformation);
    context.setSyntax(Syntax.XWIKI_2_0);
    return context;
}
Also used : MacroTransformationContext(org.xwiki.rendering.transformation.MacroTransformationContext) MacroTransformation(org.xwiki.rendering.internal.transformation.macro.MacroTransformation)

Aggregations

MacroTransformationContext (org.xwiki.rendering.transformation.MacroTransformationContext)41 Test (org.junit.Test)30 MacroBlock (org.xwiki.rendering.block.MacroBlock)17 DocumentReference (org.xwiki.model.reference.DocumentReference)15 Block (org.xwiki.rendering.block.Block)13 DocumentModelBridge (org.xwiki.bridge.DocumentModelBridge)10 XDOM (org.xwiki.rendering.block.XDOM)10 MacroExecutionException (org.xwiki.rendering.macro.MacroExecutionException)10 Expectations (org.jmock.Expectations)9 HashMap (java.util.HashMap)6 MacroMarkerBlock (org.xwiki.rendering.block.MacroMarkerBlock)6 MetaDataBlock (org.xwiki.rendering.block.MetaDataBlock)6 MetaData (org.xwiki.rendering.listener.MetaData)6 CacheMacroParameters (org.xwiki.rendering.macro.cache.CacheMacroParameters)6 IncludeMacroParameters (org.xwiki.rendering.macro.include.IncludeMacroParameters)6 ContextMacroParameters (org.xwiki.rendering.macro.context.ContextMacroParameters)5 Transformation (org.xwiki.rendering.transformation.Transformation)5 TransformationContext (org.xwiki.rendering.transformation.TransformationContext)5 StringWriter (java.io.StringWriter)4 DocumentAccessBridge (org.xwiki.bridge.DocumentAccessBridge)4