/*******************************************************************************
* Copyright © 2012, 2013 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*
*******************************************************************************/
package org.eclipse.edt.mof.egl.utils;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.edt.mof.egl.Expression;
import org.eclipse.edt.mof.impl.EObjectImpl;
import org.eclipse.edt.mof.impl.Slot;
import org.eclipse.edt.mof.utils.EList;
public class ExpressionCloner {
private Map<Object, Object> alreadyCloned = new HashMap<Object, Object>();
public static Expression clone(Expression expr) {
return new ExpressionCloner().primClone(expr);
}
private Expression primClone(Expression expr) {
if (expr == null) {
return null;
}
if (!(expr instanceof EObjectImpl)) {
return expr;
}
EObjectImpl newExpr = (EObjectImpl)expr.getEClass().newInstance();
Slot[] slots = ((EObjectImpl)expr).getSlots();
for (int i = 0; i < slots.length && i < newExpr.getSlots().length; i++) {
if(slots[i] != null) {
if (newExpr.getSlots()[i] == null) {
newExpr.getSlots()[i] = new Slot();
}
Object value = slots[i].get();
Object newValue = cloneIfNeeded(value);
newExpr.getSlots()[i].set(newValue);
}
}
return (Expression)newExpr;
}
private Object cloneIfNeeded(Object value) {
if (value == null) {
return null;
}
Object newValue = alreadyCloned.get(value);
if (newValue == null) {
if (value instanceof Expression) {
newValue = primClone((Expression)value);
}
else if (value instanceof EList) {
newValue = cloneList((EList)value);
}
else {
newValue = value;
}
alreadyCloned.put(value, newValue);
}
return newValue;
}
private EList cloneList(EList list) {
EList newList = new EList();
for (Object obj : list) {
newList.add(cloneIfNeeded(obj));
}
return newList;
}
}