1 | /** |
2 | * |
3 | */ |
4 | package de.fzi.se.accuracy.jobs; |
5 | |
6 | import java.util.ArrayList; |
7 | import java.util.List; |
8 | |
9 | import org.apache.log4j.Logger; |
10 | import org.eclipse.core.runtime.IProgressMonitor; |
11 | |
12 | import de.fzi.se.accuracy.transformation.AbstractAccuracyInfluenceSEFFTransformationStrategy; |
13 | import de.fzi.se.accuracy.transformation.AccuracyInfluenceSEFFTransformationStrategyAsSpecified; |
14 | import de.fzi.se.accuracy.transformation.AccuracyInfluenceSEFFTransformationStrategyMaximum; |
15 | import de.fzi.se.accuracy.transformation.AccuracyInfluenceSEFFTransformationStrategyMinimum; |
16 | import de.uka.ipd.sdq.pcm.allocation.Allocation; |
17 | import de.uka.ipd.sdq.pcm.allocation.AllocationContext; |
18 | import de.uka.ipd.sdq.pcm.core.composition.AssemblyContext; |
19 | import de.uka.ipd.sdq.pcm.core.composition.ComposedStructure; |
20 | import de.uka.ipd.sdq.pcm.repository.BasicComponent; |
21 | import de.uka.ipd.sdq.pcm.repository.RepositoryComponent; |
22 | import de.uka.ipd.sdq.pcm.seff.ServiceEffectSpecification; |
23 | import de.uka.ipd.sdq.workflow.IBlackboardInteractingJob; |
24 | import de.uka.ipd.sdq.workflow.OrderPreservingBlackboardCompositeJob; |
25 | import de.uka.ipd.sdq.workflow.exceptions.JobFailedException; |
26 | import de.uka.ipd.sdq.workflow.exceptions.UserCanceledException; |
27 | import de.uka.ipd.sdq.workflow.mdsd.blackboard.MDSDBlackboard; |
28 | import de.uka.ipd.sdq.workflow.pcm.blackboard.PCMResourceSetPartition; |
29 | import de.uka.ipd.sdq.workflow.pcm.configurations.AbstractPCMWorkflowRunConfiguration; |
30 | import de.uka.ipd.sdq.workflow.pcm.jobs.LoadPCMModelsIntoBlackboardJob; |
31 | |
32 | /**Job executing transformations of PCM models for the accuracy analysis. |
33 | * As it modifies the PCM models, it should only be invoked after a working copy of the models is created. |
34 | * @author groenda |
35 | * |
36 | */ |
37 | public class TransformPCMForAccuracyInfluenceAnalysisJob extends OrderPreservingBlackboardCompositeJob<MDSDBlackboard> implements |
38 | IBlackboardInteractingJob<MDSDBlackboard> { |
39 | |
40 | /** Logger for this class. */ |
41 | private static final Logger logger = Logger.getLogger(TransformPCMForAccuracyInfluenceAnalysisJob.class); |
42 | |
43 | /** Workflow configuration used by this job.*/ |
44 | private AbstractPCMWorkflowRunConfiguration configuration; |
45 | |
46 | public TransformPCMForAccuracyInfluenceAnalysisJob(AbstractPCMWorkflowRunConfiguration configuration) { |
47 | super(); |
48 | this.configuration = configuration; |
49 | } |
50 | |
51 | @Override |
52 | public void execute(IProgressMonitor monitor) throws JobFailedException, |
53 | UserCanceledException { |
54 | if (!configuration.isAccuracyInfluenceAnalysisEnabled()) { |
55 | throw new IllegalArgumentException("The transformation job on PCM models for the accuracy analysis may only be run if the accuracy influence analysis is enabled."); |
56 | } |
57 | PCMResourceSetPartition pcmPartition = (PCMResourceSetPartition) this |
58 | .getBlackboard().getPartition( |
59 | LoadPCMModelsIntoBlackboardJob.PCM_MODELS_PARTITION_ID); |
60 | // discover all SEFFs potentially used in the system |
61 | Allocation allocation = pcmPartition.getAllocation(); |
62 | List<ServiceEffectSpecification> allocatedSEFFs = new ArrayList<ServiceEffectSpecification>(); |
63 | for (AllocationContext allocationContext: allocation.getAllocationContexts_Allocation()) { |
64 | AssemblyContext outmostAssemblyContext = allocationContext.getAssemblyContext_AllocationContext(); |
65 | List<ServiceEffectSpecification> assembledSEFFs = discoverSEFFs(outmostAssemblyContext); |
66 | addElementsToList(allocatedSEFFs, assembledSEFFs); |
67 | } |
68 | |
69 | // modify SEFFs according to AccuracyInfluenceAnalysisState |
70 | AbstractAccuracyInfluenceSEFFTransformationStrategy accuracyInfluenceSEFFtransformator; |
71 | switch (configuration.getAccuracyInfluenceAnalysisState()) { |
72 | case MINIMUM: |
73 | accuracyInfluenceSEFFtransformator = new AccuracyInfluenceSEFFTransformationStrategyMinimum(pcmPartition); |
74 | break; |
75 | case AS_SPECIFIED: |
76 | accuracyInfluenceSEFFtransformator = new AccuracyInfluenceSEFFTransformationStrategyAsSpecified(pcmPartition); |
77 | break; |
78 | case MAXIMUM: |
79 | accuracyInfluenceSEFFtransformator = new AccuracyInfluenceSEFFTransformationStrategyMaximum(pcmPartition); |
80 | break; |
81 | default: |
82 | String msg = "The handling of the accuracy influence strategy " |
83 | + configuration.getAccuracyInformationModelFile() |
84 | + " provided in the configuration is not implemented."; |
85 | logger.fatal(msg); |
86 | throw new IllegalArgumentException(msg); |
87 | } |
88 | for (ServiceEffectSpecification seff : allocatedSEFFs) { |
89 | accuracyInfluenceSEFFtransformator.doSwitch(seff); |
90 | } |
91 | if (configuration.getAccuracyInfluenceIssueReceivingJob() == null) { |
92 | logger.warn("No job was specified to receive issues occured during accuracy influence analysis. There will be no notifications about warnings or errors."); |
93 | } else { |
94 | configuration.getAccuracyInfluenceIssueReceivingJob().addIssues(accuracyInfluenceSEFFtransformator.getIssues()); |
95 | } |
96 | |
97 | } |
98 | |
99 | /**Discovers all SEFFs which are used in an assembly context. |
100 | * @param outmostAssemblyContext |
101 | * @return List of discovered SEFFs. |
102 | */ |
103 | private List<ServiceEffectSpecification> discoverSEFFs( |
104 | AssemblyContext assemblyContext) { |
105 | // see Validation.emf::FromAllocationToSEFF for a graphical overview of the used nodes and references |
106 | List<ServiceEffectSpecification> composedSEFFs = new ArrayList<ServiceEffectSpecification>(); |
107 | RepositoryComponent repositoryComponent = assemblyContext.getEncapsulatedComponent__AssemblyContext(); |
108 | if (repositoryComponent instanceof ComposedStructure) { |
109 | ComposedStructure composedStructure = (ComposedStructure) repositoryComponent; |
110 | for (AssemblyContext composedComponentsContext: composedStructure.getAssemblyContexts__ComposedStructure()) { |
111 | List<ServiceEffectSpecification> assembledSEFFs = discoverSEFFs(composedComponentsContext); |
112 | addElementsToList(composedSEFFs, assembledSEFFs); |
113 | } |
114 | } else if (repositoryComponent instanceof BasicComponent) { |
115 | BasicComponent basicComponent = (BasicComponent) repositoryComponent; |
116 | addElementsToList(composedSEFFs, basicComponent.getServiceEffectSpecifications__BasicComponent()); |
117 | } else { |
118 | logger.warn("Could not process the provided repository component " + repositoryComponent.getEntityName() + " with id " + repositoryComponent.getId() + ". The component type is not supported by the implementation."); |
119 | } |
120 | return composedSEFFs; |
121 | } |
122 | |
123 | /**Adds a list of SEFFs to another list. |
124 | * Existing SEFFs are not added twice to the list. |
125 | * @param target The list which will receive the SEFFs of source. |
126 | * @param source The SEFFs to add. |
127 | */ |
128 | public static <T> void addElementsToList(List<T> target, final List<T> source) { |
129 | for (T t : source) { |
130 | if (!target.contains(t)) { |
131 | //TODO: Check if comparison works. Should do the job as only obj == obj2 should be excluded from the list |
132 | target.add(t); |
133 | } |
134 | } |
135 | } |
136 | } |