diff options
author | Eike Stepper | 2012-10-31 06:24:59 +0000 |
---|---|---|
committer | Eike Stepper | 2012-10-31 06:24:59 +0000 |
commit | 01c49a910e0aa861213745d14cf5a0ddcbd1e7b6 (patch) | |
tree | 9b75a298e880b08407a049fea5ef83d0fa7f4c5c /plugins/org.eclipse.emf.cdo.common | |
parent | ecf34dbf6e73114f17704797fa9bc80c39188152 (diff) | |
download | cdo-01c49a910e0aa861213745d14cf5a0ddcbd1e7b6.tar.gz cdo-01c49a910e0aa861213745d14cf5a0ddcbd1e7b6.tar.xz cdo-01c49a910e0aa861213745d14cf5a0ddcbd1e7b6.zip |
[392956] [Legacy] Support partial/conditional persistence of features
https://bugs.eclipse.org/bugs/show_bug.cgi?id=392956
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.common')
3 files changed, 189 insertions, 1 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassInfoImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassInfoImpl.java index 69a40cd8fb..dd833a77a6 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassInfoImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassInfoImpl.java @@ -7,18 +7,22 @@ * * Contributors: * Eike Stepper - initial API and implementation + * Christian W. Damus (CEA) - support partially persistent features */ package org.eclipse.emf.cdo.internal.common.model; import org.eclipse.emf.cdo.common.model.CDOClassInfo; import org.eclipse.emf.cdo.common.model.CDOModelUtil; import org.eclipse.emf.cdo.common.model.EMFUtil; +import org.eclipse.emf.cdo.internal.common.bundle.OM; +import org.eclipse.emf.cdo.spi.common.model.InternalCDOClassInfo; import org.eclipse.emf.common.notify.Notifier; import org.eclipse.emf.common.notify.impl.AdapterImpl; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.util.EcoreUtil; import java.util.ArrayList; import java.util.Arrays; @@ -27,12 +31,16 @@ import java.util.List; /** * @author Eike Stepper */ -public class CDOClassInfoImpl extends AdapterImpl implements CDOClassInfo +public class CDOClassInfoImpl extends AdapterImpl implements InternalCDOClassInfo { private static final int NOT_MAPPED = -1; + private static final PersistenceFilter[] NO_FILTERS = {}; + private EStructuralFeature[] allPersistentFeatures; + private PersistenceFilter[] persistenceFilters = NO_FILTERS; + private int[] featureIDMappings; public CDOClassInfoImpl() @@ -94,6 +102,17 @@ public class CDOClassInfoImpl extends AdapterImpl implements CDOClassInfo return index; } + public PersistenceFilter getPersistenceFilter(EStructuralFeature feature) + { + if (persistenceFilters == NO_FILTERS) + { + return null; + } + + int featureID = getEClass().getFeatureID(feature); + return persistenceFilters[featureID]; + } + private void init(EClass eClass) { List<EStructuralFeature> persistentFeatures = new ArrayList<EStructuralFeature>(); @@ -115,7 +134,39 @@ public class CDOClassInfoImpl extends AdapterImpl implements CDOClassInfo EStructuralFeature feature = allPersistentFeatures[i]; int featureID = eClass.getFeatureID(feature); featureIDMappings[featureID] = i; + + PersistenceFilter persistenceFilter = initPersistenceFilter(feature); + if (persistenceFilter != null) + { + if (persistenceFilters == NO_FILTERS) + { + persistenceFilters = new PersistenceFilter[allFeatures.size()]; + } + + persistenceFilters[featureID] = persistenceFilter; + } + } + } + + private PersistenceFilter initPersistenceFilter(EStructuralFeature feature) + { + CDOPersistenceFilterImpl result = null; + String filter = EcoreUtil.getAnnotation(feature, EMFUtil.CDO_ANNOTATION_SOURCE, "filter"); + + if (filter != null) + { + EStructuralFeature dependency = feature.getEContainingClass().getEStructuralFeature(filter); + if (dependency != null) + { + result = new CDOPersistenceFilterImpl(dependency); + } + else + { + OM.LOG.warn("Persistence filter '" + filter + "' not found for " + feature); + } } + + return result; } @Override diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOPersistenceFilterImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOPersistenceFilterImpl.java new file mode 100644 index 0000000000..6282fee24c --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOPersistenceFilterImpl.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) 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: + * Christian W. Damus (CEA) - initial API and implementation + */ +package org.eclipse.emf.cdo.internal.common.model; + +import org.eclipse.emf.cdo.spi.common.model.InternalCDOClassInfo.PersistenceFilter; + +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; + +import java.util.Collection; +import java.util.Collections; + +/** + * Encapsulation of a rule for filtering the persistent values + * of a {@linkplain EStructuralFeature feature} in some model element. + * <p> + * Some models (such as UML's Activity metaclass) require partial persistence + * of features, persisting a subset of the values in a feature that are also + * in some other feature (the filtering feature). Other models may apply other + * transformations to features that require partial or otherwise custom + * persistence rules. + * + * @since 4.2 + */ +public class CDOPersistenceFilterImpl implements PersistenceFilter +{ + private final EStructuralFeature dependency; + + public CDOPersistenceFilterImpl(EStructuralFeature dependency) + { + this.dependency = dependency; + } + + public Object getPersistableValue(EObject owner, Object value) + { + if (value instanceof Collection<?>) + { + Collection<?> collection = (Collection<?>)value; + return filter(collection, asCollection(owner.eGet(dependency))); + } + + if (asCollection(owner.eGet(dependency)).contains(value)) + { + return value; + } + + return null; + } + + private Collection<?> asCollection(Object value) + { + if (value instanceof Collection<?>) + { + return (Collection<?>)value; + } + + if (value == null) + { + return Collections.emptyList(); + } + + return Collections.singletonList(value); + } + + private Collection<?> filter(Collection<?> elements, Collection<?> filter) + { + Collection<?> result = new BasicEList<Object>(elements); + result.retainAll(filter); + return result; + } +} diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/model/InternalCDOClassInfo.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/model/InternalCDOClassInfo.java new file mode 100644 index 0000000000..2526cb8890 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/model/InternalCDOClassInfo.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) 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: + * Christian W. Damus (CEA) - initial API and implementation + */ +package org.eclipse.emf.cdo.spi.common.model; + +import org.eclipse.emf.cdo.common.model.CDOClassInfo; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; + +/** + * @since 4.2 + */ +public interface InternalCDOClassInfo extends CDOClassInfo +{ + /** + * Obtains a rule that filters/transforms the persist values of the given + * {@code feature}. + * + * @param feature a feature to be persisted + * @return a persistence filter rule for the {@code feature}, or {@code null} + * if it has no filter but just follows the default persistence rules + */ + public PersistenceFilter getPersistenceFilter(EStructuralFeature feature); + + /** + * Encapsulation of a rule for filtering the persistent values + * of a {@linkplain EStructuralFeature feature} in some model element. + * Some models (such as UML's Activity metaclass) require partial persistence + * of features, persisting a subset of the values in a feature that are also + * in some other feature (the filtering feature). Other models may apply other + * transformations to features that require partial or otherwise custom + * persistence rules. + */ + public interface PersistenceFilter + { + /** + * Get a subset or other transformation of the specified {@code value} of + * a persistable feature, based on its dependencies. + * + * @param owner an object this filter is to be applied to. + * @param value the value (which may be a collection) of the {@code owner}'s feature. + * + * @return the transformed value to persist. It should be a collection (possibly empty) + * if the {@code value} is a collection, or a scalar (possibly {@code null}) if the + * {@code value} is a scalar + */ + public Object getPersistableValue(EObject owner, Object value); + } +} |