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.lang.reflect.Method;
015import java.lang.reflect.Modifier;
016import java.util.ArrayList;
017import java.util.Arrays;
018import java.util.HashSet;
019import java.util.List;
020
021import org.fusesource.hawtjni.runtime.ClassFlag;
022import org.fusesource.hawtjni.runtime.JniClass;
023
024/**
025 * 
026 * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
027 */
028public class ReflectClass implements JNIClass {
029    
030    private Class<?> clazz;
031    private ArrayList<ReflectField> fields;
032    private ArrayList<ReflectMethod> methods;
033    private JniClass annotation;
034    private HashSet<ClassFlag> flags;
035    private String nativeName;
036
037    public ReflectClass(Class<?> clazz) {
038        this.clazz = clazz;
039    }
040
041    public String toString() {
042        return clazz.toString();
043    }
044    public int hashCode() {
045        return clazz.hashCode();
046    }
047    public boolean equals(Object obj) {
048        if (!(obj instanceof ReflectClass))
049            return false;
050        return ((ReflectClass) obj).clazz.equals(clazz);
051    }
052    
053    public Class<?> getWrapedClass() {
054        return clazz;
055    }
056
057    ///////////////////////////////////////////////////////////////////
058    // JNIClass interface methods
059    ///////////////////////////////////////////////////////////////////
060    
061    public String getName() {
062        return clazz.getName();
063    }
064
065    public JNIClass getSuperclass() {
066        return new ReflectClass(clazz.getSuperclass());
067    }
068    
069    public String getSimpleName() {
070        return clazz.getSimpleName();
071    }
072    
073    public String getNativeName() {
074        lazyLoad();
075        if( nativeName!=null )
076            return nativeName;
077        else
078            return getSimpleName();
079    }
080    
081    public List<JNIField> getDeclaredFields() {
082        lazyLoad();
083        return new ArrayList<JNIField>(fields);
084    }
085
086    public List<JNIMethod> getDeclaredMethods() {
087        lazyLoad();
088        return new ArrayList<JNIMethod>(methods);
089    }
090
091    public List<JNIMethod> getNativeMethods() {
092        ArrayList<JNIMethod> rc = new ArrayList<JNIMethod>();
093        for (JNIMethod method : getDeclaredMethods()) {
094            if ((method.getModifiers() & Modifier.NATIVE) == 0)
095                continue;
096            rc.add(method);
097        }
098        return rc;
099    }
100
101    public String getConditional() {
102        lazyLoad();
103        return annotation == null ? null : emptyFilter(annotation.conditional());
104    }
105
106    public boolean getGenerate() {
107        return !getFlag(ClassFlag.CLASS_SKIP);
108    }
109    
110    public boolean getFlag(ClassFlag flag) {
111        lazyLoad();
112        return flags.contains(flag);
113    }
114
115    ///////////////////////////////////////////////////////////////////
116    // Helper methods
117    ///////////////////////////////////////////////////////////////////
118    static public String emptyFilter(String value) {
119        if( value==null || value.length()==0 )
120            return null;
121        return value;
122    }
123
124    private void lazyLoad() {
125        if (fields != null)
126            return;
127        
128        this.annotation = this.clazz.getAnnotation(JniClass.class);
129        this.flags = new HashSet<ClassFlag>();
130        if( this.annotation!=null ) {
131            this.flags.addAll(Arrays.asList(this.annotation.flags()));
132            if( this.annotation.name().trim().length() > 0 ) {
133                this.nativeName = this.annotation.name().trim();
134            }
135        }
136
137        
138        Field[] fields = clazz.getDeclaredFields();
139        this.fields = new ArrayList<ReflectField>(fields.length);
140        for (Field field : fields) {
141            this.fields.add(new ReflectField(this, field));
142        }
143
144        Method[] methods = clazz.getDeclaredMethods();
145        this.methods = new ArrayList<ReflectMethod>(methods.length);
146        for (Method method : methods) {
147            this.methods.add(new ReflectMethod(this, method));
148        }
149    }
150
151}