Use Maven Artifact Version in Eclipse Code Templates
Based on waffel’s blog i wrote a eclipse plugin which provides the current artifact-version of a maven-project to the eclipse editor-templates. Waffel want to add the current plugin id/version to the @since field for class comments, i want to add the current version of my maven-eclipse-project. Let me explain my solution.
It’s easy to add a new template-variable to eclipse, you can read this. Based on org.eclipse.jface.text.templates.TemplateVariableResolver we can write a MavenVersionResolver:
/** * Resolver to resolve variable <code>pomVersion</code>. * * @author hoehmann * @since 1.0.0 */ public class MavenVersionResolver extends TemplateVariableResolver { public MavenVersionResolver() { super(); } private String getMavenVersion(final IProject project) { if (project == null) { throw new IllegalArgumentException("Missing project"); //$NON-NLS-1$ } String result = ""; //$NON-NLS-1$ try { if (project.hasNature(IMavenConstants.NATURE_ID)) { final MavenProjectManager projectManager = MavenPlugin.getDefault() .getMavenProjectManager(); final IMavenProjectFacade projectFacade = projectManager.create( project, new NullProgressMonitor()); if (projectFacade != null) { final ArtifactKey mavenProject = projectFacade.getArtifactKey(); if (mavenProject != null) { result = mavenProject.getVersion(); // remove snapshot-indicator final int index = result.lastIndexOf("-SNAPSHOT"); //$NON-NLS-1$ if (index != -1) { result = result.substring(0, index); } } } } } catch (final CoreException ex) { MavenLogger.log(ex); } return result; } /** * {@inheritDoc} */ @Override protected String resolve(final TemplateContext context) { // TODO better way to get the project?! return getMavenVersion(((CodeTemplateContext) context).getJavaProject() .getProject()); } }
With the MavenProjectManager from m2eclipse we can create a IMavenProjectFacade, this facade returns the ArtifactKey and this key have the version. If the version is a snapshot-version we can cut this trailing string off and the result is the (next) version for our maven-project (for me it doesn’t make sense to add the snapshot-version into a @since comment because the release-version should be documented in the sourcecode).
Maybe the check for the „m2eclipse“-nature is not necessary:
if (project.hasNature(IMavenConstants.NATURE_ID)) {....}
I tried without the nature-check and it works. The project must contain a „pom.xml“ to get a IMavenProjectFacade.
This was the first part of the solution. The placeholder „pom_version“ will be available for all editor-templates in the „java-context“:
Waffel described already a solution (a workaround) to use a editor-template-resolver in the code-templates. He registered a IStartup class which copies his own BundleIdResolver/BundleVersionResolver into the (internal) code-template-context-registry of the Eclipse-Java-Plugin. For waffel this was fine because he doesn’t register his resolvers as editor-template-resolvers. I want use my MavenVersionResolver in all java-templates and in the code-templates.
And i don’t want create a new instance of the resolver, i want reuse the extension-point-configured resolver. So i have only one place to define my resolver (type = ‚pom_version‘, localized name, localized description, class etc.).
I found a other way to register the resolver
- i search my MavenVersionResolver in the registered editor-templates (java-context)
- if i found one, i add this reference to the (internal) code-template-registry
/** * Currently it's not possible to provide more variables for * <tt>java-code-templates</tt>, we can only add more <tt>editor-templates</tt> * via extension-point. * * <p> * This {@link IStartup} is a workaround to register our * {@link MavenVersionResolver} for <tt>java-code-templates</tt> too. * </p> * * @author hoehmann * @since 1.0.0 */ public class RegisterResolvers implements IStartup { private static final String JAVA_PLUGIN_ID = "org.eclipse.jdt.ui"; //$NON-NLS-1$ /** * Add our resolver to each registered code-template-context. * * @param javaPlugin * must not be <code>null</code> * @param mavenVersionResolver * must not be <code>null</code> */ private void addMavenVersionResolver(final JavaPlugin javaPlugin, final MavenVersionResolver mavenVersionResolver) { Assert.isNotNull(javaPlugin); final ContextTypeRegistry codeTemplateContextRegistry = javaPlugin .getCodeTemplateContextRegistry(); Assert.isNotNull(codeTemplateContextRegistry); final Iterator ctIter = codeTemplateContextRegistry.contextTypes(); while (ctIter.hasNext()) { final TemplateContextType contextType = (TemplateContextType) ctIter .next(); contextType.addResolver(mavenVersionResolver); } } /** * {@inheritDoc} */ public void earlyStartup() { // check if plug-in org.eclipse.jdt.ui is final already active final Bundle bundle = Platform.getBundle(JAVA_PLUGIN_ID); if (bundle != null && bundle.getState() == Bundle.ACTIVE) { registerResolvers(); } else { // register listener to final get informed, when plug-in final becomes // active final BundleContext bundleContext = Activator.getDefault().getBundle() .getBundleContext(); bundleContext.addBundleListener(new BundleListener() { public void bundleChanged(final BundleEvent pEvent) { final Bundle eventBundle = pEvent.getBundle(); if (!eventBundle.getSymbolicName().equals(JAVA_PLUGIN_ID)) { // ignore other plugins return; } if (eventBundle.getState() == Bundle.ACTIVE) { registerResolvers(); bundleContext.removeBundleListener(this); } } }); } } /** * Try to find our {@link MavenVersionResolver} in the java-plugin * template-context-registry. * * @param javaPlugin * must not be <code>null</code> * @return */ private MavenVersionResolver getMavenVersionResolver( final JavaPlugin javaPlugin) { Assert.isNotNull(javaPlugin); final ContextTypeRegistry contextRegistry = javaPlugin .getTemplateContextRegistry(); Assert.isNotNull(contextRegistry); final TemplateContextType javaContextType = contextRegistry .getContextType(JavaContextType.ID_ALL); Assert.isNotNull(javaContextType); final Iterator<TemplateVariableResolver> resolvers = javaContextType .resolvers(); MavenVersionResolver mavenVersionResolver = null; while (resolvers.hasNext()) { final TemplateVariableResolver resolver = resolvers.next(); if (resolver instanceof MavenVersionResolver) { mavenVersionResolver = (MavenVersionResolver) resolver; break; } } return mavenVersionResolver; } /** * First find the maven-version-resolver from the registered resolvers. */ private void registerResolvers() { final JavaPlugin javaPlugin = JavaPlugin.getDefault(); if (javaPlugin == null) { throw new IllegalStateException(String.format( "Expected plugin '%s' is not available", JAVA_PLUGIN_ID)); } final MavenVersionResolver mavenVersionResolver = getMavenVersionResolver(javaPlugin); if (mavenVersionResolver != null) { addMavenVersionResolver(javaPlugin, mavenVersionResolver); } } }
Now its possible to use „pom_version“ in code-templates too:
Now the final test … create a „normal“ java-project, create a new class. The javadoc will not contain a version (the project doesn’t have a maven-nature):
If the project is a „real“ maven project the version will be available:
If anyone need the plugin … leave a comment.
Andreas Höhmann 13:59 am Montag, 24. August 2009 Permalink | Zum Antworten anmelden
I add a new bug to the m2eclipse jiro to provide the sourcecode https://issues.sonatype.org/browse/MNGECLIPSE-1601
medranomatias 23:30 am Dienstag, 20. Juli 2010 Permalink | Zum Antworten anmelden
Hi I need source code for this example!
Thanks!
Andreas Höhmann 16:27 am Mittwoch, 21. Juli 2010 Permalink | Zum Antworten anmelden
What kind of additional sourcecode? I posted the interesting pieces already in the article 🙂
medranomatias 16:34 am Mittwoch, 21. Juli 2010 Permalink | Zum Antworten anmelden
plugin.xml please …