001    /*
002      GRANITE DATA SERVICES
003      Copyright (C) 2007-2010 ADEQUATE SYSTEMS SARL
004    
005      This file is part of Granite Data Services.
006    
007      Granite Data Services is free software; you can redistribute it and/or modify
008      it under the terms of the GNU Library General Public License as published by
009      the Free Software Foundation; either version 2 of the License, or (at your
010      option) any later version.
011    
012      Granite Data Services is distributed in the hope that it will be useful, but
013      WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014      FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015      for more details.
016    
017      You should have received a copy of the GNU Library General Public License
018      along with this library; if not, see <http://www.gnu.org/licenses/>.
019    */
020    
021    package org.granite.generator.as3.reflect;
022    
023    import java.lang.annotation.Annotation;
024    import java.lang.reflect.Field;
025    import java.lang.reflect.Modifier;
026    import java.lang.reflect.ParameterizedType;
027    import java.lang.reflect.Type;
028    import java.util.ArrayList;
029    import java.util.Arrays;
030    import java.util.List;
031    
032    import org.granite.generator.as3.As3Type;
033    
034    
035    /**
036     * @author Franck WOLFF
037     */
038    public class JavaFieldProperty extends JavaMember<Field> implements JavaProperty {
039    
040        private final JavaMethod readMethod;
041        private final JavaMethod writeMethod;
042        private final JavaTypeFactory provider;
043    
044        public JavaFieldProperty(JavaTypeFactory provider, Field field, JavaMethod readMethod, JavaMethod writeMethod) {
045            super(field);
046    
047            this.provider = provider;
048            this.readMethod = readMethod;
049            this.writeMethod = writeMethod;
050        }
051    
052        public Class<?> getType() {
053            return getMember().getType();
054        }
055        
056        public Type[] getGenericTypes() {
057                    Type type = getMember().getGenericType();
058                    if (!(type instanceof ParameterizedType))
059                            return null;
060                    return ((ParameterizedType)type).getActualTypeArguments();
061        }
062    
063        public boolean hasTypePackage() {
064            return (getTypePackageName().length() > 0);
065        }
066        public String getTypePackageName() {
067            Package p = getType().getPackage();
068            return (p != null ? p.getName() : "");
069        }
070    
071        public String getTypeName() {
072            return getType().getSimpleName();
073        }
074    
075        public boolean isReadable() {
076            return (Modifier.isPublic(getMember().getModifiers()) || readMethod != null);
077        }
078    
079        public boolean isWritable() {
080            return (Modifier.isPublic(getMember().getModifiers()) || writeMethod != null);
081        }
082    
083        public boolean isExternalizedProperty() {
084            return false;
085        }
086    
087        public boolean isEnum() {
088            Class<?> type = getType();
089                    return (type.isEnum() || Enum.class.getName().equals(type.getName()));
090            }
091    
092        public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
093            return (
094                (getMember().isAnnotationPresent(annotationClass)) ||
095                (readMethod != null && readMethod.getMember().isAnnotationPresent(annotationClass)) ||
096                (writeMethod != null && writeMethod.getMember().isAnnotationPresent(annotationClass))
097            );
098        }
099    
100        public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
101            T annotation = getMember().getAnnotation(annotationClass);
102            if (annotation != null)
103                    return annotation;
104            
105            if (readMethod != null) {
106                    annotation = readMethod.getMember().getAnnotation(annotationClass);
107                    if (annotation != null)
108                            return annotation;
109            }
110            if (writeMethod != null) {
111                    annotation = writeMethod.getMember().getAnnotation(annotationClass);
112                    if (annotation != null)
113                            return annotation;
114            }
115            return null;
116        }
117        
118        public Annotation[] getDeclaredAnnotations() {
119            List<Annotation> annos = new ArrayList<Annotation>(Arrays.asList(getMember().getDeclaredAnnotations()));
120            if (readMethod != null)
121                    annos.addAll(Arrays.asList(readMethod.getMember().getDeclaredAnnotations()));
122            if (writeMethod != null)
123                    annos.addAll(Arrays.asList(writeMethod.getMember().getDeclaredAnnotations()));
124            
125            return annos.toArray(new Annotation[0]);
126        }
127    
128        public boolean isReadOverride() {
129            return (readMethod != null && readMethod.isOverride());
130        }
131    
132        public boolean isWriteOverride() {
133            return (writeMethod != null && writeMethod.isOverride());
134        }
135    
136        public JavaMethod getReadMethod() {
137            return readMethod;
138        }
139    
140        public JavaMethod getWriteMethod() {
141            return writeMethod;
142        }
143    
144        public As3Type getAs3Type() {
145            return provider.getAs3Type(getType());
146        }
147    
148        public int compareTo(JavaProperty o) {
149            return getName().compareTo(o.getName());
150        }
151    
152        @Override
153        public boolean equals(Object obj) {
154            if (this == obj)
155                return true;
156            if (obj instanceof JavaMethodProperty)
157                return ((JavaMethodProperty)obj).getName().equals(getName());
158            return false;
159        }
160    
161        @Override
162        public int hashCode() {
163            return getName().hashCode();
164        }
165    
166        @Override
167        public String toString() {
168            return getClass().getSimpleName() +
169                " {name=" + getName() +
170                ", readable=" + (readMethod != null) +
171                ", writable=" + (writeMethod != null) + "}";
172        }
173    }