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.apache.commons.lang3.StringUtils; 018import org.fusesource.hawtjni.runtime.FieldFlag; 019import org.fusesource.hawtjni.runtime.JniField; 020import org.fusesource.hawtjni.runtime.T32; 021 022import static org.fusesource.hawtjni.generator.util.TextSupport.*; 023import static org.fusesource.hawtjni.runtime.FieldFlag.*; 024 025/** 026 * 027 * @author <a href="http://hiramchirino.com">Hiram Chirino</a> 028 */ 029public class ReflectField implements JNIField { 030 031 private ReflectClass parent; 032 private Field field; 033 private ReflectType type; 034 private JniField annotation; 035 private HashSet<FieldFlag> flags; 036 private boolean allowConversion; 037 private ReflectFieldAccessor accessor; 038 039 public ReflectField(ReflectClass parent, Field field) { 040 this.parent = parent; 041 this.field = field; 042 lazyLoad(); 043 } 044 045 public int hashCode() { 046 return field.hashCode(); 047 } 048 049 public boolean equals(Object obj) { 050 if (!(obj instanceof ReflectField)) 051 return false; 052 return ((ReflectField) obj).field.equals(field); 053 } 054 055 public String toString() { 056 return field.toString(); 057 } 058 059 /////////////////////////////////////////////////////////////////// 060 // JNIField interface methods 061 /////////////////////////////////////////////////////////////////// 062 063 public JNIClass getDeclaringClass() { 064 return parent; 065 } 066 067 public int getModifiers() { 068 return field.getModifiers(); 069 } 070 071 public String getName() { 072 return field.getName(); 073 } 074 075 public JNIType getType() { 076 return type.asType32(allowConversion); 077 } 078 079 public JNIType getType64() { 080 return type.asType64(allowConversion); 081 } 082 083 public JNIFieldAccessor getAccessor() { 084 return accessor; 085 } 086 087 public String getCast() { 088 String rc = annotation == null ? "" : annotation.cast().trim(); 089 return cast(rc); 090 } 091 092 public boolean ignore() { 093 return getFlag(FieldFlag.FIELD_SKIP); 094 } 095 096 public boolean isPointer() { 097 if( annotation == null ) { 098 return false; 099 } 100 return getFlag(POINTER_FIELD) || ( type.getWrappedClass() == Long.TYPE && getCast().endsWith("*") ); 101 } 102 103 public String getConditional() { 104 String parentConditional = getDeclaringClass().getConditional(); 105 String myConditional = annotation == null ? null : emptyFilter(annotation.conditional()); 106 if( parentConditional!=null ) { 107 if( myConditional!=null ) { 108 return parentConditional+" && "+myConditional; 109 } else { 110 return parentConditional; 111 } 112 } 113 return myConditional; 114 } 115 116 public boolean getFlag(FieldFlag flag) { 117 return flags.contains(flag); 118 } 119 120 /////////////////////////////////////////////////////////////////// 121 // Helper methods 122 /////////////////////////////////////////////////////////////////// 123 static public String emptyFilter(String value) { 124 if( value==null || value.length()==0 ) 125 return null; 126 return value; 127 } 128 129 private void lazyLoad() { 130 this.type = new ReflectType(field.getType()); 131 this.annotation = this.field.getAnnotation(JniField.class); 132 this.flags = new HashSet<FieldFlag>(); 133 this.accessor = new ReflectFieldAccessor(this.field.getName()); 134 if( this.annotation!=null ) { 135 this.flags.addAll(Arrays.asList(this.annotation.flags())); 136 if (!StringUtils.isEmpty(this.annotation.accessor())) { 137 this.accessor = new ReflectFieldAccessor(this.annotation.accessor()); 138 } else if (!StringUtils.isEmpty(this.annotation.getter()) && 139 !StringUtils.isEmpty(this.annotation.setter())) { 140 this.accessor = new ReflectFieldAccessor( 141 this.annotation.getter(), 142 this.flags.contains(GETTER_NONMEMBER), 143 this.annotation.setter(), 144 this.flags.contains(SETTER_NONMEMBER)); 145 } 146 } 147 148 allowConversion = this.field.getAnnotation(T32.class)!=null; 149 } 150 151}