diff --git a/src/main/java/freemarker/ext/beans/ClassIntrospector.java b/src/main/java/freemarker/ext/beans/ClassIntrospector.java index a31d430ab..fb17cc7b7 100644 --- a/src/main/java/freemarker/ext/beans/ClassIntrospector.java +++ b/src/main/java/freemarker/ext/beans/ClassIntrospector.java @@ -336,7 +336,7 @@ private void addBeanInfoToClassIntrospectionData( IdentityHashMap argTypesUsedByIndexerPropReaders = null; for (int i = mdsSize - 1; i >= 0; --i) { final Method method = getMatchingAccessibleMethod(mds.get(i).getMethod(), accessibleMethods); - if (method != null && isAllowedToExpose(method)) { + if (method != null && isAllowedToExpose(clazz, method)) { decision.setDefaults(method); if (methodAppearanceFineTuner != null) { if (decisionInput == null) { @@ -663,7 +663,7 @@ private boolean containsMethodWithSameParameterTypes(List overloads, Met private void addPropertyDescriptorToClassIntrospectionData(Map introspData, PropertyDescriptor pd, Class clazz, Map> accessibleMethods) { Method readMethod = getMatchingAccessibleMethod(pd.getReadMethod(), accessibleMethods); - if (readMethod != null && !isAllowedToExpose(readMethod)) { + if (readMethod != null && !isAllowedToExpose(clazz, readMethod)) { readMethod = null; } @@ -671,7 +671,7 @@ private void addPropertyDescriptorToClassIntrospectionData(Map i if (pd instanceof IndexedPropertyDescriptor) { indexedReadMethod = getMatchingAccessibleMethod( ((IndexedPropertyDescriptor) pd).getIndexedReadMethod(), accessibleMethods); - if (indexedReadMethod != null && !isAllowedToExpose(indexedReadMethod)) { + if (indexedReadMethod != null && !isAllowedToExpose(clazz, indexedReadMethod)) { indexedReadMethod = null; } if (indexedReadMethod != null) { @@ -809,8 +809,44 @@ private void sortMethodDescriptors(List methodDescriptors) { } } - boolean isAllowedToExpose(Method method) { - return exposureLevel < BeansWrapper.EXPOSE_SAFE || !UnsafeMethods.isUnsafeMethod(method); + boolean isAllowedToExpose(Class clazz, Method method) { + return exposureLevel < BeansWrapper.EXPOSE_SAFE || !UnsafeMethods.isUnsafeMethod(method) || !isMethodAllowedToExpose(clazz, method); + } + + /** + * Checks if a method is allowed to be exposed + * using the {@link MethodAppearanceFineTuner} + * + * TODO this is just a Proof-of-concept implementation. + * + * + * @param clazz + * @param method + * @return + */ + private boolean isMethodAllowedToExpose(Class clazz, Method method) { + + if(method == null) { + return false; + } + + if (methodAppearanceFineTuner != null) { + + final MethodAppearanceDecision decision = new MethodAppearanceDecision(); + decision.setDefaults(method); + + final MethodAppearanceDecisionInput decisionInput = new MethodAppearanceDecisionInput(); + decisionInput.setContainingClass(clazz); + decisionInput.setMethod(method); + + methodAppearanceFineTuner.process(decisionInput, decision); + + if(decision.getExposeMethodAs() == null && decision.getExposeAsProperty() == null) { + return false; + } + } + + return true; } private static Map[]> getArgTypesByMethod(Map classInfo) { diff --git a/src/main/java/freemarker/ext/beans/StaticModel.java b/src/main/java/freemarker/ext/beans/StaticModel.java index 28c84bb7b..61c5c9498 100644 --- a/src/main/java/freemarker/ext/beans/StaticModel.java +++ b/src/main/java/freemarker/ext/beans/StaticModel.java @@ -131,7 +131,7 @@ private void populate() throws TemplateModelException { Method method = methods[i]; int mod = method.getModifiers(); if (Modifier.isPublic(mod) && Modifier.isStatic(mod) - && wrapper.getClassIntrospector().isAllowedToExpose(method)) { + && wrapper.getClassIntrospector().isAllowedToExpose(clazz, method)) { String name = method.getName(); Object obj = map.get(name); if (obj instanceof Method) {