001    /*******************************************************************************
002     * Copyright (C) 2009-2011 FuseSource Corp.
003     * Copyright (c) 2004, 2008 IBM Corporation and others.
004     *
005     * All rights reserved. This program and the accompanying materials
006     * are made available under the terms of the Eclipse Public License v1.0
007     * which accompanies this distribution, and is available at
008     * http://www.eclipse.org/legal/epl-v10.html
009     *
010     *******************************************************************************/
011    package org.fusesource.hawtjni.generator.model;
012    
013    import java.lang.reflect.Field;
014    import java.util.Arrays;
015    import java.util.HashSet;
016    
017    import org.fusesource.hawtjni.runtime.FieldFlag;
018    import org.fusesource.hawtjni.runtime.JniField;
019    import org.fusesource.hawtjni.runtime.T32;
020    
021    import static org.fusesource.hawtjni.generator.util.TextSupport.*;
022    import static org.fusesource.hawtjni.runtime.FieldFlag.*;
023    
024    /**
025     * 
026     * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
027     */
028    public class ReflectField implements JNIField {
029        
030        private ReflectClass parent;
031        private Field field;
032        private ReflectType type;
033        private JniField annotation;
034        private HashSet<FieldFlag> flags;
035        private boolean allowConversion;
036    
037        public ReflectField(ReflectClass parent, Field field) {
038            this.parent = parent;
039            this.field = field;
040            lazyLoad();
041        }
042    
043        public int hashCode() {
044            return field.hashCode();
045        }
046    
047        public boolean equals(Object obj) {
048            if (!(obj instanceof ReflectField))
049                return false;
050            return ((ReflectField) obj).field.equals(field);
051        }
052        
053        public String toString() {
054            return field.toString();
055        }
056    
057        ///////////////////////////////////////////////////////////////////
058        // JNIField interface methods
059        ///////////////////////////////////////////////////////////////////
060    
061        public JNIClass getDeclaringClass() {
062            return parent;
063        }
064    
065        public int getModifiers() {
066            return field.getModifiers();
067        }
068    
069        public String getName() {
070            return field.getName();
071        }
072    
073        public JNIType getType() {
074            return type.asType32(allowConversion);
075        }
076    
077        public JNIType getType64() {
078            return type.asType64(allowConversion);
079        }
080    
081        public String getAccessor() {
082            return annotation == null ? "" : annotation.accessor();
083        }
084    
085        public String getCast() {
086            String rc = annotation == null ? "" : annotation.cast().trim();
087            return cast(rc);
088        }
089    
090        public boolean ignore() {
091            return getFlag(FieldFlag.FIELD_SKIP);
092        }
093    
094        public boolean isPointer() {
095            if( annotation == null ) {
096                return false;
097            }
098            return getFlag(POINTER_FIELD) || ( type.getWrappedClass() == Long.TYPE && getCast().endsWith("*)") );
099        }
100    
101        public String getConditional() {
102            String parentConditional = getDeclaringClass().getConditional();
103            String myConditional = annotation == null ? null : emptyFilter(annotation.conditional());
104            if( parentConditional!=null ) {
105                if( myConditional!=null ) {
106                    return parentConditional+" && "+myConditional;
107                } else {
108                    return parentConditional;
109                }
110            }
111            return myConditional;
112        }
113    
114        public boolean getFlag(FieldFlag flag) {
115            return flags.contains(flag);
116        }
117    
118        ///////////////////////////////////////////////////////////////////
119        // Helper methods
120        ///////////////////////////////////////////////////////////////////
121        static public String emptyFilter(String value) {
122            if( value==null || value.length()==0 )
123                return null;
124            return value;
125        }
126        
127        private void lazyLoad() {
128            this.type = new ReflectType(field.getType());
129            this.annotation = this.field.getAnnotation(JniField.class);
130            this.flags = new HashSet<FieldFlag>();
131            if( this.annotation!=null ) {
132                this.flags.addAll(Arrays.asList(this.annotation.flags()));
133            }
134            
135            allowConversion = this.field.getAnnotation(T32.class)!=null;
136        }
137    
138    }