1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.jexl3.internal.introspection;
18
19 import java.beans.IntrospectionException;
20 import java.lang.reflect.Constructor;
21 import java.lang.reflect.InvocationTargetException;
22
23 import org.apache.commons.jexl3.JexlException;
24 import org.apache.commons.jexl3.introspection.JexlMethod;
25
26
27
28
29 public final class ConstructorMethod implements JexlMethod {
30
31
32
33
34
35
36
37
38
39 public static ConstructorMethod discover(final Introspector is, final Object ctorHandle, final Object... args) {
40 String className;
41 Class<?> clazz = null;
42 if (ctorHandle instanceof Class<?>) {
43 clazz = (Class<?>) ctorHandle;
44 className = clazz.getName();
45 } else if (ctorHandle != null) {
46 className = ctorHandle.toString();
47 } else {
48 return null;
49 }
50 final Constructor<?> ctor = is.getConstructor(clazz, new MethodKey(className, args));
51 if (ctor != null) {
52 return new ConstructorMethod(ctor);
53 }
54 return null;
55 }
56
57
58 private final Constructor<?> ctor;
59
60
61
62
63
64
65 ConstructorMethod(final Constructor<?> theCtor) {
66 this.ctor = theCtor;
67 }
68
69 @Override
70 public Class<?> getReturnType() {
71 return ctor.getDeclaringClass();
72 }
73
74 @Override
75 public Object invoke(final Object obj, final Object... params) throws Exception {
76 final Class<?> ctorClass = ctor.getDeclaringClass();
77 boolean invoke = true;
78 if (obj != null) {
79 if (obj instanceof Class<?>) {
80 invoke = ctorClass.equals(obj);
81 } else {
82 invoke = ctorClass.getName().equals(obj.toString());
83 }
84 }
85 if (invoke) {
86 return ctor.newInstance(params);
87 }
88 throw new IntrospectionException("constructor resolution error");
89 }
90
91 @Override
92 public boolean isCacheable() {
93 return true;
94 }
95
96 @Override
97 public boolean tryFailed(final Object rval) {
98 return rval == Uberspect.TRY_FAILED;
99 }
100
101 @Override
102 public Object tryInvoke(final String name, final Object obj, final Object... args) {
103
104 if (ctor.getParameterCount() > 0 || args.length == 0) {
105 try {
106 final Class<?> ctorClass = ctor.getDeclaringClass();
107 boolean invoke = true;
108 if (obj != null) {
109 if (obj instanceof Class<?>) {
110 invoke = ctorClass.equals(obj);
111 } else {
112 invoke = ctorClass.getName().equals(obj.toString());
113 }
114 }
115 invoke &= name == null || ctorClass.getName().equals(name);
116 if (invoke) {
117 return ctor.newInstance(args);
118 }
119 } catch (InstantiationException | IllegalArgumentException | IllegalAccessException xinstance) {
120 return Uberspect.TRY_FAILED;
121 } catch (final InvocationTargetException xinvoke) {
122 throw JexlException.tryFailed(xinvoke);
123 }
124 }
125 return Uberspect.TRY_FAILED;
126 }
127
128 }