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 org.fusesource.hawtjni.runtime.JniClass;
014
015/**
016 * 
017 * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
018 */
019public class ReflectType implements JNIType {
020    
021    private Class<?> clazz;
022
023    public ReflectType(Class<?> clazz) {
024        this.clazz = clazz;
025    }
026
027    public int hashCode() {
028        return clazz.hashCode();
029    }
030
031    public boolean equals(Object obj) {
032        if (obj == this)
033            return true;
034        if (!(obj instanceof ReflectType))
035            return false;
036        return ((ReflectType) obj).clazz == clazz;
037    }
038    
039    public Class<?> getWrappedClass() {
040        return clazz;
041    }
042
043    public ReflectType asType32(boolean allowConversion) {
044        if (allowConversion) {
045            if (clazz == long.class)
046                return new ReflectType(int.class);
047            else if (clazz == long[].class)
048                return new ReflectType(int[].class);
049            else if (clazz == double.class)
050                return new ReflectType(float.class);
051            else if (clazz == double[].class)
052                return new ReflectType(float[].class);
053        }
054        return this;
055    }
056
057    public ReflectType asType64(boolean allowConversion) {
058        if (allowConversion) {
059            if (clazz == int.class)
060                return new ReflectType(long.class);
061            else if (clazz == int[].class)
062                return new ReflectType(long[].class);
063            else if (clazz == float.class)
064                return new ReflectType(double.class);
065            else if (clazz == float[].class)
066                return new ReflectType(double[].class);
067        }
068        return this;
069    }
070
071    public JNIType getComponentType() {
072        return new ReflectType(clazz.getComponentType());
073    }
074
075    public String getName() {
076        return clazz.getName();
077    }
078
079    public String getSimpleName() {
080        return clazz.getSimpleName();
081    }
082
083    public String getNativeName() {
084        JniClass annotation = clazz.getAnnotation(JniClass.class);
085        if( annotation==null ) {
086            return getSimpleName();
087        } else {
088            String name = annotation.name().trim();
089            if( name.length()==0 ) {
090                return getSimpleName();
091            } else {
092                return name;
093            }
094        }
095    }
096
097    public String getTypeSignature(boolean define) {
098        if (clazz == Void.TYPE)
099            return "V";
100        if (clazz == Integer.TYPE)
101            return define ? "I_J" : "I";
102        if (clazz == Boolean.TYPE)
103            return "Z";
104        if (clazz == Long.TYPE)
105            return define ? "J_J" : "J";
106        if (clazz == Short.TYPE)
107            return "S";
108        if (clazz == Character.TYPE)
109            return "C";
110        if (clazz == Byte.TYPE)
111            return "B";
112        if (clazz == Float.TYPE)
113            return define ? "F_D" : "F";
114        if (clazz == Double.TYPE)
115            return define ? "F_D" : "D";
116        if (clazz == String.class)
117            return "Ljava/lang/String;";
118        if (clazz.isArray()) {
119            if (define)
120                return getComponentType().getTypeSignature(define) + "Array";
121            return "[" + getComponentType().getTypeSignature(define);
122        }
123        return "L" + clazz.getName().replace('.', '/') + ";";
124    }
125
126    public String getTypeSignature1(boolean define) {
127        if (clazz == Void.TYPE)
128            return "Void";
129        if (clazz == Integer.TYPE)
130            return define ? "IntLong" : "Int";
131        if (clazz == Boolean.TYPE)
132            return "Boolean";
133        if (clazz == Long.TYPE)
134            return define ? "IntLong" : "Long";
135        if (clazz == Short.TYPE)
136            return "Short";
137        if (clazz == Character.TYPE)
138            return "Char";
139        if (clazz == Byte.TYPE)
140            return "Byte";
141        if (clazz == Float.TYPE)
142            return define ? "FloatDouble" : "Float";
143        if (clazz == Double.TYPE)
144            return define ? "FloatDouble" : "Double";
145        if (clazz == String.class)
146            return "String";
147        return "Object";
148    }
149
150    public String getTypeSignature2(boolean define) {
151        if (clazz == Void.TYPE)
152            return "void";
153        if (clazz == Integer.TYPE)
154            return define ? "jintLong" : "jint";
155        if (clazz == Boolean.TYPE)
156            return "jboolean";
157        if (clazz == Long.TYPE)
158            return define ? "jintLong" : "jlong";
159        if (clazz == Short.TYPE)
160            return "jshort";
161        if (clazz == Character.TYPE)
162            return "jchar";
163        if (clazz == Byte.TYPE)
164            return "jbyte";
165        if (clazz == Float.TYPE)
166            return define ? "jfloatDouble" : "jfloat";
167        if (clazz == Double.TYPE)
168            return define ? "jfloatDouble" : "jdouble";
169        if (clazz == String.class)
170            return "jstring";
171        if (clazz == Class.class)
172            return "jclass";
173        if (clazz.isArray()) {
174            return getComponentType().getTypeSignature2(define) + "Array";
175        }
176        return "jobject";
177    }
178
179    public String getTypeSignature3(boolean define) {
180        if (clazz == Void.TYPE)
181            return "void";
182        if (clazz == Integer.TYPE)
183            return "int";
184        if (clazz == Boolean.TYPE)
185            return "boolean";
186        if (clazz == Long.TYPE)
187            return "long";
188        if (clazz == Short.TYPE)
189            return "short";
190        if (clazz == Character.TYPE)
191            return "char";
192        if (clazz == Byte.TYPE)
193            return "byte";
194        if (clazz == Float.TYPE)
195            return "float";
196        if (clazz == Double.TYPE)
197            return "double";
198        if (clazz == String.class)
199            return "String";
200        if (clazz.isArray()) {
201            return getComponentType().getTypeSignature3(define) + "[]";
202        }
203        return clazz.getName();
204    }
205
206    public String getTypeSignature4(boolean define, boolean struct) {
207        if (clazz == Void.TYPE)
208            return "void";
209        if (clazz == Integer.TYPE)
210            return define ? "jintLong" : "jint";
211        if (clazz == Boolean.TYPE)
212            return "jboolean";
213        if (clazz == Long.TYPE)
214            return define ? "jintLong" : "jlong";
215        if (clazz == Short.TYPE)
216            return "jshort";
217        if (clazz == Character.TYPE)
218            return "jchar";
219        if (clazz == Byte.TYPE)
220            return "jbyte";
221        if (clazz == Float.TYPE)
222            return define ? "jfloatDouble" : "jfloat";
223        if (clazz == Double.TYPE)
224            return define ? "jfloatDouble" : "jdouble";
225        if (clazz == String.class)
226            return "jstring";
227        if (clazz.isArray()) {
228            String sig = getComponentType().getTypeSignature4(define, struct);
229            return struct ? sig : sig + " *";
230        }
231        String sig = getNativeName();
232        return struct ? sig : sig + " *";
233    }
234
235    public boolean isArray() {
236        return clazz.isArray();
237    }
238
239    public boolean isPrimitive() {
240        return clazz.isPrimitive();
241    }
242
243    public boolean isType(String type) {
244        return clazz.getName().equals(type);
245    }
246
247}