/******************************************************************************* * 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.internal.core.refactoring; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.IAnnotation; import org.eclipse.jdt.core.IBuffer; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IField; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.ILocalVariable; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.ISourceRange; import org.eclipse.jdt.core.ISourceReference; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.text.edits.InsertEdit; import org.eclipse.text.edits.MultiTextEdit; import org.eclipse.text.edits.ReplaceEdit; import org.eclipse.text.edits.TextEdit; import org.jboss.tools.cdi.core.CDIConstants; import org.jboss.tools.cdi.core.CDICorePlugin; import org.jboss.tools.cdi.core.IBean; import org.jboss.tools.cdi.core.IBeanField; import org.jboss.tools.cdi.core.IBeanMethod; import org.jboss.tools.cdi.core.IInjectionPoint; import org.jboss.tools.cdi.core.IInjectionPointField; import org.jboss.tools.cdi.core.IInjectionPointParameter; import org.jboss.tools.cdi.core.IQualifier; import org.jboss.tools.cdi.core.IQualifierDeclaration; import org.jboss.tools.cdi.internal.core.impl.definition.AbstractTypeDefinition; import org.jboss.tools.common.refactoring.MarkerResolutionUtils; import org.jboss.tools.common.util.BeanUtil; /** * @author Daniel Azarov */ public class CDIMarkerResolutionUtils extends MarkerResolutionUtils{ public static void addQualifier(String qualifiedName, String value, ICompilationUnit compilationUnit, IJavaElement element, MultiTextEdit rootEdit) throws JavaModelException{ if(!(element instanceof ISourceReference)) return; IAnnotation annotation = findAnnotation(element, qualifiedName); if(annotation != null && annotation.exists()) return; boolean duplicateShortName = addImport(qualifiedName, compilationUnit, rootEdit); String lineDelim = SPACE; IBuffer buffer = compilationUnit.getBuffer(); String shortName = getShortName(qualifiedName); if(!value.isEmpty()) value = "("+value+")"; if(duplicateShortName) shortName = qualifiedName; annotation = findAnnotation(element, CDIConstants.INJECT_ANNOTATION_TYPE_NAME); if(rootEdit != null){ if(annotation != null && annotation.exists()){ TextEdit edit = new InsertEdit(annotation.getSourceRange().getOffset()+annotation.getSourceRange().getLength(), lineDelim+AT+shortName+value); rootEdit.addChild(edit); }else{ TextEdit edit = new InsertEdit(((ISourceReference)element).getSourceRange().getOffset(), AT+shortName+value+lineDelim); rootEdit.addChild(edit); } }else{ if(annotation != null && annotation.exists()){ buffer.replace(annotation.getSourceRange().getOffset()+annotation.getSourceRange().getLength(), 0, lineDelim+AT+shortName+value); }else{ buffer.replace(((ISourceReference)element).getSourceRange().getOffset(), 0, AT+shortName+value+lineDelim); } synchronized(compilationUnit) { compilationUnit.reconcile(ICompilationUnit.NO_AST, true, null, null); } } } public static void updateQualifier(String qualifiedName, String value, ICompilationUnit compilationUnit, IJavaElement element, MultiTextEdit rootEdit) throws JavaModelException{ if(!(element instanceof ISourceReference)) return; IAnnotation annotation = findAnnotation(element, qualifiedName); if(annotation == null || !annotation.exists()) return; boolean duplicateShortName = addImport(qualifiedName, compilationUnit, rootEdit); IBuffer buffer = compilationUnit.getBuffer(); String shortName = getShortName(qualifiedName); if(!value.isEmpty()) value = "("+value+")"; if(duplicateShortName) shortName = qualifiedName; String newValue = AT+shortName+value; if(!annotation.getSource().equals(newValue)){ if(rootEdit != null){ TextEdit edit = new ReplaceEdit(annotation.getSourceRange().getOffset(), annotation.getSourceRange().getLength(), newValue); rootEdit.addChild(edit); }else{ buffer.replace(annotation.getSourceRange().getOffset(), annotation.getSourceRange().getLength(), newValue); synchronized(compilationUnit) { compilationUnit.reconcile(ICompilationUnit.NO_AST, true, null, null); } } } } private static boolean contains(IQualifierDeclaration declaration, List<ValuedQualifier> declarations){ for(ValuedQualifier d : declarations){ if(declaration.getQualifier().getSourceType().getFullyQualifiedName().equals(d.getQualifier().getSourceType().getFullyQualifiedName())) return true; } return false; } private static List<IQualifier> findQualifiersToDelete(IInjectionPoint injectionPoint, List<ValuedQualifier> qualifiers){ ArrayList<IQualifier> list = new ArrayList<IQualifier>(); for(IQualifierDeclaration declaration : injectionPoint.getQualifierDeclarations()){ if(!contains(declaration, qualifiers)) list.add(declaration.getQualifier()); } return list; } public static ISourceRange getParameterRegion(IInjectionPointParameter injectionParameter){ try{ String paramName = injectionParameter.getName(); IMethod method = injectionParameter.getBeanMethod().getMethod(); for(ILocalVariable parameter : method.getParameters()){ if(parameter.getElementName().equals(paramName)){ return parameter.getSourceRange(); } } }catch(JavaModelException ex){ CDICorePlugin.getDefault().logError(ex); } return null; } public static void addQualifiersToInjectionPoint(List<ValuedQualifier> deployed, IInjectionPoint injectionPoint, ICompilationUnit compilationUnit, MultiTextEdit edit){ try{ IJavaElement element = getInjectedJavaElement(compilationUnit, injectionPoint); if(element == null || !element.exists()) return; // delete unneeded qualifiers List<IQualifier> toDelete = findQualifiersToDelete(injectionPoint, deployed); for(IQualifier qualifier : toDelete){ deleteAnnotation(qualifier.getSourceType().getFullyQualifiedName(), compilationUnit, element, edit); } for(ValuedQualifier declaration : deployed){ String qualifierName = declaration.getQualifier().getSourceType().getFullyQualifiedName(); String value = declaration.getValue(); if(!qualifierName.equals(CDIConstants.ANY_QUALIFIER_TYPE_NAME) && !qualifierName.equals(CDIConstants.DEFAULT_QUALIFIER_TYPE_NAME)){ addQualifier(qualifierName, value, compilationUnit, element, edit); updateQualifier(qualifierName, value, compilationUnit, element, edit); } } }catch(CoreException ex){ CDICorePlugin.getDefault().logError(ex); } } public static void addQualifiersToBean(List<ValuedQualifier> deployed, IBean bean, ICompilationUnit compilationUnit, MultiTextEdit edit){ IJavaElement beanElement = null; if(bean instanceof IBeanField){ beanElement = ((IBeanField) bean).getField(); }else if(bean instanceof IBeanMethod){ beanElement = ((IBeanMethod) bean).getMethod(); }else{ beanElement = bean.getBeanClass(); } try{ for(IQualifierDeclaration declaration : bean.getQualifierDeclarations()){ IQualifier qualifier = declaration.getQualifier(); String qualifierName = qualifier.getSourceType().getFullyQualifiedName(); if(!isQualifierNeeded(deployed, qualifier)){ deleteAnnotation(qualifierName, compilationUnit, beanElement, edit); } } for(ValuedQualifier vq : deployed){ String qualifierName = vq.getQualifier().getSourceType().getFullyQualifiedName(); String value = vq.getValue(); String elName = "\""+getELName(bean)+"\""; if(!value.isEmpty() && (!value.equals(elName) || !qualifierName.equals(CDIConstants.NAMED_QUALIFIER_TYPE_NAME))){ value = "("+value+")"; }else{ value = ""; } if(!qualifierName.equals(CDIConstants.ANY_QUALIFIER_TYPE_NAME) && !qualifierName.equals(CDIConstants.DEFAULT_QUALIFIER_TYPE_NAME)){ addAnnotation(qualifierName, compilationUnit, beanElement, value, edit); updateAnnotation(qualifierName, compilationUnit, beanElement, value, edit); } } }catch(CoreException ex){ CDICorePlugin.getDefault().logError(ex); } } private static boolean isQualifierNeeded(List<ValuedQualifier> vQualifiers, IQualifier qualifier){ for(ValuedQualifier vq : vQualifiers){ if(vq.getQualifier().equals(qualifier)) return true; } return false; } private static IJavaElement getInjectedJavaElement(ICompilationUnit compilationUnit, IInjectionPoint injectionPoint) throws JavaModelException{ if(injectionPoint instanceof IInjectionPointField){ IField field = ((IInjectionPointField)injectionPoint).getField(); IType type = field.getDeclaringType(); IType t = compilationUnit.getType(type.getElementName()); IField f = t.getField(field.getElementName()); return f; }else if(injectionPoint instanceof IInjectionPointParameter){ IMethod method = ((IInjectionPointParameter)injectionPoint).getBeanMethod().getMethod(); IType type = method.getDeclaringType(); IType t = compilationUnit.getType(type.getElementName()); IMethod m = t.getMethod(method.getElementName(), method.getParameterTypes()); for(ILocalVariable parameter : m.getParameters()){ if(parameter.getElementName().equals(((IInjectionPointParameter) injectionPoint).getName())){ return parameter; } } } return null; } public static boolean checkBeanQualifiers(IBean selectedBean, IBean bean, Collection<IQualifier> qualifiers){ Collection<ValuedQualifier> valuedQualifiers = new ArrayList<ValuedQualifier>(); for(IQualifier qualifier : qualifiers){ valuedQualifiers.add(new ValuedQualifier(qualifier)); } return checkValuedQualifiers(selectedBean, bean, valuedQualifiers); } public static boolean checkValuedQualifiers(IBean selectedBean, IBean bean, Collection<ValuedQualifier> qualifiers){ for(ValuedQualifier qualifier : qualifiers){ if(!isBeanContainQualifier(bean, qualifier)){ return false; } } if(bean.getQualifiers().size() == qualifiers.size() && bean.getQualifiers().size() != 0) return true; return false; } private static boolean isBeanContainQualifier(IBean bean, ValuedQualifier valuedQualifier){ for(IQualifier q : bean.getQualifiers()){ IQualifierDeclaration declaration = CDIMarkerResolutionUtils.findQualifierDeclaration(bean, q); ValuedQualifier vq = null; if(declaration != null){ vq = new ValuedQualifier(q, declaration); }else{ vq = new ValuedQualifier(q); } if(vq.fullyEquals(valuedQualifier)){ return true; } } return false; } public static IQualifierDeclaration findQualifierDeclaration(IBean bean, IQualifier qualifier){ Collection<IQualifierDeclaration> declarations = bean.getQualifierDeclarations(); if(declarations == null) return null; for(IQualifierDeclaration declaration : declarations){ if(declaration.getQualifier().getSourceType().getFullyQualifiedName().equals(qualifier.getSourceType().getFullyQualifiedName())) return declaration; } return null; } public static String getELName(IBean bean){ String name; if(bean instanceof IBeanField){ name = ((IBeanField) bean).getField().getElementName(); }else if(bean instanceof IBeanMethod){ name = ((IBeanMethod) bean).getMethod().getElementName(); if(BeanUtil.isGetter(((IBeanMethod) bean).getMethod())) { return BeanUtil.getPropertyName(name); } }else{ name = BeanUtil.getDefaultBeanName(bean.getBeanClass()); } return name; } }