001    /*
002     * To change this template, choose Tools | Templates
003     * and open the template in the editor.
004     */
005    
006    package org.bridj.util;
007    
008    import java.lang.reflect.ParameterizedType;
009    import java.lang.reflect.Type;
010    
011    /**
012     * Default implementation of {@link java.lang.reflect.ParameterizedType}
013     * @author Olivier
014     */
015    public class DefaultParameterizedType implements ParameterizedType {
016        private final Type[] actualTypeArguments;
017        private final Type ownerType;
018        private final Type rawType;
019    
020        public DefaultParameterizedType(Type ownerType, Type rawType, Type[] actualTypeArguments) {
021            this.ownerType = ownerType;
022            this.actualTypeArguments = actualTypeArguments;
023            this.rawType = rawType;
024        }
025        public DefaultParameterizedType(Type rawType, Type... actualTypeArguments) {
026            this(null, rawType, actualTypeArguments);
027        }
028        
029        @Override
030        public String toString() {
031                    StringBuilder b = new StringBuilder();
032                    if (ownerType != null)
033                            b.append(Utils.toString(ownerType)).append(".");
034                    b.append(rawType);
035                    if (actualTypeArguments.length > 0) {
036                            b.append("<");
037                            for (int i = 0; i < actualTypeArguments.length; i++) {
038                                    if (i > 0)
039                                            b.append(", ");
040                                    b.append(Utils.toString(actualTypeArguments[i]));
041                            }
042                            b.append(">");
043                    }       
044                    return b.toString();
045        }
046        public static Type paramType(Type rawType, Type... actualTypeArguments) {
047            return new DefaultParameterizedType(rawType, actualTypeArguments);
048        }
049        
050        //@Override
051        public Type[] getActualTypeArguments() {
052            return actualTypeArguments.clone();
053        }
054    
055        //@Override
056        public java.lang.reflect.Type getOwnerType() {
057            return ownerType;
058        }
059    
060        //@Override
061        public java.lang.reflect.Type getRawType() {
062            return rawType;
063        }
064        
065        
066            //@Override
067            public int hashCode() {
068                    int h = getRawType().hashCode();
069                    if (getOwnerType() != null)
070                            h ^= getOwnerType().hashCode();
071                    for (int i = 0, n = actualTypeArguments.length; i < n; i++)
072                            h ^= actualTypeArguments[i].hashCode();
073                    return h;
074            }
075            
076            static boolean eq(Object a, Object b) {
077                    if ((a == null) != (b == null))
078                            return false;
079                    if (a != null && !a.equals(b))
080                            return false;
081                    return true;
082            }
083            //@Override
084            public boolean equals(Object o) {
085                    if (o == null || !(o instanceof DefaultParameterizedType))
086                            return false;
087                    
088                    DefaultParameterizedType t = (DefaultParameterizedType)o;
089                    if (!eq(getRawType(), t.getRawType()))
090                            return false;
091                    if (!eq(getOwnerType(), t.getOwnerType()))
092                            return false;
093                    
094                    Object[] tp = t.actualTypeArguments;
095                    if (actualTypeArguments.length != tp.length)
096                            return false;
097                    
098                    for (int i = 0, n = actualTypeArguments.length; i < n; i++)
099                            if (!eq(actualTypeArguments[i], tp[i]))
100                                    return false;
101                            
102                    return true;
103            }
104    }