001 /*
002 GRANITE DATA SERVICES
003 Copyright (C) 2011 GRANITE DATA SERVICES S.A.S.
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.lang.reflect.TypeVariable;
029 import java.util.ArrayList;
030 import java.util.Arrays;
031 import java.util.List;
032
033 import org.granite.generator.as3.ClientType;
034
035
036 /**
037 * @author Franck WOLFF
038 */
039 public class JavaFieldProperty extends JavaMember<Field> implements JavaProperty {
040
041 private final JavaMethod readMethod;
042 private final JavaMethod writeMethod;
043 private final JavaTypeFactory provider;
044 private final ParameterizedType declaringType;
045
046 public JavaFieldProperty(JavaTypeFactory provider, Field field, JavaMethod readMethod, JavaMethod writeMethod) {
047 this(provider, field, readMethod, writeMethod, null);
048 }
049
050 public JavaFieldProperty(JavaTypeFactory provider, Field field, JavaMethod readMethod, JavaMethod writeMethod, ParameterizedType declaringType) {
051 super(field);
052
053 this.provider = provider;
054 this.readMethod = readMethod;
055 this.writeMethod = writeMethod;
056 this.declaringType = declaringType;
057 }
058
059 @Override
060 public String getCapitalizedName() {
061 return getName().substring(0, 1).toUpperCase() + getName().substring(1);
062 }
063
064 @Override
065 public Class<?> getType() {
066 Type type = getMember().getGenericType();
067 if (type instanceof TypeVariable && declaringType != null) {
068 int index = -1;
069 for (int i = 0; i < getMember().getDeclaringClass().getTypeParameters().length; i++) {
070 if (getMember().getDeclaringClass().getTypeParameters()[i] == type) {
071 index = i;
072 break;
073 }
074 }
075 if (index >= 0 && index < declaringType.getActualTypeArguments().length)
076 return (Class<?>)declaringType.getActualTypeArguments()[index];
077 }
078 return getMember().getType();
079 }
080
081 public Type getGenericType() {
082 Type type = getMember().getGenericType();
083 if (type instanceof TypeVariable && declaringType != null) {
084 int index = -1;
085 for (int i = 0; i < getMember().getDeclaringClass().getTypeParameters().length; i++) {
086 if (getMember().getDeclaringClass().getTypeParameters()[i] == type) {
087 index = i;
088 break;
089 }
090 }
091 if (index >= 0 && index < declaringType.getActualTypeArguments().length)
092 return declaringType.getActualTypeArguments()[index];
093 }
094 return getMember().getGenericType();
095 }
096
097 @Override
098 public Type[] getGenericTypes() {
099 Type type = getMember().getGenericType();
100 if (!(type instanceof ParameterizedType))
101 return null;
102 return ((ParameterizedType)type).getActualTypeArguments();
103 }
104
105 public boolean hasTypePackage() {
106 return (getTypePackageName().length() > 0);
107 }
108 public String getTypePackageName() {
109 Package p = getType().getPackage();
110 return (p != null ? p.getName() : "");
111 }
112
113 public String getTypeName() {
114 return getType().getSimpleName();
115 }
116
117 @Override
118 public boolean isReadable() {
119 return (Modifier.isPublic(getMember().getModifiers()) || readMethod != null);
120 }
121
122 @Override
123 public boolean isWritable() {
124 return (Modifier.isPublic(getMember().getModifiers()) || writeMethod != null);
125 }
126
127 @Override
128 public boolean isExternalizedProperty() {
129 return false;
130 }
131
132 @Override
133 public boolean isEnum() {
134 Class<?> type = getType();
135 return (type.isEnum() || Enum.class.getName().equals(type.getName()));
136 }
137
138 @Override
139 public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
140 return (
141 (getMember().isAnnotationPresent(annotationClass)) ||
142 (readMethod != null && readMethod.getMember().isAnnotationPresent(annotationClass)) ||
143 (writeMethod != null && writeMethod.getMember().isAnnotationPresent(annotationClass))
144 );
145 }
146
147 @Override
148 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
149 T annotation = getMember().getAnnotation(annotationClass);
150 if (annotation != null)
151 return annotation;
152
153 if (readMethod != null) {
154 annotation = readMethod.getMember().getAnnotation(annotationClass);
155 if (annotation != null)
156 return annotation;
157 }
158 if (writeMethod != null) {
159 annotation = writeMethod.getMember().getAnnotation(annotationClass);
160 if (annotation != null)
161 return annotation;
162 }
163 return null;
164 }
165
166 @Override
167 public Annotation[] getDeclaredAnnotations() {
168 List<Annotation> annos = new ArrayList<Annotation>(Arrays.asList(getMember().getDeclaredAnnotations()));
169 if (readMethod != null)
170 annos.addAll(Arrays.asList(readMethod.getMember().getDeclaredAnnotations()));
171 if (writeMethod != null)
172 annos.addAll(Arrays.asList(writeMethod.getMember().getDeclaredAnnotations()));
173
174 return annos.toArray(new Annotation[0]);
175 }
176
177 @Override
178 public boolean isReadOverride() {
179 return (readMethod != null && readMethod.isOverride());
180 }
181
182 @Override
183 public boolean isWriteOverride() {
184 return (writeMethod != null && writeMethod.isOverride());
185 }
186
187 @Override
188 public JavaMethod getReadMethod() {
189 return readMethod;
190 }
191
192 @Override
193 public JavaMethod getWriteMethod() {
194 return writeMethod;
195 }
196
197 public ClientType getAs3Type() {
198 ClientType clientType = provider.getClientType(getGenericType(), null, null, true);
199 if (clientType == null)
200 return provider.getAs3Type(getType());
201 return clientType;
202 }
203
204 @Override
205 public ClientType getClientType() {
206 return provider.getClientType(getGenericType(), null, null, true);
207 }
208
209 @Override
210 public int compareTo(JavaProperty o) {
211 return getName().compareTo(o.getName());
212 }
213
214 @Override
215 public boolean equals(Object obj) {
216 if (this == obj)
217 return true;
218 if (obj instanceof JavaMethodProperty)
219 return ((JavaMethodProperty)obj).getName().equals(getName());
220 return false;
221 }
222
223 @Override
224 public int hashCode() {
225 return getName().hashCode();
226 }
227
228 @Override
229 public String toString() {
230 return getClass().getSimpleName() +
231 " {name=" + getName() +
232 ", readable=" + (readMethod != null) +
233 ", writable=" + (writeMethod != null) + "}";
234 }
235 }