@Override public List<Function> getFunctions(Class clazz) { // Historically ClassDescriptor used to own this non-trivial logic of computing // valid functions for the class, so we'll keep it there. return new ClassDescriptor(clazz).methods; } };
@Override public List<Function> getFunctions(Class clazz) { // Historically ClassDescriptor used to own this non-trivial logic of computing // valid functions for the class, so we'll keep it there. return new ClassDescriptor(clazz).methods; } };
@Override public List<Function> getFunctions(RubyModule clazz) { // implemented as a fallback to Java through reified class, but maybe there's a better way to do this return new ClassDescriptor(toJavaClass(clazz)).methods; }
private static String loadSoleArgumentKey(StepDescriptor d) { try { String[] names = new ClassDescriptor(d.clazz).loadConstructorParamNames(); return names.length == 1 ? names[0] : null; } catch (NoStaplerConstructorException e) { return null; } }
private static String[] loadConstructorParamNames(Class<?> clazz) { return new ClassDescriptor(clazz).loadConstructorParamNames(); }
private static String[] loadConstructorParamNames(Class<?> clazz) { return new ClassDescriptor(clazz).loadConstructorParamNames(); }
/*package*/ MetaClass(WebApp webApp, Class clazz) { this.clazz = clazz; this.webApp = webApp; this.baseClass = webApp.getMetaClass(clazz.getSuperclass()); this.classLoader = MetaClassLoader.get(clazz.getClassLoader()); buildDispatchers( new ClassDescriptor(clazz,null/*support wrappers*/)); }
new ClassDescriptor(type).loadConstructorParamNames();
new ClassDescriptor(type).loadConstructorParamNames();
public Function load(Class from) { // MethdFunction for invoking a static method as a static method FunctionList methods = new ClassDescriptor(from).methods.name("fromStapler"); switch (methods.size()) { case 0: return RETURN_NULL; default: throw new IllegalArgumentException("Too many 'fromStapler' methods on "+from); case 1: Method m = ((MethodFunction)methods.get(0)).m; return new MethodFunction(m) { @Override public Class[] getParameterTypes() { return m.getParameterTypes(); } @Override public Type[] getGenericParameterTypes() { return m.getGenericParameterTypes(); } @Override public Annotation[][] getParameterAnnotations() { return m.getParameterAnnotations(); } @Override public Object invoke(StaplerRequest req, StaplerResponse rsp, Object o, Object... args) throws IllegalAccessException, InvocationTargetException { return m.invoke(null,args); } }; } } });
public Function load(Class from) { // MethdFunction for invoking a static method as a static method FunctionList methods = new ClassDescriptor(from).methods.name("fromStapler"); switch (methods.size()) { case 0: return RETURN_NULL; default: throw new IllegalArgumentException("Too many 'fromStapler' methods on "+from); case 1: Method m = ((MethodFunction)methods.get(0)).m; return new MethodFunction(m) { @Override public Class[] getParameterTypes() { return m.getParameterTypes(); } @Override public Type[] getGenericParameterTypes() { return m.getGenericParameterTypes(); } @Override public Annotation[][] getParameterAnnotations() { return m.getParameterAnnotations(); } @Override public Object invoke(StaplerRequest req, StaplerResponse rsp, Object o, Object... args) throws IllegalAccessException, InvocationTargetException { return m.invoke(null,args); } }; } } });
public <T> T bindParameters(Class<T> type, String prefix, int index) { String[] names = new ClassDescriptor(type).loadConstructorParamNames(); // the actual arguments to invoke the constructor with. Object[] args = new Object[names.length]; // constructor Constructor<T> c = findConstructor(type, names.length); Class[] types = c.getParameterTypes(); // convert parameters for( int i=0; i<names.length; i++ ) { String[] values = getParameterValues(prefix + names[i]); String param; if(values!=null) param = values[index]; else param = null; Converter converter = Stapler.lookupConverter(types[i]); if (converter==null) throw new IllegalArgumentException("Unable to convert to "+types[i]); args[i] = converter.convert(types[i],param); } return invokeConstructor(c, args); }
public <T> T bindParameters(Class<T> type, String prefix, int index) { String[] names = new ClassDescriptor(type).loadConstructorParamNames(); // the actual arguments to invoke the constructor with. Object[] args = new Object[names.length]; // constructor Constructor<T> c = findConstructor(type, names.length); Class[] types = c.getParameterTypes(); // convert parameters for( int i=0; i<names.length; i++ ) { String[] values = getParameterValues(prefix + names[i]); String param; if(values!=null) param = values[index]; else param = null; Converter converter = Stapler.lookupConverter(types[i]); if (converter==null) throw new IllegalArgumentException("Unable to convert to "+types[i]); args[i] = converter.convert(types[i],param); } return invokeConstructor(c, args); }
/** * Called after the actual type of the binding is figured out. */ private Object instantiate(Class actualType, JSONObject j) { Object r = bindInterceptor.instantiate(actualType,j); if (r!=BindInterceptor.DEFAULT) return r; for (BindInterceptor bi : getWebApp().bindInterceptors) { r = bi.instantiate(actualType,j); if (r!=BindInterceptor.DEFAULT) return r; } if (actualType==JSONObject.class || actualType==JSON.class) return actualType.cast(j); String[] names = new ClassDescriptor(actualType).loadConstructorParamNames(); // the actual arguments to invoke the constructor with. Object[] args = new Object[names.length]; // constructor Constructor c = findConstructor(actualType, names.length); Class[] types = c.getParameterTypes(); Type[] genTypes = c.getGenericParameterTypes(); // convert parameters for( int i=0; i<names.length; i++ ) { try { args[i] = bindJSON(genTypes[i],types[i],j.get(names[i])); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Failed to convert the "+names[i]+" parameter of the constructor "+c,e); } } Object o = injectSetters(invokeConstructor(c, args), j, Arrays.asList(names)); o = bindResolve(o,j); return o; }
/** * Called after the actual type of the binding is figured out. */ private Object instantiate(Class actualType, JSONObject j) { Object r = bindInterceptor.instantiate(actualType,j); if (r!=BindInterceptor.DEFAULT) return r; for (BindInterceptor bi : getWebApp().bindInterceptors) { r = bi.instantiate(actualType,j); if (r!=BindInterceptor.DEFAULT) return r; } if (actualType==JSONObject.class || actualType==JSON.class) return actualType.cast(j); String[] names = new ClassDescriptor(actualType).loadConstructorParamNames(); // the actual arguments to invoke the constructor with. Object[] args = new Object[names.length]; // constructor Constructor c = findConstructor(actualType, names.length); Class[] types = c.getParameterTypes(); Type[] genTypes = c.getGenericParameterTypes(); // convert parameters for( int i=0; i<names.length; i++ ) { try { args[i] = bindJSON(genTypes[i],types[i],j.get(names[i])); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Failed to convert the "+names[i]+" parameter of the constructor "+c,e); } } Object o = injectSetters(invokeConstructor(c, args), j, Arrays.asList(names)); o = bindResolve(o,j); return o; }
@Test public void inheritedWebMethods() throws Exception { // http://bugs.sun.com/view_bug.do?bug_id=6342411 assertEquals(1, new ClassDescriptor(Sub.class).methods.name("doDynamic").signature(StaplerRequest.class, StaplerResponse.class).size()); }
/** * D.x() overrides B.x() */ @Test public void overridingMethod() throws Exception { FunctionList methods = new ClassDescriptor(D.class).methods.name("x"); assertEquals(1, methods.size()); // we should be able to see both annotations Function f = methods.get(0); assertEquals(3, f.getAnnotation(AnnA.class).value()); assertNotNull(f.getAnnotation(AnnB.class)); // similarly parameter annotations should be fused together assertSame(Nullable.class, f.getParameterAnnotations()[0][0].annotationType()); // method should be dispatched to D.x() which overrides B.x() assertEquals(2, f.bindAndInvoke(new D(), null, null, "Hello")); }