/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.gosu.parser; import gw.config.CommonServices; import gw.internal.gosu.parser.statements.LoopStatement; import gw.lang.parser.IExpansionPropertyInfo; import gw.lang.reflect.IAnnotationInfo; import gw.lang.reflect.IFeatureInfo; import gw.lang.reflect.IPresentationInfo; import gw.lang.reflect.IPropertyAccessor; import gw.lang.reflect.IPropertyInfo; import gw.lang.reflect.IScriptabilityModifier; import gw.lang.reflect.IType; import gw.lang.reflect.TypeSystem; import gw.lang.reflect.java.JavaTypes; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; /** */ public class ArrayExpansionPropertyInfo implements IExpansionPropertyInfo { private IPropertyInfo _delegate; private IPropertyAccessor _arrayExpansionAccessor; public ArrayExpansionPropertyInfo( IPropertyInfo delegate ) { _delegate = delegate; } public boolean isReadable() { return _delegate.isReadable(); } public boolean isWritable( IType whosAskin ) { return false; } public boolean isWritable() { return isWritable( null ); } public IPropertyAccessor getAccessor() { if( _arrayExpansionAccessor == null ) { _arrayExpansionAccessor = new ArrayExpansionAccessor(); } return _arrayExpansionAccessor; } public IPresentationInfo getPresentationInfo() { return IPresentationInfo.Default.GET; } public boolean isScriptable() { return _delegate.isScriptable(); } public boolean isDeprecated() { return _delegate.isDeprecated(); } public String getDeprecatedReason() { return _delegate.getDeprecatedReason(); } public boolean isVisible( IScriptabilityModifier constraint ) { return _delegate.isVisible( constraint ); } public boolean isHidden() { return _delegate.isHidden(); } public boolean isStatic() { return _delegate.isStatic(); } public boolean isPrivate() { return _delegate.isPrivate(); } public boolean isInternal() { return _delegate.isInternal(); } public boolean isProtected() { return _delegate.isProtected(); } public boolean isPublic() { return _delegate.isPublic(); } public boolean isAbstract() { return _delegate.isAbstract(); } public boolean isFinal() { return _delegate.isFinal(); } public List<IAnnotationInfo> getAnnotations() { return Collections.emptyList(); } public List<IAnnotationInfo> getDeclaredAnnotations() { return Collections.emptyList(); } public List<IAnnotationInfo> getAnnotationsOfType( IType type ) { return Collections.emptyList(); } @Override public IAnnotationInfo getAnnotation( IType type ) { return null; } public boolean hasAnnotation( IType type ) { return false; } @Override public boolean hasDeclaredAnnotation( IType type ) { return false; } public IFeatureInfo getContainer() { return _delegate.getContainer(); } public IType getOwnersType() { return _delegate.getOwnersType(); } public String getName() { return _delegate.getName(); } public String getDisplayName() { return _delegate.getDisplayName(); } public String getDescription() { return _delegate.getDescription(); } /** * Make an array type from the delegate's type, if it's not already an array. * The idea with array expansion is to allow access to properties of X from an * array of X. We call the accessor For each X in the array we call the */ public IType getFeatureType() { if( _delegate.getFeatureType().isArray() ) { return _delegate.getFeatureType(); } return _delegate.getFeatureType().getArrayType(); } public IPropertyInfo getDelegate() { return _delegate; } class ArrayExpansionAccessor implements IPropertyAccessor { public Object getValue( Object ctx ) { IPropertyAccessor accessor = _delegate.getAccessor(); if( ctx == null ) { return null; } IType type = _delegate.getFeatureType(); IType objArrayType = TypeSystem.getFromObject( ctx ); boolean bArray = type.isArray(); List results = new ArrayList(); for( Iterator iter = LoopStatement.makeIterator( ctx, objArrayType ); iter.hasNext(); ) { Object elem = iter.next(); Object value = elem == null ? null : accessor.getValue( elem ); if( value != null && bArray ) { results.addAll( (Collection)CommonServices.getCoercionManager().convertValue( value, JavaTypes.ARRAY_LIST() ) ); } else { results.add( value ); } } return CommonServices.getCoercionManager().convertValue( results, getFeatureType() ); } public void setValue( Object ctx, Object value ) { throw new UnsupportedOperationException( "Array expansion properties are not writable." ); } } }