/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.gosu.parser; import gw.lang.reflect.FeatureManager; import gw.lang.reflect.MethodList; import gw.lang.reflect.BaseTypeInfo; import gw.lang.reflect.IAnnotationInfo; import gw.lang.reflect.IAttributedFeatureInfo; import gw.lang.reflect.IConstructorInfo; import gw.lang.reflect.IEventInfo; import gw.lang.reflect.IMethodInfo; import gw.lang.reflect.IPropertyInfo; import gw.lang.reflect.IRelativeTypeInfo; import gw.lang.reflect.IType; import gw.lang.reflect.ITypeInfo; import gw.lang.reflect.TypeInfoUtil; import gw.lang.reflect.TypeSystem; import gw.lang.reflect.MethodInfoDelegate; import gw.lang.reflect.PropertyInfoDelegate; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; /** */ public class CompoundTypeInfo extends BaseTypeInfo implements IRelativeTypeInfo { volatile private Map<CharSequence, IPropertyInfo> _propertiesByName; volatile private List<IPropertyInfo> _properties; volatile private MethodList _methods; /** */ public CompoundTypeInfo( CompoundType intrType ) { super( intrType ); } public CompoundType getOwnersType() { return (CompoundType)super.getOwnersType(); } public List<? extends IPropertyInfo> getProperties() { if( _properties == null ) { extractProperties(); } return _properties; } public IPropertyInfo getProperty( CharSequence propName ) { if( _properties == null ) { extractProperties(); } return _propertiesByName.get( propName ); } /** */ public MethodList getMethods() { if( _methods == null ) { extractMethods(); } return _methods; } public IMethodInfo getMethod( CharSequence methodName, IType... params ) { return FIND.method( getMethods(), methodName, params ); } /** */ public List<IConstructorInfo> getConstructors() { return Collections.emptyList(); } public IConstructorInfo getConstructor( IType... params ) { return null; } public IMethodInfo getCallableMethod( CharSequence strMethod, IType... params ) { return FIND.callableMethod( getMethods(), strMethod, params ); } public IConstructorInfo getCallableConstructor( IType... params ) { return FIND.callableConstructor( getConstructors(), params ); } /** */ public List<IEventInfo> getEvents() { return Collections.emptyList(); } /** */ public IEventInfo getEvent( CharSequence strEvent ) { return null; } private void extractProperties() { if( _properties == null ) { TypeSystem.lock(); try { if( _properties == null ) { _propertiesByName = new HashMap<CharSequence, IPropertyInfo>(); for( IType type : getOwnersType().getTypes() ) { ITypeInfo ti = type.getTypeInfo(); List<? extends IPropertyInfo> properties; if( ti instanceof IRelativeTypeInfo ) { properties = ((IRelativeTypeInfo)ti).getProperties( type ); } else { properties = ti.getProperties(); } for( IPropertyInfo pi : properties ) { _propertiesByName.put( pi.getName(), new PropertyInfoDelegate( this, pi ) ); } } _properties = TypeInfoUtil.makeSortedUnmodifiableRandomAccessListFromFeatures( _propertiesByName ); } } finally { TypeSystem.unlock(); } } } private void extractMethods() { if( _methods == null ) { TypeSystem.lock(); try { if( _methods == null ) { MethodList allMethods = new MethodList(); for( IType type : getOwnersType().getTypes() ) { ITypeInfo ti = type.getTypeInfo(); List<? extends IMethodInfo> methods; if( ti instanceof IRelativeTypeInfo ) { methods = ((IRelativeTypeInfo)ti).getMethods( type ); } else { methods = ti.getMethods(); } for( IMethodInfo mi : methods ) { allMethods.add( new MethodInfoDelegate( this, mi ) ); } } _methods = TypeInfoUtil.makeSortedUnmodifiableRandomAccessList( allMethods ); } } finally { TypeSystem.unlock(); } } } public List<IAnnotationInfo> getDeclaredAnnotations() { return Collections.emptyList(); } public IRelativeTypeInfo.Accessibility getAccessibilityForType( IType whosAskin ) { IRelativeTypeInfo.Accessibility accessibility = IRelativeTypeInfo.Accessibility.PRIVATE; whosAskin = whosAskin == null ? JavaTypeInfo.getCompilingClass( getOwnersType() ) : whosAskin; if( whosAskin == getOwnersType() ) { return accessibility; } for( IType type : getOwnersType().getTypes() ) { if( type == null || whosAskin == null ) { accessibility = IRelativeTypeInfo.Accessibility.PUBLIC; } else { IRelativeTypeInfo.Accessibility csr = FeatureManager.getAccessibilityForClass( type, whosAskin ); if( csr.ordinal() < accessibility.ordinal() ) { accessibility = csr; } } } return accessibility; } public List<? extends IPropertyInfo> getProperties( IType whosaskin ) { IRelativeTypeInfo.Accessibility accessibility = getAccessibilityForType( whosaskin ); List<IPropertyInfo> properties = new ArrayList<IPropertyInfo>( getProperties() ); Iterator<IPropertyInfo> iterator = properties.iterator(); while( iterator.hasNext() ) { IPropertyInfo propertyInfo = iterator.next(); boolean hidden = isHidden( accessibility, propertyInfo ); if( hidden ) { iterator.remove(); } } return properties; } public IPropertyInfo getProperty( IType whosaskin, CharSequence propName ) { IPropertyInfo property = getProperty( propName ); if( property == null || isHidden( getAccessibilityForType( whosaskin ), property ) ) { return null; } return property; } public MethodList getMethods(IType whosaskin) { IRelativeTypeInfo.Accessibility accessibility = getAccessibilityForType( whosaskin ); MethodList methods = new MethodList( getMethods() ); Iterator<IMethodInfo> iterator = methods.iterator(); while( iterator.hasNext() ) { IMethodInfo methodInfo = iterator.next(); boolean hidden = isHidden( accessibility, methodInfo ); if( hidden ) { iterator.remove(); } } return methods; } public IMethodInfo getMethod( IType whosaskin, CharSequence methodName, IType... params ) { IMethodInfo method = getMethod( methodName, params ); if( method == null || isHidden( getAccessibilityForType( whosaskin ), method ) ) { return null; } return method; } private boolean isHidden( IRelativeTypeInfo.Accessibility accessibility, IAttributedFeatureInfo fi ) { boolean hidden = false; if( fi.isPrivate() && accessibility != IRelativeTypeInfo.Accessibility.PRIVATE ) { hidden = true; } else if( fi.isInternal() && accessibility.ordinal() < IRelativeTypeInfo.Accessibility.INTERNAL.ordinal() ) { hidden = true; } else if( fi.isProtected() && accessibility.ordinal() < IRelativeTypeInfo.Accessibility.PROTECTED.ordinal() ) { hidden = true; } return hidden; } @SuppressWarnings({"UnusedDeclaration"}) public List<? extends IConstructorInfo> getConstructors( IType whosaskin ) { return Collections.emptyList(); } @SuppressWarnings({"UnusedDeclaration"}) public IConstructorInfo getConstructor( IType whosAskin, IType[] params ) { return null; } @Override public List<? extends IPropertyInfo> getDeclaredProperties() { return Collections.emptyList(); } @Override public List<? extends IMethodInfo> getDeclaredMethods() { return Collections.emptyList(); } @Override public List<? extends IConstructorInfo> getDeclaredConstructors() { return Collections.emptyList(); } }