package org.geotools.data.efeature;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EPackage;
import org.geotools.data.efeature.internal.EFeatureInfoCache;
/**
* {@link EFeature} folder information class implementation.
* <p>
*
* @author kengu
*
*/
public class EFeatureFolderInfo extends EStructureInfo<EFeaturePackageInfo> {
/**
* The {@link EFeature} folder name. An {@link EClass} containing {@link EFeature} or
* {@link EFeature} compatible data if {@link #eIsObject} is <code>true</code>.
*/
protected String eName;
/** Cached {@link EPackage#getNsURI() name space URI} */
protected String eNsURI;
/**
* If <code>true</code>, {@link #eName} is an {@link EClass} containing {@link EFeature}s or
* {@link EFeature} compatible data
*/
protected boolean eIsObject;
/**
* {@link EFeature} id to {@link EFeatureInfo} instance {@link Map}
*/
protected Map<String, EFeatureInfo> eFeatureInfoMap;
// -----------------------------------------------------
// EFeatureFolderInfo methods
// -----------------------------------------------------
@Override
public boolean isAvailable() {
// Is valid and has at least one EFeature definition?
//
return super.isAvailable() && !eFeatureInfoMap.isEmpty();
}
public String eName() {
return eName;
}
public String eNsURI() {
return eNsURI;
}
@Override
protected EFeaturePackageInfo eParentInfo(boolean checkIsValid) {
return eContext(checkIsValid).eStructure().
eGetPackageInfo(eNsURI);
}
public EFeatureInfo eGetFeatureInfo(String eName) {
return eFeatureInfoMap.get(eName);
}
public Map<String, EFeatureInfo> eFeatureInfoMap() {
return eFeatureInfoMap;
}
public boolean isFeature(String eName) {
return eFeatureInfoMap.containsKey(eName);
}
public String[] eFeatureNames() {
return eFeatureInfoMap.keySet().toArray(new String[0]);
}
/**
* Validate {@link EFeature} folder information against given {@link EPackage}.
* <p>
*
* @param ePackage - given {@link EPackage} instance
* @return <code>true</code> if valid, <code>false</code> otherwise.
*/
public EFeatureStatus validate(EPackage ePackage) {
//
// Invalidate structure
//
doInvalidate(false);
//
// 1) Verify folder name
//
if (eName == null || eName.length() == 0) {
return failure(this, eName(), "Folder name is missing");
}
// 2) Verify that instances of given
// eClass is an EObject of same class
// as given folder name?
//
EClass eParent = null;
if (eIsObject) {
EClassifier eClassifier = ePackage.getEClassifier(eName);
if (eClassifier instanceof EClass) {
eParent = (EClass) eClassifier;
} else
return failure(this, eName(), "Folder mismatch: Parent "
+ eName + " not an EClass");
}
// 3) Verify features
//
EFeatureStatus s;
for (EFeatureInfo it : eFeatureInfoMap.values()) {
if (!(s = it.validate(ePackage, eParent)).isSuccess())
{
return s;
}
}
// Confirm that structure is valid
//
return structureIsValid(eName());
}
// -----------------------------------------------------
// EStructureInfo implementation
// -----------------------------------------------------
@Override
protected void doInvalidate(boolean deep) {
if (deep) {
for (EStructureInfo<?> it : eFeatureInfoMap.values()) {
it.doInvalidate(true);
}
}
}
@Override
protected void doDispose() {
for (EFeatureInfo it : eFeatureInfoMap.values()) {
it.dispose();
}
eFeatureInfoMap.clear();
eFeatureInfoMap = null;
}
// -----------------------------------------------------
// EStructureInfo implementation
// -----------------------------------------------------
/**
* Construct {@link EFeatureFolderInfo} instances from {@link EPackage} instance.
* <p>
* @param eStoreInfo - {@link EFeaturePackageInfo} instance
* @param ePackage - {@link EPackage} instance containing EFeature and EFeature compatible classes.
* @throws IllegalArgumentException If a {@link EPackage} instance was not found.
*/
protected static EFeatureFolderInfo create(
EFeaturePackageInfo eStoreInfo, EPackage ePackage)
throws IllegalArgumentException {
EFeatureFolderInfo eInfo = new EFeatureFolderInfo();
eInfo.eName = ePackage.getName();
eInfo.eNsURI = eStoreInfo.eNsURI;
eInfo.eHints = eStoreInfo.eHints;
eInfo.eContextID = eStoreInfo.eContextID;
eInfo.eIsObject = false;
eInfo.eFactory = eStoreInfo.eFactory;
eInfo.eContext = eStoreInfo.eContext;
eInfo.eFeatureInfoMap = features(eInfo,ePackage);
return eInfo;
}
protected static Map<String, EFeatureInfo> features(EFeatureFolderInfo eFolderInfo, EPackage ePackage) {
//
// Prepare lists
//
EList<EClassifier> eList = ePackage.getEClassifiers();
Map<String, EFeatureInfo> eFeatureMap =
new HashMap<String, EFeatureInfo>(eList.size());
//
// Get EFeatureInfo cache
//
EFeatureInfoCache eCache = eFolderInfo.eContext(false).eStructure().eFeatureInfoCache();
//
// Inspect EMF package, adding all EFeature and EFeature compatible classes.
//
for(EClassifier it : eList)
{
//
// Check if it implements EFeature or contains EFeature compatible data
//
if(EFeatureUtils.isCompatible(it))
{
EClass eClass = (EClass)it;
EFeatureInfo eFeatureInfo = eCache.get(eClass);
if(eFeatureInfo==null) {
eFeatureInfo = EFeatureInfo.create(eFolderInfo, (EClass)it);
}
eFeatureInfo = eCache.get(eClass);
eFeatureMap.put(eFeatureInfo.eName(), eFeatureInfo);
}
}
//
// Finished
//
return Collections.unmodifiableMap(eFeatureMap);
}
}