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