| /******************************************************************************* |
| * Copyright (c) 2008-2018 Sonatype, Inc. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Sonatype, Inc. - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.m2e.editor.pom; |
| |
| import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.ARTIFACT_ID; |
| import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.DEPENDENCY; |
| import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.EXTENSION; |
| import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.GROUP_ID; |
| import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.NAME; |
| import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.PARENT; |
| import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.PLUGIN; |
| import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.PROPERTIES; |
| import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.VERSION; |
| |
| import java.io.File; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.w3c.dom.Element; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.NodeList; |
| import org.w3c.dom.Text; |
| |
| import org.eclipse.core.filebuffers.FileBuffers; |
| import org.eclipse.core.filebuffers.ITextFileBuffer; |
| import org.eclipse.core.filesystem.EFS; |
| import org.eclipse.core.filesystem.IFileStore; |
| import org.eclipse.core.resources.IMarker; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.jface.text.BadLocationException; |
| import org.eclipse.jface.text.IDocument; |
| import org.eclipse.jface.text.IRegion; |
| import org.eclipse.jface.text.ITextViewer; |
| import org.eclipse.jface.text.Position; |
| import org.eclipse.jface.text.Region; |
| import org.eclipse.jface.text.hyperlink.IHyperlink; |
| import org.eclipse.jface.text.hyperlink.IHyperlinkDetector; |
| import org.eclipse.jface.text.source.Annotation; |
| import org.eclipse.jface.text.source.IAnnotationModel; |
| import org.eclipse.jface.text.source.ISourceViewer; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.ui.texteditor.MarkerAnnotation; |
| import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion; |
| |
| import org.apache.maven.model.Build; |
| import org.apache.maven.model.Dependency; |
| import org.apache.maven.model.DependencyManagement; |
| import org.apache.maven.model.InputLocation; |
| import org.apache.maven.model.Model; |
| import org.apache.maven.model.Plugin; |
| import org.apache.maven.model.PluginManagement; |
| import org.apache.maven.project.MavenProject; |
| |
| import org.eclipse.m2e.core.internal.IMavenConstants; |
| import org.eclipse.m2e.core.ui.internal.actions.OpenPomAction; |
| import org.eclipse.m2e.core.ui.internal.util.XmlUtils; |
| |
| |
| /** |
| * @author Eugene Kuleshov |
| * @author Milos Kleint |
| */ |
| public class PomHyperlinkDetector implements IHyperlinkDetector { |
| public IHyperlink[] detectHyperlinks(final ITextViewer textViewer, final IRegion region, |
| boolean canShowMultipleHyperlinks) { |
| if(region == null || textViewer == null) { |
| return null; |
| } |
| |
| IDocument document = textViewer.getDocument(); |
| if(document == null) { |
| return null; |
| } |
| |
| IRegion lineInfo; |
| String line; |
| try { |
| lineInfo = document.getLineInformationOfOffset(region.getOffset()); |
| line = document.get(lineInfo.getOffset(), lineInfo.getLength()); |
| } catch(BadLocationException ex) { |
| return null; |
| } |
| |
| if(line.length() == 0) { |
| return null; |
| } |
| final List<IHyperlink> hyperlinks = new ArrayList<IHyperlink>(); |
| final int offset = region.getOffset(); |
| |
| XmlUtils.performOnCurrentElement(document, offset, (node, structured) -> { |
| if(textViewer instanceof ISourceViewer) { |
| IHyperlink[] links = openExternalMarkerDefinition((ISourceViewer) textViewer, offset); |
| if(links.length > 0) { |
| hyperlinks.addAll(Arrays.asList(links)); |
| } |
| } |
| //check if we have a property expression at cursor |
| IHyperlink link = openPropertyDefinition(node, textViewer, offset); |
| if(link != null) { |
| hyperlinks.add(link); |
| } |
| //now check if the dependency/plugin has a version element or not, if not, try searching for it in DM/PM of effective pom |
| link = openDPManagement(node, textViewer, offset); |
| if(link != null) { |
| hyperlinks.add(link); |
| } |
| //check if <module> text is selected. |
| link = openModule(node, textViewer, offset); |
| if(link != null) { |
| hyperlinks.add(link); |
| } |
| link = openPOMbyID(node, textViewer, offset); |
| if(link != null) { |
| hyperlinks.add(link); |
| } |
| }); |
| |
| if(hyperlinks.size() > 0) { |
| return hyperlinks.toArray(new IHyperlink[0]); |
| } |
| return null; |
| } |
| |
| static ManagedArtifactRegion findManagedArtifactRegion(Node current, ITextViewer textViewer, int offset) { |
| while(current != null && !(current instanceof Element)) { |
| current = current.getParentNode(); |
| } |
| if(current != null) { |
| Node artNode = null; |
| Node groupNode = null; |
| if(ARTIFACT_ID.equals(current.getNodeName())) { //$NON-NLS-1$ |
| artNode = current; |
| } |
| if(GROUP_ID.equals(current.getNodeName())) { //$NON-NLS-1$ |
| groupNode = current; |
| } |
| //only on artifactid and groupid elements.. |
| if(artNode == null && groupNode == null) { |
| return null; |
| } |
| Node root = current.getParentNode(); |
| boolean isDependency = false; |
| boolean isPlugin = false; |
| if(root != null) { |
| String name = root.getNodeName(); |
| if(DEPENDENCY.equals(name)) { //$NON-NLS-1$ |
| isDependency = true; |
| } |
| if(PLUGIN.equals(name)) { //$NON-NLS-1$ |
| isPlugin = true; |
| } |
| } else { |
| return null; |
| } |
| if(!isDependency && !isPlugin) { |
| //some kind of other identifier |
| return null; |
| } |
| //now see if version is missing |
| NodeList childs = root.getChildNodes(); |
| for(int i = 0; i < childs.getLength(); i++ ) { |
| Node child = childs.item(i); |
| if(child instanceof Element) { |
| Element el = (Element) child; |
| if(VERSION.equals(el.getNodeName())) { //$NON-NLS-1$ |
| return null; |
| } |
| if(artNode == null && ARTIFACT_ID.equals(el.getNodeName())) { //$NON-NLS-1$ |
| artNode = el; |
| } |
| if(groupNode == null && GROUP_ID.equals(el.getNodeName())) { //$NON-NLS-1$ |
| groupNode = el; |
| } |
| } |
| } |
| if(groupNode != null && artNode != null) { |
| assert groupNode instanceof IndexedRegion; |
| assert artNode instanceof IndexedRegion; |
| |
| IndexedRegion groupReg = (IndexedRegion) groupNode; |
| IndexedRegion artReg = (IndexedRegion) artNode; |
| int startOffset = Math.min(groupReg.getStartOffset(), artReg.getStartOffset()); |
| int length = Math.max(groupReg.getEndOffset(), artReg.getEndOffset()) - startOffset; |
| String groupId = XmlUtils.getTextValue(groupNode); |
| String artifactId = XmlUtils.getTextValue(artNode); |
| final MavenProject prj = XmlUtils.extractMavenProject(textViewer); |
| if(prj != null) { |
| //now we can create the region I guess, |
| return new ManagedArtifactRegion(startOffset, length, groupId, artifactId, isDependency, isPlugin, prj); |
| } |
| } |
| } |
| return null; |
| } |
| |
| public static IHyperlink createHyperlink(final ManagedArtifactRegion region) { |
| return new IHyperlink() { |
| public IRegion getHyperlinkRegion() { |
| return region; |
| } |
| |
| public String getHyperlinkText() { |
| return NLS.bind(org.eclipse.m2e.editor.internal.Messages.PomHyperlinkDetector_link_managed, |
| "" + region.groupId + ":" + region.artifactId); |
| } |
| |
| public String getTypeLabel() { |
| return "pom-dependency-plugin-management"; //$NON-NLS-1$ |
| } |
| |
| public void open() { |
| //see if we can find the plugin in plugin management of resolved project. |
| MavenProject mavprj = region.project; |
| if(mavprj != null) { |
| InputLocation openLocation = findLocationForManagedArtifact(region, mavprj); |
| if(openLocation != null) { |
| File file = XmlUtils.fileForInputLocation(openLocation, mavprj); |
| if(file != null) { |
| IFileStore fileStore = EFS.getLocalFileSystem().getStore(file.toURI()); |
| XMLEditorUtility.openXmlEditor(fileStore, openLocation.getLineNumber(), openLocation.getColumnNumber(), |
| openLocation.getSource().getModelId()); |
| } |
| } |
| } |
| } |
| }; |
| |
| } |
| |
| private IHyperlink openDPManagement(Node current, ITextViewer textViewer, int offset) { |
| final ManagedArtifactRegion region = findManagedArtifactRegion(current, textViewer, offset); |
| if(region != null) { |
| return createHyperlink(region); |
| } |
| return null; |
| } |
| |
| static InputLocation findLocationForManagedArtifact(final ManagedArtifactRegion region, MavenProject mavprj) { |
| Model mdl = mavprj.getModel(); |
| InputLocation openLocation = null; |
| if(region.isDependency) { |
| DependencyManagement dm = mdl.getDependencyManagement(); |
| if(dm != null) { |
| List<Dependency> list = dm.getDependencies(); |
| String id = region.groupId + ":" + region.artifactId + ":"; //$NON-NLS-1$ //$NON-NLS-2$ |
| if(list != null) { |
| for(Dependency dep : list) { |
| if(dep.getManagementKey().startsWith(id)) { |
| InputLocation location = dep.getLocation(ARTIFACT_ID); //$NON-NLS-1$ |
| //when would this be null? |
| if(location != null) { |
| openLocation = location; |
| break; |
| } |
| } |
| } |
| } |
| } |
| } |
| if(region.isPlugin) { |
| Build build = mdl.getBuild(); |
| if(build != null) { |
| PluginManagement pm = build.getPluginManagement(); |
| if(pm != null) { |
| List<Plugin> list = pm.getPlugins(); |
| String id = Plugin.constructKey(region.groupId, region.artifactId); |
| if(list != null) { |
| for(Plugin plg : list) { |
| if(id.equals(plg.getKey())) { |
| InputLocation location = plg.getLocation(ARTIFACT_ID); //$NON-NLS-1$ |
| //when would this be null? |
| if(location != null) { |
| openLocation = location; |
| break; |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| return openLocation; |
| } |
| |
| static ExpressionRegion findExpressionRegion(Node current, ITextViewer viewer, int offset) { |
| if(current != null && current instanceof Text) { |
| Text node = (Text) current; |
| String value = node.getNodeValue(); |
| if(value != null) { |
| assert node instanceof IndexedRegion; |
| IndexedRegion reg = (IndexedRegion) node; |
| int index = offset - reg.getStartOffset(); |
| String before = value.substring(0, Math.min(index + 1, value.length())); |
| String after = value.substring(Math.min(index + 1, value.length())); |
| int start = before.lastIndexOf("${"); //$NON-NLS-1$ |
| if(before.lastIndexOf("}") > start) {//$NON-NLS-1$ |
| //we might be in between two expressions.. |
| start = -1; |
| } |
| int end = after.indexOf("}"); //$NON-NLS-1$ |
| if(after.indexOf("${") != -1 && after.indexOf("${") < end) {//$NON-NLS-1$ |
| //we might be in between two expressions.. |
| end = -1; |
| } |
| if(start > -1 && end > -1) { |
| final int startOffset = reg.getStartOffset() + start; |
| final String expr = before.substring(start) + after.substring(0, end + 1); |
| final int length = expr.length(); |
| final String prop = before.substring(start + 2) + after.substring(0, end); |
| // there are often properties that start with project. eg. project.build.sourceEncoding |
| // if (prop.startsWith("project.") || prop.startsWith("pom.")) { //$NON-NLS-1$ //$NON-NLS-2$ |
| // return null; //ignore these, not in properties section. |
| // } |
| MavenProject prj = XmlUtils.extractMavenProject(viewer); |
| if(prj != null) { |
| return new ExpressionRegion(startOffset, length, prop, prj); |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| public static IHyperlink createHyperlink(final ExpressionRegion region) { |
| return new IHyperlink() { |
| public IRegion getHyperlinkRegion() { |
| return region; |
| } |
| |
| public String getHyperlinkText() { |
| return NLS.bind(org.eclipse.m2e.editor.internal.Messages.PomHyperlinkDetector_open_property, region.property); |
| } |
| |
| public String getTypeLabel() { |
| return "pom-property-expression"; //$NON-NLS-1$ |
| } |
| |
| public void open() { |
| //see if we can find the plugin in plugin management of resolved project. |
| MavenProject mavprj = region.project; |
| if(mavprj != null) { |
| //TODO get rid of InputLocation here and use the dom tree to find the property |
| Model mdl = mavprj.getModel(); |
| InputLocation location = null; |
| if(mdl.getProperties().containsKey(region.property)) { |
| location = mdl.getLocation(PROPERTIES).getLocation(region.property); |
| } else if(region.property != null && region.property.startsWith("project.")) {//$NON-NLS-1$ |
| if("project.version".equals(region.property)) { |
| location = mdl.getLocation(VERSION); |
| } else if("project.name".equals(region.property)) { |
| location = mdl.getLocation(NAME); |
| } |
| } |
| if(location != null) { |
| File file = XmlUtils.fileForInputLocation(location, mavprj); |
| if(file != null) { |
| IFileStore fileStore = EFS.getLocalFileSystem().getStore(file.toURI()); |
| XMLEditorUtility.openXmlEditor(fileStore, location.getLineNumber(), location.getColumnNumber(), |
| location.getSource().getModelId()); |
| } |
| } |
| } |
| } |
| }; |
| } |
| |
| public static boolean canCreateHyperLink(final ExpressionRegion region) { |
| if("project.version".equals(region.property) || "project.name".equals(region.property)) { |
| return true; |
| } |
| return region.project != null && region.project.getModel().getProperties().containsKey(region.property); |
| } |
| |
| //only create the hyperlink when the origin location for jumping is present. |
| //in some cases (managed version comes from imported dependencies) we don't have the location and have nowhere to jump) |
| public static boolean canCreateHyperLink(final ManagedArtifactRegion region) { |
| return region.project != null |
| && PomHyperlinkDetector.findLocationForManagedArtifact(region, region.project) != null; |
| } |
| |
| static IHyperlink[] openExternalMarkerDefinition(ISourceViewer sourceViewer, int offset) { |
| List<IHyperlink> toRet = new ArrayList<IHyperlink>(); |
| MarkerRegion[] regions = findMarkerRegions(sourceViewer, offset); |
| for(MarkerRegion reg : regions) { |
| if(reg.isDefinedInParent()) { |
| toRet.add(createHyperlink(reg)); |
| } |
| } |
| return toRet.toArray(new IHyperlink[0]); |
| } |
| |
| static MarkerRegion[] findMarkerRegions(ISourceViewer sourceViewer, int offset) { |
| List<MarkerRegion> toRet = new ArrayList<MarkerRegion>(); |
| IAnnotationModel model = sourceViewer.getAnnotationModel(); |
| if(model != null) { //eg. in tests |
| Iterator<Annotation> it = model.getAnnotationIterator(); |
| while(it.hasNext()) { |
| Annotation ann = it.next(); |
| if(ann instanceof MarkerAnnotation) { |
| Position pos = sourceViewer.getAnnotationModel().getPosition(ann); |
| if(pos.includes(offset)) { |
| toRet.add(new MarkerRegion(pos.getOffset(), pos.getLength(), (MarkerAnnotation) ann)); |
| } |
| } |
| } |
| } |
| return toRet.toArray(new MarkerRegion[0]); |
| } |
| |
| public static IHyperlink createHyperlink(final MarkerRegion mark) { |
| return new IHyperlink() { |
| |
| public IRegion getHyperlinkRegion() { |
| return new Region(mark.getOffset(), mark.getLength()); |
| } |
| |
| public String getTypeLabel() { |
| return "marker-error-defined-in-parent"; //$NON-NLS-1$; |
| } |
| |
| public String getHyperlinkText() { |
| return NLS.bind("Open definition in parent for {0}", mark.getAnnotation().getText()); //TODO if there are multiple markers in one spot, how to differentiate better.. |
| } |
| |
| public void open() { |
| IMarker marker = mark.getAnnotation().getMarker(); |
| String loc = marker.getAttribute(IMavenConstants.MARKER_CAUSE_RESOURCE_PATH, null); |
| if(loc != null) { |
| IFileStore fileStore = EFS.getLocalFileSystem().getStore(new Path(loc)); |
| int row = marker.getAttribute(IMavenConstants.MARKER_CAUSE_LINE_NUMBER, 0); |
| int column = marker.getAttribute(IMavenConstants.MARKER_CAUSE_COLUMN_START, 0); |
| String name = marker.getAttribute(IMavenConstants.MARKER_CAUSE_RESOURCE_ID, null); |
| // String hint = marker.getAttribute(IMavenConstants.MARKER_ATTR_EDITOR_HINT, null); |
| // if (IMavenConstants.EDITOR_HINT_NOT_COVERED_MOJO_EXECUTION.equals(hint)) { |
| // } |
| XMLEditorUtility.openXmlEditor(fileStore, row, column, name); |
| } |
| } |
| }; |
| } |
| |
| private IHyperlink openPropertyDefinition(Node current, ITextViewer viewer, int offset) { |
| final ExpressionRegion region = findExpressionRegion(current, viewer, offset); |
| if(region != null && canCreateHyperLink(region)) { |
| return createHyperlink(region); |
| } |
| return null; |
| } |
| |
| private IHyperlink openModule(Node current, ITextViewer textViewer, int offset) { |
| while(current != null && !(current instanceof Element)) { |
| current = current.getParentNode(); |
| } |
| if(current == null) { |
| return null; |
| } |
| String pathUp = XmlUtils.pathUp(current, 2); |
| if(!"modules/module".equals(pathUp)) { //$NON-NLS-1$ |
| //just in case we are in some random plugin configuration snippet.. |
| return null; |
| } |
| |
| ITextFileBuffer buf = FileBuffers.getTextFileBufferManager().getTextFileBuffer(textViewer.getDocument()); |
| if(buf == null) { |
| //for repository based poms.. |
| return null; |
| } |
| IFileStore folder = buf.getFileStore().getParent(); |
| |
| String path = XmlUtils.getTextValue(current); |
| final String fPath = path; |
| //construct IPath for the child pom file, handle relative paths.. |
| while(folder != null && path.startsWith("../")) { //$NON-NLS-1$ |
| folder = folder.getParent(); |
| path = path.substring("../".length());//$NON-NLS-1$ |
| } |
| if(folder == null) { |
| return null; |
| } |
| IFileStore modulePom = folder.getChild(path); |
| if(!modulePom.getName().endsWith("xml")) { //$NON-NLS-1$ |
| modulePom = modulePom.getChild("pom.xml");//$NON-NLS-1$ |
| } |
| final IFileStore fileStore = modulePom; |
| if(!fileStore.fetchInfo().exists()) { |
| return null; |
| } |
| assert current instanceof IndexedRegion; |
| final IndexedRegion region = (IndexedRegion) current; |
| |
| return new IHyperlink() { |
| public IRegion getHyperlinkRegion() { |
| return new Region(region.getStartOffset(), region.getEndOffset() - region.getStartOffset()); |
| } |
| |
| public String getHyperlinkText() { |
| return NLS.bind(org.eclipse.m2e.editor.internal.Messages.PomHyperlinkDetector_open_module, fPath); |
| } |
| |
| public String getTypeLabel() { |
| return "pom-module"; //$NON-NLS-1$ |
| } |
| |
| public void open() { |
| XMLEditorUtility.openXmlEditor(fileStore); |
| } |
| }; |
| } |
| |
| private IHyperlink openPOMbyID(Node current, final ITextViewer viewer, int offset) { |
| while(current != null && !(current instanceof Element)) { |
| current = current.getParentNode(); |
| } |
| if(current == null) { |
| return null; |
| } |
| current = current.getParentNode(); |
| if(current == null || !(current instanceof Element)) { |
| return null; |
| } |
| Element parent = (Element) current; |
| String parentName = parent.getNodeName(); |
| if(DEPENDENCY.equals(parentName) || PARENT.equals(parentName) || PLUGIN.equals(parentName) |
| || "reportPlugin".equals(parentName) || EXTENSION.equals(parentName)) { |
| final Node groupId = XmlUtils.findChild(parent, GROUP_ID); |
| final Node artifactId = XmlUtils.findChild(parent, ARTIFACT_ID); |
| final Node version = XmlUtils.findChild(parent, VERSION); |
| final MavenProject prj = XmlUtils.extractMavenProject(viewer); |
| |
| IHyperlink pomHyperlink = new IHyperlink() { |
| public IRegion getHyperlinkRegion() { |
| //the goal here is to have the groupid/artifactid/version combo underscored by the link. |
| //that will prevent underscoring big portions (like plugin config) underscored and |
| // will also handle cases like dependencies within plugins. |
| int max = groupId != null ? ((IndexedRegion) groupId).getEndOffset() : Integer.MIN_VALUE; |
| int min = groupId != null ? ((IndexedRegion) groupId).getStartOffset() : Integer.MAX_VALUE; |
| max = Math.max(max, artifactId != null ? ((IndexedRegion) artifactId).getEndOffset() : Integer.MIN_VALUE); |
| min = Math.min(min, artifactId != null ? ((IndexedRegion) artifactId).getStartOffset() : Integer.MAX_VALUE); |
| max = Math.max(max, version != null ? ((IndexedRegion) version).getEndOffset() : Integer.MIN_VALUE); |
| min = Math.min(min, version != null ? ((IndexedRegion) version).getStartOffset() : Integer.MAX_VALUE); |
| return new Region(min, max - min); |
| } |
| |
| public String getHyperlinkText() { |
| return NLS.bind(org.eclipse.m2e.editor.internal.Messages.PomHyperlinkDetector_hyperlink_pattern, |
| XmlUtils.getTextValue(groupId), XmlUtils.getTextValue(artifactId)); |
| } |
| |
| public String getTypeLabel() { |
| return "pom"; //$NON-NLS-1$ |
| } |
| |
| public void open() { |
| new Job(org.eclipse.m2e.editor.internal.Messages.PomHyperlinkDetector_job_name) { |
| protected IStatus run(IProgressMonitor monitor) { |
| // TODO resolve groupId if groupId==null |
| String gridString = groupId == null ? "org.apache.maven.plugins" : XmlUtils.getTextValue(groupId); //$NON-NLS-1$ |
| String artidString = artifactId == null ? null : XmlUtils.getTextValue(artifactId); |
| String versionString = version == null ? null : XmlUtils.getTextValue(version); |
| if(prj != null && gridString != null && artidString != null |
| && (versionString == null || versionString.contains("${"))) { //$NON-NLS-1$ |
| try { |
| //TODO how do we decide here if the hyperlink is a dependency or a plugin |
| // hyperlink?? |
| versionString = PomTemplateContext.extractVersion(prj, null, versionString, gridString, artidString, |
| PomTemplateContext.EXTRACT_STRATEGY_DEPENDENCY); |
| |
| } catch(CoreException e) { |
| versionString = null; |
| } |
| } |
| if(versionString == null) { |
| return Status.OK_STATUS; |
| } |
| OpenPomAction.openEditor(gridString, artidString, versionString, prj, monitor); |
| // TODO: it's preferable to open the xml page, but this code will blink and open overview first and later switch. looks bad |
| // Display.getDefault().syncExec(new Runnable() { |
| // public void run() { |
| // selectEditorPage(page); |
| // } |
| // }); |
| return Status.OK_STATUS; |
| } |
| }.schedule(); |
| } |
| |
| }; |
| return pomHyperlink; |
| } |
| return null; |
| } |
| |
| public static class ExpressionRegion implements IRegion { |
| |
| final String property; |
| |
| private int length; |
| |
| private int offset; |
| |
| final MavenProject project; |
| |
| public ExpressionRegion(int startOffset, int length, String prop, MavenProject project) { |
| this.offset = startOffset; |
| this.length = length; |
| this.property = prop; |
| this.project = project; |
| assert project != null; |
| } |
| |
| public int getLength() { |
| return length; |
| } |
| |
| public int getOffset() { |
| return offset; |
| } |
| } |
| |
| public static class ManagedArtifactRegion implements IRegion { |
| |
| private int length; |
| |
| private int offset; |
| |
| final MavenProject project; |
| |
| final String groupId; |
| |
| final String artifactId; |
| |
| final boolean isPlugin; |
| |
| final boolean isDependency; |
| |
| public ManagedArtifactRegion(int startOffset, int length, String groupId, String artifactId, boolean isDependency, |
| boolean isPlugin, MavenProject project) { |
| this.offset = startOffset; |
| this.length = length; |
| this.project = project; |
| assert project != null; |
| this.artifactId = artifactId; |
| this.groupId = groupId; |
| this.isDependency = isDependency; |
| this.isPlugin = isPlugin; |
| } |
| |
| public int getLength() { |
| return length; |
| } |
| |
| public int getOffset() { |
| return offset; |
| } |
| } |
| |
| public static class MarkerRegion implements IRegion { |
| |
| private final MarkerAnnotation ann; |
| |
| final int offset; |
| |
| final int length; |
| |
| public MarkerRegion(int offset, int length, MarkerAnnotation applicable) { |
| this.offset = offset; |
| this.length = length; |
| this.ann = applicable; |
| } |
| |
| public int getLength() { |
| return length; |
| } |
| |
| public int getOffset() { |
| return offset; |
| } |
| |
| public MarkerAnnotation getAnnotation() { |
| return ann; |
| } |
| |
| public boolean isDefinedInParent() { |
| IMarker mark = ann.getMarker(); |
| String isElsewhere = mark.getAttribute(IMavenConstants.MARKER_CAUSE_RESOURCE_PATH, null); |
| if(isElsewhere != null) { |
| return true; |
| } |
| return false; |
| } |
| |
| } |
| |
| } |