KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > google > gwt > dev > shell > DispatchClassInfo


1 /*
2  * Copyright 2007 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */

16 package com.google.gwt.dev.shell;
17
18 import java.lang.reflect.Field JavaDoc;
19 import java.lang.reflect.Member JavaDoc;
20 import java.lang.reflect.Method JavaDoc;
21 import java.util.ArrayList JavaDoc;
22 import java.util.HashMap JavaDoc;
23
24 /**
25  * Helper class for dispatching methods to Java objects. It takes methods on
26  * various Java classes and assigns DISPID's to them.
27  */

28 public class DispatchClassInfo {
29
30   private Class JavaDoc cls;
31
32   private final int clsId;
33
34   private ArrayList JavaDoc memberById;
35
36   private HashMap JavaDoc memberIdByName;
37
38   public DispatchClassInfo(Class JavaDoc cls, int classId) {
39     this.cls = cls;
40     clsId = classId;
41   }
42
43   public int getClassId() {
44     return clsId;
45   }
46
47   public Member JavaDoc getMember(int id) {
48     lazyInitTargetMembers();
49     id &= 0xffff;
50     return (Member JavaDoc) memberById.get(id);
51   }
52
53   public int getMemberId(String JavaDoc mangledMemberName) {
54     lazyInitTargetMembers();
55
56     Integer JavaDoc id = (Integer JavaDoc) memberIdByName.get(mangledMemberName);
57     if (id == null) {
58       return -1;
59     }
60
61     return id.intValue();
62   }
63
64   private void addMember(Member JavaDoc member, String JavaDoc sig) {
65     memberById.add(member);
66     int index = memberById.size() - 1;
67     memberIdByName.put(sig, new Integer JavaDoc(index));
68   }
69
70   /**
71    * @see com.google.gwt.server.magic.js.MethodInfo for the corresponding
72    * algorithm written in terms of the QDox model.
73    */

74   private String JavaDoc getJsniSignature(Method JavaDoc method) {
75     String JavaDoc name = method.getName();
76
77     StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
78     sb.append(name);
79     sb.append("(");
80     Class JavaDoc[] paramTypes = method.getParameterTypes();
81     for (int i = 0; i < paramTypes.length; ++i) {
82       Class JavaDoc type = paramTypes[i];
83       String JavaDoc typeSig = getTypeSig(type);
84       sb.append(typeSig);
85     }
86     sb.append(")");
87
88     String JavaDoc mangledName = sb.toString();
89     return mangledName;
90   }
91
92   private String JavaDoc getTypeSig(Class JavaDoc type) {
93     if (type.isArray()) {
94       return "[" + getTypeSig(type.getComponentType());
95     }
96
97     if (type.isPrimitive()) {
98       if (type.equals(int.class)) {
99         return "I";
100       } else if (type.equals(boolean.class)) {
101         return "Z";
102       } else if (type.equals(char.class)) {
103         return "C";
104       } else if (type.equals(long.class)) {
105         return "J";
106       } else if (type.equals(short.class)) {
107         return "S";
108       } else if (type.equals(float.class)) {
109         return "F";
110       } else if (type.equals(double.class)) {
111         return "D";
112       } else if (type.equals(byte.class)) {
113         return "B";
114       } else {
115         throw new RuntimeException JavaDoc("Unexpected primitive type: "
116             + type.getName());
117       }
118     } else {
119       StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
120       sb.append("L");
121       sb.append(type.getName().replace('.', '/'));
122       sb.append(";");
123       return sb.toString();
124     }
125   }
126
127   private void lazyInitTargetMembers() {
128     if (memberById == null) {
129       memberById = new ArrayList JavaDoc();
130       memberById.add(null); // 0 is reserved; it's magic on Win32
131
memberIdByName = new HashMap JavaDoc();
132       lazyInitTargetMembersUsingReflectionHelper(cls);
133     }
134   }
135
136   private void lazyInitTargetMembersUsingReflectionHelper(Class JavaDoc targetClass) {
137     // Start by analyzing the superclass recursively.
138
Class JavaDoc superclass = targetClass.getSuperclass();
139     if (superclass != null) {
140       lazyInitTargetMembersUsingReflectionHelper(superclass);
141     }
142
143     /*
144      * TODO(mmendez): How should we handle the case where a user writes JSNI
145      * code to interact with an instance that is typed as a particular
146      * interface? Should a user write JSNI code as follows:
147      *
148      * x.@com.google.gwt.HasFocus::equals(Ljava/lang/Object;)(y)
149      *
150      * or
151      *
152      * x.@java.lang.Object::equals(Ljava/lang/Object;)(y)
153      *
154      */

155
156     // Get the methods on this class/interface.
157
//
158
Method JavaDoc[] methods = targetClass.getDeclaredMethods();
159     for (int i = 0; i < methods.length; i++) {
160       methods[i].setAccessible(true);
161       String JavaDoc sig = getJsniSignature(methods[i]);
162       addMember(methods[i], sig);
163     }
164
165     // Get the fields on this class/interface.
166
Field JavaDoc[] fields = targetClass.getDeclaredFields();
167     for (int i = 0; i < fields.length; i++) {
168       fields[i].setAccessible(true);
169       addMember(fields[i], fields[i].getName());
170     }
171   }
172 }
173
Popular Tags