| //------------------------------------------------------------------------------ |
| // Copyright (c) 2005, 2007 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 implementation |
| //------------------------------------------------------------------------------ |
| package org.eclipse.epf.uma.ecore.util; |
| |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.Map; |
| |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| |
| /** |
| * @author Phong Nguyen Le |
| * @sine 1.2 |
| */ |
| public class DefaultValueManager { |
| public static final DefaultValueManager INSTANCE = new DefaultValueManager(); |
| |
| private final Map<EStructuralFeature, Map<EClass, Object>> featureToTypedDefaultValuesMap = |
| new HashMap<EStructuralFeature, Map<EClass, Object>>(); |
| |
| private final Map<EClass, Map<EStructuralFeature, Object>> typeToFeatureDefaultValueMap = |
| new HashMap<EClass, Map<EStructuralFeature,Object>>(); |
| |
| private final Map<EStructuralFeature, Map<EClass, Object>> featureToTypedStaticDefaultValuesMap = |
| new HashMap<EStructuralFeature, Map<EClass, Object>>(); |
| |
| private final Map<EClass, Map<EStructuralFeature, Object>> typeToFeatureStaticDefaultValueMap = |
| new HashMap<EClass, Map<EStructuralFeature,Object>>(); |
| |
| private volatile boolean useStatic; |
| |
| protected DefaultValueManager() { |
| |
| } |
| |
| public void setUseStatic(boolean useStatic) { |
| this.useStatic = useStatic; |
| } |
| |
| public boolean isUseStatic() { |
| return useStatic; |
| } |
| |
| private static Map<EStructuralFeature, Object> getFeatureToDefaultValueMap(EClass type, |
| Map<EStructuralFeature, Map<EClass, Object>> featureToTypedDefaultValuesMap, |
| Map<EStructuralFeature, Object> featureToStaticDefaultValueMap) { |
| Map<EStructuralFeature, Object> featureToDefaultValueMap; |
| if(featureToTypedDefaultValuesMap.isEmpty()) { |
| featureToDefaultValueMap = Collections.EMPTY_MAP; |
| } |
| else { |
| featureToDefaultValueMap = new HashMap<EStructuralFeature, Object>(); |
| for (Iterator<Map.Entry<EStructuralFeature, Map<EClass, Object>>> iter = |
| featureToTypedDefaultValuesMap.entrySet().iterator(); iter.hasNext();) { |
| Map.Entry<EStructuralFeature, Map<EClass, Object>> entry = iter.next(); |
| EStructuralFeature feature = entry.getKey(); |
| if(type.getFeatureID(feature) != -1) { |
| Object defaultValue = null; |
| EClass selectedType = type; |
| boolean found = false; |
| for (Iterator<Map.Entry<EClass, Object>> iterator = entry.getValue().entrySet().iterator(); iterator |
| .hasNext();) { |
| Map.Entry<EClass, Object> ent = iterator.next(); |
| EClass currentType = ent.getKey(); |
| if(currentType.isSuperTypeOf(type) && |
| (selectedType == null || selectedType.isSuperTypeOf(currentType))) { |
| selectedType = currentType; |
| defaultValue = ent.getValue(); |
| found = true; |
| } |
| } |
| if(found) { |
| Object staticDefaultValue = featureToStaticDefaultValueMap.get(feature); |
| if(staticDefaultValue == null) { |
| staticDefaultValue = feature.getDefaultValue(); |
| } |
| |
| // default value is overridden either via: |
| // - static default value |
| // - dynamic default value |
| // - dynamic default value that overrode a overriding static default value |
| // |
| if((defaultValue == null && staticDefaultValue != null) |
| || (defaultValue != null && (!defaultValue.equals(staticDefaultValue) || |
| (staticDefaultValue != null && !staticDefaultValue.equals(feature.getDefaultValue()))))) { |
| featureToDefaultValueMap.put(feature, defaultValue); |
| } |
| } |
| } |
| } |
| if(featureToDefaultValueMap.isEmpty()) { |
| featureToDefaultValueMap = Collections.EMPTY_MAP; |
| } |
| } |
| return featureToDefaultValueMap; |
| } |
| |
| public synchronized Map<EStructuralFeature, Object> getFeatureToDefaultValueMap(EClass type) { |
| if(useStatic) { |
| return getFeatureToStaticDefaultValueMap(type); |
| } |
| else { |
| return getFeatureToDynamicDefaultValueMap(type); |
| } |
| } |
| |
| private synchronized Map<EStructuralFeature, Object> getFeatureToDynamicDefaultValueMap(EClass type) { |
| Map<EStructuralFeature, Object> featureToDefaultValueMap = typeToFeatureDefaultValueMap.get(type); |
| if(featureToDefaultValueMap == null) { |
| featureToDefaultValueMap = getFeatureToDefaultValueMap(type, featureToTypedDefaultValuesMap, |
| getFeatureToStaticDefaultValueMap(type)); |
| typeToFeatureDefaultValueMap.put(type, featureToDefaultValueMap); |
| } |
| return featureToDefaultValueMap; |
| } |
| |
| private synchronized Map<EStructuralFeature, Object> getFeatureToStaticDefaultValueMap(EClass type) { |
| Map<EStructuralFeature, Object> featureToDefaultValueMap = typeToFeatureStaticDefaultValueMap.get(type); |
| if(featureToDefaultValueMap == null) { |
| featureToDefaultValueMap = getFeatureToDefaultValueMap(type, featureToTypedStaticDefaultValuesMap, |
| Collections.EMPTY_MAP); |
| typeToFeatureStaticDefaultValueMap.put(type, featureToDefaultValueMap); |
| } |
| return featureToDefaultValueMap; |
| } |
| |
| |
| private static final synchronized void setDefaultValue(EClass type, EStructuralFeature feature, Object defaultValue, |
| Map<EStructuralFeature, Map<EClass, Object>> featureToTypedDefaultValuesMap ) |
| { |
| if(!feature.getEContainingClass().isSuperTypeOf(type)) { |
| return; |
| } |
| Map<EClass, Object> typeToDefaultValueMap = featureToTypedDefaultValuesMap.get(feature); |
| if(typeToDefaultValueMap == null) { |
| // this map must be sorted from sub type to super type |
| // |
| typeToDefaultValueMap = new HashMap<EClass, Object>(); |
| featureToTypedDefaultValuesMap.put(feature, typeToDefaultValueMap); |
| } |
| typeToDefaultValueMap.put(type, defaultValue); |
| } |
| |
| public final synchronized void setDefaultValue(EClass type, EStructuralFeature feature, Object defaultValue) { |
| setDefaultValue(type, feature, defaultValue, featureToTypedDefaultValuesMap); |
| |
| // clear typeToFeatureDefaultValueMap so the default value will be recalculated for each class |
| // |
| typeToFeatureDefaultValueMap.clear(); |
| } |
| |
| public final synchronized void setStaticDefaultValue(EClass type, EStructuralFeature feature, Object defaultValue) { |
| setDefaultValue(type, feature, defaultValue); |
| setDefaultValue(type, feature, defaultValue, featureToTypedStaticDefaultValuesMap); |
| } |
| |
| public final void removeDefaultValue(EStructuralFeature feature) { |
| featureToTypedDefaultValuesMap.remove(feature); |
| } |
| |
| public final void removeDefaultValue(EStructuralFeature feature, EClass type) { |
| assert feature.getEContainingClass().isSuperTypeOf(type); |
| Map<EClass, Object> typeToDefaultValueMap = featureToTypedDefaultValuesMap.get(feature); |
| if(typeToDefaultValueMap != null) { |
| typeToDefaultValueMap.remove(type); |
| } |
| |
| // clear typeToFeatureDefaultValueMap so the default value will be recalculated for each class |
| // |
| typeToFeatureDefaultValueMap.clear(); |
| } |
| |
| private static void assignDefaultValues(EObject eObject, Map<EStructuralFeature, Object> featureToDefaultValueMap) { |
| if(featureToDefaultValueMap.isEmpty()) { |
| return; |
| } |
| |
| for (Iterator<Map.Entry<EStructuralFeature, Object>> iter = featureToDefaultValueMap |
| .entrySet().iterator(); iter.hasNext();) { |
| Map.Entry<EStructuralFeature, Object> entry = iter.next(); |
| eObject.eSet(entry.getKey(), entry.getValue()); |
| } |
| |
| } |
| |
| public void assignDefaultValues(EObject eObject) { |
| EClass type = eObject.eClass(); |
| Map<EStructuralFeature, Object> featureToStaticDefaultValueMap = getFeatureToStaticDefaultValueMap(type); |
| assignDefaultValues(eObject, featureToStaticDefaultValueMap); |
| Map<EStructuralFeature, Object> featureToDefaultValueMap = getFeatureToDefaultValueMap(eObject.eClass()); |
| if(featureToDefaultValueMap != featureToStaticDefaultValueMap) { |
| assignDefaultValues(eObject, featureToDefaultValueMap); |
| } |
| } |
| |
| } |