Search in sources :

Example 6 with TransformationContext

use of org.xwiki.rendering.transformation.TransformationContext 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 7 with TransformationContext

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

the class DefaultWikiComponentMethodExecutor method execute.

@Override
public Object execute(Method method, Object[] args, DocumentReference componentDocumentReference, XDOM xdom, Syntax syntax, Map<String, Object> methodContext) throws WikiComponentRuntimeException {
    // Prepare and put the method context in the XWiki Context
    Map<Object, Object> xwikiContext = (Map<Object, Object>) execution.getContext().getProperty("xwikicontext");
    this.prepareMethodContext(methodContext, args);
    xwikiContext.put("method", methodContext);
    // Save current context document, to put it back after the execution.
    Object contextDoc = xwikiContext.get(XWIKI_CONTEXT_DOC_KEY);
    try {
        // component document and not the context one.
        try {
            xwikiContext.put(XWIKI_CONTEXT_DOC_KEY, dab.getDocumentInstance(componentDocumentReference));
        } catch (Exception e) {
            throw new WikiComponentRuntimeException(String.format("Failed to load wiki component document [%s]", componentDocumentReference), e);
        }
        // We need to clone the xdom to avoid transforming the original and make it useless after the first
        // transformation
        XDOM transformedXDOM = xdom.clone();
        // Perform internal macro transformations
        try {
            TransformationContext transformationContext = new TransformationContext(transformedXDOM, syntax);
            transformationContext.setId(method.getClass().getName() + "#" + method.getName());
            ((MutableRenderingContext) renderingContext).transformInContext(macroTransformation, transformationContext, transformedXDOM);
        } catch (TransformationException e) {
            throw new WikiComponentRuntimeException(String.format("Error while executing wiki component macro transformation for method [%s]", method.getName()), e);
        }
        if (!method.getReturnType().getName().equals("void")) {
            if (methodContext.get(OUTPUT_KEY) != null && ((WikiMethodOutputHandler) methodContext.get(OUTPUT_KEY)).getValue() != null) {
                return method.getReturnType().cast(((WikiMethodOutputHandler) methodContext.get(OUTPUT_KEY)).getValue());
            } else {
                return this.castRenderedContent(transformedXDOM, method);
            }
        } else {
            return null;
        }
    } finally {
        if (contextDoc != null) {
            xwikiContext.put(XWIKI_CONTEXT_DOC_KEY, contextDoc);
        }
    }
}
Also used : TransformationException(org.xwiki.rendering.transformation.TransformationException) XDOM(org.xwiki.rendering.block.XDOM) HashMap(java.util.HashMap) Map(java.util.Map) TransformationContext(org.xwiki.rendering.transformation.TransformationContext) TransformationException(org.xwiki.rendering.transformation.TransformationException) WikiComponentRuntimeException(org.xwiki.component.wiki.WikiComponentRuntimeException) ConversionException(org.xwiki.properties.converter.ConversionException) WikiComponentRuntimeException(org.xwiki.component.wiki.WikiComponentRuntimeException) MutableRenderingContext(org.xwiki.rendering.internal.transformation.MutableRenderingContext)

Example 8 with TransformationContext

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

the class MacroContentExecutorTest method executeWhenTransformationException.

@Test
public void executeWhenTransformationException() throws Exception {
    XDOM parsedBlocks = new XDOM(Collections.emptyList());
    ContentParser contentParser = this.mocker.getInstance(ContentParser.class);
    when(contentParser.parse("", Syntax.PLAIN_1_0)).thenReturn(parsedBlocks);
    TransformationContext transformationContext = new TransformationContext();
    MacroTransformationContext context = new MacroTransformationContext(transformationContext);
    Transformation macroTransformation = this.mocker.getInstance(Transformation.class, "macro");
    doThrow(new TransformationException("error")).when(macroTransformation).transform(parsedBlocks, transformationContext);
    try {
        this.mocker.getComponentUnderTest().execute("", Syntax.PLAIN_1_0, context);
        fail("Should have raised a ContentExecutorException");
    } catch (ContentExecutorException expected) {
        assertEquals("Failed to execute content", expected.getMessage());
    }
}
Also used : Transformation(org.xwiki.rendering.transformation.Transformation) TransformationException(org.xwiki.rendering.transformation.TransformationException) XDOM(org.xwiki.rendering.block.XDOM) MacroTransformationContext(org.xwiki.rendering.transformation.MacroTransformationContext) ContentParser(org.xwiki.rendering.parser.ContentParser) ContentExecutorException(org.xwiki.rendering.executor.ContentExecutorException) MacroTransformationContext(org.xwiki.rendering.transformation.MacroTransformationContext) TransformationContext(org.xwiki.rendering.transformation.TransformationContext) Test(org.junit.Test)

Example 9 with TransformationContext

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

the class MacroContentExecutorTest method executeWithSource.

@Test
public void executeWithSource() throws Exception {
    XDOM parsedBlocks = new XDOM(Collections.emptyList());
    ContentParser contentParser = this.mocker.getInstance(ContentParser.class);
    when(contentParser.parse("", Syntax.PLAIN_1_0, DOCUMENT_REFERENCE)).thenReturn(parsedBlocks);
    TransformationContext transformationContext = new TransformationContext();
    MacroTransformationContext context = new MacroTransformationContext(transformationContext);
    this.mocker.getComponentUnderTest().execute("", Syntax.PLAIN_1_0, DOCUMENT_REFERENCE, context);
    // The test is here: Verify that the Macro Transformation has been called
    Transformation macroTransformation = this.mocker.getInstance(Transformation.class, "macro");
    verify(macroTransformation).transform(parsedBlocks, transformationContext);
}
Also used : Transformation(org.xwiki.rendering.transformation.Transformation) XDOM(org.xwiki.rendering.block.XDOM) MacroTransformationContext(org.xwiki.rendering.transformation.MacroTransformationContext) ContentParser(org.xwiki.rendering.parser.ContentParser) MacroTransformationContext(org.xwiki.rendering.transformation.MacroTransformationContext) TransformationContext(org.xwiki.rendering.transformation.TransformationContext) Test(org.junit.Test)

Example 10 with TransformationContext

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

the class MacroContentExecutorTest method executeWithNoSource.

@Test
public void executeWithNoSource() throws Exception {
    XDOM parsedBlocks = new XDOM(Collections.emptyList());
    ContentParser contentParser = this.mocker.getInstance(ContentParser.class);
    when(contentParser.parse("", Syntax.PLAIN_1_0)).thenReturn(parsedBlocks);
    TransformationContext transformationContext = new TransformationContext();
    MacroTransformationContext context = new MacroTransformationContext(transformationContext);
    this.mocker.getComponentUnderTest().execute("", Syntax.PLAIN_1_0, context);
    // The test is here: Verify that the Macro Transformation has been called
    Transformation macroTransformation = this.mocker.getInstance(Transformation.class, "macro");
    verify(macroTransformation).transform(parsedBlocks, transformationContext);
}
Also used : Transformation(org.xwiki.rendering.transformation.Transformation) XDOM(org.xwiki.rendering.block.XDOM) MacroTransformationContext(org.xwiki.rendering.transformation.MacroTransformationContext) ContentParser(org.xwiki.rendering.parser.ContentParser) MacroTransformationContext(org.xwiki.rendering.transformation.MacroTransformationContext) TransformationContext(org.xwiki.rendering.transformation.TransformationContext) Test(org.junit.Test)

Aggregations

TransformationContext (org.xwiki.rendering.transformation.TransformationContext)19 XDOM (org.xwiki.rendering.block.XDOM)16 MutableRenderingContext (org.xwiki.rendering.internal.transformation.MutableRenderingContext)8 Test (org.junit.Test)7 WikiPrinter (org.xwiki.rendering.renderer.printer.WikiPrinter)6 Transformation (org.xwiki.rendering.transformation.Transformation)6 StringReader (java.io.StringReader)5 Parser (org.xwiki.rendering.parser.Parser)5 MacroTransformationContext (org.xwiki.rendering.transformation.MacroTransformationContext)5 HashMap (java.util.HashMap)4 DefaultWikiPrinter (org.xwiki.rendering.renderer.printer.DefaultWikiPrinter)4 TransformationException (org.xwiki.rendering.transformation.TransformationException)4 ComponentLookupException (org.xwiki.component.manager.ComponentLookupException)3 ContentParser (org.xwiki.rendering.parser.ContentParser)3 BlockRenderer (org.xwiki.rendering.renderer.BlockRenderer)3 RenderingContext (org.xwiki.rendering.transformation.RenderingContext)3 TransformationManager (org.xwiki.rendering.transformation.TransformationManager)3 Block (org.xwiki.rendering.block.Block)2 CompositeBlock (org.xwiki.rendering.block.CompositeBlock)2 MetaDataBlock (org.xwiki.rendering.block.MetaDataBlock)2