1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.synchronoss.cpo.meta.domain;
22
23 import org.slf4j.*;
24 import org.synchronoss.cpo.*;
25 import org.synchronoss.cpo.helper.*;
26 import org.synchronoss.cpo.meta.CpoMetaDescriptor;
27 import org.synchronoss.cpo.meta.bean.CpoAttributeBean;
28 import org.synchronoss.cpo.transform.CpoTransform;
29
30 import java.lang.reflect.*;
31 import java.util.*;
32
33 public class CpoAttribute extends CpoAttributeBean {
34
35 private static final long serialVersionUID = 1L;
36
37 private static final Logger logger = LoggerFactory.getLogger(CpoAttribute.class);
38 protected static final String TRANSFORM_IN_NAME = "transformIn";
39 protected static final String TRANSFORM_OUT_NAME = "transformOut";
40 private String getterName_ = null;
41 private String setterName_ = null;
42 private Method getter_ = null;
43 private Method setter_ = null;
44 private int dataTypeInt = Integer.MIN_VALUE;
45
46
47 private CpoTransform cpoTransform = null;
48 private Method transformInMethod = null;
49 private Method transformOutMethod = null;
50
51 public CpoAttribute() {
52 }
53
54 public <D, J> CpoTransform<D, J> getCpoTransform() {
55 return cpoTransform;
56 }
57
58 public Method getTransformInMethod() {
59 return transformInMethod;
60 }
61
62 public Method getTransformOutMethod() {
63 return transformOutMethod;
64 }
65
66 public Class<?> getSetterParamType() {
67 return getter_.getReturnType();
68 }
69
70 public Class<?> getGetterReturnType() {
71 return getter_.getReturnType();
72 }
73
74 protected Method getGetter() {
75 return getter_;
76 }
77
78 protected Method getSetter() {
79 return setter_;
80 }
81
82 protected void setGetter(Method getter) {
83 getter_ = getter;
84 }
85
86 protected void setSetter(Method setter) {
87 setter_ = setter;
88 }
89
90 protected String getGetterName() {
91 return getterName_;
92 }
93
94 protected String getSetterName() {
95 return setterName_;
96 }
97
98 protected void setGetterName(String getterName) {
99 getterName_ = getterName;
100 }
101
102 protected void setSetterName(String setterName) {
103 setterName_ = setterName;
104 }
105
106 public void setDataTypeInt(int dataTypeInt) {
107 this.dataTypeInt = dataTypeInt;
108 }
109
110 public int getDataTypeInt() {
111 return this.dataTypeInt;
112 }
113
114 protected List<Method> findMethods(Class<?> clazz, String methodName, int args, boolean hasReturn) throws CpoException {
115 List<Method> retMethods = new ArrayList<>();
116
117 try {
118 Method[] methods = clazz.getMethods();
119
120
121 for (Method m : methods) {
122
123 if (!m.isSynthetic() && !m.isBridge() && m.getName().equals(methodName) && m.getParameterTypes().length == args) {
124 if ((!hasReturn && m.getReturnType() == java.lang.Void.TYPE) || (hasReturn && m.getReturnType() != java.lang.Void.TYPE)) {
125 retMethods.add(m);
126 }
127 }
128 }
129 } catch (Exception e) {
130 throw new CpoException("findMethod() Failed - Method Not Found: " + methodName);
131 }
132 return retMethods;
133 }
134
135 protected String buildMethodName(String prefix, String base) {
136
137 StringBuilder methodName = new StringBuilder();
138 methodName.append(prefix);
139 methodName.append(base);
140 methodName.setCharAt(3, Character.toUpperCase(methodName.charAt(3)));
141
142 return methodName.toString();
143 }
144
145 public void invokeSetter(Object instanceObject, CpoData cpoData) throws CpoException {
146 Logger localLogger = instanceObject == null ? logger : LoggerFactory.getLogger(instanceObject.getClass());
147
148 try {
149 setter_.invoke(instanceObject, cpoData.invokeGetter());
150 } catch (IllegalAccessException | InvocationTargetException e) {
151 localLogger.debug("Error Invoking Setter Method: " + ExceptionHelper.getLocalizedMessage(e));
152 }
153 }
154
155 public Object invokeGetter(Object obj) throws CpoException {
156 Logger localLogger = obj == null ? logger : LoggerFactory.getLogger(obj.getClass());
157
158 try {
159 return getGetter().invoke(obj, (Object[])null);
160 } catch (IllegalAccessException | InvocationTargetException e) {
161 localLogger.debug("Error Invoking Getter Method: " + ExceptionHelper.getLocalizedMessage(e));
162 }
163
164 throw new CpoException("invokeGetter: Could not find a Getter for " + obj.getClass());
165 }
166
167 private void dumpMethod(Method m) {
168 logger.debug("========================");
169 logger.debug("===> Declaring Class: " + m.getDeclaringClass().getName());
170 logger.debug("===> Method Signature: " + m.toString());
171 logger.debug("===> Generic Signature: " + m.toGenericString());
172 logger.debug("===> Method isBridge: " + m.isBridge());
173 logger.debug("===> Method isSynthetic: " + m.isSynthetic());
174 logger.debug("========================");
175 }
176
177 static public boolean isPrimitiveAssignableFrom(Class<?> clazz, Class<?> paramClass) {
178
179
180 if (clazz.isPrimitive() ^ paramClass.isPrimitive()) {
181
182 Class<?> primClass, objClass;
183 if (clazz.isPrimitive()) {
184 primClass = clazz;
185 objClass = paramClass;
186 } else {
187 primClass = paramClass;
188 objClass = clazz;
189 }
190
191
192 if (objClass.getSimpleName().toLowerCase().startsWith(primClass.getSimpleName())) {
193
194
195 for (Constructor<?> ctor : objClass.getConstructors()) {
196 Class<?>[] types = ctor.getParameterTypes();
197 if (types.length > 0 && types[0].isAssignableFrom(primClass)) {
198 return true;
199 }
200 }
201 } else {
202 logger.debug("Wrapper Class:" + objClass.getName().toLowerCase() + "does not start with " + primClass.getName());
203 }
204 }
205
206 return false;
207 }
208
209 public void loadRunTimeInfo(CpoMetaDescriptor metaDescriptor, Class<?> metaClass) throws CpoException {
210 StringBuilder failedMessage = new StringBuilder();
211 setGetterName(buildMethodName("get", getJavaName()));
212 setSetterName(buildMethodName("set", getJavaName()));
213
214 try {
215 initTransformClass(metaDescriptor);
216 } catch (Exception ce2) {
217 failedMessage.append(ce2.getMessage());
218 }
219 if (metaClass != null) {
220 try {
221 List<Method> methods = findMethods(metaClass, getGetterName(), 0, true);
222 if (methods.isEmpty()) {
223 failedMessage.append("loadRunTimeInfo: Could not find a Getter:" + getGetterName() + "(" + metaClass.getName() + ")");
224 } else {
225 setGetter(methods.get(0));
226 }
227 } catch (CpoException ce1) {
228 failedMessage.append(ce1.getMessage());
229 }
230 try {
231 Class<?> actualClass = getGetterReturnType();
232
233 for (Method setter : findMethods(metaClass, getSetterName(), 1, false)) {
234 if (setter.getParameterTypes()[0].isAssignableFrom(actualClass) || isPrimitiveAssignableFrom(setter.getParameterTypes()[0], actualClass)) {
235 setSetter(setter);
236 }
237 }
238 if (getSetter() == null) {
239 failedMessage.append("loadRunTimeInfo: Could not find a Setter:" + getSetterName() + "(" + actualClass.getName() + ")");
240 }
241 } catch (Exception ce2) {
242 failedMessage.append(ce2.getMessage());
243 }
244 }
245 if (failedMessage.length() > 0) {
246 throw new CpoException(failedMessage.toString());
247 }
248 }
249
250 protected void initTransformClass(CpoMetaDescriptor metaDescriptor) throws CpoException {
251 String className = getTransformClassName();
252 Class<?> transformClass;
253 Logger localLogger = className == null ? logger : LoggerFactory.getLogger(className);
254
255 if (className != null && className.length() > 0) {
256 try {
257 transformClass = CpoClassLoader.forName(className);
258 } catch (Exception e) {
259 localLogger.error("Invalid Transform Class specified:<" + className + ">");
260 throw new CpoException("Invalid Transform Class specified:<" + className + ">:");
261 }
262
263 Object transformObject;
264 try {
265 transformObject = transformClass.newInstance();
266 } catch (Exception e) {
267 localLogger.debug("Error Setting Transform Class: " + ExceptionHelper.getLocalizedMessage(e));
268 throw new CpoException(e);
269 }
270
271 if (transformObject instanceof CpoTransform) {
272 cpoTransform = (CpoTransform)transformObject;
273 List<Method> methods = findMethods(transformClass, TRANSFORM_IN_NAME, 1, true);
274 if (methods.size() > 0) {
275 transformInMethod = methods.get(0);
276 }
277 methods = findMethods(transformClass, TRANSFORM_OUT_NAME, 1, true);
278 if (methods.size() > 0) {
279 transformOutMethod = methods.get(0);
280 }
281 } else {
282 localLogger.error("Invalid CpoTransform Class specified:<" + className + ">");
283 throw new CpoException("Invalid CpoTransform Class specified:<" + className + ">");
284 }
285 }
286 }
287
288 @Override
289 public String toString() {
290 return this.getJavaName();
291 }
292
293 public String toStringFull() {
294 return super.toString();
295 }
296 }