org.eclipse.xtext.util.EmfStructureComparator Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2008 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
*******************************************************************************/
package org.eclipse.xtext.util;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
/**
* @author Jan K?hnlein - Initial contribution and API
*
*/
public class EmfStructureComparator {
protected static final Logger log = Logger.getLogger(EmfStructureComparator.class);
private int counter;
private StringBuilder errorMessage = new StringBuilder(512);
public void assertSameStructure(EObject left, EObject right) {
if(!isSameStructure(left, right)) {
log.error(getErrorMessage());
throw new AssertionError(getErrorMessage());
}
if (log.isTraceEnabled())
log.trace("" + counter + " elements compared");
}
protected String getErrorMessage() {
return errorMessage.toString();
}
public boolean isSameStructure(EObject left, EObject right) {
counter = 0;
return internalIsSameStructure(left, right);
}
public boolean internalIsSameStructure(EObject left, EObject right) {
++counter;
if (left == null) {
errorMessage.append("left hand side was null").append('\n');
return false;
}
if (right == null) {
errorMessage.append("right hand side was null.").append('\n');
return false;
}
if (!isSameClass(left.eClass(), right.eClass())) {
errorMessage.append("Classes are not equal: " + left + " != " + right).append('\n');
return false;
}
List leftChildren = getRelevantChildren(left);
List rightChildren = getRelevantChildren(right);
if(leftChildren.size() != rightChildren.size()) {
errorMessage.append("Number of children differs " + left + " " + right + " " + leftChildren.size() + " <> " + rightChildren.size()).append('\n');
return false;
}
for (int i = 0; i < leftChildren.size(); ++i) {
if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get(i))) {
errorMessage.append("Children differ " + left + " " + right + " with children " + leftChildren.get(i) + " " + rightChildren.get(i)).append('\n');
return false;
}
}
return true;
}
protected boolean isSameClass(EClass left, EClass right) {
return left.getName().equals(right.getName())
&& left.getEPackage().getNsURI().equals(right.getEPackage().getNsURI());
}
protected List getRelevantChildren(EObject _this) {
List relevantChildren = new ArrayList(_this.eContents());
for (Iterator i = relevantChildren.iterator(); i.hasNext();) {
EObject next = i.next();
if (!isRelevantChild(_this, next)) {
i.remove();
}
}
return relevantChildren;
}
protected boolean isRelevantChild(EObject container, EObject child) {
return true;
}
}