BeagleController.java
package de.uka.ipd.sdq.beagle.core.facade;
import de.uka.ipd.sdq.beagle.core.AnalysisController;
import de.uka.ipd.sdq.beagle.core.AnalysisState;
import de.uka.ipd.sdq.beagle.core.Blackboard;
import de.uka.ipd.sdq.beagle.core.LaunchConfiguration;
import de.uka.ipd.sdq.beagle.core.ProjectInformation;
import de.uka.ipd.sdq.beagle.core.analysis.MeasurementResultAnalyserContributionsHandler;
import de.uka.ipd.sdq.beagle.core.analysis.ProposedExpressionAnalyserContributionsHandler;
import de.uka.ipd.sdq.beagle.core.failurehandling.FailureHandler;
import de.uka.ipd.sdq.beagle.core.failurehandling.FailureReport;
import de.uka.ipd.sdq.beagle.core.judge.AbstractionAndPrecisionFitnessFunction;
import de.uka.ipd.sdq.beagle.core.measurement.MeasurementToolContributionsHandler;
import de.uka.ipd.sdq.beagle.core.pcmconnection.PcmRepositoryBlackboardFactoryAdder;
import de.uka.ipd.sdq.beagle.core.pcmconnection.PcmRepositoryWriter;
import de.uka.ipd.sdq.beagle.core.pcmsourcestatementlink.PcmSourceStatementLinkReader;
import de.uka.ipd.sdq.beagle.core.pcmsourcestatementlink.PcmSourceStatementLinkRepository;
import org.apache.commons.lang3.Validate;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IJavaProject;
import java.nio.charset.Charset;
import java.util.HashSet;
import java.util.Set;
/**
* Controls the execution of the Beagle Analysis. {@code BeagleController} can start,
* pause, continue, and abort an Analysis. The controller has to be initialised through
* {@link #initialise()} before it can be used.
*
* @author Christoph Michelbach
* @author Roman Langrehr
*/
public class BeagleController {
/**
* The failure handler for this class.
*/
private static final FailureHandler FAILURE_HANDLER = FailureHandler.getHandler(BeagleConfiguration.class);
/**
* The analysis controller used for this project.
*/
private AnalysisController analysisController;
/**
* The final {@link BeagleConfiguration} for this analysis.
*/
private final BeagleConfiguration beagleConfiguration;
/**
* The {@link Blackboard} for this analysis.
*/
private Blackboard blackboard;
/**
* Will be set to {@code true} after {@link #initialise()} has been run.
*/
private boolean inited;
/**
* Will be set to {@code true} after {@link #startAnalysis()} has been run.
*/
private boolean started;
/**
* Constructs a new {@code BeagleController} with the given
* {@link BeagleConfiguration}.
*
* @param beagleConfiguration The {@link BeagleConfiguration} this BeagleController
* has permanently. It cannot be changed.
* {@link BeagleConfiguration#finalise()} must have been called.
*/
public BeagleController(final BeagleConfiguration beagleConfiguration) {
Validate.isTrue(beagleConfiguration.isFinal(),
"The BeagleConfiguration must be final for the BeagleController");
this.beagleConfiguration = beagleConfiguration;
}
/**
* Initialises this controller, making it ready to start the analysis.
*/
public void initialise() {
final BlackboardCreator blackboardFactory = new BlackboardCreator();
final SourceCodeFileProvider sourceCodeFileProvider =
new JdtProjectSourceCodeFileProvider(this.beagleConfiguration.getJavaProject());
final PcmSourceStatementLinkReader linkReader =
new PcmSourceStatementLinkReader(this.beagleConfiguration.getSourceStatementLinkFile());
final PcmSourceStatementLinkRepository linkRepository = linkReader.getPcmSourceLinkRepository();
if (this.beagleConfiguration.getElements() == null) {
new PcmRepositoryBlackboardFactoryAdder(this.beagleConfiguration.getRepositoryFile(),
sourceCodeFileProvider, linkRepository).getBlackboardForAllElements(blackboardFactory);
} else {
new PcmRepositoryBlackboardFactoryAdder(this.beagleConfiguration.getRepositoryFile(),
sourceCodeFileProvider, linkRepository).getBlackboardForIds(this.beagleConfiguration.getElements(),
blackboardFactory);
}
final Charset charset = this.readCharset(this.beagleConfiguration.getJavaProject());
final String buildPath =
new JdtProjectClasspathExtractor(this.beagleConfiguration.getJavaProject()).getClasspath();
final Set<LaunchConfiguration> launchConfigurations = this.beagleConfiguration.getLaunchConfigurations();
blackboardFactory.setProjectInformation(new ProjectInformation(this.beagleConfiguration.getTimeout(),
sourceCodeFileProvider, buildPath, charset, launchConfigurations));
blackboardFactory.setFitnessFunction(new AbstractionAndPrecisionFitnessFunction());
this.blackboard = blackboardFactory.createBlackboard();
this.analysisController = new AnalysisController(this.blackboard,
new HashSet<>(new MeasurementToolContributionsHandler().getAvailableMeasurmentTools()),
new HashSet<>(new MeasurementResultAnalyserContributionsHandler().getAvailableMeasurmentResultAnalysers()),
new HashSet<>(
new ProposedExpressionAnalyserContributionsHandler().getAvailableProposedExpressionAnalysers()));
this.inited = true;
}
/**
* Starts the analysis. This method can only be used once per {@link BeagleController}
* . Further calls will be ignored.
*
* @throws IllegalStateException If {@link #initialise()} has not been called yet.
*/
public void startAnalysis() {
Validate.validState(this.inited, "The Beagle Controller has not yet been initialised!");
if (!this.started) {
this.started = true;
this.analysisController.performAnalysis();
new PcmRepositoryWriter(this.blackboard).writeTo(this.beagleConfiguration.getRepositoryFile());
}
}
/**
* Reads the default charset of an {@link IJavaProject}.
*
* @param javaProject the {@link IJavaProject} to read from.
* @return the charset specified by {@link IProject#getDefaultCharset()}
*/
private Charset readCharset(final IJavaProject javaProject) {
try {
return Charset.forName(javaProject.getProject().getDefaultCharset());
} catch (final CoreException coreException) {
final FailureReport<Charset> failure = new FailureReport<Charset>().cause(coreException)
.continueWith(Charset::defaultCharset)
.retryWith(() -> this.readCharset(javaProject));
return FAILURE_HANDLER.handle(failure);
}
}
/**
* Pauses the analysis. The call will be directed to the {@link AnalysisController}
* started by this controller.
*
* @throws IllegalStateException If the analysis has not been started yet or this
* controller has not been initialised yet.
*/
public void pauseAnalysis() {
Validate.validState(this.inited, "The Beagle Controller has not yet been initialised!");
Validate.validState(this.started, "The analysis has not yet been started!");
this.analysisController.setAnalysisState(AnalysisState.ENDING);
}
/**
* Continues the analysis if it is paused. The call will be directed to the
* {@link AnalysisController} started by this controller.
*
* @throws IllegalStateException If the analysis has not been started yet or this
* controller has not been initialised yet.
*/
public void continueAnalysis() {
Validate.validState(this.inited, "The Beagle Controller has not yet been initialised!");
Validate.validState(this.started, "The analysis has not yet been started!");
this.analysisController.setAnalysisState(AnalysisState.RUNNING);
}
/**
* Aborts the analysis. The call will be directed to the {@link AnalysisController}
* started by this controller.
*
* @throws IllegalStateException If the analysis has not been started yet or this
* controller has not been initialised yet.
*/
public void abortAnalysis() {
Validate.validState(this.inited, "The Beagle Controller has not yet been initialised!");
Validate.validState(this.started, "The analysis has not yet been started!");
this.analysisController.setAnalysisState(AnalysisState.ABORTING);
}
}