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 *******************************************************************************/
011package org.fusesource.hawtjni.generator.model;
012
013import java.lang.reflect.Field;
014import java.util.Arrays;
015import java.util.HashSet;
016
017import org.fusesource.hawtjni.runtime.FieldFlag;
018import org.fusesource.hawtjni.runtime.JniField;
019import org.fusesource.hawtjni.runtime.T32;
020
021import static org.fusesource.hawtjni.generator.util.TextSupport.*;
022import static org.fusesource.hawtjni.runtime.FieldFlag.*;
023
024/**
025 * 
026 * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
027 */
028public 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}