Search in sources :

Example 1 with MetaBeanProperty

use of groovy.lang.MetaBeanProperty in project groovity by disney.

the class MetaPropertyLookup method getOrderedGettableProperties.

public static final MetaProperty[] getOrderedGettableProperties(Object o) {
    final Class<?> c = o.getClass();
    MetaProperty[] properties = orderedPropertiesCache.get(c);
    if (properties == null) {
        MetaClass mc = GroovySystem.getMetaClassRegistry().getMetaClass(c);
        List<MetaProperty> mps = mc.getProperties();
        TreeMap<String, MetaProperty> sortedProps;
        String[] declaredOrder = null;
        ModelOrder order = c.getAnnotation(ModelOrder.class);
        if (order != null) {
            declaredOrder = order.value();
        } else {
            XmlType xmlType = c.getAnnotation(XmlType.class);
            if (xmlType != null) {
                declaredOrder = xmlType.propOrder();
            }
        }
        if (declaredOrder != null && declaredOrder.length > 0) {
            final String[] declared = declaredOrder;
            final int dl = declared.length;
            Comparator<String> comp = new Comparator<String>() {

                @Override
                public int compare(String o1, String o2) {
                    int p1 = dl;
                    int p2 = dl;
                    for (int i = 0; i < dl; i++) {
                        String d = declared[i];
                        if (o1.equals(d)) {
                            p1 = i;
                        }
                        if (o2.equals(d)) {
                            p2 = i;
                        }
                        if (p1 < dl && p2 < dl) {
                            break;
                        }
                    }
                    if (p1 == p2) {
                        return o1.compareTo(o2);
                    }
                    return p1 - p2;
                }
            };
            sortedProps = new TreeMap<>(comp);
        } else {
            sortedProps = new TreeMap<>();
        }
        List<String> skipProperties = new ArrayList<>();
        skipProperties.add("class");
        skipProperties.add("binding");
        if (Map.class.isAssignableFrom(c) || Collection.class.isAssignableFrom(c)) {
            skipProperties.add("empty");
            if (NavigableMap.class.isAssignableFrom(c)) {
                skipProperties.add("firstEntry");
                skipProperties.add("lastEntry");
            }
        }
        for (MetaProperty mp : mps) {
            if (!skipProperties.contains(mp.getName()) && !Closeable.class.isAssignableFrom(mp.getType())) {
                // now check for skip annotations
                if (mp instanceof MetaBeanProperty) {
                    MetaBeanProperty mbp = ((MetaBeanProperty) mp);
                    if (mbp.getField() != null) {
                        ModelSkip skipAnn = mbp.getField().field.getAnnotation(ModelSkip.class);
                        if (skipAnn != null) {
                            continue;
                        }
                        if (mbp.getField().isStatic()) {
                            continue;
                        }
                    }
                    MetaMethod getter = mbp.getGetter();
                    if (getter instanceof CachedMethod) {
                        CachedMethod cm = (CachedMethod) getter;
                        ModelSkip skipAnn = cm.getCachedMethod().getAnnotation(ModelSkip.class);
                        if (skipAnn != null) {
                            continue;
                        }
                        if (cm.isStatic()) {
                            continue;
                        }
                        if (!cm.getCachedMethod().getDeclaringClass().equals(c)) {
                            // we may have an overridden method here
                            try {
                                Method override = c.getDeclaredMethod(cm.getCachedMethod().getName(), cm.getCachedMethod().getParameterTypes());
                                if (override.getAnnotation(ModelSkip.class) != null) {
                                    continue;
                                }
                            } catch (NoSuchMethodException | SecurityException e) {
                            }
                        }
                    }
                    if (mbp.getGetter() == null && mbp.getField() == null) {
                        continue;
                    }
                }
                sortedProps.put(mp.getName(), mp);
            }
        }
        properties = sortedProps.values().toArray(new MetaProperty[0]);
        orderedPropertiesCache.putIfAbsent(c, properties);
    }
    return properties;
}
Also used : ArrayList(java.util.ArrayList) CachedMethod(org.codehaus.groovy.reflection.CachedMethod) Comparator(java.util.Comparator) MethodMetaProperty(org.codehaus.groovy.runtime.metaclass.MethodMetaProperty) MetaProperty(groovy.lang.MetaProperty) MetaMethod(groovy.lang.MetaMethod) MetaBeanProperty(groovy.lang.MetaBeanProperty) CachedMethod(org.codehaus.groovy.reflection.CachedMethod) MetaMethod(groovy.lang.MetaMethod) Method(java.lang.reflect.Method) ModelOrder(com.disney.groovity.model.ModelOrder) XmlType(javax.xml.bind.annotation.XmlType) ModelSkip(com.disney.groovity.model.ModelSkip) MetaClass(groovy.lang.MetaClass) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) NavigableMap(java.util.NavigableMap) TreeMap(java.util.TreeMap) Map(java.util.Map)

Example 2 with MetaBeanProperty

use of groovy.lang.MetaBeanProperty in project groovity by disney.

the class TestModel method testMeta.

@SuppressWarnings("rawtypes")
@Test
public void testMeta() throws Exception {
    ModelCheck mc = new ModelCheck();
    mc.setFoo("bar");
    Map mc1 = (Map) Model.mapObject(mc);
    Assert.assertEquals(1, mc1.size());
    Assert.assertEquals("bar", mc1.get("foo"));
    AtomicReference<String> abcref = new AtomicReference<String>(null);
    MetaClassImpl meta = new MetaClassImpl(ModelCheck.class);
    meta.initialize();
    MetaBeanProperty abc = new MetaBeanProperty("abc", String.class, new MetaMethod() {

        @Override
        public Object invoke(Object arg0, Object[] arg1) {
            return abcref.get();
        }

        @Override
        public Class getReturnType() {
            return String.class;
        }

        @Override
        public String getName() {
            return "getAbc";
        }

        @Override
        public int getModifiers() {
            return Modifier.PUBLIC;
        }

        @Override
        public CachedClass getDeclaringClass() {
            return ReflectionCache.getCachedClass(ModelCheck.class);
        }
    }, new MetaMethod() {

        @Override
        public Object invoke(Object arg0, Object[] arg1) {
            abcref.set((String) arg1[0]);
            return null;
        }

        @Override
        public Class getReturnType() {
            return null;
        }

        @Override
        public String getName() {
            return "setAbc";
        }

        @Override
        public int getModifiers() {
            return Modifier.PUBLIC;
        }

        @Override
        public CachedClass getDeclaringClass() {
            return ReflectionCache.getCachedClass(ModelCheck.class);
        }
    });
    meta.addMetaBeanProperty(abc);
    GroovySystem.getMetaClassRegistry().setMetaClass(ModelCheck.class, meta);
    Map mc2 = (Map) Model.mapObject(mc);
    Assert.assertEquals(2, mc2.size());
    Assert.assertNull(mc2.get("abc"));
    Model.put(mc, "abc", "xyz");
    Map mc3 = (Map) Model.mapObject(mc);
    Assert.assertEquals("xyz", mc3.get("abc"));
    MetaClassImpl meta2 = new MetaClassImpl(ModelCheck.class);
    meta2.initialize();
    GroovySystem.getMetaClassRegistry().setMetaClass(ModelCheck.class, meta2);
    Map mc4 = (Map) Model.mapObject(mc);
    Assert.assertEquals(1, mc4.size());
}
Also used : MetaMethod(groovy.lang.MetaMethod) AtomicReference(java.util.concurrent.atomic.AtomicReference) MetaBeanProperty(groovy.lang.MetaBeanProperty) CachedClass(org.codehaus.groovy.reflection.CachedClass) CachedClass(org.codehaus.groovy.reflection.CachedClass) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) MetaClassImpl(groovy.lang.MetaClassImpl) Test(org.junit.Test)

Example 3 with MetaBeanProperty

use of groovy.lang.MetaBeanProperty in project groovity by disney.

the class Model method put.

/**
 * Update the property of an object by name; relies on Groovy MetaProperties to located fields,
 * and GroovyObjectConverter to perform type conversions.
 *
 * @param o
 * @param name
 * @param value
 * @return true if the property value applied to this object, false if not
 */
@SuppressWarnings("unchecked")
public static boolean put(final Object o, final String name, Object value) {
    if (o == null) {
        return false;
    }
    if (o instanceof Collection) {
        if (name.startsWith("_item")) {
            ((Collection<Object>) o).add(value);
            return true;
        }
    }
    boolean didSet = false;
    final MetaProperty mp = MetaPropertyLookup.getSettableMetaProperty(o, name);
    if (mp != null) {
        try {
            if (mp instanceof MetaBeanProperty) {
                MetaBeanProperty mbp = (MetaBeanProperty) mp;
                CachedField cf = mbp.getField();
                Type type = mp.getType();
                if (cf != null) {
                    type = cf.field.getGenericType();
                }
                if (type != null) {
                    value = GroovityObjectConverter.convert(value, type);
                }
            }
            mp.setProperty(o, value);
        } catch (RuntimeException e) {
            String message = "Error setting property " + name + " on " + o.getClass().getName();
            if (value != null) {
                message += " to value type " + value.getClass().getName();
            }
            throw new RuntimeException(message, e);
        }
        didSet = true;
    }
    if (!didSet) {
        if (o instanceof Map) {
            ((Map<String, Object>) o).put(name, value);
            didSet = true;
        }
    }
    return didSet;
}
Also used : Type(java.lang.reflect.Type) Collection(java.util.Collection) MetaBeanProperty(groovy.lang.MetaBeanProperty) MetaProperty(groovy.lang.MetaProperty) CachedField(org.codehaus.groovy.reflection.CachedField) Map(java.util.Map)

Example 4 with MetaBeanProperty

use of groovy.lang.MetaBeanProperty in project groovity by disney.

the class MetaPropertyLookup method getSettableMetaProperty.

public static final MetaProperty getSettableMetaProperty(Object o, String name) {
    final Class<?> c = o.getClass();
    ConcurrentHashMap<String, MetaProperty> properties = singlePropertyCache.get(c);
    if (properties == null) {
        MetaClass mc = GroovySystem.getMetaClassRegistry().getMetaClass(c);
        List<MetaProperty> mps = mc.getProperties();
        properties = new ConcurrentHashMap<>();
        for (MetaProperty mp : mps) {
            if (mp instanceof MetaBeanProperty) {
                MetaBeanProperty mbp = ((MetaBeanProperty) mp);
                if (mbp.getSetter() == null) {
                    CachedField cf = mbp.getField();
                    if (cf == null || cf.isFinal() || cf.isStatic()) {
                        continue;
                    }
                }
            } else if (mp instanceof MethodMetaProperty) {
                continue;
            }
            properties.put(mp.getName(), mp);
        }
        singlePropertyCache.putIfAbsent(c, properties);
    }
    return properties.get(name);
}
Also used : MetaClass(groovy.lang.MetaClass) MetaBeanProperty(groovy.lang.MetaBeanProperty) MethodMetaProperty(org.codehaus.groovy.runtime.metaclass.MethodMetaProperty) MethodMetaProperty(org.codehaus.groovy.runtime.metaclass.MethodMetaProperty) MetaProperty(groovy.lang.MetaProperty) CachedField(org.codehaus.groovy.reflection.CachedField)

Example 5 with MetaBeanProperty

use of groovy.lang.MetaBeanProperty in project groovity by disney.

the class MetaPropertyLookup method getAnnotation.

public static final <T extends Annotation> T getAnnotation(MetaProperty mp, Class<T> annotationClass) {
    if (mp instanceof MetaBeanProperty) {
        MetaBeanProperty mbp = (MetaBeanProperty) mp;
        MetaMethod mm = mbp.getGetter();
        if (mm instanceof CachedMethod) {
            CachedMethod cm = (CachedMethod) mm;
            T anno = cm.getCachedMethod().getAnnotation(annotationClass);
            if (anno != null) {
                return anno;
            }
        }
        CachedField cf = mbp.getField();
        if (cf != null) {
            return cf.field.getAnnotation(annotationClass);
        }
    }
    return null;
}
Also used : MetaMethod(groovy.lang.MetaMethod) CachedMethod(org.codehaus.groovy.reflection.CachedMethod) MetaBeanProperty(groovy.lang.MetaBeanProperty) CachedField(org.codehaus.groovy.reflection.CachedField)

Aggregations

MetaBeanProperty (groovy.lang.MetaBeanProperty)5 MetaMethod (groovy.lang.MetaMethod)3 MetaProperty (groovy.lang.MetaProperty)3 Map (java.util.Map)3 CachedField (org.codehaus.groovy.reflection.CachedField)3 MetaClass (groovy.lang.MetaClass)2 Collection (java.util.Collection)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 CachedMethod (org.codehaus.groovy.reflection.CachedMethod)2 MethodMetaProperty (org.codehaus.groovy.runtime.metaclass.MethodMetaProperty)2 ModelOrder (com.disney.groovity.model.ModelOrder)1 ModelSkip (com.disney.groovity.model.ModelSkip)1 MetaClassImpl (groovy.lang.MetaClassImpl)1 Method (java.lang.reflect.Method)1 Type (java.lang.reflect.Type)1 ArrayList (java.util.ArrayList)1 Comparator (java.util.Comparator)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 NavigableMap (java.util.NavigableMap)1