All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sampullara.mustache.DefaultObjectHandler Maven / Gradle / Ivy

The newest version!
package com.sampullara.mustache;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Lookup objects using reflection and execute them the same way.
 * 

* User: sam * Date: 7/24/11 * Time: 3:02 PM */ public class DefaultObjectHandler implements ObjectHandler { // Create a map if one doesn't already exist -- MapMaker.computerHashMap seems to be // very inefficient, had to improvise protected static Map> cache = new HashMap>() { public synchronized Map get(Object c) { Map o = super.get(c); if (o == null) { o = new HashMap(); put((Class) c, o); } return o; } }; private static Logger logger = Logger.getLogger(Mustache.class.getName()); private static class Nothing extends AccessibleObject { } private static Nothing nothing = new Nothing(); @Override public Object handleObject(Object parent, Scope scope, String name) { if (parent == null) return null; if (parent instanceof Future) { try { parent = ((Future) parent).get(); } catch (Exception e) { throw new RuntimeException("Failed to get value from future", e); } } Object value = null; if (parent instanceof Map) { return ((Map) parent).get(name); } Class aClass = parent.getClass(); Map members; // Don't overload methods in your contexts members = cache.get(aClass); AccessibleObject member; synchronized (members) { member = members.get(name); } if (member == nothing) return null; if (member == null) { try { member = getField(name, aClass); synchronized (members) { members.put(name, member); } } catch (NoSuchFieldException e) { // Not set } } if (member == null) { try { synchronized (members) { member = getMethod(name, aClass); members.put(name, member); } } catch (NoSuchMethodException e) { try { synchronized (members) { member = getMethod(name, aClass, Scope.class); members.put(name, member); } } catch (NoSuchMethodException e1) { String propertyname = name.substring(0, 1).toUpperCase() + (name.length() > 1 ? name.substring(1) : ""); try { synchronized (members) { member = getMethod("get" + propertyname, aClass); members.put(name, member); } } catch (NoSuchMethodException e2) { try { synchronized (members) { member = getMethod("is" + propertyname, aClass); members.put(name, member); } } catch (NoSuchMethodException e3) { // Nothing to be done } } } } } try { if (member instanceof Field) { Field field = (Field) member; value = field.get(parent); if (value == null) { if (field.getType().isAssignableFrom(Iterable.class)) { value = Scope.EMPTY; } else { value = Scope.NULL; } } } else if (member instanceof Method) { Method method = (Method) member; if (method.getParameterTypes().length == 0) { value = method.invoke(parent); } else { value = method.invoke(parent, scope); } if (value == null) { if (method.getReturnType().isAssignableFrom(Iterable.class)) { value = Scope.EMPTY; } else { value = Scope.NULL; } } } } catch (Exception e) { // Might be nice for debugging but annoying in practice logger.log(Level.WARNING, "Failed to get value for " + name, e); } if (member == null) { synchronized (members) { members.put(name, nothing); } } return value; } @Override public Iterator iterate(Object object) { Iterator i; if (object instanceof Iterator) { return (Iterator) object; } else if (object instanceof Iterable) { i = ((Iterable) object).iterator(); } else { i = new SingleValueIterator(object); } return i; } public static Method getMethod(String name, Class aClass, Class... params) throws NoSuchMethodException { Method member; try { member = aClass.getDeclaredMethod(name, params); } catch (NoSuchMethodException nsme) { Class superclass = aClass.getSuperclass(); if (superclass != Object.class) { return getMethod(name, superclass, params); } throw nsme; } if ((member.getModifiers() & Modifier.PRIVATE) == Modifier.PRIVATE) { throw new NoSuchMethodException("Only public, protected and package methods allowed"); } member.setAccessible(true); return member; } public static Field getField(String name, Class aClass) throws NoSuchFieldException { Field member; try { member = aClass.getDeclaredField(name); } catch (NoSuchFieldException nsfe) { Class superclass = aClass.getSuperclass(); if (superclass != Object.class) { return getField(name, superclass); } throw nsfe; } if ((member.getModifiers() & Modifier.PRIVATE) == Modifier.PRIVATE) { throw new NoSuchFieldException("Only public, protected and package fields allowed"); } member.setAccessible(true); return member; } protected static class SingleValueIterator implements Iterator { private boolean done; private Object value; public SingleValueIterator(Object value) { this.value = value; } @Override public boolean hasNext() { return !done; } @Override public Object next() { if (!done) { done = true; return value; } throw new NoSuchElementException(); } @Override public void remove() { done = true; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy