blob: 00b5f5172f0ed9746816ef1c53e501b89f6a4b7e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2018 SAP AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* SAP AG - initial API and implementation
******************************************************************************/
package org.eclipse.ocl.examples.impactanalyzer.instanceScope.traceback;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.ocl.ecore.OCLExpression;
import org.eclipse.ocl.ecore.OppositePropertyCallExp;
import org.eclipse.ocl.examples.impactanalyzer.impl.OperationBodyToCallMapper;
import org.eclipse.ocl.examples.impactanalyzer.instanceScope.unusedEvaluation.UnusedEvaluationRequestFactory;
import org.eclipse.ocl.examples.impactanalyzer.instanceScope.unusedEvaluation.UnusedEvaluationRequestSet;
import org.eclipse.ocl.examples.impactanalyzer.util.AnnotatedEObject;
import org.eclipse.ocl.examples.impactanalyzer.util.OCLFactory;
import org.eclipse.ocl.examples.impactanalyzer.util.OperationCallExpKeyedSet;
public class OppositePropertyCallTracebackStep extends AbstractTracebackStep<OppositePropertyCallExp> implements TracebackStep {
private final TracebackStepAndScopeChange nextStep;
private final boolean isMany;
private final EReference reference;
public OppositePropertyCallTracebackStep(OppositePropertyCallExp sourceExpression, EClass context,
OperationBodyToCallMapper operationBodyToCallMapper, Stack<String> tupleLiteralNamesToLookFor,
TracebackStepCache tracebackStepCache, UnusedEvaluationRequestFactory unusedEvaluationRequestFactory, OCLFactory oclFactory) {
super(sourceExpression, tupleLiteralNamesToLookFor, tracebackStepCache.getOppositeEndFinder(), operationBodyToCallMapper, unusedEvaluationRequestFactory, oclFactory);
OCLExpression source = (OCLExpression) sourceExpression.getSource();
reference = (EReference) sourceExpression.getReferredOppositeProperty();
nextStep = createTracebackStepAndScopeChange(sourceExpression, source, context, operationBodyToCallMapper,
tupleLiteralNamesToLookFor, tracebackStepCache);
isMany = sourceExpression.getReferredOppositeProperty().isMany();
}
@Override
protected OperationCallExpKeyedSet performSubsequentTraceback(AnnotatedEObject source,
UnusedEvaluationRequestSet pendingUnusedEvalRequests, org.eclipse.ocl.examples.impactanalyzer.instanceScope.traceback.TracebackCache tracebackCache, Notification changeEvent) {
OperationCallExpKeyedSet result;
List<OperationCallExpKeyedSet> resultList = new LinkedList<OperationCallExpKeyedSet>();
Object o = source.eGet(reference);
if (isMany) {
if (o instanceof EList<?>) {
@SuppressWarnings("unchecked")
EList<EObject> refObjects = (EList<EObject>) o;
for (EObject obj : refObjects) {
resultList.add(nextStep.traceback(annotateEObject(source, obj), pendingUnusedEvalRequests, tracebackCache, changeEvent));
}
result = tracebackCache.getOperationCallExpKeyedSetFactory().createOperationCallExpKeyedSet(resultList);
} else {
result = tracebackCache.getOperationCallExpKeyedSetFactory().emptySet();
}
} else {
AnnotatedEObject oSingle = annotateEObject(source, (EObject) source.eGet(reference));
if (oSingle != null) {
result = nextStep.traceback(oSingle, pendingUnusedEvalRequests, tracebackCache, changeEvent);
} else {
result = tracebackCache.getOperationCallExpKeyedSetFactory().emptySet();
}
}
return result;
}
}