package org.geotools.data.efeature.util;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.query.conditions.eobjects.EObjectCondition;
import org.eclipse.emf.query.conditions.eobjects.structuralfeatures.IEStructuralFeatureValueGetter;
import org.geotools.data.efeature.EFeatureInfo;
import org.geotools.data.efeature.EFeaturePackage;
/**
* @author kengu - 11. juni 2011
*
*/
public final class EFeatureValueGetter implements IEStructuralFeatureValueGetter {
/** eFeatureMap */
private static Map<EAttribute, Map<EClass, EAttribute>> eFeatureMap;
/** eAttributeMap */
private Map<EAttribute, Map<EClass, EAttribute>> eAttributeMap;
// -----------------------------------------------------
// Constructors
// -----------------------------------------------------
/**
* @param eMappingMap
*/
public EFeatureValueGetter(EFeatureInfo...eFeatureInfos) {
this.eAttributeMap = create(eFeatureInfos);
}
// -----------------------------------------------------
// IEStructuralFeatureValueGetter implementation
// -----------------------------------------------------
@Override
public EObject resolve(EObject eObject) {
//
// Do nothing, just return the same object
//
return eObject;
}
@Override
public Object eGet(EObject eObject, EStructuralFeature eFeature, boolean resolve) {
//
// Prepare information
//
EClass eObjectClass = eObject.eClass();
EClass eFeatureClass = EFeaturePackage.eINSTANCE.getEFeature();
//
// Is direct lookup possible or only option?
//
if(eAttributeMap.size()==0 || eFeatureClass.isSuperTypeOf(eObjectClass)) {
return eObject.eGet(eFeature);
}
//
// Get EClass to EAttribute mapping for given feature
//
Map<EClass,EAttribute> eClassMap = eAttributeMap.get(eFeature);
if(eClassMap==null) {
//
// Not found, just fall through leaving the problem for EMF to solve
//
return eObject.eGet(eFeature);
}
//
// Map given feature to EAttribute in given object
//
eFeature = eClassMap.get(eObject.eClass());
//
// Use EMF reflection to retrieve value
//
return eObject.eGet(eFeature);
}
@Override
public List<EObject> eContents(EObject eObject, EObjectCondition eCondition) {
//
// TODO Implement content filtering
//
return eObject.eContents();
}
// -----------------------------------------------------
// Helper methods
// -----------------------------------------------------
/**
* Construct mapping from array of {@link EFeatureInfo}s
* </p>
* @param eFeatureInfos
* @return a new {@link EFeatureValueGetter}
*/
private final static Map<EAttribute, Map<EClass, EAttribute>> create(EFeatureInfo...eFeatureInfos) {
//
// Prepare construction of EFeature mappings
//
EFeaturePackage ePackage = EFeaturePackage.eINSTANCE;
EClass eFeatureClass = ePackage.getEFeature();
//
// Initialize create mapping onto EFeature?
//
if(eFeatureMap==null) {
eFeatureMap = new HashMap<EAttribute, Map<EClass,EAttribute>>();
for(EAttribute it : eFeatureClass.getEAllAttributes()) {
Map<EClass,EAttribute> eClassMap = new HashMap<EClass,EAttribute>();
eClassMap.put(eFeatureClass, it);
eFeatureMap.put(it,eClassMap);
}
}
//
// Copy from EFeature onto mapping
//
final Map<EAttribute, Map<EClass,EAttribute>>
eAttributeMap = new HashMap<EAttribute, Map<EClass,EAttribute>>(eFeatureMap);
//
// Then add mappings from implementations onto EFeature
//
for(EFeatureInfo it : eFeatureInfos) {
//
// Prepare information about structure
//
EClass eClass = it.eClass();
//
// Add mapping from EFeature ID to implementation (is required)
//
eAttributeMap.get(ePackage.getEFeature_ID()).put(eClass,it.eIDAttribute());
//
// Add mapping from EFeature SRID to implementation (optional)
//
EAttribute eAttribute = it.eSRIDAttribute();
if(eAttribute!=null) {
eAttributeMap.get(ePackage.getEFeature_SRID()).put(eClass,eAttribute);
}
//
// Add mapping from EFeature default geometry to implementation (optional)
//
eAttribute = it.eDefaultGeometry();
if(eAttribute!=null) {
eAttributeMap.get(ePackage.getEFeature_Default()).put(eClass,it.eDefaultGeometry());
}
}
//
// Construct structural value getter
//
return eAttributeMap;
}
}