Check runtime allowed dynamic loading of check projects. In this chapter we describe the API used by dynamically pluggable checks.
Check catalog files within a check project generate code which is executed at run-time. One check catalog will result in half a dozen files being generated, whereas one of those represents the actual validator executed by the check run-time.
We explain the derived resources of a check catalog by example.
Assume we are about to write a Static Code Analysis library for our Format DSL. Here is a possible structure of an SCA plugin with one Check catalog.
Example
In our example FormatConventions
is an empty catalog
package com.avaloq.tools.xtext.format.sca
/**
* Check catalog for com.avaloq.tools.ddk.xtext.format.Format
*/
catalog FormatConventions
for grammar com.avaloq.tools.ddk.xtext.format.Format {
}
FormatConventionsQuickfixProvider.java
Check project wizard creates FormatConventionsQuickfixProvider
is a stub for future Quck Fixes
package com.avaloq.tools.xtext.format.sca;
import com.avaloq.tools.ddk.check.runtime.quickfix.ICoreQuickfixProvider;
/**
* Default quickfix provider for FormatConventions.
* <p>
* Note that this class name must start with the catalog name and have <em>QuickfixProvider</em>
* as suffix. It must be located in the same Java package as the catalog file.
* </p>
*/
public class FormatConventionsQuickfixProvider implements ICoreQuickfixProvider {
// @CoreFix(value = MyIssueCodes.NAME_ENTITY_0)
// public void fixEntityNameFirstUpper(final Issue issue,
// ICoreIssueResolutionAcceptor acceptor) {
// acceptor.accept(issue, "Correct entity name",
// "Correct name by setting first letter to upper case.",
// null, new ICoreSemanticModification() {
// public void apply(EObject element, ICoreModificationContext context) {
// if (element instanceof Entity) {
// final Entity entity = (Entity) element;
// String newName = String.valueOf(entity.getName().charAt(0)).toUpperCase();
// if (entity.getName().length() > 1) {
// newName += entity.getName().substring(1, entity.getName().length());
// }
// entity.setName(newName);
// }
// }
// });
// }
}
As developers we only work with *.check
and *QuickfixProvider.java
files.
The remainig glue code is generated by the DSL Developer Kit.
Activation in IDE via plugin.xml
Both FormatConventions
catalog and FormatConventionsQuickfixProvider
are registered using the generated plugin.xml.
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension
id="com.avaloq.tools.xtext.format.sca.formatconventions.validator"
name="Check extension for FormatConventions"
point="com.avaloq.tools.ddk.check.runtime.core.check">
<validator
catalog="com/avaloq/tools/xtext/format/sca/FormatConventions.check"
language="com.avaloq.tools.ddk.xtext.format.Format"
targetClass="com.avaloq.tools.xtext.format.sca.FormatConventionsCheckImpl">
</validator>
</extension>
<extension
id="com.avaloq.tools.xtext.format.sca.formatconventions.quickfix"
name="Check quickfix extension for FormatConventions"
point="com.avaloq.tools.ddk.check.runtime.core.checkquickfix">
<provider
language="com.avaloq.tools.ddk.xtext.format.Format"
targetClass="com.avaloq.tools.xtext.format.sca.FormatConventionsQuickfixProvider">
</provider>
</extension>
<extension
id="com.avaloq.tools.xtext.format.sca.formatconventions.preference"
name="Preferences extension for FormatConventions"
point="org.eclipse.core.runtime.preferences">
<initializer
class="com.avaloq.tools.xtext.format.sca.FormatConventionsPreferenceInitializer">
</initializer>
</extension>
<extension
name="Context sensitive help for check"
point="org.eclipse.help.contexts">
<contexts
file="docs/contexts.xml">
</contexts>
</extension>
<extension
name="Help extension for Check"
point="org.eclipse.help.toc">
<toc
file="docs/toc.xml"
primary="false">
</toc>
</extension>
</plugin>
Notice the important extension points used to contribute checks
-
com.avaloq.tools.ddk.check.runtime.core.check
-
com.avaloq.tools.ddk.check.runtime.core.checkquickfix
-
org.eclipse.core.runtime.preferences
Activation in standalone builder
For headless standalone builder Check catalog is also registered as a service for a non-OSGi environment.
Each check project has the following file
META-INF/services/com.avaloq.tools.ddk.check.runtime.registry.ICheckValidatorStandaloneSetup
For our example this files contains only one service implementation registered
com.avaloq.tools.xtext.format.sca.FormatConventionsStandaloneSetup
which is used to initialize our catalog for a standalone builder.
Here is a sample of generated standalone setup
package com.avaloq.tools.xtext.format.sca;
import org.apache.log4j.Logger;
import com.avaloq.tools.ddk.check.runtime.configuration.ModelLocation;
import com.avaloq.tools.ddk.check.runtime.registry.ICheckCatalogRegistry;
import com.avaloq.tools.ddk.check.runtime.registry.ICheckValidatorRegistry;
import com.avaloq.tools.ddk.check.runtime.registry.ICheckValidatorStandaloneSetup;
/**
* Standalone setup for FormatConventions as required by the standalone builder.
*/
@SuppressWarnings("nls")
public class FormatConventionsStandaloneSetup implements ICheckValidatorStandaloneSetup {
private static final Logger LOG = Logger.getLogger(FormatConventionsStandaloneSetup.class);
private static final String GRAMMAR_NAME = "com.avaloq.tools.ddk.xtext.format.Format";
private static final String CATALOG_FILE_PATH = "com/avaloq/tools/xtext/format/sca/FormatConventions.check";
/** {@inheritDoc} */
public void doSetup() {
ICheckValidatorRegistry.INSTANCE.registerValidator(GRAMMAR_NAME, new FormatConventionsCheckImpl());
ICheckCatalogRegistry.INSTANCE.registerCatalog(GRAMMAR_NAME, new ModelLocation(
FormatConventionsStandaloneSetup.class.getClassLoader().getResource(CATALOG_FILE_PATH), CATALOG_FILE_PATH));
LOG.info("Standalone setup done for com/avaloq/tools/xtext/format/sca/FormatConventions.check");
}
@Override
public String toString() {
return "CheckValidatorSetup(/resource/com.avaloq.tools.xtext.format.sca/src/com/avaloq/tools/xtext/format/sca/FormatConventions.check)";
}
}
As you can notice standalone setup similarly to plugin.xml
registers FormatConventionsCheckImpl
as a validator for the Format language.