blob: f08651f3d1ebea7556044a08d45ea19a22ac1877 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013 RCP Vision (http://www.rcp-vision.com) 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
*******************************************************************************/
/**
*
*/
package org.eclipse.emf.parsley.ui.provider;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.parsley.EmfParsleyActivator;
import org.eclipse.emf.parsley.ecore.FeatureResolver;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
/**
* Provides the list of {@link EStructuralFeature} of an {@link EClass}. The
* default is to return the list of all the features in the EClass, but the
* programmer can customize it (for instance, by returning only a superset, or
* using a different order) on an EClass-based strategy. The customization can
* be done redefining buildMap and adding mappings.
*
* @author Lorenzo Bettini
*
*/
public class FeaturesProvider {
@Inject
private FeatureResolver featureResolver;
public FeatureResolver getFeatureResolver() {
return featureResolver;
}
public void setFeatureResolver(FeatureResolver featureResolver) {
this.featureResolver = featureResolver;
}
public static class EClassToEStructuralFeatureMap extends
HashMap<EClass, List<EStructuralFeature>> {
private static final long serialVersionUID = 670116975392207101L;
public void mapTo(EClass eClass, EStructuralFeature... features) {
put(eClass, Lists.newArrayList(features));
}
}
protected EClassToEStructuralFeatureMap map = null;
protected EClassToEStructuralFeatureAsStringsMap stringMap = null;
public List<EStructuralFeature> getFeatures(EObject eObject) {
if (eObject == null)
return Collections.emptyList();
return getFeatures(eObject.eClass());
}
public List<EStructuralFeature> getFeatures(EClass eClass) {
if (eClass == null)
return Collections.emptyList();
List<EStructuralFeature> fromMap = getFromMap(eClass);
if (fromMap != null)
return fromMap;
else {
fromMap = getFromStringMap(eClass);
if (fromMap != null)
return fromMap;
}
return new BasicEList<EStructuralFeature>(
eClass.getEAllStructuralFeatures());
}
protected List<EStructuralFeature> getFromMap(EClass eClass) {
if (map == null)
buildMapInternal();
return map.get(eClass);
}
protected List<EStructuralFeature> getFromStringMap(EClass eClass) {
if (stringMap == null)
buildStringMapInternal();
List<String> list = stringMap.get(eClass.getInstanceClassName());
if (list == null)
return null;
LinkedList<EStructuralFeature> result = new LinkedList<EStructuralFeature>();
for (String featureName : list) {
EStructuralFeature feature = featureResolver.getFeature(eClass, featureName);
if (feature != null)
result.add(feature);
else
EmfParsleyActivator.logError("cannot find feature '"
+ featureName + "' in EClass '" + eClass.getName()
+ "'");
}
return result;
}
private void buildMapInternal() {
buildMap(getMap());
}
public EClassToEStructuralFeatureMap getMap() {
if (map == null)
map = new EClassToEStructuralFeatureMap();
return map;
}
private void buildStringMapInternal() {
buildStringMap(getStringMap());
}
public EClassToEStructuralFeatureAsStringsMap getStringMap() {
if (stringMap == null)
stringMap = new EClassToEStructuralFeatureAsStringsMap();
return stringMap;
}
/**
* Derived classes should redefine this method to map an {@link EClass} to
* {@link EStructuralFeature}s.
*
* @param map
*/
protected void buildMap(EClassToEStructuralFeatureMap map) {
// default implementation is empty
}
/**
* Derived classes should redefine this method to map an {@link EClass}'s
* name to {@link EStructuralFeature}s' names; the {@link EClass}'s name
* should be obtained using getInstanceClassName().
*
* @param stringMap
*/
protected void buildStringMap(
EClassToEStructuralFeatureAsStringsMap stringMap) {
// default implementation is empty
}
public void addToStringMap(EClass eClass, String...featuresNames) {
getStringMap().mapTo(eClass.getInstanceClassName(), featuresNames);
}
}