Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Tanasenko2016-03-17 23:58:36 +0000
committerAnton Tanasenko2016-03-20 19:48:58 +0000
commitfdc97365308e3422a055311b43e1e5dde78ffeba (patch)
tree390fb09c036d37881fb35ace1a98d76e04b8afc0 /org.eclipse.m2e.editor.xml
parent89cd40ba907e178d523f40ac22f7eac0291de37b (diff)
downloadm2e-core-fdc97365308e3422a055311b43e1e5dde78ffeba.tar.gz
m2e-core-fdc97365308e3422a055311b43e1e5dde78ffeba.tar.xz
m2e-core-fdc97365308e3422a055311b43e1e5dde78ffeba.zip
489755 Provide content assist on resources' <directory> nodes
Change-Id: Iaaf18f7763420ec422f7f0013383b9122aa1d130 Signed-off-by: Anton Tanasenko <atg.sleepless@gmail.com>
Diffstat (limited to 'org.eclipse.m2e.editor.xml')
-rw-r--r--org.eclipse.m2e.editor.xml/OSGI-INF/l10n/bundle.properties2
-rw-r--r--org.eclipse.m2e.editor.xml/plugin.xml30
-rw-r--r--org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/InsertExpressionProposal.java8
-rw-r--r--org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/MvnImages.java25
-rw-r--r--org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/MvnIndexPlugin.java1
-rw-r--r--org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/PomContentAssistProcessor.java112
-rw-r--r--org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/PomTemplate.java73
-rw-r--r--org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/PomTemplateContext.java482
-rw-r--r--org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/PomTemplateProposal.java78
-rw-r--r--org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/internal/Messages.java4
-rw-r--r--org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/internal/messages.properties2
11 files changed, 669 insertions, 148 deletions
diff --git a/org.eclipse.m2e.editor.xml/OSGI-INF/l10n/bundle.properties b/org.eclipse.m2e.editor.xml/OSGI-INF/l10n/bundle.properties
index eb4580ca..c7bc3d4c 100644
--- a/org.eclipse.m2e.editor.xml/OSGI-INF/l10n/bundle.properties
+++ b/org.eclipse.m2e.editor.xml/OSGI-INF/l10n/bundle.properties
@@ -25,7 +25,9 @@ contextType.packaging = Packaging
contextType.scope = Scope
contextType.phase = Phase
contextType.goal = Goal
+contextType.modules = Modules
contextType.module = Module
+contextType.file = File or directory
template.project.description = New project element
template.project.name = project
template.parent.description = New parent element
diff --git a/org.eclipse.m2e.editor.xml/plugin.xml b/org.eclipse.m2e.editor.xml/plugin.xml
index c6535a4d..29a73566 100644
--- a/org.eclipse.m2e.editor.xml/plugin.xml
+++ b/org.eclipse.m2e.editor.xml/plugin.xml
@@ -97,49 +97,57 @@
id="org.eclipse.m2e.editor.xml.templates.contextType.repositories"/>
<contextType name="%contextType.groupid"
- class="org.eclipse.jface.text.templates.TemplateContextType"
+ class="org.eclipse.m2e.editor.xml.PomTemplateContextType"
id="org.eclipse.m2e.editor.xml.templates.contextType.groupId"/>
<contextType name="%contextType.artifactid"
- class="org.eclipse.jface.text.templates.TemplateContextType"
+ class="org.eclipse.m2e.editor.xml.PomTemplateContextType"
id="org.eclipse.m2e.editor.xml.templates.contextType.artifactId"/>
<contextType name="%contextType.version"
- class="org.eclipse.jface.text.templates.TemplateContextType"
+ class="org.eclipse.m2e.editor.xml.PomTemplateContextType"
id="org.eclipse.m2e.editor.xml.templates.contextType.version"/>
<contextType name="%contextType.classifier"
- class="org.eclipse.jface.text.templates.TemplateContextType"
+ class="org.eclipse.m2e.editor.xml.PomTemplateContextType"
id="org.eclipse.m2e.editor.xml.templates.contextType.classifier"/>
<contextType name="%contextType.type"
- class="org.eclipse.jface.text.templates.TemplateContextType"
+ class="org.eclipse.m2e.editor.xml.PomTemplateContextType"
id="org.eclipse.m2e.editor.xml.templates.contextType.type"/>
<contextType name="%contextType.systemPath"
- class="org.eclipse.jface.text.templates.TemplateContextType"
+ class="org.eclipse.m2e.editor.xml.PomTemplateContextType"
id="org.eclipse.m2e.editor.xml.templates.contextType.systemPath"/>
<contextType name="%contextType.packaging"
- class="org.eclipse.jface.text.templates.TemplateContextType"
+ class="org.eclipse.m2e.editor.xml.PomTemplateContextType"
id="org.eclipse.m2e.editor.xml.templates.contextType.packaging"/>
<contextType name="%contextType.scope"
- class="org.eclipse.jface.text.templates.TemplateContextType"
+ class="org.eclipse.m2e.editor.xml.PomTemplateContextType"
id="org.eclipse.m2e.editor.xml.templates.contextType.scope"/>
<contextType name="%contextType.phase"
- class="org.eclipse.jface.text.templates.TemplateContextType"
+ class="org.eclipse.m2e.editor.xml.PomTemplateContextType"
id="org.eclipse.m2e.editor.xml.templates.contextType.phase"/>
<contextType name="%contextType.goal"
- class="org.eclipse.jface.text.templates.TemplateContextType"
+ class="org.eclipse.m2e.editor.xml.PomTemplateContextType"
id="org.eclipse.m2e.editor.xml.templates.contextType.goal"/>
+ <contextType name="%contextType.modules"
+ class="org.eclipse.m2e.editor.xml.PomTemplateContextType"
+ id="org.eclipse.m2e.editor.xml.templates.contextType.modules"/>
+
<contextType name="%contextType.module"
- class="org.eclipse.jface.text.templates.TemplateContextType"
+ class="org.eclipse.m2e.editor.xml.PomTemplateContextType"
id="org.eclipse.m2e.editor.xml.templates.contextType.module"/>
+ <contextType name="%contextType.file"
+ class="org.eclipse.m2e.editor.xml.PomTemplateContextType"
+ id="org.eclipse.m2e.editor.xml.templates.contextType.file"/>
+
<template id="org.eclipse.m2e.editor.xml.templates.project.skeleton"
contextTypeId="org.eclipse.m2e.editor.xml.templates.contextType.#document"
name="%template.project.name"
diff --git a/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/InsertExpressionProposal.java b/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/InsertExpressionProposal.java
index 973c6837..6dedd533 100644
--- a/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/InsertExpressionProposal.java
+++ b/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/InsertExpressionProposal.java
@@ -24,6 +24,7 @@ import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
+import org.eclipse.wst.sse.ui.internal.contentassist.IRelevanceCompletionProposal;
import org.apache.maven.model.InputLocation;
import org.apache.maven.model.InputSource;
@@ -38,7 +39,8 @@ import org.eclipse.m2e.editor.xml.internal.Messages;
*
* @author mkleint
*/
-public class InsertExpressionProposal implements ICompletionProposal, ICompletionProposalExtension5 {
+public class InsertExpressionProposal
+ implements ICompletionProposal, ICompletionProposalExtension5, IRelevanceCompletionProposal {
private static final Logger log = LoggerFactory.getLogger(InsertExpressionProposal.class);
private MavenProject project;
@@ -124,4 +126,8 @@ public class InsertExpressionProposal implements ICompletionProposal, ICompletio
return null;
}
+ public int getRelevance() {
+ return 2000;
+ }
+
}
diff --git a/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/MvnImages.java b/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/MvnImages.java
index 417f7b4b..d1fbb471 100644
--- a/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/MvnImages.java
+++ b/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/MvnImages.java
@@ -12,6 +12,9 @@
package org.eclipse.m2e.editor.xml;
+import java.util.HashMap;
+import java.util.Map;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -43,6 +46,8 @@ public class MvnImages {
public static final ImageDescriptor IMGD_EXECUTION = create("execution_obj.gif"); //$NON-NLS-1$
+ public static final Image IMG_DISCOVERY = createImage("insp_sbook.gif"); //$NON-NLS-1$
+
public static final Image IMG_EXECUTION = createImage("execution_obj.gif"); //$NON-NLS-1$
public static final Image IMG_GOAL = createImage("goal_obj.gif"); //$NON-NLS-1$
@@ -87,6 +92,8 @@ public class MvnImages {
public static final ImageDescriptor IMGD_WARNINGS = create("warnings.png"); //$NON-NLS-1$
+ private static Map<ImageDescriptor, Image> customImages = new HashMap<>();
+
private static ImageDescriptor create(String key) {
try {
ImageDescriptor imageDescriptor = createDescriptor(key);
@@ -122,4 +129,22 @@ public class MvnImages {
return AbstractUIPlugin.imageDescriptorFromPlugin(MvnIndexPlugin.PLUGIN_ID, "icons/" + image); //$NON-NLS-1$
}
+ public static Image getImage(ImageDescriptor imageDescriptor) {
+ Image image = customImages.get(imageDescriptor);
+ if(image != null) {
+ return image;
+ }
+ image = imageDescriptor.createImage();
+ if(image != null) {
+ customImages.put(imageDescriptor, image);
+ }
+ return image;
+ }
+
+ static void disposeCustomImages() {
+ for(Image img : customImages.values()) {
+ img.dispose();
+ }
+ customImages.clear();
+ }
}
diff --git a/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/MvnIndexPlugin.java b/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/MvnIndexPlugin.java
index 707f188b..131e666e 100644
--- a/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/MvnIndexPlugin.java
+++ b/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/MvnIndexPlugin.java
@@ -49,6 +49,7 @@ public class MvnIndexPlugin extends AbstractUIPlugin {
@Override
public void stop(BundleContext context) throws Exception {
super.stop(context);
+ MvnImages.disposeCustomImages();
defaultInstance = null;
}
diff --git a/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/PomContentAssistProcessor.java b/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/PomContentAssistProcessor.java
index 5df52b75..9c33d4c0 100644
--- a/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/PomContentAssistProcessor.java
+++ b/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/PomContentAssistProcessor.java
@@ -12,6 +12,8 @@
package org.eclipse.m2e.editor.xml;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Properties;
@@ -26,7 +28,6 @@ import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.text.BadLocationException;
-import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
@@ -49,7 +50,6 @@ import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.core.utils.StringUtils;
import org.eclipse.wst.sse.ui.contentassist.CompletionProposalInvocationContext;
-import org.eclipse.wst.sse.ui.internal.contentassist.IRelevanceCompletionProposal;
import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;
import org.eclipse.wst.xml.ui.internal.contentassist.DefaultXMLCompletionProposalComputer;
@@ -76,9 +76,18 @@ public class PomContentAssistProcessor extends DefaultXMLCompletionProposalCompu
PomTemplateContext.CLASSIFIER, PomTemplateContext.SCOPE, PomTemplateContext.SYSTEM_PATH, //
PomTemplateContext.PROPERTIES, PomTemplateContext.MODULE, //
PomTemplateContext.PHASE, PomTemplateContext.GOAL, PomTemplateContext.CONFIGURATION, //
+ PomTemplateContext.SOURCEDIRECTORY, PomTemplateContext.SCRIPTSOURCEDIRECTORY,
+ PomTemplateContext.TESTSOURCEDIRECTORY, //
+ PomTemplateContext.OUTPUTDIRECTORY, PomTemplateContext.TESTOUTPUTDIRECTORY, //
+ PomTemplateContext.DIRECTORY, PomTemplateContext.FILTER, //
//this one is both important and troubling.. but having a context for everything is weird.
PomTemplateContext.UNKNOWN);
+ private static List<String> hardwiredProperties = Collections.unmodifiableList(Arrays.asList( //
+ "basedir", "project.basedir", //
+ "project.version", "project.groupId", "project.artifactId", "project.version", "project.name", //
+ "project.build.directory", "project.build.outputDirectory"));
+
protected void addTagNameProposals(ContentAssistRequest contentAssistRequest, int childPosition,
CompletionProposalInvocationContext ctx) {
PomTemplateContext context = PomTemplateContext.fromNode(contentAssistRequest.getParent());
@@ -110,7 +119,7 @@ public class PomContentAssistProcessor extends DefaultXMLCompletionProposalCompu
* @param request
* @param context
* @param currentNode
- * @param prefix
+ * @param prefixPath
*/
private void addExpressionProposals(ContentAssistRequest request, PomTemplateContext context,
ITextViewer sourceViewer) {
@@ -129,11 +138,23 @@ public class PomContentAssistProcessor extends DefaultXMLCompletionProposalCompu
MavenProject prj = XmlUtils.extractMavenProject(sourceViewer);
Region region = new Region(request.getReplacementBeginPosition() + exprStart, realExpressionPrefix.length());
Set<String> collect = new TreeSet<String>();
+
+ String currentProp = null;
+ Node node = request.getParent();
+ if(PomTemplateContext.getAncestor(node, "properties", "project") != null
+ || PomTemplateContext.getAncestor(node, "properties", "profile", "profiles", "project") != null) {
+ currentProp = node.getLocalName();
+ }
+
if(prj != null) {
Properties props = prj.getProperties();
if(props != null) {
for(Object key : props.keySet()) {
String keyString = key.toString();
+ if(keyString.equals(currentProp)) {
+ // do not allow recursive property usage
+ continue;
+ }
if(("${" + keyString).startsWith(realExpressionPrefix)) { //$NON-NLS-1$
collect.add(keyString);
}
@@ -142,20 +163,10 @@ public class PomContentAssistProcessor extends DefaultXMLCompletionProposalCompu
}
//add a few hardwired values as well
- if("${basedir}".startsWith(realExpressionPrefix)) { //$NON-NLS-1$
- collect.add("basedir"); //$NON-NLS-1$
- }
- if("${project.version}".startsWith(realExpressionPrefix)) { //$NON-NLS-1$
- collect.add("project.version"); //$NON-NLS-1$
- }
- if("${project.groupId}".startsWith(realExpressionPrefix)) { //$NON-NLS-1$
- collect.add("project.groupId"); //$NON-NLS-1$
- }
- if("${project.artifactId}".startsWith(realExpressionPrefix)) { //$NON-NLS-1$
- collect.add("project.artifactId"); //$NON-NLS-1$
- }
- if("${project.build.directory}".startsWith(realExpressionPrefix)) { //$NON-NLS-1$
- collect.add("project.build.directory"); //$NON-NLS-1$
+ for(String prop : hardwiredProperties) {
+ if(("${" + prop).startsWith(realExpressionPrefix)) { //$NON-NLS-1$
+ collect.add(prop);
+ }
}
for(String key : collect) {
request.addProposal(new InsertExpressionProposal(region, key, prj));
@@ -301,6 +312,22 @@ public class PomContentAssistProcessor extends DefaultXMLCompletionProposalCompu
String prefix = request.getMatchString();
int len = prefix.length();
+ // replace text until the next whitespace or tag end
+ IndexedRegion ir = (IndexedRegion) request.getNode();
+ if(ir instanceof Text) {
+ IDocument document = sourceViewer.getDocument();
+ for(int i = offset + len; i < ir.getEndOffset(); i++ ) {
+ try {
+ if(Character.isWhitespace(document.getChar(i))) {
+ break;
+ }
+ } catch(BadLocationException e) {
+ break;
+ }
+ len++ ;
+ }
+ }
+
// also replace opening '<'
if(tagProposals) {
offset-- ;
@@ -318,28 +345,31 @@ public class PomContentAssistProcessor extends DefaultXMLCompletionProposalCompu
// add the user defined templates - separate them from the rest of the templates
// so that we know what they are and can assign proper icon to them.
- Image image = MvnImages.IMG_USER_TEMPLATE;
List<TemplateProposal> matches = new ArrayList<TemplateProposal>();
TemplateStore store = MvnIndexPlugin.getDefault().getTemplateStore();
if(store != null) {
Template[] templates = store.getTemplates(context.getContextTypeId());
for(Template template : templates) {
- TemplateProposal proposal = createProposalForTemplate(prefix, region, templateContext, image, template, true);
+ TemplateProposal proposal = createProposalForTemplate(prefix, region, templateContext,
+ MvnImages.IMG_USER_TEMPLATE, template, true);
if(proposal != null) {
matches.add(proposal);
}
}
}
- if(context == PomTemplateContext.CONFIGURATION) {
- image = MvnImages.IMG_PARAMETER;
- } else {
- //other suggestions from the templatecontext are to be text inside the element, not actual
- //elements..
- image = null;
- }
Template[] templates = context.getTemplates(prj, eclipseprj, parentNode, prefix);
for(Template template : templates) {
+ Image image = null;
+
+ if(template instanceof PomTemplate) {
+ image = ((PomTemplate) template).getImage();
+ }
+
+ if(image == null && context == PomTemplateContext.CONFIGURATION) {
+ image = MvnImages.IMG_PARAMETER;
+ }
+
TemplateProposal proposal = createProposalForTemplate(prefix, region, templateContext, image, template, false);
if(proposal != null) {
matches.add(proposal);
@@ -392,6 +422,12 @@ public class PomContentAssistProcessor extends DefaultXMLCompletionProposalCompu
//TODO we should have different relevance for user defined templates and generated proposals..
protected int getRelevance(Template template, String prefix) {
+ if(template instanceof PomTemplate) {
+ int rel = ((PomTemplate) template).getRelevance();
+ if(rel != -1)
+ return rel;
+ }
+
if(template.getName().startsWith(prefix))
return 1900;
return 1500;
@@ -426,28 +462,4 @@ public class PomContentAssistProcessor extends DefaultXMLCompletionProposalCompu
}
}
- private static class PomTemplateProposal extends TemplateProposal implements IRelevanceCompletionProposal {
-
- public PomTemplateProposal(Template template, TemplateContext context, IRegion region, Image image, int relevance) {
- super(template, context, region, image, relevance);
- }
-
- @Override
- public boolean validate(IDocument document, int offset, DocumentEvent event) {
- try {
- int replaceOffset = getReplaceOffset();
- if(offset >= replaceOffset) {
- String content = document.get(replaceOffset, offset - replaceOffset);
- if(!content.isEmpty() && content.charAt(0) == '<') {
- content = content.substring(1);
- }
- return getTemplate().getName().toLowerCase().startsWith(content.toLowerCase());
- }
- } catch(BadLocationException e) {
- // concurrent modification - ignore
- }
- return false;
- }
- }
-
}
diff --git a/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/PomTemplate.java b/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/PomTemplate.java
new file mode 100644
index 00000000..66b5c214
--- /dev/null
+++ b/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/PomTemplate.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Anton Tanasenko
+ * 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:
+ * Anton Tanasenko - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.m2e.editor.xml;
+
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.swt.graphics.Image;
+
+
+/**
+ * PomTemplate
+ *
+ * @author atanasenko
+ */
+public class PomTemplate extends Template {
+
+ private Image image;
+
+ private int relevance;
+
+ private String matchValue;
+
+ private boolean retriggerOnApply;
+
+ public PomTemplate(String name, String description, String contextTypeId, String pattern, boolean isAutoInsertable) {
+ super(name, description, contextTypeId, pattern, isAutoInsertable);
+ }
+
+ public Image getImage() {
+ return this.image;
+ }
+
+ public PomTemplate image(Image image) {
+ this.image = image;
+ return this;
+ }
+
+ public int getRelevance() {
+ return this.relevance;
+ }
+
+ public PomTemplate relevance(int relevance) {
+ this.relevance = relevance;
+ return this;
+ }
+
+ public String getMatchValue() {
+ return this.matchValue;
+ }
+
+ public PomTemplate matchValue(String matchValue) {
+ this.matchValue = matchValue;
+ return this;
+ }
+
+ public boolean isRetriggerOnApply() {
+ return this.retriggerOnApply;
+ }
+
+ public PomTemplate retriggerOnApply(boolean retriggerOnApply) {
+ this.retriggerOnApply = retriggerOnApply;
+ return this;
+ }
+
+}
diff --git a/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/PomTemplateContext.java b/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/PomTemplateContext.java
index a700d5c6..2f45c17b 100644
--- a/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/PomTemplateContext.java
+++ b/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/PomTemplateContext.java
@@ -12,12 +12,22 @@
package org.eclipse.m2e.editor.xml;
import java.io.File;
-import java.io.FileFilter;
+import java.io.IOException;
+import java.nio.file.FileVisitOption;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.Comparator;
+import java.util.EnumSet;
import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
@@ -30,15 +40,22 @@ import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.model.IWorkbenchAdapter;
import org.codehaus.plexus.interpolation.InterpolationException;
import org.codehaus.plexus.interpolation.PrefixedObjectValueSource;
import org.codehaus.plexus.interpolation.PropertiesBasedValueSource;
import org.codehaus.plexus.interpolation.RegexBasedInterpolator;
-import org.codehaus.plexus.util.StringUtils;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DependencyManagement;
@@ -81,8 +98,6 @@ public enum PomTemplateContext {
RELATIVE_PATH("relativePath"), // //$NON-NLS-1$
- MODULES("modules"), // //$NON-NLS-1$
-
PROPERTIES("properties"), // //$NON-NLS-1$
DEPENDENCIES("dependencies"), // //$NON-NLS-1$
@@ -192,7 +207,8 @@ public enum PomTemplateContext {
MojoParameter param = result.getContainer(configPath);
if(param != null) {
- for(MojoParameter parameter : param.getNestedParameters()) {
+ List<MojoParameter> nestedParameters = param.getNestedParameters();
+ for(MojoParameter parameter : nestedParameters) {
String name = parameter.getName();
if(name.startsWith(prefix)) {
@@ -229,6 +245,25 @@ public enum PomTemplateContext {
}
+ if(nestedParameters.size() == 1) {
+ MojoParameter nestedParam = nestedParameters.get(0);
+ if(nestedParam.isMultiple()) {
+ boolean containsFiles = File.class.getSimpleName().equals(nestedParam.getType())
+ || PomTemplateContext.fromNodeName(nestedParam.getName()).handlesFiles();
+ if(containsFiles) {
+ addFileTemplates(project, eclipseprj, proposals, node, prefix,
+ param.getName().toLowerCase().endsWith("directory"), nestedParam.getName());
+ }
+ }
+ }
+
+ boolean containsFiles = File.class.getSimpleName().equals(param.getType())
+ || PomTemplateContext.fromNodeName(param.getName()).handlesFiles();
+ if(containsFiles) {
+ addFileTemplates(project, eclipseprj, proposals, node, prefix,
+ param.getName().toLowerCase().endsWith("directory"), null);
+ }
+
}
}
},
@@ -392,7 +427,7 @@ public enum PomTemplateContext {
checkAndAdd(proposals, prefix, "runtime"); //$NON-NLS-1$
checkAndAdd(proposals, prefix, "system"); //$NON-NLS-1$
- if(checkAncestors(node.getParentNode(), "dependency", "dependencies", "dependencyManagement")) {// $NON-NLS-1$ $NON-NLS-2$ $NON-NLS-3$
+ if(getAncestor(node, "dependency", "dependencies", "dependencyManagement") != null) {// $NON-NLS-1$ $NON-NLS-2$ $NON-NLS-3$
checkAndAdd(proposals, prefix, "import"); //$NON-NLS-1$
}
}
@@ -484,85 +519,31 @@ public enum PomTemplateContext {
}
},
- MODULE("module") { //$NON-NLS-1$
+ MODULES("modules") { //$NON-NLS-1$
@Override
public void addTemplates(MavenProject project, IProject eclipseprj, Collection<Template> proposals, Node node,
String prefix) {
- if(project == null) {
- //shall not happen just double check.
- return;
- }
- //MNGECLIPSE-2204 collect the existing values from the surrounding xml content only..
- List<String> existings = new ArrayList<String>();
- Node moduleNode = node;
- if(moduleNode != null) {
- Node modulesNode = moduleNode.getParentNode();
- if(modulesNode != null) {
- for(Element el : XmlUtils.findChilds((Element) modulesNode, "module")) {
- if(el != moduleNode) {
- String val = XmlUtils.getTextValue(el);
- if(val != null) {
- existings.add(val);
- }
- }
- }
- }
- }
+ addModuleTemplates(project, eclipseprj, proposals, node, prefix, true);
+ }
+ },
- File directory = new File(eclipseprj.getLocationURI());
- final File currentPom = new File(directory, "pom.xml");
- String path = prefix;
- boolean endingSlash = path.endsWith("/"); //$NON-NLS-1$
- String[] elems = StringUtils.split(path, "/"); //$NON-NLS-1$
- String lastElement = null;
- for(int i = 0; i < elems.length; i++ ) {
- if("..".equals(elems[i])) { //$NON-NLS-1$
- directory = directory != null ? directory.getParentFile() : null;
- } else if(i < elems.length - (endingSlash ? 0 : 1)) {
- directory = directory != null ? new File(directory, elems[i]) : null;
- } else {
- lastElement = elems[i];
- }
- }
- path = lastElement != null ? path.substring(0, path.length() - lastElement.length()) : path;
- FileFilter filter = new FileFilter() {
- public boolean accept(File pathname) {
- if(pathname.isDirectory()) {
- File pom = new File(pathname, "pom.xml"); //$NON-NLS-1$
- //TODO shall also handle polyglot maven :)
- return pom.exists() && pom.isFile() && !pom.equals(currentPom);
- }
- return false;
- }
- };
- if(directory != null && directory.exists() && directory.isDirectory()) {
- File[] offerings = directory.listFiles(filter);
- for(File candidate : offerings) {
- if(lastElement == null || candidate.getName().startsWith(lastElement)) {
- String val = path + candidate.getName();
- if(!existings.contains(val)) { //only those not already being added in the surrounding area
- checkAndAdd(proposals, prefix, val, NLS.bind(Messages.PomTemplateContext_candidate, candidate));
- }
- }
- }
- if(path.length() == 0 && directory.equals(currentPom.getParentFile())) {
- //for the empty value, when searching in current directory, propose also stuff one level up.
- File currentParent = directory.getParentFile();
- if(currentParent != null && currentParent.exists()) {
- offerings = currentParent.listFiles(filter);
- for(File candidate : offerings) {
- String val = "../" + candidate.getName();
- if(!existings.contains(val)) { //only those not already being added in the surrounding area
- checkAndAdd(proposals, prefix, val, NLS.bind(Messages.PomTemplateContext_candidate, candidate));
- }
- }
- }
- }
- }
+ MODULE("module") { //$NON-NLS-1$
+ @Override
+ public void addTemplates(MavenProject project, IProject eclipseprj, Collection<Template> proposals, Node node,
+ String prefix) {
+ addModuleTemplates(project, eclipseprj, proposals, node, prefix, false);
}
},
- LICENSES("licenses");
+ SOURCEDIRECTORY("sourceDirectory", "file"), //$NON-NLS-1$ //$NON-NLS-2$
+ SCRIPTSOURCEDIRECTORY("scriptSourceDirectory", "file"), //$NON-NLS-1$ //$NON-NLS-2$
+ TESTSOURCEDIRECTORY("testSourceDirectory", "file"), //$NON-NLS-1$ //$NON-NLS-2$
+ OUTPUTDIRECTORY("outputDirectory", "file"), //$NON-NLS-1$ //$NON-NLS-2$
+ TESTOUTPUTDIRECTORY("testOutputDirectory", "file"), //$NON-NLS-1$ //$NON-NLS-2$
+ DIRECTORY("directory", "file"), //$NON-NLS-1$ //$NON-NLS-2$
+ FILTER("filter", "file"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ LICENSES("licenses"); //$NON-NLS-1$
private static final Logger log = LoggerFactory.getLogger(PomTemplateContext.class);
@@ -570,14 +551,25 @@ public enum PomTemplateContext {
private final String nodeName;
+ private final String contextSuffix;
+
private PomTemplateContext(String nodeName) {
+ this(nodeName, nodeName);
+ }
+
+ private PomTemplateContext(String nodeName, String contextSuffix) {
this.nodeName = nodeName;
+ this.contextSuffix = contextSuffix;
}
public boolean handlesSubtree() {
return false;
}
+ public boolean handlesFiles() {
+ return "file".equals(contextSuffix); //$NON-NLS-1$
+ }
+
/**
* Return templates depending on the context type.
*/
@@ -601,6 +593,301 @@ public enum PomTemplateContext {
*/
protected void addTemplates(MavenProject project, IProject eclipsePrj, Collection<Template> templates,
Node currentNode, String prefix) throws CoreException {
+ if(handlesFiles()) {
+ addFileTemplates(project, eclipsePrj, templates, currentNode, prefix, name().toLowerCase().endsWith("directory"),
+ null);
+ }
+ }
+
+ protected FileProposalContext getFileProposalContext(MavenProject project, IProject eclipsePrj, String prefix) {
+ if(project == null && eclipsePrj == null) {
+ return null;
+ }
+
+ File projectDir;
+ if(project != null) {
+ projectDir = project.getFile().getParentFile();
+ } else {
+ projectDir = new File(eclipsePrj.getLocationURI());
+ }
+
+ String parentPath;
+ String prefixPath;
+ int lastSep = prefix.lastIndexOf('/');
+ if(lastSep != -1) {
+ prefixPath = prefix.substring(0, lastSep) + '/';
+ prefix = prefix.substring(lastSep + 1);
+ } else {
+ prefixPath = "";
+ }
+ String interpolated = simpleInterpolate(project, prefixPath);
+ parentPath = interpolated == null ? prefixPath : interpolated;
+
+ File parentDir;
+ if(!new File(parentPath).isAbsolute()) {
+ parentDir = new File(projectDir, parentPath);
+ } else {
+ parentDir = new File(parentPath);
+ }
+ if(!parentDir.isDirectory()) {
+ return null;
+ }
+ return new FileProposalContext(projectDir, parentDir, prefixPath, prefix);
+ }
+
+ protected void addFileTemplates(MavenProject project, IProject eclipsePrj, Collection<Template> templates,
+ Node currentNode, String prefix, boolean dirsOnly, String wrapperNode) {
+
+ FileProposalContext pctx = getFileProposalContext(project, eclipsePrj, prefix);
+ if(pctx == null) {
+ return;
+ }
+
+ List<File> files = Arrays.asList(pctx.parentDir.listFiles());
+ Collections.sort(files, Comparator.<File, Integer> comparing(r -> r.isDirectory() ? 0 : 1)
+ .thenComparing(Comparator.comparing(r -> r.getName())));
+
+ int rel = 4000;
+ for(File f : files) {
+ if(f.getName().startsWith(pctx.prefix)) {
+ String value = pctx.prefixPath + f.getName();
+ String template = value;
+ boolean retrigger = false;
+
+ if(f.isDirectory()) {
+ if(hasContents(f, dirsOnly)) {
+ template += '/';
+ retrigger = true;
+ }
+ } else if(dirsOnly) {
+ continue;
+ }
+ template = template.replace("$", "$$");
+
+ if(wrapperNode != null) {
+ template = '<' + wrapperNode + '>' + template + "${cursor}</" + wrapperNode + '>';
+ }
+
+ templates.add(new PomTemplate(f.getName(), "", getContextTypeId(), template, false).image(getFileIcon(f))
+ .matchValue(value).relevance(rel-- ).retriggerOnApply(retrigger));
+ }
+ }
+ }
+
+ private boolean hasContents(File f, boolean dirsOnly) {
+ // using nio is faster for large dirs compared to File#listFiles()
+ boolean[] res = new boolean[] {false};
+ Path thisPath = f.toPath();
+ try {
+ Files.walkFileTree(thisPath, new SimpleFileVisitor<Path>() {
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+ if(thisPath.equals(dir)) {
+ return FileVisitResult.CONTINUE;
+ }
+ res[0] = true;
+ return FileVisitResult.TERMINATE;
+ }
+
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ if(dirsOnly) {
+ return FileVisitResult.CONTINUE;
+ }
+ res[0] = true;
+ return FileVisitResult.TERMINATE;
+ }
+ });
+ } catch(IOException ex) {
+ }
+ return res[0];
+ }
+
+ protected void addModuleTemplates(MavenProject project, IProject eclipseprj, Collection<Template> proposals,
+ Node node, String prefix, boolean wrap) {
+ if(project == null) {
+ //shall not happen just double check.
+ return;
+ }
+ FileProposalContext pctx = getFileProposalContext(project, eclipseprj, prefix);
+ if(pctx == null) {
+ return;
+ }
+
+ //MNGECLIPSE-2204 collect the existing values from the surrounding xml content only..
+ // also, if it's a profile modules list, consider main modules as well
+ Set<String> existings = new HashSet<>();
+ Node moduleNode = node;
+ if(moduleNode != null) {
+ Node modulesNode;
+ if(moduleNode.getLocalName().equals("modules")) {
+ modulesNode = moduleNode;
+ } else {
+ modulesNode = moduleNode.getParentNode();
+ }
+ while(modulesNode != null) {
+ for(Element el : XmlUtils.findChilds((Element) modulesNode, "module")) {
+ if(el != moduleNode) {
+ String val = XmlUtils.getTextValue(el);
+ if(val != null) {
+ existings.add(val);
+ }
+ }
+ }
+ Node profileProjectNode = getAncestor(modulesNode, "profile", "profiles", "project");
+ if(profileProjectNode != null) {
+ modulesNode = getChildWithName(profileProjectNode, "modules");
+ } else {
+ modulesNode = null;
+ }
+ }
+ }
+
+ Set<String> subProjects = new LinkedHashSet<>();
+ try {
+ Path projectPath = pctx.projectDir.toPath().toRealPath();
+ Path parentPath = pctx.parentDir.toPath().toRealPath();
+
+ FileVisitor<Path> visitor = new SimpleFileVisitor<Path>() {
+
+ boolean submodulesSearch;
+
+ boolean submodulesFound;
+
+ Path submodulesSearchBase;
+
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+
+ if(submodulesSearch && submodulesFound) {
+ // drop out quickly if we were searching for submodules and at least one was already found
+ return FileVisitResult.SKIP_SIBLINGS;
+ }
+
+ String name = dir.getFileName().toString();
+ if(name.startsWith(".")) {
+ // skip dotfiles
+ return FileVisitResult.SKIP_SUBTREE;
+ }
+
+ if(parentPath.equals(dir)) {
+ // don't propose the dir we are looking under
+ return FileVisitResult.CONTINUE;
+ }
+
+ if(projectPath.equals(dir) && pctx.prefixPath.startsWith("../")) {
+ // skip this project's dir entirely when looking for modules in parent dir
+ return FileVisitResult.SKIP_SUBTREE;
+ }
+
+ if(projectPath.startsWith(dir)) {
+ // skip ancestors of current dir
+ return FileVisitResult.CONTINUE;
+ }
+
+ //TODO polyglot?
+ if(Arrays.asList("src", "target", "bin").contains(name) && dir.resolve("../pom.xml").toFile().exists()) {
+ // skip recursing into certain the project dirs
+ return FileVisitResult.SKIP_SUBTREE;
+ }
+
+ if(dir.resolve("pom.xml").toFile().exists()) {
+
+ if(submodulesSearch) {
+ // we were looking for submodules and found at least one
+ submodulesFound = true;
+ return FileVisitResult.SKIP_SIBLINGS;
+ }
+
+ // found a candidate
+ String path = projectPath.relativize(dir).toString().replace('\\', '/');
+ if(!existings.contains(path)) {
+ subProjects.add(path);
+ }
+
+ // now we need to check for submodules, and if there are any, add a <path>/ proposal
+ submodulesSearch = true;
+ submodulesSearchBase = dir;
+ submodulesFound = false;
+ }
+ return FileVisitResult.CONTINUE;
+ }
+
+ public FileVisitResult postVisitDirectory(Path dir, IOException e) {
+ if(submodulesSearch && dir.equals(submodulesSearchBase)) {
+
+ // finish search for submodules
+ if(submodulesFound) {
+ String path = projectPath.relativize(dir).toString().replace('\\', '/');
+ subProjects.add(path + '/');
+ }
+
+ submodulesSearch = false;
+ submodulesSearchBase = null;
+ submodulesFound = false;
+ }
+
+ return FileVisitResult.CONTINUE;
+ }
+ };
+
+ Files.walkFileTree(parentPath, EnumSet.of(FileVisitOption.FOLLOW_LINKS), 5, visitor);
+ } catch(IOException e) {
+ }
+
+ subProjects.removeAll(existings);
+
+ int moduleRel = 8000;
+ int submoduleRel = 4000;
+ for(String path : subProjects) {
+ if(path.startsWith(prefix)) {
+ String value = path;
+ String template = value;
+ template = template.replace("$", "$$");
+
+ Image image;
+ String description;
+ int rel;
+ boolean retrigger = false;
+ if(path.endsWith("/")) {
+ image = MvnImages.IMG_DISCOVERY;
+ description = NLS.bind(Messages.PomTemplateContext_submodules, path);
+ rel = submoduleRel-- ;
+ retrigger = true;
+ } else {
+ image = getFileIcon(new File(pctx.projectDir, path));
+ description = NLS.bind(Messages.PomTemplateContext_module, path);
+ rel = moduleRel-- ;
+ }
+ if(wrap) {
+ template = "<module>" + template + "${cursor}</module>";
+ }
+
+ proposals.add(new PomTemplate(value, description, getContextTypeId(), template, false).image(image)
+ .relevance(rel).retriggerOnApply(retrigger));
+ }
+ }
+ }
+
+ protected static Image getFileIcon(File f) {
+ IWorkspaceRoot wroot = ResourcesPlugin.getWorkspace().getRoot();
+ IResource[] resources;
+ if(f.isDirectory()) {
+ resources = wroot.findContainersForLocationURI(f.toURI());
+ } else {
+ resources = wroot.findFilesForLocationURI(f.toURI());
+ }
+ IResource res = resources.length > 0 ? resources[0] : null;
+ if(res != null) {
+ IWorkbenchAdapter wbAdapter = res.getAdapter(IWorkbenchAdapter.class);
+ if(wbAdapter == null) {
+ return null;
+ }
+ ImageDescriptor id = wbAdapter.getImageDescriptor(res);
+ return id != null ? MvnImages.getImage(id) : null;
+ }
+
+ if(f.isDirectory()) {
+ return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
+ }
+ return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FILE);
}
protected String getNodeName() {
@@ -608,7 +895,7 @@ public enum PomTemplateContext {
}
public String getContextTypeId() {
- return PREFIX + nodeName;
+ return PREFIX + contextSuffix;
}
public static PomTemplateContext fromId(String contextTypeId) {
@@ -718,8 +1005,12 @@ public enum PomTemplateContext {
}
protected void checkAndAdd(Collection<Template> proposals, String prefix, String name, String description) {
+ checkAndAdd(proposals, prefix, name, name, -1);
+ }
+
+ protected void checkAndAdd(Collection<Template> proposals, String prefix, String name, String description, int rel) {
if(name.startsWith(prefix)) {
- proposals.add(new Template(name, description, getContextTypeId(), name, false));
+ proposals.add(new PomTemplate(name, description, getContextTypeId(), name, false).relevance(rel));
}
}
@@ -858,13 +1149,32 @@ public enum PomTemplateContext {
return null;
}
- protected static boolean checkAncestors(Node n, String... names) {
+ protected static Node getAncestor(Node node, String... names) {
int i = 0;
- while(n != null && i < names.length) {
- if(!names[i++ ].equals(n.getNodeName()))
- return false;
- n = n.getParentNode();
+ for(; i < names.length; i++ ) {
+ Node parent = node.getParentNode();
+ if(parent == null || !names[i].equals(parent.getNodeName()))
+ return null;
+ node = parent;
}
- return i == names.length;
+ return i == names.length ? node : null;
+ }
+
+ private static class FileProposalContext {
+ final File projectDir;
+
+ final File parentDir;
+
+ final String prefixPath;
+
+ final String prefix;
+
+ FileProposalContext(File projectDir, File parentDir, String prefixPath, String prefix) {
+ this.projectDir = projectDir;
+ this.parentDir = parentDir;
+ this.prefixPath = prefixPath;
+ this.prefix = prefix;
+ }
+
}
}
diff --git a/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/PomTemplateProposal.java b/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/PomTemplateProposal.java
new file mode 100644
index 00000000..5cc3fc56
--- /dev/null
+++ b/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/PomTemplateProposal.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2010 Sonatype, Inc.
+ * 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:
+ * Sonatype, Inc. - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.m2e.editor.xml;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextOperationTarget;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateContext;
+import org.eclipse.jface.text.templates.TemplateProposal;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.wst.sse.ui.internal.contentassist.IRelevanceCompletionProposal;
+
+
+@SuppressWarnings("restriction")
+public class PomTemplateProposal extends TemplateProposal implements IRelevanceCompletionProposal {
+
+ public PomTemplateProposal(Template template, TemplateContext context, IRegion region, Image image, int relevance) {
+ super(template, context, region, image, relevance);
+ }
+
+ @Override
+ public boolean validate(IDocument document, int offset, DocumentEvent event) {
+ try {
+ int replaceOffset = getReplaceOffset();
+ if(offset >= replaceOffset) {
+ String content = document.get(replaceOffset, offset - replaceOffset);
+ if(!content.isEmpty() && content.charAt(0) == '<') {
+ content = content.substring(1);
+ }
+ return getMatchValue().toLowerCase().startsWith(content.toLowerCase());
+ }
+ } catch(BadLocationException e) {
+ // concurrent modification - ignore
+ }
+ return false;
+ }
+
+ public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) {
+ super.apply(viewer, trigger, stateMask, offset);
+ if(retriggerOnApply()) {
+ Display.getDefault()
+ .asyncExec(() -> ((ITextOperationTarget) viewer).doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS));
+ }
+ }
+
+ private boolean retriggerOnApply() {
+ if(getTemplate() instanceof PomTemplate) {
+ return ((PomTemplate) getTemplate()).isRetriggerOnApply();
+ }
+ return false;
+ }
+
+ private String getMatchValue() {
+ String matchValue = null;
+ if(getTemplate() instanceof PomTemplate) {
+ matchValue = ((PomTemplate) getTemplate()).getMatchValue();
+ }
+ if(matchValue == null) {
+ return getTemplate().getName();
+ }
+ return matchValue;
+ }
+}
diff --git a/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/internal/Messages.java b/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/internal/Messages.java
index cd41239d..1ab91673 100644
--- a/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/internal/Messages.java
+++ b/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/internal/Messages.java
@@ -118,6 +118,8 @@ public class Messages extends NLS {
public static String PomTemplateContext_insertParameter;
+ public static String PomTemplateContext_module;
+
public static String PomTemplateContext_resolvingPlugin;
public static String PomTemplateContext_package;
@@ -160,6 +162,8 @@ public class Messages extends NLS {
public static String PomTemplateContext_sitedeploy;
+ public static String PomTemplateContext_submodules;
+
public static String PomTemplateContext_test;
public static String PomTemplateContext_testcompile;
diff --git a/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/internal/messages.properties b/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/internal/messages.properties
index e6005218..7e60e908 100644
--- a/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/internal/messages.properties
+++ b/org.eclipse.m2e.editor.xml/src/main/java/org/eclipse/m2e/editor/xml/internal/messages.properties
@@ -48,6 +48,7 @@ PomTemplateContext_generatetestsources=Generate any test source code for inclusi
PomTemplateContext_install=Install the package into the local repository, for use as a dependency in other projects locally
PomTemplateContext_integrationtest=Process and deploy the package if necessary into an environment where integration tests can be run
PomTemplateContext_insertParameter=Insert parameter {0}
+PomTemplateContext_module=Module {0}
PomTemplateContext_package=Take the compiled code and package it in its distributable format, such as a JAR
PomTemplateContext_param=<b>required:</b> {0}<br><b>type:</b> {1}<br>
PomTemplateContext_param_def=default: {0}<br>
@@ -69,6 +70,7 @@ PomTemplateContext_project_version_hint=For projects developed in sync only.
PomTemplateContext_resolvingPlugin=Resolving plugin
PomTemplateContext_site=Generates the project's site documentation
PomTemplateContext_sitedeploy=Deploys the generated site documentation to the specified web server
+PomTemplateContext_submodules=Potential submodules exist under {0}
PomTemplateContext_test=Run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed
PomTemplateContext_testcompile=Compile the test source code into the test destination directory
PomTemplateContext_validate=Validate the project is correct and all necessary information is available

Back to the top