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.ParameterizedType;
025    import java.lang.reflect.Type;
026    import java.util.ArrayList;
027    import java.util.Arrays;
028    import java.util.List;
029    
030    import org.granite.generator.as3.As3Type;
031    import org.granite.messaging.amf.io.util.externalizer.annotation.ExternalizedProperty;
032    
033    /**
034     * @author Franck WOLFF
035     */
036    public class JavaMethodProperty implements JavaProperty {
037    
038        private final String name;
039        private final JavaMethod readMethod;
040        private final JavaMethod writeMethod;
041        private final Class<?> type;
042        private final As3Type as3Type;
043        private final boolean externalizedProperty;
044    
045        public JavaMethodProperty(JavaTypeFactory provider, String name, JavaMethod readMethod, JavaMethod writeMethod) {
046            if (name == null || (readMethod == null && writeMethod == null))
047                throw new NullPointerException("Invalid parameters");
048            this.name = name;
049            this.readMethod = readMethod;
050            this.writeMethod = writeMethod;
051            this.type = (
052                readMethod != null ?
053                readMethod.getMember().getReturnType() :
054                writeMethod.getMember().getParameterTypes()[0]
055            );
056            this.as3Type = provider.getAs3Type(type);
057            this.externalizedProperty = (
058                    readMethod != null &&
059                    readMethod.getMember().isAnnotationPresent(ExternalizedProperty.class)
060            );
061        }
062    
063        public String getName() {
064            return name;
065        }
066    
067        public Class<?> getType() {
068            return type;
069        }
070        
071        public Type[] getGenericTypes() {
072                    Type type = readMethod != null ? readMethod.getMember().getGenericReturnType() : writeMethod.getMember().getGenericParameterTypes()[0];
073                    if (!(type instanceof ParameterizedType))
074                            return null;
075                    return ((ParameterizedType)type).getActualTypeArguments();
076        }
077    
078        public boolean isReadable() {
079            return (readMethod != null);
080        }
081    
082        public boolean isWritable() {
083            return (writeMethod != null);
084        }
085    
086        public boolean isExternalizedProperty() {
087            return externalizedProperty;
088        }
089    
090        public boolean isEnum() {
091                    return (type.isEnum() || Enum.class.getName().equals(type.getName()));
092            }
093    
094            public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
095            return (
096                (readMethod != null && readMethod.getMember().isAnnotationPresent(annotationClass)) ||
097                (writeMethod != null && writeMethod.getMember().isAnnotationPresent(annotationClass))
098            );
099        }
100    
101        public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
102            T annotation = null;
103            if (readMethod != null) {
104                    annotation = readMethod.getMember().getAnnotation(annotationClass);
105                    if (annotation != null)
106                            return annotation;
107            }
108            if (writeMethod != null) {
109                    annotation = writeMethod.getMember().getAnnotation(annotationClass);
110                    if (annotation != null)
111                            return annotation;
112            }
113            return null;
114        }
115        
116        public Annotation[] getDeclaredAnnotations() {
117            List<Annotation> annos = new ArrayList<Annotation>();
118            if (readMethod != null)
119                    annos.addAll(Arrays.asList(readMethod.getMember().getDeclaredAnnotations()));
120            if (writeMethod != null)
121                    annos.addAll(Arrays.asList(writeMethod.getMember().getDeclaredAnnotations()));
122            return annos.toArray(new Annotation[0]);
123        }
124    
125        public boolean isReadOverride() {
126            return (readMethod != null && readMethod.isOverride());
127        }
128    
129        public boolean isWriteOverride() {
130            return (writeMethod != null && writeMethod.isOverride());
131        }
132    
133        public JavaMethod getReadMethod() {
134            return readMethod;
135        }
136    
137        public JavaMethod getWriteMethod() {
138            return writeMethod;
139        }
140    
141        public As3Type getAs3Type() {
142            return as3Type;
143        }
144    
145        public int compareTo(JavaProperty o) {
146            return name.compareTo(o.getName());
147        }
148    
149        @Override
150        public boolean equals(Object obj) {
151            if (this == obj)
152                return true;
153            if (obj instanceof JavaMethodProperty)
154                return ((JavaMethodProperty)obj).name.equals(name);
155            return false;
156        }
157    
158        @Override
159        public int hashCode() {
160            return name.hashCode();
161        }
162    }