/******************************************************************************* * 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.seam.text.ext.hyperlink; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; 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.texteditor.ITextEditor; 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.IBeanMember; import org.jboss.tools.cdi.core.ICDIProject; import org.jboss.tools.cdi.core.IClassBean; import org.jboss.tools.cdi.core.IInjectionPoint; import org.jboss.tools.cdi.core.IInjectionPointParameter; import org.jboss.tools.cdi.seam.solder.core.generic.GenericClassBean; import org.jboss.tools.cdi.seam.text.ext.CDISeamExtPlugin; public class GenericInjectedPointHyperlinkDetector extends AbstractHyperlinkDetector{ protected IRegion region; protected IDocument document; protected ITextViewer viewer; public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) { this.region = region; this.viewer = textViewer; ITextEditor textEditor= (ITextEditor)getAdapter(ITextEditor.class); if (region == null || !canShowMultipleHyperlinks || !(textEditor instanceof JavaEditor)) return null; int offset= region.getOffset(); ITypeRoot input = EditorUtility.getEditorInputJavaElement(textEditor, false); if (input == null) return null; 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; CDICoreNature cdiNature = CDIUtil.getCDINatureWithProgress(project); if(cdiNature == 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>(); int position = 0; if(elements[0] instanceof IType){ elements[0] = input.getElementAt(wordRegion.getOffset()); if(elements[0] == null) return null; if(elements[0] instanceof IMethod){ position = offset; } } findInjectedBeans(cdiNature, elements[0], position, input.getPath(), hyperlinks); if (hyperlinks != null && !hyperlinks.isEmpty()) { return (IHyperlink[])hyperlinks.toArray(new IHyperlink[hyperlinks.size()]); } } catch (JavaModelException jme) { CDISeamExtPlugin.getDefault().logError(jme); } return null; } protected void findInjectedBeans(CDICoreNature nature, IJavaElement element, int offset, IPath path, ArrayList<IHyperlink> hyperlinks){ ICDIProject cdiProject = nature.getDelegate(); if(cdiProject == null) { return; } Collection<IBean> beans = cdiProject.getBeans(path); Set<IInjectionPoint> injectionPoints = findInjectionPoints(beans, element, offset); if(injectionPoints.isEmpty()) { return; } Set<IBean> resultBeanSet2 = new HashSet<IBean>(); for (IInjectionPoint injectionPoint: injectionPoints) { Collection<IBean> resultBeanSet = cdiProject.getBeans(true, injectionPoint); for (IBean b: resultBeanSet) { IClassBean cb = null; if(b instanceof IClassBean) { cb = (IClassBean)b; } if(b instanceof IBeanMember) { cb = ((IBeanMember)b).getClassBean(); } if(cb instanceof GenericClassBean) { GenericClassBean gcb = (GenericClassBean)cb; IBean gpb = gcb.getGenericProducerBean(); if(gpb != null) { resultBeanSet2.add(gpb); } } else if(injectionPoint.getClassBean() instanceof GenericClassBean && injectionPoint.isAnnotationPresent(((GenericClassBean)injectionPoint.getClassBean()).getVersion().getInjectGenericAnnotationTypeName())) { resultBeanSet2.add(b); } } } List<IBean> resultBeanList = CDIUtil.sortBeans(resultBeanSet2); if(resultBeanList.size() == 1) { hyperlinks.add(new GenericInjectedPointHyperlink(region, resultBeanList.get(0), document)); } else if(resultBeanList.size() > 0) { hyperlinks.add(new GenericInjectedPointListHyperlink(region, resultBeanList, viewer, document)); } } public static Set<IInjectionPoint> findInjectionPoints(Collection<IBean> beans, IJavaElement element, int position) { Set<IInjectionPoint> results = new HashSet<IInjectionPoint>(); for (IBean bean : beans) { Collection<IInjectionPoint> injectionPoints = bean.getInjectionPoints(); for (IInjectionPoint iPoint : injectionPoints) { if(element != null && iPoint.isDeclaredFor(element)) { results.add(iPoint); } else if(iPoint instanceof IInjectionPointParameter && position != 0) { if(iPoint.getStartPosition() <= position && (iPoint.getStartPosition()+iPoint.getLength()) >= position) results.add(iPoint); } } } return results; } }