1 21 package org.lobobrowser.js; 22 23 import java.util.*; 24 import java.lang.reflect.*; 25 import org.mozilla.javascript.*; 26 27 public class JavaClassWrapper { 28 private final Class javaClass; 29 private final Map functions = new HashMap(); 30 private final Map properties = new HashMap(); 31 private PropertyInfo nameIndexer; 32 private PropertyInfo integerIndexer; 33 34 35 public JavaClassWrapper(Class class1) { 36 super(); 37 this.javaClass = class1; 38 this.scanMethods(); 39 } 40 41 public Object newInstance() throws InstantiationException , IllegalAccessException { 42 return this.javaClass.newInstance(); 43 } 44 45 public String getClassName() { 46 String className = this.javaClass.getName(); 47 int lastDotIdx = className.lastIndexOf('.'); 48 return lastDotIdx == -1 ? className : className.substring(lastDotIdx+1); 49 } 50 51 public Function getFunction(String name) { 52 return (Function) this.functions.get(name); 53 } 54 55 public PropertyInfo getProperty(String name) { 56 return (PropertyInfo) this.properties.get(name); 57 } 58 59 private void scanMethods() { 60 Method[] methods = this.javaClass.getMethods(); 61 int len = methods.length; 62 for(int i = 0; i < len; i++) { 63 Method method = methods[i]; 64 String name = method.getName(); 65 if(isPropertyMethod(name, method)) { 66 this.ensurePropertyKnown(name, method); 67 } 68 if(isNameIndexer(name, method)) { 69 this.updateNameIndexer(name, method); 70 } 71 else if(this.isIntegerIndexer(name, method)) { 72 this.updateIntegerIndexer(name, method); 73 } 74 else { 75 JavaFunctionObject f = (JavaFunctionObject) this.functions.get(name); 76 if(f == null) { 77 f = new JavaFunctionObject(name); 78 this.functions.put(name, f); 79 } 80 f.addMethod(method); 81 } 82 } 83 } 84 85 private boolean isNameIndexer(String name, Method method) { 86 return ("namedItem".equals(name) && method.getParameterTypes().length == 1) || 87 ("setNamedItem".equals(name) && method.getParameterTypes().length == 2); 88 } 89 90 private boolean isIntegerIndexer(String name, Method method) { 91 return ("item".equals(name) && method.getParameterTypes().length == 1) || 92 ("setItem".equals(name) && method.getParameterTypes().length == 2); 93 } 94 95 private void updateNameIndexer(String methodName, Method method) { 96 boolean getter = true; 97 if(methodName.startsWith("set")) { 98 getter = false; 99 } 100 PropertyInfo indexer = this.nameIndexer; 101 if(indexer == null) { 102 indexer = new PropertyInfo("$item", Object .class); 103 this.nameIndexer = indexer; 104 } 105 if(getter) { 106 indexer.setGetter(method); 107 } 108 else { 109 indexer.setSetter(method); 110 } 111 } 112 113 private void updateIntegerIndexer(String methodName, Method method) { 114 boolean getter = true; 115 if(methodName.startsWith("set")) { 116 getter = false; 117 } 118 PropertyInfo indexer = this.integerIndexer; 119 if(indexer == null) { 120 Class pt = getter ? method.getReturnType() : method.getParameterTypes()[1]; 121 indexer = new PropertyInfo("$item", pt); 122 this.integerIndexer = indexer; 123 } 124 if(getter) { 125 indexer.setGetter(method); 126 } 127 else { 128 indexer.setSetter(method); 129 } 130 } 131 132 public PropertyInfo getIntegerIndexer() { 133 return this.integerIndexer; 134 } 135 136 public PropertyInfo getNameIndexer() { 137 return this.nameIndexer; 138 } 139 140 private boolean isPropertyMethod(String name, Method method) { 141 if(name.startsWith("get") || name.startsWith("is")) { 142 return method.getParameterTypes().length == 0; 143 } 144 else if(name.startsWith("set")) { 145 return method.getParameterTypes().length == 1; 146 } 147 else { 148 return false; 149 } 150 } 151 152 private String uncapitalize(String text) { 153 try { 154 return Character.toLowerCase(text.charAt(0)) + text.substring(1); 155 } catch(IndexOutOfBoundsException iob) { 156 return text; 157 } 158 } 159 160 private void ensurePropertyKnown(String methodName, Method method) { 161 String capPropertyName; 162 String propertyName; 163 boolean getter = false; 164 if(methodName.startsWith("get")) { 165 capPropertyName = methodName.substring(3); 166 propertyName = uncapitalize(capPropertyName); 167 getter = true; 168 } 169 else if(methodName.startsWith("set")) { 170 capPropertyName = methodName.substring(3); 171 propertyName = uncapitalize(capPropertyName); 172 } 173 else if(methodName.startsWith("is")) { 174 capPropertyName = methodName.substring(2); 175 propertyName = uncapitalize(capPropertyName); 176 getter = true; 177 } 178 else { 179 throw new IllegalArgumentException ("methodName=" + methodName); 180 } 181 PropertyInfo pinfo = (PropertyInfo) this.properties.get(propertyName); 182 if(pinfo == null) { 183 Class pt = getter ? method.getReturnType() : method.getParameterTypes()[0]; 184 pinfo = new PropertyInfo(propertyName, pt); 185 this.properties.put(propertyName, pinfo); 186 } 187 if(getter) { 188 pinfo.setGetter(method); 189 } 190 else { 191 pinfo.setSetter(method); 192 } 193 } 194 195 public String toString() { 196 return this.javaClass.getName(); 197 } 198 } 199 | Popular Tags |