/******************************************************************************* * Copyright (c) 2009-2011 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.common.java.impl; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.IAnnotation; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.IMemberValuePair; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.ISourceReference; import org.eclipse.jdt.core.IType; import org.jboss.tools.common.core.CommonCorePlugin; import org.jboss.tools.common.java.IAnnotationDeclaration; import org.jboss.tools.common.java.IAnnotationType; import org.jboss.tools.common.java.IJavaAnnotation; /** * * @author Viacheslav Kabanovich * */ public class AnnotationDeclaration implements IAnnotationDeclaration { public static final String VALUE = "value"; //$NON-NLS-1$ protected IJavaAnnotation annotation; protected IValues values = EmptyValues.instance; protected IValues constants = EmptyValues.instance; protected IValues defaults = EmptyValues.instance; public AnnotationDeclaration() {} public void setDeclaration(IJavaAnnotation annotation) { this.annotation = annotation; IMemberValuePair[] pairs = getMemberValuePairs(); if(pairs.length > 0) { ValueResolver r = new ValueResolver(getJavaAnnotation()); for (IMemberValuePair pair: pairs) { String name = pair.getMemberName(); Object value = r.resolvePair(pair); if(value != null) { values = values.put(name, value); } if(r.getConstant() != null) { constants = constants.put(name, r.getConstant()); } } r.dispose(); } try { loadDefaults(); } catch (CoreException e) { CommonCorePlugin.getDefault().logError(e); } } private void loadDefaults() throws CoreException { IType type = getType(); if(type == null) { return; } IMethod[] ms = type.getMethods(); for (IMethod m: ms) { String n = m.getElementName(); IMemberValuePair p = m.getDefaultValue(); if (p != null) { n = p.getMemberName(); Object o = p.getValue(); // Default value can be null since JDT does not computes complex values // E.g. values (char)7 or (2 + 3) will be resolved to null. if(o == null) { String expression = null; String s = ((ISourceReference)m).getSource(); if(s != null) { int i = s.indexOf("default"); int j = s.lastIndexOf(';'); if(i > 0 && j > i) { expression = s.substring(i + 7, j).trim(); } } if(expression != null) { ValueResolver r = new ValueResolver(m); o = r.resolveExpression(expression); r.dispose(); } } if(o != null) { defaults = defaults.put(n, o); } } } } public IJavaAnnotation getDeclaration() { return annotation; } public IResource getResource() { return annotation.getResource(); } public IMemberValuePair[] getMemberValuePairs() { return annotation.getMemberValuePairs(); } /** * Returns value 'as is', it may be a qualified name without resolving its value. */ public Object getMemberValue(String name) { if(name == null) name = VALUE; return values.get(name); } public Object getMemberConstantValue(String name) { if(name == null) name = VALUE; return constants.get(name); } /** * For a value resolved to a field reference, tries to get its value. * If it cannot be resolved, 'as is' value is returned. * @param name * @param resolve * @return */ public Object getMemberValue(String name, boolean resolve) { Object result = null; if(resolve) { result = getMemberConstantValue(name); } if(result == null) { result = getMemberValue(name); } return result; } public Object getMemberDefaultValue(String name) { if(name == null) name = VALUE; return defaults.get(name); } public IMember getParentMember() { return annotation.getParentMember(); } public String getTypeName() { return annotation.getTypeName(); } public IType getType() { return annotation.getType(); } public int getLength() { return annotation.getLength(); } public int getStartPosition() { return annotation.getStartPosition(); } public IAnnotationType getAnnotation() { return null; } public IAnnotation getJavaAnnotation() { if(annotation instanceof JavaAnnotation) { return ((JavaAnnotation) annotation).getAnnotation(); } return null; } @Override public IMember getSourceMember() { return getParentMember(); } @Override public IJavaElement getSourceElement() { return annotation.getParentElement(); } } interface IValues { Object get(String name); IValues put(String name, Object value); } class EmptyValues implements IValues { static EmptyValues instance = new EmptyValues(); public Object get(String name) { return null; } public IValues put(String name, Object value) { return ("value".equals(name)) ? new Value(value) : new Values(name, value); } } class Value implements IValues { Object value; Value(Object value) { this.value = value; } public Object get(String name) { return "value".equals(name) ? value : null; } public IValues put(String name, Object value) { Values values = new Values("value", this.value); values.put(name, value); return values; } } class Values implements IValues { List<String> names = new ArrayList<String>(2); List<Object> values = new ArrayList<Object>(2); public Values(String name, Object value) { names.add(name); values.add(value); } public Object get(String name) { for (int i = 0; i < names.size(); i++) { if(name.equals(names.get(i))) return values.get(i); } return null; } public IValues put(String name, Object value) { names.add(name); values.add(value); return this; } }