001 /*
002 * Copyright 2010-2012 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.codehaus.griffon.runtime.core;
017
018 import griffon.core.GriffonApplication;
019 import griffon.core.GriffonControllerClass;
020 import griffon.util.GriffonClassUtils;
021 import griffon.util.GriffonNameUtils;
022 import groovy.lang.Closure;
023 import groovy.lang.MetaMethod;
024 import groovy.lang.MetaProperty;
025 import org.codehaus.groovy.ast.ClassHelper;
026
027 import java.lang.reflect.Method;
028 import java.util.LinkedHashSet;
029 import java.util.Set;
030
031 /**
032 * @author Andres Almiray
033 * @since 0.9.1
034 */
035 public class DefaultGriffonControllerClass extends DefaultGriffonClass implements GriffonControllerClass {
036 protected final Set<String> actionsCache = new LinkedHashSet<String>();
037
038 public DefaultGriffonControllerClass(GriffonApplication app, Class<?> clazz) {
039 super(app, clazz, TYPE, TRAILING);
040 }
041
042 public void resetCaches() {
043 super.resetCaches();
044 actionsCache.clear();
045 }
046
047 public String[] getActionNames() {
048 if (actionsCache.isEmpty()) {
049 for (String propertyName : getPropertiesWithFields()) {
050 if (!STANDARD_PROPERTIES.contains(propertyName) &&
051 !actionsCache.contains(propertyName) &&
052 !GriffonClassUtils.isEventHandler(propertyName) &&
053 getPropertyValue(propertyName, Closure.class) != null) {
054 actionsCache.add(propertyName);
055 }
056 }
057 for (Method method : getClazz().getMethods()) {
058 String methodName = method.getName();
059 if (!actionsCache.contains(methodName) &&
060 GriffonClassUtils.isPlainMethod(method) &&
061 !GriffonClassUtils.isEventHandler(methodName) &&
062 hasVoidOrDefAsReturnType(method)) {
063 actionsCache.add(methodName);
064 }
065 }
066 for (MetaProperty p : getMetaProperties()) {
067 String propertyName = p.getName();
068 if (GriffonClassUtils.isGetter(p, true)) {
069 propertyName = GriffonNameUtils.uncapitalize(propertyName.substring(3));
070 }
071 if (!STANDARD_PROPERTIES.contains(propertyName) &&
072 !actionsCache.contains(propertyName) &&
073 !GriffonClassUtils.isEventHandler(propertyName) &&
074 isClosureMetaProperty(p)) {
075 actionsCache.add(propertyName);
076 }
077 }
078 for (MetaMethod method : getMetaClass().getMethods()) {
079 String methodName = method.getName();
080 if (!actionsCache.contains(methodName) &&
081 GriffonClassUtils.isPlainMethod(method) &&
082 !GriffonClassUtils.isEventHandler(methodName) &&
083 hasVoidOrDefAsReturnType(method)) {
084 actionsCache.add(methodName);
085 }
086 }
087 }
088
089 return actionsCache.toArray(new String[actionsCache.size()]);
090 }
091
092 private boolean hasVoidOrDefAsReturnType(Method method) {
093 Class<?> returnType = method.getReturnType();
094 return returnType == ClassHelper.DYNAMIC_TYPE.getTypeClass() ||
095 returnType == ClassHelper.VOID_TYPE.getTypeClass();
096 }
097
098 private boolean hasVoidOrDefAsReturnType(MetaMethod method) {
099 Class<?> returnType = method.getReturnType();
100 return returnType == ClassHelper.DYNAMIC_TYPE.getTypeClass() ||
101 returnType == ClassHelper.VOID_TYPE.getTypeClass();
102 }
103 }
|