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