/* * Copyright 2013 Guidewire Software, Inc. */ package gw.lang.parser; import gw.lang.reflect.IType; import gw.lang.reflect.ITypeVariableType; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; /** */ public class TypeVarToTypeMap { public static final TypeVarToTypeMap EMPTY_MAP = new TypeVarToTypeMap( true ); private Map<Object, IType> _map; public TypeVarToTypeMap() { this( false ); } public TypeVarToTypeMap( boolean bEmpty ) { if( bEmpty ) { _map = Collections.emptyMap(); } else { _map = new LinkedHashMap<Object, IType>( 2 ); } } public TypeVarToTypeMap( TypeVarToTypeMap actualParamByVarName ) { this(); _map.putAll( actualParamByVarName._map ); } public IType get( ITypeVariableType tvType ) { IType type = _map.get( tvType ); if( type == null ) { for( Object key : _map.keySet() ) { if( looseEquals( tvType, key ) ) { type = _map.get( key ); break; } } } return type; } public IType getByString( String strName ) { IType type = _map.get( strName ); if( type == null ) { for( Object key : _map.keySet() ) { if( looseEquals( key, strName ) ) { type = _map.get( key ); break; } } } return type; } public IType getRaw( Object o ) { IType type = _map.get( o ); if( type == null ) { for( Object key : _map.keySet() ) { if( looseEquals( key, o ) ) { type = _map.get( key ); break; } } } return type; } public boolean containsKey( ITypeVariableType tvType ) { if( _map.containsKey( tvType ) ) { return true; } for( Object key : _map.keySet() ) { if( looseEquals( key, tvType ) ) { return true; } } return false; } public boolean containsKeyRaw( Object o ) { if( _map.containsKey( o ) ) { return true; } for( Object key : _map.keySet() ) { if( looseEquals( key, o ) ) { return true; } } return false; } public static boolean looseEquals( Object p1, Object p2 ) { if( p1 instanceof ITypeVariableType ) { if( p2 instanceof ITypeVariableType ) { return p1.equals( p2 ); } if( p2 instanceof String ) { ITypeVariableType tvType = (ITypeVariableType)p1; return p2.equals( tvType.getRelativeName() ) || p2.equals( tvType.getName() ); } } else if( p1 instanceof String ) { if( p2 instanceof String ) { return p1.equals( p2 ); } if( p2 instanceof ITypeVariableType ) { ITypeVariableType tvType = (ITypeVariableType)p2; return p1.equals( tvType.getRelativeName() ) || p1.equals( tvType.getName() ); } } throw new IllegalStateException( "Unexpected types: " + p1.getClass() + ", " + p2.getClass() ); } public IType put( ITypeVariableType tvType, IType type ) { IType existing = remove( tvType ); _map.put( tvType, type ); return existing; } public void putAll( TypeVarToTypeMap from ) { for( Object x : from._map.keySet() ) { putRaw( x, from.getRaw( x ) ); } } public IType putByString( String strName, IType object ) { return _map.put( strName, object ); } public IType putRaw( Object o, IType type ) { return _map.put( o, type ); } public boolean isEmpty() { return _map.isEmpty(); } public int size() { return _map.size(); } public Set<Object> keySet() { return _map.keySet(); } public Set<Map.Entry<Object,IType>> entrySet() { return _map.entrySet(); } public IType remove( ITypeVariableType tvType ) { IType type = _map.remove( tvType ); if( type == null ) { for( Iterator iter = _map.keySet().iterator(); iter.hasNext(); ) { Object key = iter.next(); if( looseEquals( tvType, key ) ) { type = _map.get( key ); iter.remove(); break; } } } return type; } public IType removeByString( String strName ) { return _map.remove( strName ); } public Collection<IType> values() { return _map.values(); } }