PcmRepositoryExtractor.java
package de.uka.ipd.sdq.beagle.core.pcmconnection;
import de.uka.ipd.sdq.beagle.core.Blackboard;
import de.uka.ipd.sdq.beagle.core.ExternalCallParameter;
import de.uka.ipd.sdq.beagle.core.ResourceDemandingInternalAction;
import de.uka.ipd.sdq.beagle.core.SeffBranch;
import de.uka.ipd.sdq.beagle.core.SeffLoop;
import de.uka.ipd.sdq.beagle.core.facade.BlackboardCreator;
import de.uka.ipd.sdq.beagle.core.facade.SourceCodeFileProvider;
import de.uka.ipd.sdq.beagle.core.pcmsourcestatementlink.PcmSourceStatementLinkRepository;
import de.uka.ipd.sdq.identifier.Identifier;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.palladiosimulator.pcm.repository.RepositoryComponent;
import org.palladiosimulator.pcm.repository.impl.BasicComponentImpl;
import org.palladiosimulator.pcm.repository.impl.RepositoryImpl;
import org.palladiosimulator.pcm.seff.AbstractBranchTransition;
import org.palladiosimulator.pcm.seff.ServiceEffectSpecification;
import org.palladiosimulator.pcm.seff.impl.ResourceDemandingBehaviourImpl;
import org.palladiosimulator.pcm.seff.impl.ResourceDemandingSEFFImpl;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
/**
* Extracting a given Pcm repository. Offering 2 methods:
* {@link #getBlackboardForAllElements(RepositoryImpl, BlackboardCreator)} and
* {@link #getBlackboardForIds(RepositoryImpl, Collection, BlackboardCreator)}
*
* @author Ansgar Spiegler
* @author Roman Langrehr
*/
public class PcmRepositoryExtractor {
/**
* Temporary storage for all extracted {@link SeffLoop SeffLoops} that should be
* written on the {@link Blackboard}.
*/
private Set<SeffLoop> seffLoopSet;
/**
* Temporary storage for all extracted {@link SeffBranch SeffBranches} that should be
* written on the {@link Blackboard}.
*/
private Set<SeffBranch> seffBranchSet;
/**
* Temporary storage for all extracted {@link ResourceDemandingInternalAction rdSeffs}
* that should be written on the {@link Blackboard}.
*/
private Set<ResourceDemandingInternalAction> rdiaSet;
/**
* Temporary storage for all extracted {@link ExternalCallParameter} that should be
* written on the {@link Blackboard}.
*/
private Set<ExternalCallParameter> externalCallParameterSet;
/**
* Helping class instance for extracting, creating and adding SEFF elements to Sets.
*/
private PcmRepositorySeffExtractor pcmSeffExtractor;
/**
* The {@link SourceCodeFileProvider} for the project under analysis.
*/
private final SourceCodeFileProvider sourceCodeFileProvider;
/**
* The {@link PcmSourceStatementLinkRepository} for the project under analysis.
*/
private final PcmSourceStatementLinkRepository sourceStatementLinkRepository;
/**
* Creates a new name parser for a specific project to analyse.
*
* @param sourceCodeFileProvider The {@link SourceCodeFileProvider} for the project
* under analysis.
* @param sourceStatementLinkRepository The repository containing the linking of
* seffElements to SourceCode
*/
public PcmRepositoryExtractor(final SourceCodeFileProvider sourceCodeFileProvider,
final PcmSourceStatementLinkRepository sourceStatementLinkRepository) {
this.sourceCodeFileProvider = sourceCodeFileProvider;
this.sourceStatementLinkRepository = sourceStatementLinkRepository;
}
/**
* Builds a new blackboard and writes the Beagle objects representing all found
* <em>PCM elements</em> to it. Only <em>PCM elements</em> that fulfil the
* restrictions described in the class description will be written.
*
* @param repository The repository to look up.
* @param blackboardFactory all translated <em>PCM elements</em> will be written on
* it. The rdias, seffLoops, seffBranches and externalCallPAramerts will
* never be {@code null} afterwards.
*/
public void getBlackboardForAllElements(final RepositoryImpl repository,
final BlackboardCreator blackboardFactory) {
final PcmBeagleMappings pcmMappings = new PcmBeagleMappings();
this.seffLoopSet = new HashSet<SeffLoop>();
this.seffBranchSet = new HashSet<SeffBranch>();
this.rdiaSet = new HashSet<ResourceDemandingInternalAction>();
this.externalCallParameterSet = new HashSet<ExternalCallParameter>();
this.pcmSeffExtractor = new PcmRepositorySeffExtractor(this.seffLoopSet, this.seffBranchSet, this.rdiaSet,
this.externalCallParameterSet, pcmMappings, this.sourceCodeFileProvider,
this.sourceStatementLinkRepository);
this.scanRepository(repository);
blackboardFactory.setRdias(this.rdiaSet);
blackboardFactory.setBranches(this.seffBranchSet);
blackboardFactory.setLoops(this.seffLoopSet);
blackboardFactory.setExternalCalls(this.externalCallParameterSet);
blackboardFactory.setPcmMappings(pcmMappings);
}
/**
* Builds a new blackboard and writes the Beagle objects representing <em>PCM
* elements</em> related to {@code ids} to it. Only <em>PCM elements</em> that fulfil
* the restrictions described in the class description will be written.
*
* <p>For any provided ID {@code id}, <em>PCM elements</em> will be selected to be
* written on the blackboard as follows:
*
* <ul>
*
* <li>If {@code id} describes a component, all <em>PCM elements</em> that are part of
* the component’s service effect specification will be selected. Nested components
* will be inspected recursively.
*
* <li>If {@code id} describes a repository, all contained components will be
* inspected as if their ID had been provided.
*
* <li>If {@code id} describes a <em>PCM element</em>, it will be selected.
*
* <li>Any other ID will be silently ignored.
*
* </ul>
*
*
* @param repository The repository to look up.
* @param identifiers Identifiers of elements in the repository files that shall be
* written to the Blackboard.
* @param blackboardFactory all translated <em>PCM elements</em> will be written on
* it. The rdias, seffLoops, seffBranches and externalCallPAramerts will
* never be {@code null} afterwards.
*/
public void getBlackboardForIds(final RepositoryImpl repository, final Collection<String> identifiers,
final BlackboardCreator blackboardFactory) {
final PcmBeagleMappings pcmMappings = new PcmBeagleMappings();
final Set<EObject> setOfIdentifiedObjects = new HashSet<EObject>();
this.seffLoopSet = new HashSet<SeffLoop>();
this.seffBranchSet = new HashSet<SeffBranch>();
this.rdiaSet = new HashSet<ResourceDemandingInternalAction>();
this.externalCallParameterSet = new HashSet<ExternalCallParameter>();
this.pcmSeffExtractor = new PcmRepositorySeffExtractor(this.seffLoopSet, this.seffBranchSet, this.rdiaSet,
this.externalCallParameterSet, pcmMappings, this.sourceCodeFileProvider,
this.sourceStatementLinkRepository);
if (identifiers.contains(repository.getId())) {
this.scanRepository(repository);
blackboardFactory.setRdias(this.rdiaSet);
blackboardFactory.setBranches(this.seffBranchSet);
blackboardFactory.setLoops(this.seffLoopSet);
blackboardFactory.setExternalCalls(this.externalCallParameterSet);
blackboardFactory.setPcmMappings(pcmMappings);
}
// Look up for each Repository-object ID if its found in the
// identifiers-Collection
// If so, the Object is added to a Set named "setOfIdentifiedObjects"
final TreeIterator<EObject> contentIterator = repository.eAllContents();
while (contentIterator.hasNext()) {
final EObject content = contentIterator.next();
Identifier contentIdentifier = null;
if (content instanceof Identifier) {
contentIdentifier = (Identifier) content;
if (identifiers.contains(contentIdentifier.getId())) {
setOfIdentifiedObjects.add(content);
}
}
}
this.extractMeaningfulElements(setOfIdentifiedObjects);
// Add the sets to the blackboard and return
blackboardFactory.setRdias(this.rdiaSet);
blackboardFactory.setBranches(this.seffBranchSet);
blackboardFactory.setLoops(this.seffLoopSet);
blackboardFactory.setExternalCalls(this.externalCallParameterSet);
blackboardFactory.setPcmMappings(pcmMappings);
}
/**
* Finds all PCM elements that are meaningful to Beagle in the provided set of
* {@code contentObjects}. Populates {@link #rdiaSet}, {@link #seffBranchSet},
* {@link #seffLoopSet} and {@link #externalCallParameterSet}.
*
* @param contentObjects The objects to check for meanigfulness.
*/
private void extractMeaningfulElements(final Set<EObject> contentObjects) {
for (final EObject object : contentObjects) {
if (object.getClass() == BasicComponentImpl.class) {
this.extractBasicComponentAndAddContentsToSet((BasicComponentImpl) object);
} else if (object.getClass() == ResourceDemandingSEFFImpl.class) {
this.extractResourceDemandingSEFFImplAndAddContentsToSet((ResourceDemandingSEFFImpl) object);
} else if (object instanceof AbstractBranchTransition) {
final EList<EObject> specificBranchContentList = object.eContents();
for (final EObject specificBranchContent : specificBranchContentList) {
if (specificBranchContent.getClass() == ResourceDemandingBehaviourImpl.class) {
for (final EObject stepBehaviour : ((ResourceDemandingBehaviourImpl) specificBranchContent)
.eContents()) {
this.pcmSeffExtractor.extractBehaviourAndAddToSet(stepBehaviour);
}
}
}
} else {
this.pcmSeffExtractor.extractBehaviourAndAddToSet(object);
}
}
}
/**
* This method takes the whole {@link PcmRepositoryBlackboardFactoryAdder#repository}
* and extracts all needed content into the storing sets.
*
* @param repositoryToScan The repository to read from.
*/
private void scanRepository(final RepositoryImpl repositoryToScan) {
final EList<RepositoryComponent> componentList = repositoryToScan.getComponents__Repository();
for (final RepositoryComponent component : componentList) {
if (component.getClass() == BasicComponentImpl.class) {
this.extractBasicComponentAndAddContentsToSet((BasicComponentImpl) component);
}
}
}
/**
* BasicComponent extracting method. Looking for all included SEFFs. Recursive calls
* to methods that save all needed SEFF-elements into the sets.
*
* @param basicComponent Component of the Repository.
*/
private void extractBasicComponentAndAddContentsToSet(final BasicComponentImpl basicComponent) {
final EList<ServiceEffectSpecification> seffList =
basicComponent.getServiceEffectSpecifications__BasicComponent();
for (final ServiceEffectSpecification seff : seffList) {
if (seff.getClass() == ResourceDemandingSEFFImpl.class) {
this.extractResourceDemandingSEFFImplAndAddContentsToSet((ResourceDemandingSEFFImpl) seff);
}
}
}
/**
* ResourceDemandingSEFF extracting method. Looking for all including Contents.
* Recursive calls to methods that save all needed SEFF-elements into the sets.
*
* @param rdSeff rdSeff of the Repository.
*/
private void extractResourceDemandingSEFFImplAndAddContentsToSet(final ResourceDemandingSEFFImpl rdSeff) {
final EList<EObject> rdSeffContentList = rdSeff.eContents();
for (final EObject rdSeffContent : rdSeffContentList) {
this.pcmSeffExtractor.extractBehaviourAndAddToSet(rdSeffContent);
}
}
}