/**
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sdo.impl;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.tuscany.sdo.SDOFactory;
import org.apache.tuscany.sdo.SDOPackage;
import org.apache.tuscany.sdo.util.BasicSequence;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.UniqueEList;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.change.ChangeDescription;
import org.eclipse.emf.ecore.change.FeatureChange;
import org.eclipse.emf.ecore.change.impl.ChangeDescriptionImpl;
import org.eclipse.emf.ecore.change.util.ChangeRecorder;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.util.BasicExtendedMetaData;
import org.eclipse.emf.ecore.util.DelegatingFeatureMap;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.FeatureMapUtil;
import org.eclipse.emf.ecore.util.InternalEList;
import commonj.sdo.ChangeSummary;
//import commonj.sdo.ChangeSummary.Setting;
import commonj.sdo.DataGraph;
import commonj.sdo.DataObject;
import commonj.sdo.Property;
import commonj.sdo.Sequence;
/**
*
* An implementation of the model object 'EChange Summary'.
*
*
* The following features are implemented:
*
* - {@link org.apache.tuscany.sdo.impl.ChangeSummaryImpl#getEDataGraph EData Graph}
*
*
*
* @generated
*/
public class ChangeSummaryImpl extends ChangeDescriptionImpl implements ChangeSummary
{
/**
* The cached value of the '{@link #getEDataGraph() EData Graph}' reference.
*
*
* @see #getEDataGraph()
* @generated
* @ordered
*/
protected DataGraph eDataGraph = null;
protected ChangeRecorder changeRecorder = null;
protected EList cachedObjectsToDetach = null;
protected HashMap cachedSDOObjectChanges = new HashMap();
/**
*
*
* @generated
*/
protected ChangeSummaryImpl()
{
super();
}
/**
*
*
* @generated
*/
protected EClass eStaticClass()
{
return SDOPackage.eINSTANCE.getChangeSummary();
}
/**
*
*
* @generated NOT
*/
public boolean isLogging()
{
return changeRecorder != null;
}
/**
*
*
* @generated
*/
public DataGraph getEDataGraph()
{
return eDataGraph;
}
/**
*
*
* @generated
*/
public NotificationChain basicSetEDataGraph(DataGraph newEDataGraph, NotificationChain msgs)
{
DataGraph oldEDataGraph = eDataGraph;
eDataGraph = newEDataGraph;
if (eNotificationRequired())
{
ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, SDOPackage.CHANGE_SUMMARY__EDATA_GRAPH, oldEDataGraph, newEDataGraph);
if (msgs == null) msgs = notification; else msgs.add(notification);
}
return msgs;
}
/**
*
*
* @generated
*/
public void setEDataGraph(DataGraph newEDataGraph)
{
if (newEDataGraph != eDataGraph)
{
NotificationChain msgs = null;
if (eDataGraph != null)
msgs = ((InternalEObject)eDataGraph).eInverseRemove(this, SDOPackage.DATA_GRAPH__ECHANGE_SUMMARY, DataGraph.class, msgs);
if (newEDataGraph != null)
msgs = ((InternalEObject)newEDataGraph).eInverseAdd(this, SDOPackage.DATA_GRAPH__ECHANGE_SUMMARY, DataGraph.class, msgs);
msgs = basicSetEDataGraph(newEDataGraph, msgs);
if (msgs != null) msgs.dispatch();
}
else if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, SDOPackage.CHANGE_SUMMARY__EDATA_GRAPH, newEDataGraph, newEDataGraph));
}
/**
*
*
* @generated NOT
*/
public void beginLogging()
{
if (isLogging())
{
throw new IllegalStateException("Already logging");
}
getObjectsToAttach().clear();
getObjectChanges().clear();
getResourceChanges().clear();
oldContainmentInformation = null;
changeRecorder = new SDOChangeRecorder();
changeRecorder.beginRecording(Collections.singleton(((DataGraphImpl)getEDataGraph()).getRootResource()));
// if (eNotificationRequired())
// eNotify(new ENotificationImpl(this, Notification.SET, SDOPackage.ECHANGE_SUMMARY__LOGGING, false, true));
}
/**
*
*
* @generated NOT
*/
public void resumeLogging()
{
if (isLogging())
{
throw new IllegalStateException("Already logging");
}
oldContainmentInformation = null;
changeRecorder = new SDOChangeRecorder();
changeRecorder.beginRecording(this, Collections.singleton(((DataGraphImpl)getEDataGraph()).getRootResource()));
// if (eNotificationRequired())
// eNotify(new ENotificationImpl(this, Notification.SET, SDOPackage.ECHANGE_SUMMARY__LOGGING, false, true));
}
/**
*
*
* @generated
*/
public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, Class baseClass, NotificationChain msgs)
{
if (featureID >= 0)
{
switch (eDerivedStructuralFeatureID(featureID, baseClass))
{
case SDOPackage.CHANGE_SUMMARY__EDATA_GRAPH:
if (eDataGraph != null)
msgs = ((InternalEObject)eDataGraph).eInverseRemove(this, SDOPackage.DATA_GRAPH__ECHANGE_SUMMARY, DataGraph.class, msgs);
return basicSetEDataGraph((DataGraph)otherEnd, msgs);
default:
return eDynamicInverseAdd(otherEnd, featureID, baseClass, msgs);
}
}
if (eInternalContainer() != null)
msgs = eBasicRemoveFromContainer(msgs);
return eBasicSetContainer(otherEnd, featureID, msgs);
}
/**
*
*
* @generated
*/
public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, Class baseClass, NotificationChain msgs)
{
if (featureID >= 0)
{
switch (eDerivedStructuralFeatureID(featureID, baseClass))
{
case SDOPackage.CHANGE_SUMMARY__OBJECT_CHANGES:
return ((InternalEList)getObjectChanges()).basicRemove(otherEnd, msgs);
case SDOPackage.CHANGE_SUMMARY__OBJECTS_TO_ATTACH:
return ((InternalEList)getObjectsToAttach()).basicRemove(otherEnd, msgs);
case SDOPackage.CHANGE_SUMMARY__RESOURCE_CHANGES:
return ((InternalEList)getResourceChanges()).basicRemove(otherEnd, msgs);
case SDOPackage.CHANGE_SUMMARY__EDATA_GRAPH:
return basicSetEDataGraph(null, msgs);
default:
return eDynamicInverseRemove(otherEnd, featureID, baseClass, msgs);
}
}
return eBasicSetContainer(null, featureID, msgs);
}
/**
*
*
* @generated
*/
public Object eGet(int featureID, boolean resolve, boolean coreType)
{
switch (featureID)
{
case SDOPackage.CHANGE_SUMMARY__OBJECT_CHANGES:
if (coreType) return getObjectChanges();
else return getObjectChanges().map();
case SDOPackage.CHANGE_SUMMARY__OBJECTS_TO_DETACH:
return getObjectsToDetach();
case SDOPackage.CHANGE_SUMMARY__OBJECTS_TO_ATTACH:
return getObjectsToAttach();
case SDOPackage.CHANGE_SUMMARY__RESOURCE_CHANGES:
return getResourceChanges();
case SDOPackage.CHANGE_SUMMARY__EDATA_GRAPH:
return getEDataGraph();
}
return eDynamicGet(featureID, resolve, coreType);
}
/**
*
*
* @generated
*/
public void eSet(int featureID, Object newValue)
{
switch (featureID)
{
case SDOPackage.CHANGE_SUMMARY__OBJECT_CHANGES:
((EStructuralFeature.Setting)getObjectChanges()).set(newValue);
return;
case SDOPackage.CHANGE_SUMMARY__OBJECTS_TO_DETACH:
getObjectsToDetach().clear();
getObjectsToDetach().addAll((Collection)newValue);
return;
case SDOPackage.CHANGE_SUMMARY__OBJECTS_TO_ATTACH:
getObjectsToAttach().clear();
getObjectsToAttach().addAll((Collection)newValue);
return;
case SDOPackage.CHANGE_SUMMARY__RESOURCE_CHANGES:
getResourceChanges().clear();
getResourceChanges().addAll((Collection)newValue);
return;
case SDOPackage.CHANGE_SUMMARY__EDATA_GRAPH:
setEDataGraph((DataGraph)newValue);
return;
}
eDynamicSet(featureID, newValue);
}
/**
*
*
* @generated
*/
public void eUnset(int featureID)
{
switch (featureID)
{
case SDOPackage.CHANGE_SUMMARY__OBJECT_CHANGES:
getObjectChanges().clear();
return;
case SDOPackage.CHANGE_SUMMARY__OBJECTS_TO_DETACH:
getObjectsToDetach().clear();
return;
case SDOPackage.CHANGE_SUMMARY__OBJECTS_TO_ATTACH:
getObjectsToAttach().clear();
return;
case SDOPackage.CHANGE_SUMMARY__RESOURCE_CHANGES:
getResourceChanges().clear();
return;
case SDOPackage.CHANGE_SUMMARY__EDATA_GRAPH:
setEDataGraph((DataGraph)null);
return;
}
eDynamicUnset(featureID);
}
/**
*
*
* @generated
*/
public boolean eIsSet(int featureID)
{
switch (featureID)
{
case SDOPackage.CHANGE_SUMMARY__OBJECT_CHANGES:
return objectChanges != null && !objectChanges.isEmpty();
case SDOPackage.CHANGE_SUMMARY__OBJECTS_TO_DETACH:
return objectsToDetach != null && !objectsToDetach.isEmpty();
case SDOPackage.CHANGE_SUMMARY__OBJECTS_TO_ATTACH:
return objectsToAttach != null && !objectsToAttach.isEmpty();
case SDOPackage.CHANGE_SUMMARY__RESOURCE_CHANGES:
return resourceChanges != null && !resourceChanges.isEmpty();
case SDOPackage.CHANGE_SUMMARY__EDATA_GRAPH:
return eDataGraph != null;
}
return eDynamicIsSet(featureID);
}
protected class SDOChangeRecorder extends ChangeRecorder
{
public SDOChangeRecorder()
{
super();
}
public void beginRecording(ChangeDescription changeDescription, Collection rootObjects)
{
deletedObjects = null;
cachedObjectsToDetach = null;
cachedSDOObjectChanges.clear();
super.beginRecording(changeDescription, rootObjects);
}
protected ChangeDescription createChangeDescription()
{
return ChangeSummaryImpl.this;
}
protected FeatureChange createFeatureChange(EObject eObject, EStructuralFeature eStructuralFeature, Object value, boolean isSet)
{
Property property = (Property)eStructuralFeature;
if (property.isReadOnly())
{
if (((DataObject)eObject).getDataGraph() != null)
{
throw
new IllegalStateException
("The property '" + property.getName() + "' of type '" +
property.getContainingType().getName() + "' is read only");
}
}
return (FeatureChange)SDOFactory.eINSTANCE.createChangeSummarySetting(eStructuralFeature, value, isSet);
}
protected void consolidateChanges()
{
deletedObjects = null;
cachedObjectsToDetach = null;
cachedSDOObjectChanges.clear();
super.consolidateChanges();
}
protected void addAdapter(Notifier notifier)
{
if (notifier instanceof DataObjectImpl)
((DataObjectImpl)notifier).setChangeRecorder(this);
else
super.addAdapter(notifier);
}
protected void removeAdapter(Notifier notifier)
{
if (notifier instanceof DataObjectImpl)
((DataObjectImpl)notifier).setChangeRecorder(null);
else
super.removeAdapter(notifier);
}
}
/**
*
*
* @generated NOT
*/
public void endLogging()
{
if (!isLogging())
{
throw new IllegalStateException("Not currently logging");
}
changeRecorder.endRecording();
changeRecorder.dispose();
changeRecorder = null;
// if (eNotificationRequired())
// eNotify(new ENotificationImpl(this, Notification.SET, SDOPackage.ECHANGE_SUMMARY__LOGGING, true, false));
}
/**
*
*
* @generated NOT
*/
public boolean isCreated(DataObject dataObject)
{
return getObjectsToDetach().contains(dataObject);
}
/**
*
*
* @generated NOT
*/
public boolean isDeleted(DataObject dataObject)
{
return getDeletedObjects().contains(dataObject);
}
/**
*
*
* @generated NOT
*/
public List getOldValues(DataObject dataObject)
{
List sdoSettings = (List)cachedSDOObjectChanges.get(dataObject);
if (sdoSettings != null)
{
return sdoSettings;
}
List settings = (List)getObjectChanges().get(dataObject);
if (settings == null)
{
settings = Collections.EMPTY_LIST;
}
else
{
for (int i = 0; i < settings.size(); i++)
{
FeatureChange change = (FeatureChange)settings.get(i);
EStructuralFeature feature = change.getFeature();
if (FeatureMapUtil.isFeatureMap(feature))
{
final List values = (List)change.getValue();
if (sdoSettings == null)
{
sdoSettings = new BasicEList(settings);
}
DelegatingFeatureMap featureMap = new DelegatingFeatureMap(((InternalEObject)dataObject), feature)
{
protected final List theList = values;
protected List delegateList()
{
return theList;
}
};
// create new settings and replace the setting for mixed feature
sdoSettings.set(i, SDOFactory.eINSTANCE.createChangeSummarySetting(feature, new BasicSequence(featureMap), change.isSet()));
// add all derived features
for (int k = 0; k < featureMap.size(); k++)
{
EStructuralFeature f = featureMap.getEStructuralFeature(k);
sdoSettings.add(SDOFactory.eINSTANCE.createChangeSummarySetting(f, featureMap.get(f, false), true));
}
}
}
}
sdoSettings = (sdoSettings != null) ? sdoSettings : settings;
cachedSDOObjectChanges.put(dataObject, sdoSettings);
return sdoSettings;
}
/**
*
*
* @generated NOT
*/
public boolean isModified(DataObject dataObject)
{
return getObjectChanges().containsKey(dataObject) && !isDeleted(dataObject) && !isCreated(dataObject);
}
/**
*
*
* @generated NOT
*/
public void summarize()
{
if (!isLogging())
{
throw new IllegalStateException("Not currently logging");
}
changeRecorder.summarize();
}
public Setting getOldValue(DataObject dataObject, Property property)
{
for (Iterator i = getOldValues(dataObject).iterator(); i.hasNext(); )
{
Setting setting = (Setting)i.next();
if (setting.getProperty() == property)
{
return setting;
}
}
return null;
}
public DataObject getOldContainer(DataObject dataObject)
{
return (DataObject)getOldContainer((EObject)dataObject);
}
public Property getOldContainmentProperty(DataObject dataObject)
{
return (Property)getOldContainmentFeature((EObject)dataObject);
}
/**
*
*
* @generated NOT
*/
public Sequence getOldSequence(DataObject dataObject)
{
EAttribute mixedFeature = BasicExtendedMetaData.INSTANCE.getMixedFeature((EClass)dataObject.getType());
if (mixedFeature != null)
{
return (Sequence)getOldValue(dataObject, (Property)mixedFeature).getValue();
}
return null;
}
/**
*
*
* @generated NOT
*/
public void undoChanges()
{
if (isLogging())
{
changeRecorder.summarize();
}
apply();
}
public EList getObjectsToDetach()
{
if (cachedObjectsToDetach == null)
{
cachedObjectsToDetach = super.getObjectsToDetach();
}
return cachedObjectsToDetach;
}
/**
*
*
* @generated NOT
*/
public DataGraph getDataGraph()
{
return getEDataGraph();
}
protected Set deletedObjects;
protected void preApply(boolean reverse)
{
super.preApply(reverse);
deletedObjects = null;
}
protected Set getDeletedObjects()
{
if (deletedObjects == null)
{
deletedObjects = new HashSet();
for (Iterator i = EcoreUtil.getAllContents(getObjectsToAttach()); i.hasNext(); )
{
deletedObjects.add(i.next());
}
}
return deletedObjects;
}
/**
*
*
* @generated NOT
*/
public List getChangedDataObjects()
{
EList result = new UniqueEList.FastCompare(getDeletedObjects());
result.addAll(getObjectsToDetach());
for (Iterator i = getObjectChanges().iterator(); i.hasNext(); )
{
Map.Entry entry = (Map.Entry)i.next();
result.add(entry.getKey());
}
return result;
}
/**
*
*
* @generated NOT
*/
public DataObject getRootObject()
{
DataGraph dataGraph = getDataGraph();
if (dataGraph != null)
{
return dataGraph.getRootObject();
}
// TODO: handle ChangeSummary-type property
return null;
}
} //EChangeSummaryImpl