Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.noahsloan.grails.dwr;
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- import java.util.Collection;
- import java.util.Map;
- import org.directwebremoting.convert.BeanConverter;
- import org.directwebremoting.convert.CollectionConverter;
- import org.directwebremoting.extend.InboundContext;
- import org.directwebremoting.extend.Property;
- import org.directwebremoting.extend.TypeHintContext;
- import org.directwebremoting.util.Logger;
- import com.sun.tools.jdi.LinkedHashMap;
- /**
- * Converter for Grails ORM classes. Uses the hasMany map to determine the type
- * of collections so we can convert them inbound.
- *
- * @author noah
- *
- */
- @SuppressWarnings("unchecked")
- public class DwrGormConverter extends BeanConverter {
- private static final Logger LOG = org.directwebremoting.util.Logger
- .getLogger(DwrGormConverter.class);
- protected TypeHintContext createTypeHintContext(InboundContext inctx,
- final Property property) {
- // check collections
- if (Collection.class.isAssignableFrom(property.getPropertyType())) {
- final Class type = getCollectionType(property);
- if (type != null) {
- return createHint(property.getSetter(), type);
- }
- }
- return super.createTypeHintContext(inctx, property);
- }
- /**
- * Pulled out for readability. Creates a type hint for the
- * {@link CollectionConverter} with the given type.
- *
- * @param setter TODO is this necessary?
- * @param type
- * @return
- */
- protected TypeHintContext createHint(final Method setter,
- final Class type) {
- return new TypeHintContext(converterManager, setter, 0) {
- public TypeHintContext createChildContext(int newParameterNumber) {
- return new TypeHintContext(converterManager, setter, 0) {
- public Class getExtraTypeInfo() {
- return type;
- }
- };
- }
- };
- }
- protected static Map<Class, Map<String, Class>> _cache = new LinkedHashMap();
- /**
- * Determines the type of the collection by examining the declaring class'
- * static hasMany property.
- *
- * @param property
- * @return the type of the elements of the collection property.
- */
- protected Class getCollectionType(Property property) {
- // determine the class the collection is attached to by examining
- // the setter (which is the domain class)
- Method setter = property.getSetter();
- if (setter == null) {
- // XXX in theory this should not happen because BeanConverter should
- // always provide PropertyDescriptionPropertys
- LOG.error("setter for "
- + property.getName() + " is null."
- + " Property is not a PropertyDescriptionProperty.");
- return null;
- }
- Class gormType = setter.getDeclaringClass();
- if (_cache.containsKey(gormType)) {
- Map<String, Class> map = _cache.get(gormType);
- return map == null ? null : map.get(property.getName());
- }
- try {
- Field field = gormType.getDeclaredField("hasMany");
- Map<String, Class> map = null;
- if (field != null) {
- if (!field.isAccessible()) {
- field.setAccessible(true);
- }
- map = ((Map<String, Class>) field.get(null));
- }
- _cache.put(gormType, map);
- return map == null ? null : map.get(property.getName());
- } catch (Exception e) {
- LOG.error("Exception getting GORM collection type info.", e);
- return null;
- }
- }
- }
Add Comment
Please, Sign In to add comment