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;
}
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());
}
}
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);
}
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));
}
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;
}
Aggregations