/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.gosu.parser.java.classinfo; import gw.internal.gosu.parser.java.IJavaASTNode; import gw.internal.gosu.parser.java.JavaASTConstants; import gw.internal.gosu.parser.java.JavaParser; import gw.internal.gosu.parser.java.LeafASTNode; import gw.lang.reflect.IAnnotationInfo; import gw.lang.reflect.Modifier; import gw.lang.reflect.java.IJavaAnnotatedElement; import gw.lang.reflect.java.IJavaClassInfo; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.List; public class JavaSourceModifierList implements IModifierList { private static final JavaSourceAnnotationInfo[] NONE = new JavaSourceAnnotationInfo[0]; private IJavaASTNode _modifiersOrAnnotationsNode; private int _modifiers; private IJavaAnnotatedElement _owner; private JavaSourceAnnotationInfo[] _annotations; /** * For enum constants. */ public JavaSourceModifierList(JavaSourceEnumConstant owner, IJavaASTNode annotationsNode, int modifiers) { _owner = owner; _modifiers = modifiers; _modifiersOrAnnotationsNode = annotationsNode; } public JavaSourceModifierList(IJavaAnnotatedElement owner, IJavaASTNode modifiersNode) { _owner = owner; _modifiersOrAnnotationsNode = modifiersNode; for (IJavaASTNode child : modifiersNode.getChildren()) { if (child.isLeaf()) { int tokenType = ((LeafASTNode) child).getTokenType(); switch (tokenType) { case JavaParser.PUBLIC: _modifiers |= Modifier.PUBLIC; break; case JavaParser.PROTECTED: _modifiers |= Modifier.PROTECTED; break; case JavaParser.PRIVATE: _modifiers |= Modifier.PRIVATE; break; case JavaParser.STATIC: _modifiers |= Modifier.STATIC; break; case JavaParser.ABSTRACT: _modifiers |= Modifier.ABSTRACT; break; case JavaParser.FINAL: _modifiers |= Modifier.FINAL; break; case JavaParser.NATIVE: _modifiers |= Modifier.NATIVE; break; case JavaParser.SYNCHRONIZED: _modifiers |= Modifier.SYNCHRONIZED; break; case JavaParser.STRICTFP: _modifiers |= Modifier.STRICT; break; case JavaParser.TRANSIENT: _modifiers |= Modifier.TRANSIENT; break; case JavaParser.VOLATILE: _modifiers |= Modifier.VOLATILE; break; default: throw new RuntimeException("Unknown modifier " + child.getText()); } } } IJavaClassInfo declaringOwner = owner instanceof JavaSourceType ? (IJavaClassInfo) owner : owner.getEnclosingClass(); if (declaringOwner.isInterface() || declaringOwner.isAnnotation()) { _modifiers |= Modifier.PUBLIC; _modifiers |= Modifier.ABSTRACT; if (owner instanceof JavaSourceField) { _modifiers |= Modifier.STATIC; } } // Types, nested in interfaces are public and static if (owner instanceof JavaSourceType && declaringOwner.getEnclosingClass() instanceof JavaSourceInterface) { _modifiers |= Modifier.PUBLIC; _modifiers |= Modifier.STATIC; } if (declaringOwner.getEnclosingClass() == null && !hasModifier(Modifier.PUBLIC) && !hasModifier(Modifier.PROTECTED) && !hasModifier(Modifier.PRIVATE)) { _modifiers |= Modifier.INTERNAL; } } public boolean hasModifier(int modifierType) { return (_modifiers & modifierType) != 0; } @Override public int getModifiers() { return _modifiers; } private void maybeInitAnnotations() { if (_annotations == null) { if (_modifiersOrAnnotationsNode == null) { _annotations = NONE; } else { List<IJavaASTNode> annotationNodes = _modifiersOrAnnotationsNode.getChildrenOfTypes(JavaASTConstants.annotation); List<JavaSourceAnnotationInfo> annotations = new ArrayList<JavaSourceAnnotationInfo>(); for (IJavaASTNode annotationNode : annotationNodes) { annotations.add(new JavaSourceAnnotationInfo(annotationNode, _owner)); } _annotations = annotations.toArray(new JavaSourceAnnotationInfo[annotations.size()]); } } } @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) { return getAnnotation(annotationClass) != null; } public IAnnotationInfo[] getAnnotations() { maybeInitAnnotations(); return _annotations; } @Override public IAnnotationInfo getAnnotation(Class annotationClass) { maybeInitAnnotations(); for (JavaSourceAnnotationInfo annotation : _annotations) { if (annotation.getName().equals(annotationClass.getName().replace('$', '.'))) { return annotation; } } return null; } public void setModifiers(int modifiers) { this._modifiers = modifiers; } public String toString() { return _owner.toString(); } }