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