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

tools.dynamia.actions.ActionLoader Maven / Gradle / Ivy

There is a newer version: 5.3.0
Show newest version
/*
 * Copyright (C) 2023 Dynamia Soluciones IT S.A.S - NIT 900302344-1
 * Colombia / South America
 *
 * 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 tools.dynamia.actions;

import tools.dynamia.commons.BeanUtils;
import tools.dynamia.commons.LocalizedMessagesProvider;
import tools.dynamia.integration.Containers;
import tools.dynamia.integration.ObjectMatcher;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

/**
 * Load actions and control access using {@link ActionRestriction}
 *
 * @param 
 */
public class ActionLoader {

    private final Class targetActionClass;
    private Map actionAttributes = null;
    private boolean ignoreRestrictions;

    private boolean autolocalize = true;

    public ActionLoader(Class targetClass) {
        super();
        this.targetActionClass = targetClass;
    }

    public void setActionAttributes(Map actionAttributes) {
        this.actionAttributes = actionAttributes;
    }

    public List load(ObjectMatcher matcher) {
        final var localizer = findDefaultLocalizedMessagesProvider();
        Collection allActions = Containers.get().findObjects(targetActionClass, matcher);
        List actions = new ArrayList<>();
        for (T action : allActions) {
            if (isActionAllowed(action)) {
                actions.add(action);
                configureAttributes(action);
                if (isAutolocalize() && action instanceof AbstractAction) {
                    ((AbstractAction) action).setLocalizedMessagesProvider(localizer);
                }

                if (action instanceof ActionLifecycleAware ala) {
                    ala.onCreate();
                }
            }
        }
        actions.sort(new ActionComparator());
        return actions;
    }

    public List getActionsReferences(ObjectMatcher matcher) {
        Collection allActions = Containers.get().findObjects(targetActionClass, matcher);
        List actions = new ArrayList<>();
        for (Action action : allActions) {
            actions.add(action);
            configureAttributes(action);
        }
        return actions;

    }

    @SuppressWarnings("unchecked")
    private void configureAttributes(Action action) {
        if (actionAttributes != null) {
            @SuppressWarnings("unchecked") Map params = (Map) actionAttributes.get(action.getId());
            if (params != null) {
                BeanUtils.setupBean(action, params);
                if (params.get("attributes") != null && params.get("attributes") instanceof Map) {
                    //noinspection unchecked
                    action.getAttributes().putAll((Map) params.get("attributes"));
                }
            }
        }

    }

    public List load() {
        return load(null);
    }

    public boolean isActionAllowed(Action action) {
        if (isIgnoreRestrictions()) {
            return true;
        }

        Boolean allowed = ActionRestrictions.allowAccess(action);
        if (allowed == null) {
            allowed = true;
        }
        return allowed;
    }


    public boolean isIgnoreRestrictions() {
        return ignoreRestrictions;
    }

    public void setIgnoreRestrictions(boolean ignoreRestrictions) {
        this.ignoreRestrictions = ignoreRestrictions;
    }

    public static List loadActionCommands(Object object) {
        List actionsCommands = new ArrayList<>();

        if (object != null) {
            Method[] methods = BeanUtils.getMethodsWithAnnotation(object.getClass(), ActionCommand.class);
            final var localizer = findDefaultLocalizedMessagesProvider();
            for (Method method : methods) {
                ActionCommand actionCommand = method.getAnnotation(ActionCommand.class);
                FastAction action = new FastAction(actionCommand.name(), actionCommand.image(),
                        actionCommand.description(), null, evt -> invokeActionCommand(object, method, evt));

                if (actionCommand.name().isEmpty()) {
                    action.setName(method.getName());
                }

                if (actionCommand.autolocalize()) {
                    action.setLocalizedMessagesProvider(localizer);
                }

                action.setActionRendererClass(actionCommand.actionRenderer());
                actionsCommands.add(action);
            }
        }

        return actionsCommands;
    }

    private static void invokeActionCommand(Object object, Method method, ActionEvent evt) {
        try {
            method.setAccessible(true);
            switch (method.getParameterCount()) {
                case 0 -> method.invoke(object);
                case 1 -> method.invoke(object, evt);
                default -> throw new ActionLoaderException(
                        "Invalid ActionCommand " + method.getName() + " from " + object.getClass());
            }

        } catch (IllegalAccessException e) {
            throw new ActionLoaderException("ActionCommand method cannot be access, make sure is public method", e);
        } catch (IllegalArgumentException e) {
            throw new ActionLoaderException(
                    "ActionCommand has more than zero arguments and first is not ActionEvent type", e);
        } catch (InvocationTargetException e) {
            throw new ActionLoaderException(e.getCause().getMessage(), e);
        }

    }

    public static  T findActionById(Class actionType, String actionId) {
        return Containers.get().findObjects(actionType)
                .stream().filter(a -> a.getId().equals(actionId))
                .findFirst()
                .orElse(null);
    }

    public boolean isAutolocalize() {
        return autolocalize;
    }

    public void setAutolocalize(boolean autolocalize) {
        this.autolocalize = autolocalize;
    }

    private static LocalizedMessagesProvider findDefaultLocalizedMessagesProvider() {
        return Containers.get().findObjects(LocalizedMessagesProvider.class)
                .stream().min(Comparator.comparingInt(LocalizedMessagesProvider::getPriority))
                .orElse(null);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy