1 package org.andromda.translation.ocl.validation;
2
3 import java.lang.reflect.Method;
4
5 import org.andromda.core.common.Introspector;
6 import org.andromda.translation.ocl.syntax.OCLPatterns;
7 import org.apache.commons.lang.StringUtils;
8 import org.apache.commons.lang.exception.ExceptionUtils;
9 import org.apache.log4j.Logger;
10
11
12
13
14
15
16
17
18 public final class OCLIntrospector
19 {
20 private static final Logger logger = Logger.getLogger(OCLIntrospector.class);
21
22
23
24
25
26
27
28
29
30 public static final Object invoke(
31 final Object element,
32 String feature)
33 {
34 Object result = null;
35 try
36 {
37 feature = StringUtils.trimToEmpty(feature);
38 if (OCLPatterns.isOperation(feature))
39 {
40 result = invoke(element, feature, null);
41 } else
42 {
43 result = Introspector.instance().getProperty(element, feature);
44 }
45 }
46 catch (final NullPointerException ignore)
47 {
48
49 }
50 catch (final OCLIntrospectorException throwable)
51 {
52
53
54
55 throw throwable;
56 }
57 catch (Throwable throwable)
58 {
59 throwable = getRootCause(throwable);
60
61
62
63 if (throwable instanceof OCLIntrospectorException)
64 {
65 throw (OCLIntrospectorException) throwable;
66 }
67 throw new OCLIntrospectorException(throwable);
68 }
69 return result;
70 }
71
72
73
74
75
76
77
78
79
80
81 public static Object invoke(
82 final Object element,
83 String feature,
84 final Object[] arguments)
85 {
86 Object result = null;
87 try
88 {
89
90 int parenIndex = feature.indexOf('(');
91 if (parenIndex != -1)
92 {
93 feature = feature.substring(0, parenIndex).trim();
94 }
95 result = invokeMethod(element, feature, arguments);
96 }
97 catch (final NullPointerException exception)
98 {
99
100 }
101 catch (Throwable throwable)
102 {
103
104 StackTraceElement[] trace = throwable.getStackTrace();
105 String location = " AT " + trace[0].getClassName() + '.' + trace[0].getMethodName() + ':' + trace[0].getLineNumber();
106 if (throwable.getMessage() != null)
107 {
108 location += ' ' + throwable.getMessage();
109 }
110
111
112
113 throwable = getRootCause(throwable);
114 logger.error("OCLIntrospector " + throwable + " invoking " + element + " METHOD " + feature + " WITH " + StringUtils.join(arguments, ',') + location);
115 throw new OCLIntrospectorException(throwable);
116 }
117 return result;
118 }
119
120 private static final Object invokeMethod(
121 final Object element,
122 final String methodName,
123 final Object[] arguments)
124 throws Exception
125 {
126 Object property = null;
127
128 if (element != null && StringUtils.isNotBlank(methodName))
129 {
130 Class[] argumentTypes = getObjectTypes(arguments);
131
132 final Method method = element.getClass().getMethod(methodName, argumentTypes);
133 property = method.invoke(element, arguments);
134 }
135
136 return property;
137 }
138
139 private static final Class[] getObjectTypes(final Object[] objects)
140 {
141 Class[] objectTypes = null;
142 if (objects != null)
143 {
144 objectTypes = new Class[objects.length];
145 for (int ctr = 0; ctr < objects.length; ctr++)
146 {
147 final Object object = objects[ctr];
148 if (object != null)
149 {
150 objectTypes[ctr] = object.getClass();
151 }
152 }
153 }
154 return objectTypes;
155 }
156
157
158
159
160
161
162
163
164 private static final Throwable getRootCause(Throwable throwable)
165 {
166 Throwable root = ExceptionUtils.getRootCause(throwable);
167 if (root != null)
168 {
169 throwable = root;
170 }
171 return throwable;
172 }
173 }