/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
package com.nokia.sdt.emf.dm.impl;
import com.nokia.sdt.component.property.IPropertyInformation;
import com.nokia.sdt.datamodel.IDesignerDataModel;
import com.nokia.sdt.datamodel.util.ModelUtils;
import com.nokia.sdt.emf.dm.*;
import com.nokia.cpp.internal.api.utils.core.Check;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.NotificationImpl;
import org.eclipse.emf.common.util.EList;
import org.eclipse.ui.views.properties.IPropertySource;
import java.util.Iterator;
public class NodeCopier {
public interface IFilter {
/**
* @param node
* @return true if should be copied
*/
boolean test(INode node);
}
private INode theCopy;
private IDesignerData localModelRoot;
public NodeCopier(IDesignerData modelRoot, INode srcNode, boolean preserveLocalizedStringKeys, IFilter filter) {
init(modelRoot, srcNode, preserveLocalizedStringKeys, false, filter);
}
public NodeCopier(IDesignerData modelRoot, INode srcNode, boolean preserveLocalizedStringKeys) {
init(modelRoot, srcNode, preserveLocalizedStringKeys, false, null);
}
public NodeCopier(INode srcNode, boolean preserveEventBindings, IFilter filter) {
// set up a simple temporary model with a simple root object
// to hold the value we're copying
IDesignerData modelRoot = DmFactory.eINSTANCE.createIDesignerData();
// make a dummy root node, because our copy routine needs a parent
INode rootNode = DmFactory.eINSTANCE.createINode();
modelRoot.getRootContainers().add(rootNode);
init(modelRoot, srcNode, true, preserveEventBindings, filter);
}
public NodeCopier(INode srcNode, IFilter filter) {
this(srcNode, false, filter);
}
public NodeCopier(INode srcNode) {
this(srcNode, null);
}
private void init(IDesignerData modelRoot, INode srcNode,
boolean preserveLocalizedStringKeys, boolean preserveEventBindings, IFilter filter) {
Check.checkArg(modelRoot);
Check.checkArg(srcNode);
// need it to be in a model so we can get localized strings
Check.checkArg(srcNode.getDesignerData() != null);
localModelRoot = modelRoot;
Check.checkState(!localModelRoot.getRootContainers().isEmpty());
INode rootNode = (INode) localModelRoot.getRootContainers().get(0);
theCopy = copyNodeToEnd(srcNode, rootNode,
preserveLocalizedStringKeys, preserveEventBindings, filter);
}
IDesignerData getRoot() {
return localModelRoot;
}
public INode getCopy() {
return theCopy;
}
private static INode copyNodeToEnd(INode srcNode, INode destParent,
boolean preserveLocalizedStringKeys, boolean preserveEventBindings, IFilter filter) {
return copyNode(srcNode, destParent, IDesignerDataModel.AT_END,
preserveLocalizedStringKeys, preserveEventBindings, filter);
}
public static INode copyNode(INode srcNode, INode destParent, int index,
boolean preserveLocalizedStringKeys) {
return copyNode(srcNode, destParent, index, preserveLocalizedStringKeys, false);
}
public static INode copyNode(INode srcNode, INode destParent, int index,
boolean preserveLocalizedStringKeys, boolean preserveEventBindings) {
return copyNode(srcNode, destParent, index,
preserveLocalizedStringKeys, preserveEventBindings, null);
}
public static INode copyNode(INode srcNode, INode destParent, int index,
boolean preserveLocalizedStringKeys, IFilter filter) {
return copyNode(srcNode, destParent, index, preserveLocalizedStringKeys, false, filter);
}
public static INode copyNode(INode srcNode, INode destParent, int index,
boolean preserveLocalizedStringKeys, boolean preserveEventBindings, IFilter filter) {
// If a filter exists, ensure the srcNode passes the test
if ((filter != null) && !filter.test(srcNode))
return null;
INode result = DmFactory.eINSTANCE.createINode();
// Set the configured flag so initializers can
// distinguish between brand new and already configured objects
result.setConfigured(true);
// First, set the component id, so parenting doesn't fail
result.setComponentId(srcNode.getComponentId());
// The new node should be parented before copying properties
// so the string tables can be found
EList children = destParent.getChildren();
// turn off notifications until copy is complete
boolean saveDeliver = destParent.eDeliver();
destParent.eSetDeliver(false);
if (index == IDesignerDataModel.AT_END)
children.add(result);
else
children.add(index, result);
// if the new node could not be parented, we should abort everything else
if (!children.contains(result))
return null;
new PropertyContainerCopier(
srcNode.getProperties(), result.getProperties(), false, preserveLocalizedStringKeys);
// refresh the properties of the result, in case of promoted properties
IPropertySource propertySource = ModelUtils.getPropertySource(result);
if (propertySource instanceof IPropertyInformation)
((IPropertyInformation) propertySource).refresh();
// copy the event bindings
if (preserveEventBindings) {
for (Object object : srcNode.getEventBindings()) {
IEventBinding binding = (IEventBinding) object;
IEventBinding copy = DmFactory.eINSTANCE.createIEventBinding();
copy.setEventID(binding.getEventID());
copy.setEventHandlerDisplayText(binding.getEventHandlerDisplayText());
copy.setEventHandlerInfo(binding.getEventHandlerInfo());
result.getEventBindings().add(copy);
}
}
for (Iterator iter = srcNode.getChildren().iterator(); iter.hasNext();) {
INode srcChild = (INode) iter.next();
copyNodeToEnd(srcChild, result, preserveLocalizedStringKeys, preserveEventBindings, filter);
}
// reset notifications and fire child added
destParent.eSetDeliver(saveDeliver);
if (children instanceof ValidatingEObjectContainmentEList) {
ValidatingEObjectContainmentEList list = (ValidatingEObjectContainmentEList) children;
NotificationImpl notification = list.createNotification(Notification.ADD, null, result, index, false);
list.dispatchNotification(notification);
}
return result;
}
}