Search in sources :

Example 46 with MacroExecutionException

use of org.xwiki.rendering.macro.MacroExecutionException in project xwiki-platform by xwiki.

the class DefaultWikiMacro method validate.

/**
 * Check validity of the given macro parameters and content.
 *
 * @param parameters the macro parameters
 * @param macroContent the macro content
 * @throws MacroExecutionException given parameters of content is invalid
 */
private void validate(WikiMacroParameters parameters, String macroContent) throws MacroExecutionException {
    // First verify that all mandatory parameters are provided.
    // Note that we currently verify automatically mandatory parameters in Macro Transformation but for the moment
    // this is only checked for Java-based macros. Hence why we need to check here too.
    Map<String, ParameterDescriptor> parameterDescriptors = getDescriptor().getParameterDescriptorMap();
    for (ParameterDescriptor parameterDescriptor : parameterDescriptors.values()) {
        Object parameterValue = parameters.get(parameterDescriptor.getId());
        if (parameterDescriptor.isMandatory() && (null == parameterValue)) {
            throw new MacroParameterException(String.format("Parameter [%s] is mandatory", parameterDescriptor.getId()));
        }
        // Set default parameter value if applicable.
        Object parameterDefaultValue = parameterDescriptor.getDefaultValue();
        if (parameterValue == null && parameterDefaultValue != null) {
            parameters.set(parameterDescriptor.getId(), parameterDefaultValue);
        }
    }
    // Verify the a macro content is not empty if it was declared mandatory.
    if (getDescriptor().getContentDescriptor() != null && getDescriptor().getContentDescriptor().isMandatory()) {
        if (macroContent == null || macroContent.length() == 0) {
            throw new MacroExecutionException("Missing macro content: this macro requires content (a body)");
        }
    }
}
Also used : ParameterDescriptor(org.xwiki.rendering.macro.descriptor.ParameterDescriptor) MacroExecutionException(org.xwiki.rendering.macro.MacroExecutionException) MacroParameterException(org.xwiki.rendering.macro.parameter.MacroParameterException)

Example 47 with MacroExecutionException

use of org.xwiki.rendering.macro.MacroExecutionException in project xwiki-platform by xwiki.

the class DefaultWikiMacro method execute.

@Override
public List<Block> execute(WikiMacroParameters parameters, String macroContent, MacroTransformationContext context) throws MacroExecutionException {
    validate(parameters, macroContent);
    // Parse the wiki macro content.
    XDOM xdom = prepareWikiMacroContent(context);
    // Prepare macro context.
    Map<String, Object> macroBinding = new HashMap<>();
    macroBinding.put(MACRO_PARAMS_KEY, parameters);
    macroBinding.put(MACRO_CONTENT_KEY, macroContent);
    macroBinding.put(MACRO_DESCRIPTOR_KEY, getDescriptor());
    macroBinding.put(MACRO_CONTEXT_KEY, context);
    macroBinding.put(MACRO_RESULT_KEY, null);
    // Extension point to add more wiki macro bindings
    try {
        List<WikiMacroBindingInitializer> bindingInitializers = this.componentManager.getInstanceList(WikiMacroBindingInitializer.class);
        for (WikiMacroBindingInitializer bindingInitializer : bindingInitializers) {
            bindingInitializer.initialize(this.macroDocumentReference, parameters, macroContent, context, macroBinding);
        }
    } catch (ComponentLookupException e) {
    // TODO: we should probably log something but that should never happen
    }
    // Execute the macro
    ObservationManager observation = null;
    try {
        observation = this.componentManager.getInstance(ObservationManager.class);
    } catch (ComponentLookupException e) {
    // TODO: maybe log something
    }
    // Get XWiki context
    Map<String, Object> xwikiContext = null;
    try {
        Execution execution = this.componentManager.getInstance(Execution.class);
        ExecutionContext econtext = execution.getContext();
        if (econtext != null) {
            xwikiContext = (Map<String, Object>) execution.getContext().getProperty("xwikicontext");
        }
    } catch (ComponentLookupException e) {
    // TODO: maybe log something
    }
    try {
        Transformation macroTransformation = this.componentManager.getInstance(Transformation.class, MACRO_HINT);
        if (xwikiContext != null) {
            // Place macro context inside xwiki context ($xcontext.macro).
            xwikiContext.put(MACRO_KEY, macroBinding);
        }
        MacroBlock wikiMacroBlock = context.getCurrentMacroBlock();
        MacroMarkerBlock wikiMacroMarker = new MacroMarkerBlock(wikiMacroBlock.getId(), wikiMacroBlock.getParameters(), wikiMacroBlock.getContent(), xdom.getChildren(), wikiMacroBlock.isInline());
        // Make sure to use provided metadatas
        MetaDataBlock metaDataBlock = new MetaDataBlock(Collections.<Block>singletonList(wikiMacroMarker), xdom.getMetaData());
        // Make sure the context XDOM contains the wiki macro content
        wikiMacroBlock.getParent().replaceChild(metaDataBlock, wikiMacroBlock);
        // "Emulate" the fact that wiki macro block is still part of the XDOM (what is in the XDOM is a
        // MacroMarkerBlock and MacroTransformationContext current macro block only support MacroBlock so we can't
        // switch it without breaking some APIs)
        wikiMacroBlock.setParent(metaDataBlock.getParent());
        wikiMacroBlock.setNextSiblingBlock(metaDataBlock.getNextSibling());
        wikiMacroBlock.setPreviousSiblingBlock(metaDataBlock.getPreviousSibling());
        try {
            if (observation != null) {
                observation.notify(STARTEXECUTION_EVENT, this, macroBinding);
            }
            // Perform internal macro transformations.
            TransformationContext txContext = new TransformationContext(context.getXDOM(), this.syntax);
            txContext.setId(context.getId());
            RenderingContext renderingContext = componentManager.getInstance(RenderingContext.class);
            ((MutableRenderingContext) renderingContext).transformInContext(macroTransformation, txContext, wikiMacroMarker);
        } finally {
            // Restore context XDOM to its previous state
            metaDataBlock.getParent().replaceChild(wikiMacroBlock, metaDataBlock);
        }
        return extractResult(wikiMacroMarker.getChildren(), macroBinding, context);
    } catch (Exception ex) {
        throw new MacroExecutionException("Error while performing internal macro transformations", ex);
    } finally {
        if (xwikiContext != null) {
            xwikiContext.remove(MACRO_KEY);
        }
        if (observation != null) {
            observation.notify(ENDEXECUTION_EVENT, this);
        }
    }
}
Also used : RenderingContext(org.xwiki.rendering.transformation.RenderingContext) MutableRenderingContext(org.xwiki.rendering.internal.transformation.MutableRenderingContext) Transformation(org.xwiki.rendering.transformation.Transformation) XDOM(org.xwiki.rendering.block.XDOM) HashMap(java.util.HashMap) MacroMarkerBlock(org.xwiki.rendering.block.MacroMarkerBlock) ComponentLookupException(org.xwiki.component.manager.ComponentLookupException) ObservationManager(org.xwiki.observation.ObservationManager) TransformationContext(org.xwiki.rendering.transformation.TransformationContext) MacroTransformationContext(org.xwiki.rendering.transformation.MacroTransformationContext) MacroExecutionException(org.xwiki.rendering.macro.MacroExecutionException) ComponentLookupException(org.xwiki.component.manager.ComponentLookupException) MacroParameterException(org.xwiki.rendering.macro.parameter.MacroParameterException) Execution(org.xwiki.context.Execution) ExecutionContext(org.xwiki.context.ExecutionContext) MacroExecutionException(org.xwiki.rendering.macro.MacroExecutionException) MutableRenderingContext(org.xwiki.rendering.internal.transformation.MutableRenderingContext) MacroBlock(org.xwiki.rendering.block.MacroBlock) MetaDataBlock(org.xwiki.rendering.block.MetaDataBlock)

Example 48 with MacroExecutionException

use of org.xwiki.rendering.macro.MacroExecutionException in project xwiki-platform by xwiki.

the class TranslationMacro method execute.

@Override
public List<Block> execute(TranslationMacroParameters parameters, String content, MacroTransformationContext context) throws MacroExecutionException {
    Locale locale = parameters.getLocale() != null ? parameters.getLocale() : this.localizationContext.getCurrentLocale();
    Translation translation = this.localization.getTranslation(parameters.getKey(), locale);
    List<Block> blocks;
    if (translation != null) {
        Block block = parameters.getParameters() != null ? translation.render(locale, (Object[]) parameters.getParameters()) : translation.render(locale);
        if (block instanceof CompositeBlock) {
            blocks = block.getChildren();
        } else {
            blocks = Arrays.asList(block);
        }
        if (!context.getCurrentMacroBlock().isInline()) {
            // Make the content standalone
            blocks = Arrays.<Block>asList(new GroupBlock(blocks));
        }
    } else if (content != null) {
        blocks = this.macroContentParser.parse(content, context, false, context.getCurrentMacroBlock().isInline()).getChildren();
    } else {
        try {
            blocks = this.plainParser.parse(new StringReader(parameters.getKey())).getChildren();
            if (context.getCurrentMacroBlock().isInline()) {
                PARSERUTILS.removeTopLevelParagraph(blocks);
            }
        } catch (ParseException e) {
            throw new MacroExecutionException("Failed to parse key [" + parameters.getKey() + "]", e);
        }
    }
    return blocks;
}
Also used : Locale(java.util.Locale) Translation(org.xwiki.localization.Translation) GroupBlock(org.xwiki.rendering.block.GroupBlock) StringReader(java.io.StringReader) MacroExecutionException(org.xwiki.rendering.macro.MacroExecutionException) CompositeBlock(org.xwiki.rendering.block.CompositeBlock) Block(org.xwiki.rendering.block.Block) GroupBlock(org.xwiki.rendering.block.GroupBlock) CompositeBlock(org.xwiki.rendering.block.CompositeBlock) ParseException(org.xwiki.rendering.parser.ParseException)

Aggregations

MacroExecutionException (org.xwiki.rendering.macro.MacroExecutionException)48 Test (org.junit.Test)12 Block (org.xwiki.rendering.block.Block)12 MacroTransformationContext (org.xwiki.rendering.transformation.MacroTransformationContext)10 DocumentReference (org.xwiki.model.reference.DocumentReference)9 DocumentModelBridge (org.xwiki.bridge.DocumentModelBridge)7 MacroBlock (org.xwiki.rendering.block.MacroBlock)7 XDOM (org.xwiki.rendering.block.XDOM)7 MetaDataBlock (org.xwiki.rendering.block.MetaDataBlock)6 Expectations (org.jmock.Expectations)5 DocumentDisplayerParameters (org.xwiki.display.internal.DocumentDisplayerParameters)5 StringReader (java.io.StringReader)4 ComponentLookupException (org.xwiki.component.manager.ComponentLookupException)4 ResourceReference (org.xwiki.rendering.listener.reference.ResourceReference)4 IncludeMacroParameters (org.xwiki.rendering.macro.include.IncludeMacroParameters)4 HashMap (java.util.HashMap)3 AttachmentReference (org.xwiki.model.reference.AttachmentReference)3 GroupBlock (org.xwiki.rendering.block.GroupBlock)3 MacroMarkerBlock (org.xwiki.rendering.block.MacroMarkerBlock)3 TableBlock (org.xwiki.rendering.block.TableBlock)3