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