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(Messages.PomHyperlinkDetector_open_module, fPath); } public String getTypeLabel() { return "pom-module"; //$NON-NLS-1$ } public void open() { openXmlEditor(fileStore); } }; }
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 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, new NodeOperation<Node>() { public void process(Node node, IStructuredDocument 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; }
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( Messages.PomHyperlinkDetector_hyperlink_pattern, XmlUtils.getTextValue(groupId), XmlUtils.getTextValue(artifactId)); } public String getTypeLabel() { return "pom"; //$NON-NLS-1$ } public void open() { new Job(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, 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; }
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; }