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

cdc.applic.mountability.core.MountabilityComputerImpl Maven / Gradle / Ivy

The newest version!
package cdc.applic.mountability.core;

import java.util.ArrayList;
import java.util.List;
import java.util.function.UnaryOperator;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import cdc.applic.dictionaries.handles.DictionaryHandle;
import cdc.applic.expressions.Expression;
import cdc.applic.mountability.Interchangeability;
import cdc.applic.mountability.MountabilityComputer;
import cdc.applic.mountability.MountabilityComputerFeatures;
import cdc.applic.mountability.MountabilityData;
import cdc.applic.mountability.events.ErrorEvent;
import cdc.applic.mountability.events.MountabilityComputationEvent;
import cdc.applic.mountability.events.MountabilityEvent;
import cdc.applic.mountability.handlers.MountabilityHandler;
import cdc.applic.simplification.Simplifier;
import cdc.applic.simplification.SimplifierFeatures;
import cdc.applic.simplification.core.SimplifierImpl;
import cdc.util.events.ProgressController;
import cdc.util.events.ProgressSupplier;

/**
 * Implementation of {@link MountabilityComputer}.
 *
 * @param  The use point type.
 * @param  The variant type.
 */
public class MountabilityComputerImpl implements MountabilityComputer {
    static final Logger LOGGER = LogManager.getLogger(MountabilityComputerImpl.class);

    private final Simplifier simplifier;
    private final SimplifierFeatures features;

    public MountabilityComputerImpl(DictionaryHandle handle,
                                    SimplifierFeatures features) {
        this.simplifier = new SimplifierImpl(handle);
        this.features = features;
    }

    private Expression simplify(Expression expression) {
        return simplifier.simplify(expression, features).getValue();
    }

    @Override
    public void compute(MountabilityData data,
                        MountabilityHandler handler,
                        MountabilityComputerFeatures features,
                        ProgressController controller) {
        LOGGER.debug("compute(...)");

        final ProgressSupplier progress = new ProgressSupplier(controller);

        progress.reset(data.getVariantsCount(), "Compute mountability");

        handler.processBeginUsePoints();
        // The use point index
        int rank = 0;

        // Iterate on each use point
        for (final U usePoint : data.getUsePoints()) {
            rank++;
            handler.processBeginUsePoint(usePoint);

            // Wrap all variants
            final List> buckets = new ArrayList<>();
            boolean first = true;
            // Are all buckets valid?
            boolean valid = true;
            for (final V variant : data.getVariants(usePoint)) {
                final Expression applicability = data.getVariantApplicability(usePoint, variant);
                final Interchangeability interchangeability = data.getVariantInterchangeability(usePoint, variant);
                final Interchangeability inter;
                if (first) {
                    inter = null;
                } else if (interchangeability == null) {
                    inter = Interchangeability.NOT_INTERCHANGEABLE;
                } else {
                    inter = interchangeability;
                }
                final Bucket bucket = new Bucket<>(variant, inter, applicability);
                buckets.add(bucket);
                first = false;
                if (!bucket.isValid()) {
                    valid = false;
                }
            }
            LOGGER.debug("buckets: {} {}", buckets, (valid ? " all valid" : "some invalid"));
            if (!buckets.isEmpty()) {
                if (valid) {
                    try {
                        // Create computer for use point
                        final Computer computer = new Computer<>(usePoint, buckets);
                        // And do computation
                        if (features.isEnabled(MountabilityComputerFeatures.Hint.SIMPLIFY)) {
                            computer.process(handler, this::simplify, progress);
                        } else {
                            computer.process(handler, UnaryOperator.identity(), progress);
                        }
                    } catch (final RuntimeException e) {
                        handler.processError(e);
                        if (!features.isEnabled(MountabilityComputerFeatures.Hint.KEEP_GOING)) {
                            LOGGER.fatal("Exception raised when processing {}th use point '{}'.", rank, usePoint);
                            LOGGER.fatal("{}", e.getMessage());
                            throw e;
                        }
                    }
                } else {
                    final RuntimeException e =
                            new RuntimeException("There are some invalid buckets in use point '" + usePoint + "'");
                    handler.processError(e);
                    if (!features.isEnabled(MountabilityComputerFeatures.Hint.KEEP_GOING)) {
                        LOGGER.fatal(e.getMessage());
                        throw e;
                    }
                }
            }
            handler.processEndUsePoint(usePoint);
        }
        handler.processEndUsePoints();
    }

    @Override
    public List compute(MountabilityData data,
                                           MountabilityComputerFeatures features,
                                           ProgressController controller) {
        final List events = new ArrayList<>();
        final MountabilityHandler handler = new MountabilityHandler() {
            @Override
            public void processBeginUsePoints() {
                events.add(MountabilityComputationEvent.newBeginUsePoints());
            }

            @Override
            public void processEndUsePoints() {
                events.add(MountabilityComputationEvent.newEndUsePoints());
            }

            @Override
            public void processBeginUsePoint(U usePoint) {
                events.add(MountabilityComputationEvent.newBeginUsePoint(usePoint));
            }

            @Override
            public void processEndUsePoint(U usePoint) {
                events.add(MountabilityComputationEvent.newEndUsePoint(usePoint));
            }

            @Override
            public void processVariantMountability(U usePoint,
                                                   V variant,
                                                   Expression mountability) {
                events.add(MountabilityComputationEvent.newVariantMountability(usePoint, variant, mountability));
            }

            @Override
            public void processError(RuntimeException e) {
                events.add(ErrorEvent.newRuntimeExceptionEvent(e));
            }
        };
        try {
            compute(data, handler, features, controller);
        } catch (final RuntimeException e) {
            LOGGER.catching(e);
            events.add(ErrorEvent.newRuntimeExceptionEvent(e));
        }
        return events;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy