Java tutorial
/******************************************************************************* * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * *******************************************************************************/ package com.liferay.ide.portlet.ui.editor; import com.liferay.ide.core.util.CoreUtil; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.search.IJavaSearchConstants; import org.eclipse.jdt.core.search.IJavaSearchScope; import org.eclipse.jdt.core.search.SearchEngine; import org.eclipse.jdt.core.search.SearchMatch; import org.eclipse.jdt.core.search.SearchParticipant; import org.eclipse.jdt.core.search.SearchPattern; import org.eclipse.jdt.core.search.SearchRequestor; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocumentExtension4; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.Region; import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector; import org.eclipse.jface.text.hyperlink.IHyperlink; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; import org.eclipse.wst.xml.search.core.util.DOMUtils; import org.w3c.dom.Node; /** * @author Gregory Amerson */ @SuppressWarnings("restriction") public class PortletURLHyperlinkDetector extends AbstractHyperlinkDetector { private IFile lastFile; private long lastModStamp; private IRegion lastNodeRegion; private IMethod[] lastActionUrlMethods; private static class ActionMethodCollector extends SearchRequestor { private final List<IMethod> results; public ActionMethodCollector(List<IMethod> results) { super(); this.results = results; } @Override public void acceptSearchMatch(SearchMatch match) throws CoreException { final Object element = match.getElement(); if (element instanceof IMethod && isActionMethod((IMethod) element)) { this.results.add((IMethod) element); } } } private static boolean isActionMethod(IMethod method) { final String[] paramTypes = method.getParameterTypes(); return paramTypes.length == 2 && paramTypes[0].toLowerCase().contains("request") && paramTypes[1].toLowerCase().contains("response"); } public PortletURLHyperlinkDetector() { super(); } public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) { IHyperlink[] retval = null; if (shouldDetectHyperlinks(textViewer, region)) { final IDocument document = textViewer.getDocument(); final int offset = region.getOffset(); final IDOMNode currentNode = DOMUtils.getNodeByOffset(document, offset); final IRegion nodeRegion = new Region(currentNode.getStartOffset(), currentNode.getEndOffset() - currentNode.getStartOffset()); if (isActionURL(currentNode)) { final Node name = currentNode.getAttributes().getNamedItem("name"); if (name != null) { final long modStamp = ((IDocumentExtension4) document).getModificationStamp(); final IFile file = DOMUtils.getFile(document); IMethod[] actionUrlMethods = null; if (file.equals(this.lastFile) && modStamp == this.lastModStamp && nodeRegion.equals(this.lastNodeRegion)) { actionUrlMethods = this.lastActionUrlMethods; } else { final String nameValue = name.getNodeValue(); // search for this method in any portlet classes actionUrlMethods = findPortletMethods(document, nameValue); this.lastModStamp = modStamp; this.lastFile = file; this.lastNodeRegion = nodeRegion; this.lastActionUrlMethods = actionUrlMethods; } if (!CoreUtil.isNullOrEmpty(actionUrlMethods)) { final List<IHyperlink> links = new ArrayList<IHyperlink>(); for (IMethod method : actionUrlMethods) { if (method.exists()) { links.add(new BasicJavaElementHyperlink(nodeRegion, method)); } } if (links.size() != 0) { if (canShowMultipleHyperlinks) { retval = links.toArray(new IHyperlink[0]); } else { retval = new IHyperlink[] { links.get(0) }; } } } } } } return retval; } private IMethod[] findPortletMethods(IDocument document, String nameValue) { IMethod[] retval = null; final IFile file = DOMUtils.getFile(document); if (file != null && file.exists()) { final IJavaProject project = JavaCore.create(file.getProject()); if (project != null && project.exists()) { try { final IType portlet = project.findType("javax.portlet.Portlet"); if (portlet != null) { final List<IMethod> methods = new ArrayList<IMethod>(); final SearchRequestor requestor = new ActionMethodCollector(methods); final IJavaSearchScope scope = SearchEngine.createStrictHierarchyScope(project, portlet, true, false, null); final SearchPattern search = SearchPattern.createPattern(nameValue, IJavaSearchConstants.METHOD, IJavaSearchConstants.DECLARATIONS, SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE); new SearchEngine().search(search, new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }, scope, requestor, new NullProgressMonitor()); retval = methods.toArray(new IMethod[0]); } } catch (JavaModelException e) { } catch (CoreException e) { } } } return retval; } private boolean isActionURL(Node currentNode) { return currentNode != null && currentNode.getNodeName() != null && currentNode.getNodeType() == Node.ELEMENT_NODE && currentNode.getNodeName().endsWith("actionURL"); } private boolean shouldDetectHyperlinks(final ITextViewer textViewer, final IRegion region) { return region != null && textViewer != null; } }