/******************************************************************************* * Copyright 2014 Rafael Garcia Moreno. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package com.bladecoder.engineeditor.common; import java.io.IOException; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.HashMap; import java.util.Hashtable; import com.badlogic.gdx.utils.reflect.ClassReflection; import com.badlogic.gdx.utils.reflect.ReflectionException; import com.bladecoder.engine.actions.Action; import com.bladecoder.engine.actions.ActionDescription; import com.bladecoder.engine.actions.ActionFactory; import com.bladecoder.engine.actions.DisableActionAction; import com.bladecoder.engine.actions.EndAction; import com.bladecoder.engine.util.ActionUtils; import eu.infomas.annotation.AnnotationDetector; import eu.infomas.annotation.AnnotationDetector.TypeReporter; public class ActionDetector { private static HashMap<String, Class<?>> actions = null; public static void detect() { actions = new HashMap<String, Class<?>>(); final TypeReporter reporter = new TypeReporter() { @SuppressWarnings("unchecked") @Override public Class<? extends Annotation>[] annotations() { return new Class[] { ActionDescription.class }; } @SuppressWarnings("unchecked") @Override public void reportTypeAnnotation(Class<? extends Annotation> annotation, String className) { Class<Action> c = null; try { c = ClassReflection.forName(className); } catch (ReflectionException e) { EditorLogger.printStackTrace(e); } String name = ActionUtils.getName(c); if ( !c.isAssignableFrom(EndAction.class) && !c.isAssignableFrom(DisableActionAction.class )) actions.put(name, c); } }; final AnnotationDetector cf = new AnnotationDetector(reporter); try { cf.detect(); } catch (IOException e) { EditorLogger.printStackTrace(e); } } public static String[] getActionNames() { if (actions == null) { detect(); } ArrayList<String> names = new ArrayList<String>(); names.addAll(actions.keySet()); addCustomActions(names); return names.toArray(new String[names.size()]); } public static Action create(String name, HashMap<String, String> params) { Class<?> c = actions.get(name); if(c == null) { // Search in custom actions c = getCustomActionByName(name); } if (c == null) { EditorLogger.error("Action with name '" + name + "' not found."); return null; } try { return ActionFactory.createByClass(c.getName(), params); } catch (ClassNotFoundException | ReflectionException e) { EditorLogger.error("Action with name '" + name + "' not found."); return null; } } private static void addCustomActions(ArrayList<String> names) { Hashtable<String, Class<?>> coreClasses = ((FolderClassLoader) ActionFactory.getActionClassLoader()) .getClasses(); for (Class<?> c : coreClasses.values()) { if (c.getAnnotation(ActionDescription.class) != null) { names.add(ActionUtils.getName(c)); } } } private static Class<?> getCustomActionByName(String name) { Hashtable<String, Class<?>> coreClasses = ((FolderClassLoader) ActionFactory.getActionClassLoader()) .getClasses(); for (Class<?> c : coreClasses.values()) { if (c.getAnnotation(ActionDescription.class) != null) { if(name.equals(ActionUtils.getName(c))) return c; } } return null; } }