private DocumentReference resolve(MacroBlock block, IncludeMacroParameters parameters) throws MacroExecutionException { String reference = parameters.getReference(); if (reference == null) { throw new MacroExecutionException( "You must specify a 'reference' parameter pointing to the entity to include."); } return this.macroDocumentReferenceResolver.resolve(reference, block); }
@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.getDocument(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()); 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); }