1 package org.synchronoss.cpo.core.meta.domain;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import java.lang.reflect.Constructor;
26 import java.lang.reflect.InvocationTargetException;
27 import java.lang.reflect.Method;
28 import java.util.ArrayList;
29 import java.util.List;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32 import org.synchronoss.cpo.core.CpoData;
33 import org.synchronoss.cpo.core.CpoException;
34 import org.synchronoss.cpo.core.helper.CpoClassLoader;
35 import org.synchronoss.cpo.core.helper.ExceptionHelper;
36 import org.synchronoss.cpo.core.meta.CpoMetaDescriptor;
37 import org.synchronoss.cpo.core.meta.bean.CpoAttributeBean;
38 import org.synchronoss.cpo.core.transform.CpoTransform;
39
40
41
42
43
44
45
46
47
48
49 public class CpoAttribute extends CpoAttributeBean {
50
51 private static final long serialVersionUID = 1L;
52
53 private static final Logger logger = LoggerFactory.getLogger(CpoAttribute.class);
54 protected static final String TRANSFORM_IN_NAME = "transformIn";
55 protected static final String TRANSFORM_OUT_NAME = "transformOut";
56
57
58 private String getterName_ = null;
59
60
61 private String setterName_ = null;
62
63
64 private Method getter_ = null;
65
66
67 private Method setter_ = null;
68
69
70 private int dataTypeInt = Integer.MIN_VALUE;
71
72
73
74 private CpoTransform cpoTransform = null;
75
76
77 private Method transformInMethod = null;
78
79
80 private Method transformOutMethod = null;
81
82
83
84 private Class<?> transformInParamType = null;
85
86
87 public CpoAttribute() {}
88
89
90
91
92
93
94
95
96 public <D, J> CpoTransform<D, J> getCpoTransform() {
97 return cpoTransform;
98 }
99
100
101
102
103
104
105 public Method getTransformInMethod() {
106 return transformInMethod;
107 }
108
109
110
111
112
113
114 public Method getTransformOutMethod() {
115 return transformOutMethod;
116 }
117
118
119
120
121
122
123 public Class<?> getTransformInParamType() {
124 return transformInParamType;
125 }
126
127
128
129
130
131
132 public Class<?> getSetterParamType() {
133 return getter_.getReturnType();
134 }
135
136
137
138
139
140
141 public Class<?> getGetterReturnType() {
142 return getter_.getReturnType();
143 }
144
145 protected Method getGetter() {
146 return getter_;
147 }
148
149 protected Method getSetter() {
150 return setter_;
151 }
152
153 protected void setGetter(Method getter) {
154 getter_ = getter;
155 }
156
157 protected void setSetter(Method setter) {
158 setter_ = setter;
159 }
160
161 protected String getGetterName() {
162 return getterName_;
163 }
164
165 protected String getSetterName() {
166 return setterName_;
167 }
168
169 protected void setGetterName(String getterName) {
170 getterName_ = getterName;
171 }
172
173 protected void setSetterName(String setterName) {
174 setterName_ = setterName;
175 }
176
177
178
179
180
181
182 public void setDataTypeInt(int dataTypeInt) {
183 this.dataTypeInt = dataTypeInt;
184 }
185
186
187
188
189
190
191 public int getDataTypeInt() {
192 return this.dataTypeInt;
193 }
194
195 protected List<Method> findMethods(Class<?> clazz, String methodName, int args, boolean hasReturn)
196 throws CpoException {
197 List<Method> retMethods = new ArrayList<>();
198
199 try {
200 Method[] methods = clazz.getMethods();
201
202
203 for (Method m : methods) {
204
205 if (!m.isSynthetic()
206 && !m.isBridge()
207 && m.getName().equals(methodName)
208 && m.getParameterTypes().length == args
209 && ((!hasReturn && m.getReturnType() == Void.TYPE)
210 || (hasReturn && m.getReturnType() != Void.TYPE))) {
211 retMethods.add(m);
212 }
213 }
214 } catch (SecurityException e) {
215 throw new CpoException("findMethod() Failed: " + methodName);
216 }
217 return retMethods;
218 }
219
220 protected String buildMethodName(String prefix, String base) {
221
222 StringBuilder methodName = new StringBuilder();
223 methodName.append(prefix);
224 methodName.append(base);
225 methodName.setCharAt(3, Character.toUpperCase(methodName.charAt(3)));
226
227 return methodName.toString();
228 }
229
230
231
232
233
234
235
236
237 public void invokeSetter(Object instanceObject, CpoData cpoData) throws CpoException {
238 try {
239 setter_.invoke(instanceObject, cpoData.invokeGetter());
240 } catch (IllegalAccessException | InvocationTargetException | IllegalArgumentException e) {
241 Logger localLogger =
242 instanceObject == null ? logger : LoggerFactory.getLogger(instanceObject.getClass());
243 String msg =
244 "Error Invoking Setter Method: "
245 + getDataName()
246 + ":"
247 + getJavaName()
248 + ":"
249 + setterName_;
250 localLogger.debug(msg + ExceptionHelper.getLocalizedMessage(e));
251 throw new CpoException(msg, e);
252 }
253 }
254
255
256
257
258
259
260
261
262 public Object invokeGetter(Object obj) throws CpoException {
263 try {
264 return getGetter().invoke(obj, (Object[]) null);
265 } catch (IllegalAccessException | InvocationTargetException e) {
266 Logger localLogger = LoggerFactory.getLogger(obj.getClass());
267 String msg = "invokeGetter: Could not invoke getter for " + obj.getClass();
268 localLogger.debug(msg);
269 throw new CpoException(msg, e);
270 }
271 }
272
273 private void dumpMethod(Method m) {
274 logger.trace("========================");
275 logger.trace("===> Declaring Class: " + m.getDeclaringClass().getName());
276 logger.trace("===> Method Signature: " + m.toString());
277 logger.trace("===> Generic Signature: " + m.toGenericString());
278 logger.trace("===> Method isBridge: " + m.isBridge());
279 logger.trace("===> Method isSynthetic: " + m.isSynthetic());
280 logger.trace("========================");
281 }
282
283
284
285
286
287
288
289
290
291
292
293 public static boolean isPrimitiveAssignableFrom(Class<?> clazz, Class<?> paramClass) {
294
295
296 if (clazz.isPrimitive() ^ paramClass.isPrimitive()) {
297
298 Class<?> primClass, objClass;
299 if (clazz.isPrimitive()) {
300 primClass = clazz;
301 objClass = paramClass;
302 } else {
303 primClass = paramClass;
304 objClass = clazz;
305 }
306
307
308 if (objClass.getSimpleName().toLowerCase().startsWith(primClass.getSimpleName())) {
309
310
311 for (Constructor<?> ctor : objClass.getConstructors()) {
312 Class<?>[] types = ctor.getParameterTypes();
313 if (types.length > 0 && types[0].isAssignableFrom(primClass)) {
314 return true;
315 }
316 }
317 } else {
318 logger.debug(
319 "Wrapper Class:"
320 + objClass.getName().toLowerCase()
321 + "does not start with "
322 + primClass.getName());
323 }
324 }
325
326 return false;
327 }
328
329
330
331
332
333
334
335
336
337
338
339
340
341 public void loadRunTimeInfo(CpoMetaDescriptor metaDescriptor, Class<?> metaClass)
342 throws CpoException {
343 StringBuilder failedMessage = new StringBuilder();
344 setGetterName(buildMethodName("get", getJavaName()));
345 setSetterName(buildMethodName("set", getJavaName()));
346
347 try {
348 initTransformClass(metaDescriptor);
349 } catch (Exception ce2) {
350 failedMessage.append(ce2.getMessage());
351 }
352 if (metaClass != null) {
353 try {
354 List<Method> methods = findMethods(metaClass, getGetterName(), 0, true);
355 if (methods.isEmpty()) {
356 failedMessage.append(
357 "loadRunTimeInfo: Could not find a Getter:"
358 + getGetterName()
359 + "("
360 + metaClass.getName()
361 + ")");
362 } else {
363 setGetter(methods.get(0));
364 dumpMethod(getGetter());
365 }
366 } catch (CpoException ce1) {
367 failedMessage.append(ce1.getMessage());
368 }
369 try {
370 Class<?> actualClass = getGetterReturnType();
371
372 for (Method setter : findMethods(metaClass, getSetterName(), 1, false)) {
373 if (setter.getParameterTypes()[0].isAssignableFrom(actualClass)
374 || isPrimitiveAssignableFrom(setter.getParameterTypes()[0], actualClass)) {
375 setSetter(setter);
376 dumpMethod(getSetter());
377 }
378 }
379 if (getSetter() == null) {
380 failedMessage.append(
381 "loadRunTimeInfo: Could not find a Setter:"
382 + getSetterName()
383 + "("
384 + actualClass.getName()
385 + ")");
386 }
387 } catch (Exception ce2) {
388 failedMessage.append(ce2.getMessage());
389 }
390 }
391 if (!failedMessage.isEmpty()) {
392 throw new CpoException(failedMessage.toString());
393 }
394 }
395
396 protected void initTransformClass(CpoMetaDescriptor metaDescriptor) throws CpoException {
397 String className = getTransformClassName();
398 Class<?> transformClass;
399
400 if (className != null && !className.isEmpty()) {
401 try {
402 transformClass = CpoClassLoader.forName(className);
403 } catch (ClassNotFoundException e) {
404 String msg = "Invalid Transform Class specified:<" + className + ">";
405 throw new CpoException(msg, e);
406 }
407
408 Object transformObject;
409 try {
410 transformObject = transformClass.getDeclaredConstructor().newInstance();
411 } catch (InstantiationException
412 | IllegalAccessException
413 | InvocationTargetException
414 | NoSuchMethodException e) {
415 String msg = "Error Setting Transform Class: ";
416 throw new CpoException(msg, e);
417 }
418
419 if (transformObject instanceof CpoTransform) {
420 cpoTransform = (CpoTransform) transformObject;
421 List<Method> methods = findMethods(transformClass, TRANSFORM_IN_NAME, 1, true);
422 if (methods.size() > 0) {
423 transformInMethod = methods.get(0);
424 transformInParamType = transformInMethod.getParameterTypes()[0];
425 }
426 methods = findMethods(transformClass, TRANSFORM_OUT_NAME, 1, true);
427 if (methods.size() > 0) {
428 transformOutMethod = methods.get(0);
429 }
430 } else {
431 throw new CpoException("Invalid CpoTransform Class specified:<" + className + ">");
432 }
433 }
434 }
435
436 @Override
437 public String toString() {
438 return this.getJavaName();
439 }
440
441
442
443
444
445
446
447 public String toStringFull() {
448 return super.toString();
449 }
450 }