From: <mol...@us...> - 2007-11-05 17:48:03
|
Revision: 492 http://openutils.svn.sourceforge.net/openutils/?rev=492&view=rev Author: molaschi Date: 2007-11-05 08:36:06 -0800 (Mon, 05 Nov 2007) Log Message: ----------- jsonexporter Modified Paths: -------------- trunk/openutils-spring/src/main/java/it/openutils/spring/remoting/exporters/JSONServiceExporter.java Modified: trunk/openutils-spring/src/main/java/it/openutils/spring/remoting/exporters/JSONServiceExporter.java =================================================================== --- trunk/openutils-spring/src/main/java/it/openutils/spring/remoting/exporters/JSONServiceExporter.java 2007-10-31 18:00:39 UTC (rev 491) +++ trunk/openutils-spring/src/main/java/it/openutils/spring/remoting/exporters/JSONServiceExporter.java 2007-11-05 16:36:06 UTC (rev 492) @@ -1,112 +1,253 @@ package it.openutils.spring.remoting.exporters; +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.lang.reflect.TypeVariable; +import java.util.Collection; import java.util.Enumeration; +import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import net.sf.json.JSON; +import net.sf.json.JSONArray; +import net.sf.json.JSONNull; import net.sf.json.JSONObject; import org.apache.commons.beanutils.ConvertUtils; +import org.apache.commons.lang.ClassUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; -import org.springframework.beans.factory.InitializingBean; +import org.hibernate.Hibernate; import org.springframework.remoting.support.RemoteInvocation; import org.springframework.remoting.support.RemoteInvocationBasedExporter; import org.springframework.remoting.support.RemoteInvocationResult; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; - /** * @author mmolaschi * @version $Id: $ */ -public class JSONServiceExporter extends RemoteInvocationBasedExporter implements Controller -{ - private static final String METHOD = "__method__"; +public class JSONServiceExporter extends RemoteInvocationBasedExporter + implements Controller { + private static final String METHOD = "__method__"; - private static final String PARAM_PREFIX = "param"; + private static final String PARAM_PREFIX = "param"; - private static final String CONTENT_TYPE = "text/x-json"; + private static final String CONTENT_TYPE = "text/x-json"; - /** - * {@inheritDoc} - */ - public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception - { - if (request.getParameter(METHOD) != null) - { - String methodRequest = request.getParameter(METHOD); - Method[] methods = this.getServiceInterface().getMethods(); - for (Method method : methods) - { - if (method.getName().equals(methodRequest)) - { - Class[] types = method.getParameterTypes(); - Object[] values = new Object[types.length]; - if (values.length > 0) - { - int i = 0; - Enumeration<String> names = request.getParameterNames(); - while (names.hasMoreElements()) - { - String name = names.nextElement(); - if (name != null && name.startsWith(PARAM_PREFIX)) - { - String posStr = StringUtils.substringAfter(name, PARAM_PREFIX); - int pos = NumberUtils.toInt(posStr); + /** + * {@inheritDoc} + */ + public ModelAndView handleRequest(HttpServletRequest request, + HttpServletResponse response) throws Exception { + if (request.getParameter(METHOD) != null) { + String methodRequest = request.getParameter(METHOD); + Method[] methods = this.getServiceInterface().getMethods(); + for (Method method : methods) { + if (method.getName().equals(methodRequest)) { + Class[] types = method.getParameterTypes(); + Object[] values = new Object[types.length]; + if (values.length > 0) { + int i = 0; + Enumeration<String> names = request.getParameterNames(); + while (names.hasMoreElements()) { + String name = names.nextElement(); + if (name != null && name.startsWith(PARAM_PREFIX)) { + String posStr = StringUtils.substringAfter( + name, PARAM_PREFIX); + int pos = NumberUtils.toInt(posStr); - String[] reqValues = request.getParameterValues(name); - if (reqValues != null && reqValues.length > 0) - { - if (types[pos].isArray()) - { - values[pos] = ConvertUtils.convert(reqValues, types[pos]); - } - else - { - values[pos] = ConvertUtils.convert(reqValues[0], types[pos]); - } - } - else - { - values[pos] = null; - } + String[] reqValues = request + .getParameterValues(name); + if (reqValues != null && reqValues.length > 0) { + if (types[pos].isArray()) { + values[pos] = ConvertUtils.convert( + reqValues, types[pos]); + } else { + values[pos] = ConvertUtils.convert( + reqValues[0], types[pos]); + } + } else { + values[pos] = null; + } - } - } - } + } + } + } - RemoteInvocation invocation = new RemoteInvocation(); - invocation.setArguments(values); - invocation.setParameterTypes(types); - invocation.setMethodName(methodRequest); + RemoteInvocation invocation = new RemoteInvocation(); + invocation.setArguments(values); + invocation.setParameterTypes(types); + invocation.setMethodName(methodRequest); - RemoteInvocationResult result = invokeAndCreateResult(invocation, this.getProxyForService()); + RemoteInvocationResult result = invokeAndCreateResult( + invocation, this.getProxyForService()); - JSONObject obj = null; - if (result.hasException()) - { - obj = JSONObject.fromBean(result.getException()); - obj.put("exception", true); - } - else - { - obj = JSONObject.fromBean(result.getValue()); - obj.put("exception", false); - } + response.setContentType(CONTENT_TYPE); + JSON json; + if (result.hasException()) { + JSONObject obj = JSONObject.fromBean(result + .getException()); + obj.put("exception", true); - response.setContentType(CONTENT_TYPE); - obj.write(response.getWriter()); + json = obj; + } else { + Object value = cleanLazy(result.getValue()); + if (value != null) { + if (ClassUtils.getAllInterfaces(value.getClass()) + .contains(Collection.class)) { + json = JSONArray + .fromCollection((Collection) value); + } else if (ClassUtils.getAllInterfaces( + value.getClass()).contains(Map.class)) { + json = JSONObject.fromMap((Map) value); + } else if (value.getClass().isArray()) { + json = JSONArray.fromArray((Object[]) value); + } else { + JSONObject obj = JSONObject.fromBean(value); + json = obj; + } + } else { + json = JSONNull.getInstance(); + } + } + json.write(response.getWriter()); - break; - } - } + break; + } + } - } - return null; - } + } + return null; + } + + public Object cleanLazy(Object bean) throws IllegalAccessException, + InstantiationException, IntrospectionException, + InvocationTargetException { + if (bean == null) { + return null; + } + Class<?> clazz = bean.getClass(); + if (bean instanceof Collection) { + Collection collection = (Collection) bean; + + Collection newCollection; + newCollection = collection.getClass().newInstance(); + for (Object myObject : collection) { + newCollection.add(cleanLazy(myObject)); + } + collection.clear(); + collection.addAll(newCollection); + } + if (bean instanceof Map) { + Map<Object, Object> map = (Map<Object, Object>) bean; + Map<Object, Object> newMap = map.getClass().newInstance(); + for (Map.Entry entry : map.entrySet()) { + Object key = cleanLazy(entry.getKey()); + Object value = cleanLazy(entry.getValue()); + newMap.put(key, value); + } + map.clear(); + map.putAll(newMap); + } + if (clazz.isArray()) { + Object[] array = (Object[]) bean; + for (int i = 0; i < array.length; i++) { + array[i] = cleanLazy(array[i]); + } + } + boolean isHibernate = !clazz.equals(Hibernate.getClass(bean)); + if (isHibernate) { + Class<?> noProxyClass = Hibernate.getClass(bean); + Object noHibernateBean = noProxyClass.newInstance(); + BeanInfo info = Introspector.getBeanInfo(noProxyClass); + PropertyDescriptor[] descriptors = info.getPropertyDescriptors(); + for (PropertyDescriptor descriptor : descriptors) { + String name = descriptor.getName(); + + if ("class".equals(name)) { + descriptor.getWriteMethod().invoke(noHibernateBean, + new Object[] { null }); + continue; + } + + if ("hibernateLazyInitializer".equals(name)) { + descriptor.getWriteMethod().invoke(noHibernateBean, + new Object[] { null }); + continue; + } + + if (descriptor.getReadMethod() == null + || descriptor.getWriteMethod() == null) { + descriptor.getWriteMethod().invoke(noHibernateBean, + new Object[] { null }); + continue; + } + + Method method = findGetter(bean, name); + + if (method == null) { + descriptor.getWriteMethod().invoke(noHibernateBean, + new Object[] { null }); + continue; + } + + if (!Hibernate.isPropertyInitialized(bean, name)) { + descriptor.getWriteMethod().invoke(noHibernateBean, + new Object[] { null }); + continue; + } + + // This might be a lazy-collection so we need to double check + Object retval = method.invoke(bean); + if (!Hibernate.isInitialized(retval)) { + descriptor.getWriteMethod().invoke(noHibernateBean, + new Object[] { null }); + continue; + } + descriptor.getWriteMethod().invoke(noHibernateBean, + new Object[] { cleanLazy(bean) }); + + } + + bean = noHibernateBean; + } else { + BeanInfo info = Introspector.getBeanInfo(clazz); + PropertyDescriptor[] descriptors = info.getPropertyDescriptors(); + for (PropertyDescriptor descriptor : descriptors) { + Object value = descriptor.getReadMethod().invoke(bean, null); + descriptor.getWriteMethod().invoke(bean, + new Object[] { cleanLazy(bean) }); + } + } + return bean; + } + + protected Method findGetter(Object bean, String name) + throws IntrospectionException { + Class<?> clazz = Hibernate.getClass(bean); + // String key = clazz.getName() + ":" + property; + + Method method = null; // methods.get(key); + // if (method == null) + // { + PropertyDescriptor[] props = Introspector.getBeanInfo(clazz) + .getPropertyDescriptors(); + for (PropertyDescriptor prop : props) { + if (prop.getName().equalsIgnoreCase(name)) { + method = prop.getReadMethod(); + } + } + + // methods.put(key, method); + // } + + return method; + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |