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

pl.fhframework.trees.SubsystemElementsLiteTree Maven / Gradle / Ivy

package pl.fhframework.trees;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Scope;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Service;
import pl.fhframework.core.FhCL;
import pl.fhframework.core.cloud.config.ExposedMenuElement;
import pl.fhframework.core.cloud.config.ExposedUseCaseDefinition;
import pl.fhframework.core.cloud.event.LocalServerDefinitionChangedEvent;
import pl.fhframework.core.logging.FhLogger;
import pl.fhframework.core.security.AuthorizationManager;
import pl.fhframework.model.security.SystemUser;
import pl.fhframework.subsystems.Subsystem;
import pl.fhframework.subsystems.SubsystemManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;

@Service
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
@ConditionalOnProperty(value = "fhframework.subsystem.menu.custom", havingValue = "false")
public class SubsystemElementsLiteTree extends SubsystemElementsTree {

    protected List _allTreeElements = new ArrayList<>();
    protected List _allTreeElementsView = Collections.unmodifiableList(_allTreeElements);
    protected List treeRoots = new ArrayList<>();

    @Autowired
    protected AuthorizationManager authorizationManager;
    @Autowired
    protected ApplicationEventPublisher eventPublisher;

    protected SubsystemElementsLiteTree() {
        _allTreeElements.addAll(getStaticGroupsAndSubsystemsHierarchy(this.getClass()));
        treeRoots.addAll(getDynamicGroupsAndSubsystemsHierarchy());
        _allTreeElements.addAll(mergeRoots(treeRoots));

    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        getAllTreeElements();
        readAllowedSystemFunctions();
    }

    protected void readAllowedSystemFunctions() {
        treeRoots.forEach(
                root -> readAllowedSystemFunctions(root.getSubelements())
        );
    }

    /**
     * Reads and refreshes information about allowed system function and system roles for use cases from tree.
     * If useCaseName parameter is given than only that use case information is refreshed.
     * If useCaseName parameter is null than all use cases are refreshed.
     * Method works recursively.
     * @param treeElements tree elements
     */
    protected void readAllowedSystemFunctions(List treeElements) {
        for (ITreeElement treeElement : treeElements) {
            if (treeElement instanceof UseCaseInformation) {
                setAllowedSystemFunctionsFor((UseCaseInformation) treeElement);
                setAllowedSystemRolesFor((UseCaseInformation) treeElement);
            } else {
                readAllowedSystemFunctions(treeElement.getSubelements());
            }
        }
    }

    protected void setAllowedSystemFunctionsFor(UseCaseInformation useCaseInformation) {
        try {
            Class clazz = FhCL.classLoader.loadClass(useCaseInformation.getRef());
            if (clazz != null) {
                useCaseInformation.setAllowedSystemFunctions(
                        UseCaseInformation.getAllowedSystemFunctions(clazz)
                );
            }
        } catch (ClassNotFoundException e) {
            FhLogger.error(e);
        }
    }

    protected void setAllowedSystemRolesFor(UseCaseInformation useCaseInformation) {
        try {
            Class clazz = FhCL.classLoader.loadClass(useCaseInformation.getRef());
            if (clazz != null) {
                useCaseInformation.setAllowedSystemRoles(
                        UseCaseInformation.getAllowedSystemRoles(clazz)
                );
            }
        } catch (ClassNotFoundException e) {
            // FhLogger.error(e);
        }
    }

    public void aktualizujHierarchieDynamicznychGrupIPodsystemow() {
        synchronized (this) {
            _allTreeElements.clear();
            _allTreeElements.addAll(getStaticGroupsAndSubsystemsHierarchy(this.getClass()));
            treeRoots = getDynamicGroupsAndSubsystemsHierarchy();
            _allTreeElements.addAll(mergeRoots(treeRoots));
            readAllowedSystemFunctions();
        }
    }

    public List getAllTreeElements() {
        if (requiresRefresh()) {
            aktualizujHierarchieDynamicznychGrupIPodsystemow();
        }
        synchronized (this) {//TODO: Reads can run in parallel, but synchronization is only during dynamic elements update
            return _allTreeElementsView;
        }
    }

    public List getAllAvailableTreeElements(SystemUser systemUser, List activeProfiles) {
        return filterAvailableTreeElements(getAllTreeElements(), systemUser, activeProfiles);
    }

    public void updateCloudServerMenu(String cloudServerName, AtomicBoolean activityToken, List newRootElements, List serverUseCases) {
        synchronized (this) {
            // removing all server's elements from root
            _allTreeElements.removeIf(elem -> cloudServerName.equals(elem.getCloudServerName()));
            // adding new server's elements
            _allTreeElements.addAll(DynamicUseCasesGroup.newCloudInstances(cloudServerName, activityToken, newRootElements, serverUseCases));
        }
    }

    protected List filterAvailableTreeElements(List allTreeElements, SystemUser systemUser, List activeProfiles) {
        List result = new ArrayList<>();
        for (ITreeElement element : allTreeElements) {
            if (element instanceof UseCaseInformation) {
                if (((UseCaseInformation) element).availableFor(authorizationManager, systemUser, activeProfiles)) {
                    result.add(element);
                }
            } else if (element instanceof DynamicUseCasesGroup) {
                DynamicUseCasesGroup current = (DynamicUseCasesGroup) element;
                List allSubelements = current.getSubelements();
                if (current.isAvailableForMode(activeProfiles)) {
                    List available = filterAvailableTreeElements(allSubelements, systemUser, activeProfiles);
                    if (available.size() > 0) {
                        DynamicUseCasesGroup usdg = new DynamicUseCasesGroup(current.label, current.getDescription(), current.getIcon(), current.getPosition(), current.getModes(), available, current.getCloudServerName(), current.getActivityToken());
                        result.add(usdg);
                    }
                }
            }
        }
        return result;
    }

    protected boolean requiresRefresh() {
        for (Subsystem subsystem : SubsystemManager.getSubsystemInfos()) {
            if (subsystem.requiresUpdate()) {
                return true;
            }
        }

        for (TreeRoot treeRoot : treeRoots) {
            if (!treeRoot.getSubsystem().isStatic() && requiresUpdate(treeRoot)) {
                return true;
            }
        }

        return false;
    }

    @Override
    public void exportMenu(Subsystem subsystem, String xml) {
        super.exportMenu(subsystem, xml);
        //update ourself menu structure, for cloud usage
        aktualizujHierarchieDynamicznychGrupIPodsystemow();
        eventPublisher.publishEvent(new LocalServerDefinitionChangedEvent(subsystem));
    }

    protected Optional findUseCaseInformation(List treeElements, String useCaseName) { // TODO
        for (ITreeElement treeElement : treeElements) {
            if (treeElement instanceof UseCaseInformation && treeElement.getRef().equals(useCaseName)) {
                return Optional.of(((UseCaseInformation) treeElement));
            } else {
                Optional result = findUseCaseInformation(treeElement.getSubelements(), useCaseName);
                if (result.isPresent()) {
                    return result;
                }
            }
        }
        return Optional.empty();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy