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