blob: 9dd0a8777fff71414c23ce0dff8d74ed931bfd48 [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;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.ocl.ecore.OCLExpression;
import org.eclipse.ocl.ecore.opposites.OppositeEndFinder;
import org.eclipse.ocl.examples.impactanalyzer.util.AnnotatedEObject;
import org.eclipse.ocl.examples.impactanalyzer.util.SemanticIdentity;
public class OppositePropertyNavigationStep extends AbstractNavigationStep {
private final EStructuralFeature property;
private final OppositeEndFinder oppositeEndFinder;
private final SemanticIdentity semanticIdentity;
public OppositePropertyNavigationStep(EClass sourceType, EClass targetType, EStructuralFeature property,
OCLExpression debugInfo, OppositeEndFinder oppositeEndFinder) {
super(sourceType, targetType, debugInfo);
this.property = property;
this.oppositeEndFinder = oppositeEndFinder;
this.semanticIdentity = new OppositePropertyNavigationStepIdentity();
}
private class OppositePropertyNavigationStepIdentity extends SemanticIdentity {
public OppositePropertyNavigationStep getNavigationStep() {
return OppositePropertyNavigationStep.this;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || hashCode() != o.hashCode()) {
return false;
}
return getSemanticIdentityOfSuper().equals(o)
&& property.equals(((OppositePropertyNavigationStepIdentity) o).getNavigationStep().property);
}
@Override
public int calculateHashCode() {
return getSemanticIdentityOfSuper().hashCode() ^ property.hashCode();
}
@Override
public NavigationStep getStep() {
return getNavigationStep();
}
}
public SemanticIdentity getSemanticIdentityOfSuper() {
return super.getSemanticIdentity();
}
@Override
protected Set<AnnotatedEObject> navigate(AnnotatedEObject fromObject, TracebackCache cache,
Notification changeEvent) {
Collection<EObject> result = new HashSet<EObject>();
Set<AnnotatedEObject> returnValue = new HashSet<AnnotatedEObject>();
if (property instanceof EReference) {
// EcoreHelper.getInstance().reverseNavigate(fromObject.getAnnotatedObject(),
// (EReference) property, scope, result);
Object navigationResult = oppositeEndFinder.navigateOppositePropertyWithBackwardScope((EReference) property,
fromObject.getAnnotatedObject());
if (navigationResult instanceof Collection<?>) {
@SuppressWarnings("unchecked")
Collection<? extends EObject> eObjectCollectionNavigationResult = (Collection<? extends EObject>) navigationResult;
result.addAll(eObjectCollectionNavigationResult);
} else {
if (navigationResult != null) {
result.add((EObject) navigationResult);
}
}
}
for (EObject o : result) {
returnValue.add(annotateEObject(fromObject, o));
}
return returnValue;
}
@Override
public String contentToString(Map<NavigationStep, Integer> visited, int indent) {
return "opposite of "+property.getName();
}
@Override
public SemanticIdentity getSemanticIdentity() {
return semanticIdentity;
}
}