Search in sources :

Example 21 with DocumentModelBridge

use of org.xwiki.bridge.DocumentModelBridge in project xwiki-platform by xwiki.

the class IncludeMacro method execute.

@Override
public List<Block> execute(IncludeMacroParameters parameters, String content, MacroTransformationContext context) throws MacroExecutionException {
    // Step 1: Perform checks.
    if (parameters.getReference() == null) {
        throw new MacroExecutionException("You must specify a 'reference' parameter pointing to the entity to include.");
    }
    DocumentReference includedReference = resolve(context.getCurrentMacroBlock(), parameters);
    checkRecursiveInclusion(context.getCurrentMacroBlock(), includedReference);
    if (!this.documentAccessBridge.isDocumentViewable(includedReference)) {
        throw new MacroExecutionException(String.format("Current user [%s] doesn't have view rights on document [%s]", this.documentAccessBridge.getCurrentUserReference(), this.defaultEntityReferenceSerializer.serialize(includedReference)));
    }
    Context parametersContext = parameters.getContext();
    // Step 2: Retrieve the included document.
    DocumentModelBridge documentBridge;
    try {
        documentBridge = this.documentAccessBridge.getDocumentInstance(includedReference);
    } catch (Exception e) {
        throw new MacroExecutionException("Failed to load Document [" + this.defaultEntityReferenceSerializer.serialize(includedReference) + "]", e);
    }
    // Step 3: Display the content of the included document.
    // Check the value of the "context" parameter.
    // 
    // If CONTEXT_NEW then display the content in an isolated execution and transformation context.
    // 
    // if CONTEXT_CURRENT then display the content without performing any transformations (we don't want any Macro
    // to be executed at this stage since they should be executed by the currently running Macro Transformation.
    DocumentDisplayerParameters displayParameters = new DocumentDisplayerParameters();
    displayParameters.setContentTransformed(parametersContext == Context.NEW);
    displayParameters.setExecutionContextIsolated(displayParameters.isContentTransformed());
    displayParameters.setSectionId(parameters.getSection());
    displayParameters.setTransformationContextIsolated(displayParameters.isContentTransformed());
    displayParameters.setTransformationContextRestricted(context.getTransformationContext().isRestricted());
    displayParameters.setTargetSyntax(context.getTransformationContext().getTargetSyntax());
    displayParameters.setContentTranslated(true);
    Stack<Object> references = this.inclusionsBeingExecuted.get();
    if (parametersContext == Context.NEW) {
        if (references == null) {
            references = new Stack<Object>();
            this.inclusionsBeingExecuted.set(references);
        }
        references.push(includedReference);
    }
    XDOM result;
    try {
        result = this.documentDisplayer.display(documentBridge, displayParameters);
    } catch (Exception e) {
        throw new MacroExecutionException(e.getMessage(), e);
    } finally {
        if (parametersContext == Context.NEW) {
            references.pop();
        }
    }
    // Step 4: Wrap Blocks in a MetaDataBlock with the "source" meta data specified so that we know from where the
    // content comes and "base" meta data so that reference are properly resolved
    MetaDataBlock metadata = new MetaDataBlock(result.getChildren(), result.getMetaData());
    String source = this.defaultEntityReferenceSerializer.serialize(includedReference);
    metadata.getMetaData().addMetaData(MetaData.SOURCE, source);
    if (parametersContext == Context.NEW) {
        metadata.getMetaData().addMetaData(MetaData.BASE, source);
    }
    return Arrays.<Block>asList(metadata);
}
Also used : MacroTransformationContext(org.xwiki.rendering.transformation.MacroTransformationContext) Context(org.xwiki.rendering.macro.include.IncludeMacroParameters.Context) DocumentDisplayerParameters(org.xwiki.display.internal.DocumentDisplayerParameters) XDOM(org.xwiki.rendering.block.XDOM) DocumentModelBridge(org.xwiki.bridge.DocumentModelBridge) MacroExecutionException(org.xwiki.rendering.macro.MacroExecutionException) Block(org.xwiki.rendering.block.Block) MacroMarkerBlock(org.xwiki.rendering.block.MacroMarkerBlock) MetaDataBlock(org.xwiki.rendering.block.MetaDataBlock) MacroBlock(org.xwiki.rendering.block.MacroBlock) DocumentReference(org.xwiki.model.reference.DocumentReference) MacroExecutionException(org.xwiki.rendering.macro.MacroExecutionException) MetaDataBlock(org.xwiki.rendering.block.MetaDataBlock)

Example 22 with DocumentModelBridge

use of org.xwiki.bridge.DocumentModelBridge 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 23 with DocumentModelBridge

use of org.xwiki.bridge.DocumentModelBridge 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 24 with DocumentModelBridge

use of org.xwiki.bridge.DocumentModelBridge in project xwiki-platform by xwiki.

the class IntegrationTests method initialize.

@RenderingTestSuite.Initialized
public void initialize(MockitoComponentManager componentManager) throws Exception {
    // For performance reasons we mock some components to avoid having to draw all oldcore components
    // Macro Reference Resolver
    DocumentReferenceResolver<String> macroResolver = componentManager.registerMockComponent(new DefaultParameterizedType(null, DocumentReferenceResolver.class, String.class), "macro");
    DocumentReference referencedDocumentReference = new DocumentReference("Wiki", "Space", "Page");
    when(macroResolver.resolve(eq("Space.Page"), any(MacroBlock.class))).thenReturn(referencedDocumentReference);
    // Document Access Bridge mock
    // Simulate the XDOM of the referenced document
    DocumentAccessBridge dab = componentManager.registerMockComponent(DocumentAccessBridge.class);
    DocumentModelBridge dmb = mock(DocumentModelBridge.class);
    when(dab.getTranslatedDocumentInstance(referencedDocumentReference)).thenReturn(dmb);
    Parser parser = componentManager.getInstance(Parser.class, "xwiki/2.1");
    XDOM xdom = parser.parse(new StringReader("= heading1 =\n==heading2=="));
    when(dmb.getXDOM()).thenReturn(xdom);
}
Also used : DocumentReferenceResolver(org.xwiki.model.reference.DocumentReferenceResolver) XDOM(org.xwiki.rendering.block.XDOM) DocumentModelBridge(org.xwiki.bridge.DocumentModelBridge) DocumentAccessBridge(org.xwiki.bridge.DocumentAccessBridge) StringReader(java.io.StringReader) DefaultParameterizedType(org.xwiki.component.util.DefaultParameterizedType) DocumentReference(org.xwiki.model.reference.DocumentReference) MacroBlock(org.xwiki.rendering.block.MacroBlock) Parser(org.xwiki.rendering.parser.Parser)

Example 25 with DocumentModelBridge

use of org.xwiki.bridge.DocumentModelBridge in project xwiki-platform by xwiki.

the class IncludeMacroTest method testIncludeMacroWithRecursiveIncludeContextNew.

@Test
public void testIncludeMacroWithRecursiveIncludeContextNew() throws Exception {
    final DocumentDisplayer mockDocumentDisplayer = getMockery().mock(DocumentDisplayer.class);
    this.includeMacro.setDocumentAccessBridge(mockSetup.bridge);
    this.includeMacro.setDocumentDisplayer(mockDocumentDisplayer);
    final MacroTransformationContext macroContext = createMacroTransformationContext("wiki:space.page", false);
    final IncludeMacroParameters parameters = new IncludeMacroParameters();
    parameters.setReference("wiki:space.page");
    parameters.setContext(Context.NEW);
    getMockery().checking(new Expectations() {

        {
            allowing(mockDocumentReferenceResolver).resolve("wiki:space.page", macroContext.getCurrentMacroBlock());
            will(returnValue(new DocumentReference("wiki", "space", "page")));
            allowing(mockSetup.bridge).isDocumentViewable(with(any(DocumentReference.class)));
            will(returnValue(true));
            allowing(mockSetup.bridge).getDocumentInstance(with(any(DocumentReference.class)));
            will(returnValue(null));
            allowing(mockDocumentDisplayer).display(with(same((DocumentModelBridge) null)), with(any(DocumentDisplayerParameters.class)));
            will(new CustomAction("recursively call the include macro again") {

                @Override
                public Object invoke(Invocation invocation) throws Throwable {
                    try {
                        includeMacro.execute(parameters, null, macroContext);
                    } catch (Exception expected) {
                        if (expected.getMessage().contains("Found recursive inclusion")) {
                            throw new ExpectedRecursiveInclusionException();
                        }
                    }
                    return true;
                }
            });
        }
    });
    try {
        this.includeMacro.execute(parameters, null, macroContext);
        Assert.fail("The include macro hasn't checked the recursive inclusion");
    } catch (MacroExecutionException expected) {
        if (!(expected.getCause() instanceof ExpectedRecursiveInclusionException)) {
            throw expected;
        }
    }
}
Also used : Expectations(org.jmock.Expectations) DocumentDisplayerParameters(org.xwiki.display.internal.DocumentDisplayerParameters) DocumentDisplayer(org.xwiki.display.internal.DocumentDisplayer) DocumentModelBridge(org.xwiki.bridge.DocumentModelBridge) Invocation(org.jmock.api.Invocation) CustomAction(org.jmock.lib.action.CustomAction) IncludeMacroParameters(org.xwiki.rendering.macro.include.IncludeMacroParameters) MacroTransformationContext(org.xwiki.rendering.transformation.MacroTransformationContext) MacroExecutionException(org.xwiki.rendering.macro.MacroExecutionException) DocumentReference(org.xwiki.model.reference.DocumentReference) MacroExecutionException(org.xwiki.rendering.macro.MacroExecutionException) Test(org.junit.Test)

Aggregations

DocumentModelBridge (org.xwiki.bridge.DocumentModelBridge)58 DocumentReference (org.xwiki.model.reference.DocumentReference)43 Test (org.junit.Test)39 Expectations (org.jmock.Expectations)18 XDOM (org.xwiki.rendering.block.XDOM)18 DocumentAccessBridge (org.xwiki.bridge.DocumentAccessBridge)14 Syntax (org.xwiki.rendering.syntax.Syntax)11 MacroTransformationContext (org.xwiki.rendering.transformation.MacroTransformationContext)10 MacroBlock (org.xwiki.rendering.block.MacroBlock)9 DocumentDisplayerParameters (org.xwiki.display.internal.DocumentDisplayerParameters)8 ResourceReference (org.xwiki.rendering.listener.reference.ResourceReference)7 MacroExecutionException (org.xwiki.rendering.macro.MacroExecutionException)7 Block (org.xwiki.rendering.block.Block)6 HashMap (java.util.HashMap)5 DefaultParameterizedType (org.xwiki.component.util.DefaultParameterizedType)5 DocumentDisplayer (org.xwiki.display.internal.DocumentDisplayer)5 MetaDataBlock (org.xwiki.rendering.block.MetaDataBlock)5 MetaData (org.xwiki.rendering.listener.MetaData)5 DocumentResourceReference (org.xwiki.rendering.listener.reference.DocumentResourceReference)5 StringReader (java.io.StringReader)4