/******************************************************************************* * Copyright (c) 2010 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.cdi.text.ext.hyperlink; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IPath; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.ITypeRoot; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility; import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; import org.eclipse.jdt.internal.ui.text.JavaWordFinder; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector; import org.eclipse.jface.text.hyperlink.IHyperlink; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.texteditor.ITextEditor; import org.jboss.tools.cdi.core.CDIConstants; import org.jboss.tools.cdi.core.CDICoreNature; import org.jboss.tools.cdi.core.CDIUtil; import org.jboss.tools.cdi.core.IBean; import org.jboss.tools.cdi.core.IBeanMethod; import org.jboss.tools.cdi.core.ICDIProject; import org.jboss.tools.cdi.core.IClassBean; import org.jboss.tools.cdi.core.IProducer; import org.jboss.tools.cdi.core.IProducerMethod; import org.jboss.tools.cdi.text.ext.CDIExtensionsPlugin; public class ProducerDisposerHyperlinkDetector extends AbstractHyperlinkDetector { protected IFile file; public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) { ITextEditor textEditor= (ITextEditor)getAdapter(ITextEditor.class); if (region == null || !(textEditor instanceof JavaEditor)) return null; if(textEditor.getEditorInput() instanceof IFileEditorInput){ file = ((IFileEditorInput)textEditor.getEditorInput()).getFile(); } int offset= region.getOffset(); ITypeRoot input= EditorUtility.getEditorInputJavaElement(textEditor, true); if (input == null) return null; IDocument document= textEditor.getDocumentProvider().getDocument(textEditor.getEditorInput()); IRegion wordRegion= JavaWordFinder.findWord(document, offset); if (wordRegion == null) return null; IProject project = null; project = input.getJavaProject().getProject(); if(project == null) return null; Collection<IBean> beans = getBeans(project, input.getPath(), textEditor.isDirty()); if(beans == null) return null; IJavaElement[] elements = null; try { elements = input.codeSelect(wordRegion.getOffset(), wordRegion.getLength()); if (elements == null) return null; if(elements.length != 1) return null; ArrayList<IHyperlink> hyperlinks = new ArrayList<IHyperlink>(); if(elements[0] instanceof IType){ if(CDIConstants.PRODUCES_ANNOTATION_TYPE_NAME.equals(((IType) elements[0]).getFullyQualifiedName())){ elements[0] = input.getElementAt(wordRegion.getOffset()); if(elements[0] == null) return null; } } if (elements[0] instanceof IMethod) { for(IBean bean : beans){ if(bean instanceof IClassBean){ IProducerMethod producer = getProducer((IClassBean)bean, (IMethod)elements[0]); if(producer != null){ List<IMethod> disposers = findDisposerMethods(producer); for(IMethod method : disposers){ hyperlinks.add(new DisposerHyperlink(region, method, document)); } }else{ IBeanMethod disposer = getDisposer((IClassBean)bean, (IMethod)elements[0]); if(disposer != null){ List<IMethod> producers = findProducerMethods((IClassBean)bean, disposer); for(IMethod method : producers){ hyperlinks.add(new ProducerHyperlink(region, method, document)); } } } } } } if (hyperlinks != null && !hyperlinks.isEmpty()) { return (IHyperlink[])hyperlinks.toArray(new IHyperlink[hyperlinks.size()]); } } catch (JavaModelException jme) { CDIExtensionsPlugin.getDefault().logError(jme); } return null; } private Collection<IBean> getBeans(IProject project, IPath path, boolean dirty){ CDICoreNature cdiNature = CDIUtil.getCDINatureWithProgress(project); if(cdiNature == null) return null; ICDIProject cdiProject = CDIUtil.getCDIProject(file, cdiNature, dirty); if(cdiProject == null) return null; return cdiProject.getBeans(path); } private IProducerMethod getProducer(IClassBean classBean, IMethod method){ for(IProducer producer : classBean.getProducers()){ if(producer instanceof IProducerMethod && ((IProducerMethod)producer).getMethod().equals(method)) return (IProducerMethod)producer; } return null; } private IBeanMethod getDisposer(IClassBean classBean, IMethod method){ for(IBeanMethod disposer : classBean.getDisposers()){ if(disposer.getMethod().equals(method)) return disposer; } return null; } private List<IMethod> findProducerMethods(IClassBean classBean, IBeanMethod disposer){ ArrayList<IMethod> methods = new ArrayList<IMethod>(); for(IProducer producer : classBean.getProducers()){ if(producer instanceof IProducerMethod){ for(IBeanMethod beanMethod : producer.getCDIProject().resolveDisposers((IProducerMethod)producer)){ if(beanMethod.equals(disposer)) methods.add(((IProducerMethod)producer).getMethod()); } } } return methods; } private List<IMethod> findDisposerMethods(IProducerMethod producer){ ArrayList<IMethod> methods = new ArrayList<IMethod>(); for(IBeanMethod beanMethod : producer.getCDIProject().resolveDisposers(producer)){ methods.add(beanMethod.getMethod()); } return methods; } }