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