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;
}
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());
}
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;
}
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);
}
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;
}
Aggregations