diff --git a/com.avaloq.tools.ddk.checkcfg.ui/src/com/avaloq/tools/ddk/checkcfg/ui/CheckCfgUiModule.java b/com.avaloq.tools.ddk.checkcfg.ui/src/com/avaloq/tools/ddk/checkcfg/ui/CheckCfgUiModule.java index 6df8cb665..b3721f481 100644 --- a/com.avaloq.tools.ddk.checkcfg.ui/src/com/avaloq/tools/ddk/checkcfg/ui/CheckCfgUiModule.java +++ b/com.avaloq.tools.ddk.checkcfg.ui/src/com/avaloq/tools/ddk/checkcfg/ui/CheckCfgUiModule.java @@ -15,12 +15,15 @@ import org.eclipse.xtext.ui.editor.IXtextEditorCallback; import org.eclipse.xtext.ui.editor.contentassist.ITemplateProposalProvider; import org.eclipse.xtext.ui.editor.templates.CrossReferenceTemplateVariableResolver; +import org.eclipse.xtext.ui.editor.templates.XtextTemplateContextType; import org.eclipse.xtext.xbase.compiler.GeneratorConfigProvider; import org.eclipse.xtext.xbase.compiler.IGeneratorConfigProvider; +import com.avaloq.tools.ddk.checkcfg.ui.templates.CheckCfgTemplateContextType; import com.avaloq.tools.ddk.checkcfg.ui.templates.CheckCfgTemplateProposalProvider; import com.avaloq.tools.ddk.xtext.ui.editor.FixedDirtyStateEditorSupport; import com.avaloq.tools.ddk.xtext.ui.templates.KeywordAwareCrossReferenceTemplateVariableResolver; +import com.avaloq.tools.ddk.xtext.ui.templates.SimpleEnumTemplateVariableResolver; /** @@ -31,6 +34,15 @@ public CheckCfgUiModule(final AbstractUIPlugin plugin) { super(plugin); } + /** + * Binds a {@link XtextTemplateContextType} which adds {@link SimpleEnumTemplateVariableResolver}. + * + * @return {@link CheckCfgTemplateContextType} + */ + public Class bindXtextTemplateContextType() { + return CheckCfgTemplateContextType.class; + } + /** Binds a proposal provider for check configuration templates. {@inheritDoc} */ @Override public Class bindITemplateProposalProvider() { diff --git a/com.avaloq.tools.ddk.checkcfg.ui/src/com/avaloq/tools/ddk/checkcfg/ui/templates/CheckCfgTemplateContextType.java b/com.avaloq.tools.ddk.checkcfg.ui/src/com/avaloq/tools/ddk/checkcfg/ui/templates/CheckCfgTemplateContextType.java new file mode 100644 index 000000000..4663e2203 --- /dev/null +++ b/com.avaloq.tools.ddk.checkcfg.ui/src/com/avaloq/tools/ddk/checkcfg/ui/templates/CheckCfgTemplateContextType.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2016 Avaloq Evolution AG and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Avaloq Evolution AG - initial API and implementation + *******************************************************************************/ +package com.avaloq.tools.ddk.checkcfg.ui.templates; + +import org.eclipse.xtext.ui.editor.templates.XtextTemplateContextType; + +import com.avaloq.tools.ddk.xtext.ui.templates.SimpleEnumTemplateVariableResolver; + + +/** + * Used for adding custom template variable resolvers. + */ +public class CheckCfgTemplateContextType extends XtextTemplateContextType { + + @Override + protected void addDefaultTemplateVariables() { + super.addDefaultTemplateVariables(); + addResolver(new SimpleEnumTemplateVariableResolver()); + } + +} diff --git a/com.avaloq.tools.ddk.checkcfg.ui/src/com/avaloq/tools/ddk/checkcfg/ui/templates/CheckCfgTemplateProposalProvider.java b/com.avaloq.tools.ddk.checkcfg.ui/src/com/avaloq/tools/ddk/checkcfg/ui/templates/CheckCfgTemplateProposalProvider.java index fbac863b5..7ae894586 100644 --- a/com.avaloq.tools.ddk.checkcfg.ui/src/com/avaloq/tools/ddk/checkcfg/ui/templates/CheckCfgTemplateProposalProvider.java +++ b/com.avaloq.tools.ddk.checkcfg.ui/src/com/avaloq/tools/ddk/checkcfg/ui/templates/CheckCfgTemplateProposalProvider.java @@ -12,6 +12,8 @@ import java.util.List; import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.StringJoiner; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.jface.text.templates.ContextTypeRegistry; @@ -22,6 +24,7 @@ import org.eclipse.jface.text.templates.persistence.TemplateStore; import org.eclipse.swt.graphics.Image; import org.eclipse.xtext.EcoreUtil2; +import org.eclipse.xtext.common.types.JvmType; import org.eclipse.xtext.conversion.impl.QualifiedNameValueConverter; import org.eclipse.xtext.resource.IEObjectDescription; import org.eclipse.xtext.scoping.IScopeProvider; @@ -31,6 +34,7 @@ import org.eclipse.xtext.ui.editor.templates.DefaultTemplateProposalProvider; import org.eclipse.xtext.util.Strings; import org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter; +import org.eclipse.xtext.xbase.jvmmodel.JvmTypeReferenceBuilder; import com.avaloq.tools.ddk.check.check.Check; import com.avaloq.tools.ddk.check.check.CheckCatalog; @@ -70,6 +74,9 @@ public class CheckCfgTemplateProposalProvider extends DefaultTemplateProposalPro private final TemplateStore templateStore; + @Inject + private JvmTypeReferenceBuilder.Factory typeRefBuilderFactory; + @Inject public CheckCfgTemplateProposalProvider(final TemplateStore templateStore, final ContextTypeRegistry registry, final ContextTypeIdHelper helper) { super(templateStore, registry, helper); @@ -125,8 +132,8 @@ protected void createTemplates(final TemplateContext templateContext, final Cont */ @SuppressWarnings("all") private void addCatalogConfigurations(final TemplateContext templateContext, final ContentAssistContext context, final ITemplateAcceptor acceptor) { - final String templateName = "Add all registered catalogs"; - final String templateDescription = "configures all missing catalogs"; + final String templateName = "Add all registered catalogs"; //$NON-NLS-1$ + final String templateDescription = "configures all missing catalogs"; //$NON-NLS-1$ final String contextTypeId = templateContext.getContextType().getId(); if (context.getRootModel() instanceof CheckConfiguration) { @@ -145,12 +152,12 @@ private void addCatalogConfigurations(final TemplateContext templateContext, fin } else if (allElements.indexOf(description) > 0) { builder.append(Strings.newLine()); } - builder.append("catalog ").append(qualifiedNameValueConverter.toString(description.getQualifiedName().toString())).append(" {").append(Strings.newLine()); + builder.append("catalog ").append(qualifiedNameValueConverter.toString(description.getQualifiedName().toString())).append(" {").append(Strings.newLine()); //$NON-NLS-1$ //$NON-NLS-2$ for (Check check : catalog.getAllChecks()) { - builder.append(" default ").append(qualifiedNameValueConverter.toString(check.getName())).append(Strings.newLine()); + builder.append(" default ").append(qualifiedNameValueConverter.toString(check.getName())).append(Strings.newLine()); //$NON-NLS-1$ } // CHECKSTYLE:OFF - builder.append("}"); + builder.append("}"); //$NON-NLS-1$ builder.append(Strings.newLine()); // CHECKSTYLE:ON } @@ -158,7 +165,7 @@ private void addCatalogConfigurations(final TemplateContext templateContext, fin } if (builder.length() > 0) { - builder.append("${cursor}"); + builder.append("${cursor}"); //$NON-NLS-1$ Template t = new Template(templateName, templateDescription, contextTypeId, builder.toString(), true); TemplateProposal tp = createProposal(t, templateContext, context, images.forConfiguredCatalog(), getRelevance(t)); acceptor.accept(tp); @@ -216,31 +223,29 @@ public String apply(final ConfiguredCheck from) { } }), Predicates.notNull()); final CheckCatalog catalog = configuredCatalog.getCatalog(); + final JvmType stringType = typeRefBuilderFactory.create(context.getResource().getResourceSet()).typeRef(String.class).getType(); for (final Check check : catalog.getAllChecks()) { // create a template on the fly final String checkName = check.getName(); if (!Iterables.contains(alreadyConfiguredCheckNames, checkName)) { // check if referenced check has configurable parameters - String paramString = ""; //$NON-NLS-1$ - if (!check.getFormalParameters().isEmpty()) { - StringBuilder params = new StringBuilder("("); //$NON-NLS-1$ - for (final FormalParameter p : check.getFormalParameters()) { - final String paramName = p.getName(); - final String defaultValue = String.valueOf(interpreter.evaluate(p.getRight()).getResult()); - params.append(paramName).append(" = ").append("${").append(defaultValue).append('}'); //$NON-NLS-1$ //$NON-NLS-2$ - params.append(", "); //$NON-NLS-1$ - } - if (params.length() > 2) { - paramString = params.substring(0, params.length() - 2) + ')'; - } + final StringJoiner paramsJoiner = new StringJoiner(", ", " ( ", ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + paramsJoiner.setEmptyValue(""); //$NON-NLS-1$ + for (final FormalParameter param : check.getFormalParameters()) { + final JvmType paramType = param.getType().getType(); + final String paramName = param.getName(); + final String defaultValue = String.valueOf(interpreter.evaluate(param.getRight()).getResult()); + + // Use SimpleEnumTemplateVariableResolver with strings because otherwise TemplateTranslator can't cope with whitespace + paramsJoiner.add(paramName + " = " + (Objects.equals(stringType, paramType) ? "\"${defaultValue:SimpleEnum('" + defaultValue + "')}\"" //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ + : "${" + defaultValue + '}')); //$NON-NLS-1$ } final String severity = (catalog.isFinal() || check.isFinal()) ? "default " : "${default:Enum('SeverityKind')} "; //$NON-NLS-1$ //$NON-NLS-2$ final String description = "Configures the check \"" + check.getLabel() + "\""; //$NON-NLS-1$ //$NON-NLS-2$ final String contextTypeId = "com.avaloq.tools.ddk.checkcfg.CheckCfg.ConfiguredCheck." + checkName; //$NON-NLS-1$ - final String pattern = severity + qualifiedNameValueConverter.toString(checkName) - + (paramString.length() == 0 ? "${cursor}" : " " + paramString + "${cursor}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + final String pattern = severity + qualifiedNameValueConverter.toString(checkName) + paramsJoiner + "${cursor}"; //$NON-NLS-1$ Template t = new Template(checkName, description, contextTypeId, pattern, true); TemplateProposal tp = createProposal(t, templateContext, context, images.forConfiguredCheck(check.getDefaultSeverity()), getRelevance(t)); diff --git a/com.avaloq.tools.ddk.xtext.ui/src/com/avaloq/tools/ddk/xtext/ui/templates/SimpleEnumTemplateVariableResolver.java b/com.avaloq.tools.ddk.xtext.ui/src/com/avaloq/tools/ddk/xtext/ui/templates/SimpleEnumTemplateVariableResolver.java new file mode 100644 index 000000000..7b36ae9aa --- /dev/null +++ b/com.avaloq.tools.ddk.xtext.ui/src/com/avaloq/tools/ddk/xtext/ui/templates/SimpleEnumTemplateVariableResolver.java @@ -0,0 +1,25 @@ +package com.avaloq.tools.ddk.xtext.ui.templates; + +import java.util.List; +import java.util.stream.Collectors; + +import org.eclipse.jface.text.templates.TemplateVariable; +import org.eclipse.xtext.ui.editor.templates.AbstractTemplateVariableResolver; +import org.eclipse.xtext.ui.editor.templates.XtextTemplateContext; + + +/** + * Simple enumeration template where enumeration is passed as string arguments to the template. + */ +public class SimpleEnumTemplateVariableResolver extends AbstractTemplateVariableResolver { + + public SimpleEnumTemplateVariableResolver() { + super("SimpleEnum", ""); //$NON-NLS-1$ //$NON-NLS-2$ + } + + @Override + public List resolveValues(final TemplateVariable variable, final XtextTemplateContext castedContext) { + return variable.getVariableType().getParams().stream().filter(param -> param instanceof String).collect(Collectors.toList()); + } + +}