package org.geotools.data.efeature;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.ecore.EPackage;
import org.geotools.data.FeatureStore;
import org.opengis.feature.simple.SimpleFeatureType;
/**
* {@link EPackage} information class implementation.
* <p>
*
* @author kengu
*
*/
public class EFeaturePackageInfo extends EStructureInfo<EFeatureContextInfo> {
/** Cached {@link EPackage} name space */
protected String eNsURI;
/** Map of {@link EFeatureFolderInfo} instances */
protected Map<String, EFeatureFolderInfo> eFolderInfoMap;
// -----------------------------------------------------
// EFeaturePackage methods
// -----------------------------------------------------
@Override
public boolean isAvailable() {
if(super.isAvailable()){
for (EFeatureFolderInfo it : eFolderInfoMap.values()) {
if (it.isAvailable())
return true;
}
}
return false;
}
public String eNsURI() {
return eNsURI;
}
public EPackage ePackage()
{
return eContext().eGetPackage(eNsURI);
}
@Override
protected EFeatureContextInfo eParentInfo(boolean checkIsValid) {
return eContext(checkIsValid).eStructure();
}
public EFeatureFolderInfo eGetFolderInfo(String eName) {
return eFolderInfoMap.get(eName);
}
public Map<String, EFeatureFolderInfo> eFolderInfoMap() {
return eFolderInfoMap;
}
/**
* Check if this data store contains a folder with given name
*
* @param eName - {@link EFeature} folder name
* @return <code>true</code> if exists, <code>false</code> otherwise
*/
public boolean isFolder(String eName) {
return eFolderInfoMap.containsKey(eName);
}
/**
* Get {@link EFeature} folder name from {@link SimpleFeatureType} name
* <p>
* {@link SimpleFeatureType} names have the following
*
* <pre>
* eType=<eFolder>.<eFeature>
*
* where
*
* eFolder = {@link EFeature} folder name
* eFeature = {@link EFeature} class | reference name
* </pre>
*
* @param eType - given {@link SimpleFeatureType} name
* @return a {@link EFeature} folder name if {@link #isSimpleFeatureType(String)},
* <code>null</code> otherwise.
*/
public String toFolderName(String eType) {
return EFeatureUtils.toFolderName(eType);
}
/**
* Get {@link EFeature} name from {@link SimpleFeatureType} name
* <p>
* {@link SimpleFeatureType} names have the following
*
* <pre>
* eType=<eFolder>.<eFeature>
*
* where
*
* eFolder = {@link EFeature} folder name
* eFeature = {@link EFeature} class | reference name
* </pre>
*
* @param eType - given {@link SimpleFeatureType} name
* @return a {@link EFeature} name if {@link #isSimpleFeatureType(String)}, <code>null</code>
* otherwise.
*/
public String toFeatureName(String eType) {
return EFeatureUtils.toFeatureName(eType);
}
/**
* Get {@link EFeature} folder names in this {@link FeatureStore} definition.
* <p>
*
* @param eQuery - (optional) query used to select which {@link EFeature} folders to include
* @return an array of {@link EFeature} folder names if found, <code>empty</code> array
* otherwise.
*/
public String[] eGetFolderNames(String eQuery) {
Set<String> subSet = new HashSet<String>(eFolderInfoMap.keySet());
if( !( eQuery==null || eQuery.length()==0) )
{
Set<String> eNames = new HashSet<String>();
for (String eFolder : eQuery.split("+")) {
int i = eFolder.indexOf(':');
eNames.add(i == -1 ? eFolder : eFolder.substring(0, i - 1));
}
subSet.retainAll(eNames);
}
return subSet.toArray(new String[0]);
}
/**
* Check if given eType is a {@link SimpleFeatureType}.
* <p>
* {@link SimpleFeatureType} names have the following
*
* <pre>
* eType=<eFolder>.<eFeature>
*
* where
*
* eFolder = {@link EFeature} folder name
* eFeature = {@link EFeature} class | reference name
* </pre>
*
* @param eType - given {@link SimpleFeatureType} name
* @return a {@link EFeatureInfo} instance if found, <code>null</code> otherwise.
* @see {@link EFeatureInfo#getReferenceName()}
*/
public boolean isSimpleFeatureType(String eType) {
if (!(eType == null || eType.length() == 0)) {
String[] eParts = eType.split(".");
if (eParts.length == 2) {
EFeatureFolderInfo eFolderInfo = eFolderInfoMap.get(eParts[0]);
if (eFolderInfo != null) {
return eFolderInfo.isFeature(eParts[1]);
}
}
}
return false;
}
/**
* Get {@link EFeature} with given name.
* <p>
* {@link SimpleFeatureType} names have the following format:
*
* <pre>
* eType=<eFolder>.<eFeature>
*
* where
*
* eFolder = {@link EFeature} folder name
* eFeature = {@link EFeature} class | reference name
* </pre>
*
* @param eType - given {@link SimpleFeatureType} name
* @return a {@link EFeatureInfo} instance if found, <code>null</code> otherwise.
* @see {@link EFeatureInfo#getReferenceName()}
* @throws IllegalArgumentException
*/
public EFeatureInfo eGetFeatureInfo(String eType) throws IllegalArgumentException {
if (!(eType == null || eType.length() == 0)) {
String[] eParts = eType.split("\\.");
if (eParts.length == 2) {
EFeatureFolderInfo eFolderInfo = eFolderInfoMap.get(eParts[0]);
if (eFolderInfo != null) {
return eFolderInfo.eGetFeatureInfo(eParts[1]);
}
}
throw new IllegalArgumentException("Type name have illegal format. Expected \"<efolder>.<efeature>\"");
}
throw new IllegalArgumentException("Type name can not be null or empty");
}
/**
* Get {@link SimpleFeatureType} names defined by this {@link FeatureStore} information.
* <p>
* {@link SimpleFeatureType} names have the following format:
*
* <pre>
* eType=<eFolder>.<eFeature>
*
* where
*
* eFolder = {@link EFeature} folder name
* eFeature = {@link EFeature} class | reference name
* </pre>
*
* @param eQuery - query used to select which {@link EFeature} folders to include
* @return an array of {@link SimpleFeatureType} names if found, <code>empty</code> array
* otherwise.
*/
public String[] getTypeNames(String eQuery) {
Set<String> eNames = new HashSet<String>();
for (String eFolder : eGetFolderNames(eQuery)) {
EFeatureFolderInfo eFolderInfo = eGetFolderInfo(eFolder);
for (String eName : eFolderInfo.eFeatureNames()) {
eNames.add(eFolder + "." + eName);
}
}
return eNames.toArray(new String[0]);
}
/**
* Validate given {@link EPackage} instance against
* the {@link EFeaturePackageInfo structure} .
*/
public EFeatureStatus validate() {
//
// 1) Verify that not disposed
//
if(isDisposed)
{
return failure(this, eNsURI, "Is disposed");
}
//
// Invalidate structure
//
invalidate(false);
//
// 2) Verify that registry is cached
//
if(!isCached(eContextID))
{
return failure(this, eNsURI, "EFeatureContext with ID: " + eContextID + " not found");
}
EFeatureContext eContext = eContext(false);
//
// 3) Verify name space URI
//
EPackage ePackage = eContext.eGetPackage(eNsURI);
if (!this.eNsURI.equals(ePackage.getNsURI())) {
return failure(this, eNsURI, "Package mismatch: namespace (" + ePackage + ")");
}
//
// 4) Verify ALL folders (query == null)
//
EFeatureStatus s;
for (String eName : eGetFolderNames(null)) {
EFeatureFolderInfo eInfo = eFolderInfoMap.get(eName);
if (eInfo != null) {
if (!(s = eInfo.validate(ePackage)).isSuccess()){
return s;
}
} else {
return failure(this, eNsURI, "Package mismatch: Folder " + eName + " not found");
}
}
//
// Confirm that structure is valid
//
return structureIsValid(eNsURI());
}
// -----------------------------------------------------
// EStructureInfo implementation
// -----------------------------------------------------
@Override
protected void doInvalidate(boolean deep) {
if (deep) {
for (EStructureInfo<?> it : eFolderInfoMap.values()) {
it.doInvalidate(true);
}
}
}
@Override
protected void doDispose() {
for (EFeatureFolderInfo it : eFolderInfoMap.values()) {
it.dispose();
}
eFolderInfoMap.clear();
eFolderInfoMap = null;
}
// -----------------------------------------------------
// Helper methods
// -----------------------------------------------------
/**
* Create a {@link EFeaturePackageInfo} from {@link EFeatureContext}
* information cached with given ids.
* @param eContextInfo - {@link EFeatureContextInfo} instance
* @param eNsURI - {@link EPackage#getNsURI() name space URI}
*/
protected static EFeaturePackageInfo create(EFeatureContextFactory eFactory,
EFeatureContextInfo eContextInfo, String eNsURI)
throws IllegalArgumentException {
EFeaturePackageInfo eInfo = new EFeaturePackageInfo();
eInfo.eHints = eContextInfo.eHints;
eInfo.eContextID = eContextInfo.eContextID;
eInfo.eNsURI = eNsURI;
eInfo.eFactory = eContextInfo.eFactory;
eInfo.eContext = eContextInfo.eContext;
eInfo.eFolderInfoMap = folders(eInfo);
return eInfo;
}
/**
* Construct {@link EFeatureFolderInfo} instances from {@link EFeaturePackageInfo} instance.
* <p>
* @param ePackageInfo - {@link EFeaturePackageInfo} instance
* @throws IllegalArgumentException If a {@link EPackage} instance was not found.
*/
protected static Map<String, EFeatureFolderInfo> folders(EFeaturePackageInfo ePackageInfo)
throws IllegalArgumentException {
//
// Prepare
//
Map<String, EFeatureFolderInfo> eMap = new HashMap<String, EFeatureFolderInfo>();
//
// Get context instance
//
EFeatureContext eContext = ePackageInfo.eContext(false);
//
// Get EMF package from name space URI
//
EPackage ePackage = eContext.eGetPackage(ePackageInfo.eNsURI);
//
// Create single folder that contains all EFeature classes.
//
EFeatureFolderInfo eFolderInfo = EFeatureFolderInfo.create(ePackageInfo, ePackage);
//
// Map name to instance
//
eMap.put(eFolderInfo.eName,eFolderInfo);
//
// Success
//
return eMap;
}
}