cdc.applic.mountability.core.MountabilityComputerImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cdc-applic-mountability-core Show documentation
Show all versions of cdc-applic-mountability-core Show documentation
Applicabilities Mountability Core.
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;
}
}