package de.FeatureModellingTool.FeatureModel;
import javax.swing.event.SwingPropertyChangeSupport;
import java.util.*;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyChangeListener;
/**
* author: zhangwei
* Date: 2003-5-23
* Time: 19:23:36
*/
class FeatureModelImplementation implements FeatureModel {
protected String name = null;
protected String description = null;
/**
* ��Map�д洢������ģ���а����������������洢��ʽΪ (ID,Featute) pair
*/
protected TreeMap<String, Feature> allFeatures = null;
/**
* ��Hashtable�� ���������ϵ������Ϊ��ֵ���洢��һ�� (name, Map) pair,
* ÿ��name��Ӧ��map�д洢�����и����͵�������ϵ���洢��ʽΪ(ID, FeatureRelation)
*/
protected Hashtable<String, Map<String, FeatureRelation>> allRelations = null;
protected FeatureEditor featureEditor = null;
protected FeatureModelEditor featureModelEditor = null;
protected FeatureModelPropertyEditor featureModelPropertyEditor = null;
protected FeatureRelationManager featureRelationManager = null;
protected PropertyChangeSupport propertyChangeSupport = null;
public FeatureModelImplementation() {
allFeatures = new TreeMap<String, Feature>();
allRelations = new Hashtable<String, Map<String, FeatureRelation>>();
propertyChangeSupport = new SwingPropertyChangeSupport(this);
featureEditor = new FeatureEditorImplementation(this, propertyChangeSupport);
featureModelEditor = new FeatureModelEditorImplementation();
featureModelPropertyEditor = new FeatureModelPropertyEditorImplementation();
featureRelationManager = new FeatureRelationManagerImplementation();
}
FeatureEditor getFeatureEditor() {
return featureEditor;
}
FeatureModelEditor getFeatureModelEditor() {
return featureModelEditor;
}
FeatureModelPropertyEditor getFeatureModelPropertyEditor() {
return featureModelPropertyEditor;
}
FeatureRelationManager getFeatureRelationManager() {
return featureRelationManager;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public Map getAllFeature() {
return (Map) allFeatures.clone();
}
public Set getAllFeatureRelationNames() {
return allRelations.keySet();
}
public Map getAllFeatureRelation() {
Collection collect = allRelations.values();
if (collect.isEmpty())
return null;
Iterator children = collect.iterator();
TreeMap rv = new TreeMap();
while (children.hasNext()) {
Map child = (Map) children.next();
rv.putAll(child);
}
return rv;
}
/* public Map<String, FeatureRelation> getAllFeatureRelation(String relationName) {
if (relationName == null)
return null;
if (relationName.equals(""))
return null;
Map<String, FeatureRelation> child = allRelations.get(relationName);
if (child == null)
return null;
else
return child;
}*/
public Map getAllFeatureRelation(String relationName) {
if (relationName == null)
return null;
if (relationName.equals(""))
return null;
TreeMap child = (TreeMap) allRelations.get(relationName);
if (child == null)
return null;
else
return (Map) child.clone();
}
public Feature getFeature(String id) {
if (id == null) return null;
return (Feature) allFeatures.get(id);
}
public Feature getParentFeature(String id) {
String parentId = null;
if (id != null) {
Map mapInclude = getFeatureRelation(FeatureRelationProperties.DECOMPOSE, id, false);
Map mapDimVal = getFeatureRelation(FeatureRelationProperties.ATTRIBUTE, id, false);
//--unite 2 maps
Map map = mapInclude;
if (map != null) {
if (mapDimVal != null)
map.putAll(mapDimVal);
} else {
map = mapDimVal;
}
//--no parent
if ((map == null) || map.size() == 0)
return null;
//--mutiple parent
if (map.size() > 1)
throw new RuntimeException("model error founded: mutiple refinement relation pointed to one feature");
//--one parent
Iterator it = map.values().iterator();
if (it.hasNext()) {
FeatureRelation fr = (FeatureRelation) it.next();
parentId = fr.getStartFeature().getID();
}
}
if (parentId != null)
return getFeature(parentId);
return null;
}
public Feature getRootFeature(String id) {
String rootId = id;
while (id != null) {
rootId = id;
Feature parent = getParentFeature(id);
if (parent != null)
id = parent.getID();
else
id = null;
}
if (rootId != null)
return getFeature(rootId);
return null;
}
public List<Feature> getChildrenFeature(String id) {
List<Feature> listChildren = new ArrayList<Feature>();
if (id == null)
return listChildren;
Map mapInclude = getFeatureRelation(FeatureRelationProperties.DECOMPOSE, id, true);
Map mapDimVal = getFeatureRelation(FeatureRelationProperties.ATTRIBUTE, id, true);
//--unite 2 maps
Map map = mapInclude;
if (map != null) {
if (mapDimVal != null)
map.putAll(mapDimVal);
} else {
map = mapDimVal;
}
if (map == null)
return listChildren;
Iterator it = map.values().iterator();
while (it.hasNext()) {
FeatureRelation fr = (FeatureRelation) it.next();
Feature feature = fr.getEndFeature();
listChildren.add(feature);
}
return listChildren;
}
public List<Feature> getChildrenFeatureByComposition(String id) {
return getChildrenFeatureByRelation(id, FeatureRelationProperties.DECOMPOSE);
}
public List<Feature> getChildrenFeatureByCharacterization(String id) {
return getChildrenFeatureByRelation(id, FeatureRelationProperties.ATTRIBUTE);
}
private List<Feature> getChildrenFeatureByRelation(String id, String relation) {
List<Feature> listChildren = new ArrayList<Feature>();
if (id == null)
return listChildren;
Map map = getFeatureRelation(relation, id, true);
if (map == null)
return listChildren;
Iterator it = map.values().iterator();
while (it.hasNext()) {
FeatureRelation fr = (FeatureRelation) it.next();
Feature feature = fr.getEndFeature();
listChildren.add(feature);
}
return listChildren;
}
public FeatureRelation getFeatureRelation(String id) {
if (id == null) return null;
Iterator iterator = allRelations.values().iterator();
while (iterator.hasNext()) {
Map map = (Map) iterator.next();
Object rv = map.get(id);
if (rv != null)
return (FeatureRelation) rv;
}
return null;
}
public FeatureRelation getFeatureRelation(String relationName, String startFID, String endFID) {
Feature start = getFeature(startFID);
Feature end = getFeature(endFID);
return getFeatureRelation(relationName, start, end);
}
public FeatureRelation getFeatureRelation(String relationName, Feature start, Feature end) {
if ((relationName == null) || (start == null) || (end == null)) {
return null;
}
Map child = (Map) allRelations.get(relationName);
if (child == null)
return null;
Iterator iterator = child.values().iterator();
while (iterator.hasNext()) {
FeatureRelation relation = (FeatureRelation) iterator.next();
if ((relation.getStartFeature() == start) && (relation.getEndFeature() == end))
return relation;
}
return null;
}
public Map getFeatureRelation(String relationName, String featureID, boolean isStart) {
Feature feature = getFeature(featureID);
return getFeatureRelation(relationName, feature, isStart);
}
public Map getFeatureRelation(String relationName, Feature feature, boolean isStart) {
if ((relationName == null) || (feature == null)) {
return null;
}
Map child = (Map) allRelations.get(relationName);
if (child == null)
return null;
Map rv = new TreeMap();
Iterator iterator = child.values().iterator();
while (iterator.hasNext()) {
FeatureRelation relation = (FeatureRelation) iterator.next();
if (isStart) {
if (relation.getStartFeature() == feature) {
rv.put(relation.getID(), relation);
}
} else {
if (relation.getEndFeature() == feature) {
rv.put(relation.getID(), relation);
}
}
}
return rv;
}
public Map getFeatureRelation(String relationName, String featureID) {
Feature feature = getFeature(featureID);
return getFeatureRelation(relationName, feature);
}
public Map getFeatureRelation(String relationName, Feature feature) {
if ((relationName == null) || (feature == null)) {
return null;
}
Map child = (Map) allRelations.get(relationName);
if (child == null)
return null;
Map rv = new TreeMap();
Iterator iterator = child.values().iterator();
while (iterator.hasNext()) {
FeatureRelation relation = (FeatureRelation) iterator.next();
if ((relation.getStartFeature() == feature) || (relation.getEndFeature() == feature)) {
rv.put(relation.getID(), relation);
}
}
return rv;
}
public boolean contains(Feature feature) {
return allFeatures.containsKey(feature.getID());
}
public boolean containsFeature(String id) {
if (id == null) return false;
return allFeatures.containsKey(id);
}
public boolean contains(FeatureRelation relation) {
return contains(relation.getName(), relation.getStartFeature(), relation.getEndFeature());
}
public boolean containsFeatureRelation(String id) {
Iterator iterator = allRelations.values().iterator();
while (iterator.hasNext()) {
Map map = (Map) iterator.next();
Object rv = map.get(id);
if (rv != null)
return true;
}
return false;
}
public boolean containsFeatureRelations(String relationName) {
if (relationName == null) {
return false;
}
Map child = (Map) allRelations.get(relationName);
if (child == null)
return false;
else
return true;
}
public boolean contains(String relationName, Feature start, Feature end) {
if ((relationName == null) || (start == null) || (end == null)) {
return false;
}
Map child = (Map) allRelations.get(relationName);
if (child == null)
return false;
boolean isSymmetric = featureRelationManager.isSymmetric(relationName);
Iterator iterator = child.values().iterator();
while (iterator.hasNext()) {
FeatureRelation relation = (FeatureRelation) iterator.next();
if (!isSymmetric) {
if ((relation.getStartFeature() == start) && (relation.getEndFeature() == end))
return true;
} else {
if (((relation.getStartFeature() == start) && (relation.getEndFeature() == end))
|| ((relation.getStartFeature() == end) && (relation.getEndFeature() == start)))
return true;
}
}
return false;
}
public boolean contains(String relationName, String startFID, String endFID) {
Feature start = getFeature(startFID);
Feature end = getFeature(endFID);
return contains(relationName, start, end);
}
/**
* ���ݹ�ϵ���ͣ���ѯһ��Ϊ�ض������Ĺ�ϵ�Ƿ����
*
* @param relationName
* @param feature
* @param isStart
* @return
*/
public boolean containsFeatureRelation(String relationName, Feature feature, boolean isStart) {
if ((relationName == null) || (feature == null)) {
return false;
}
Map child = (Map) allRelations.get(relationName);
if (child == null)
return false;
boolean flag = false;
Iterator iterator = child.values().iterator();
while (iterator.hasNext()) {
FeatureRelation relation = (FeatureRelation) iterator.next();
if (isStart) {
if (relation.getStartFeature() == feature) {
flag = true;
break;
}
} else {
if (relation.getEndFeature() == feature) {
flag = true;
break;
}
}
}
return flag;
}
public boolean containsFeatureRelation(String relationName, String featureID, boolean isStart) {
Feature feature = getFeature(featureID);
return containsFeatureRelation(relationName, feature, isStart);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(listener);
}
public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
}
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(propertyName, listener);
}
class FeatureModelPropertyEditorImplementation implements FeatureModelPropertyEditor {
public void setName(String name) {
String oldName = FeatureModelImplementation.this.name;
FeatureModelImplementation.this.name = name;
propertyChangeSupport.firePropertyChange(FeatureModelProperties.NAME, oldName, name);
}
public void setDescription(String description) {
String oldDescription = FeatureModelImplementation.this.description;
FeatureModelImplementation.this.description = description;
propertyChangeSupport.firePropertyChange(FeatureModelProperties.DESCRIPTION, oldDescription, description);
}
}
class FeatureModelEditorImplementation implements FeatureModelEditor {
public Feature addFeature(String name, String id) {
if (name == null) return null;
Feature feature = new FeatureImplementation(name, id, FeatureModelImplementation.this.allRelations);
getFeatureEditor().setName(feature, name);
allFeatures.put(feature.getID(), feature);
propertyChangeSupport.firePropertyChange(FeatureModelProperties.FEATURE_ADDED, null, feature);
return feature;
}
public Feature addFeature(String name) {
if (name == null) return null;
Feature feature = new FeatureImplementation(name, FeatureModelImplementation.this.allRelations);
getFeatureEditor().setName(feature, name);
allFeatures.put(feature.getID(), feature);
propertyChangeSupport.firePropertyChange(FeatureModelProperties.FEATURE_ADDED, null, feature);
return feature;
}
public void removeFeature(String id) {
removeFeature(getFeature(id));
}
public void removeFeature(Feature feature) {
if (feature == null) return;
if (!FeatureModelImplementation.this.contains(feature)) return;
//clear all its relation with other features in the feature model
Set relationSet = feature.getAllRelatedRelation();
if (relationSet != null) {
Iterator iterator = relationSet.iterator();
while (iterator.hasNext()) {
FeatureRelation relation = (FeatureRelation) iterator.next();
removeRelation(relation);
}
}
allFeatures.remove(feature.getID());
propertyChangeSupport.firePropertyChange(FeatureModelProperties.FEATURE_REMOVED, feature, null);
}
public FeatureRelation addRelation(FeatureRelation relation) {
return addRelation(relation.getName(), relation.getStartFeature(), relation.getEndFeature());
}
public FeatureRelation addRelation(String relationName, Feature start, Feature end) {
if ((relationName == null) || (start == null) || (end == null)) {
return null;
}
relationName = relationName.trim();
if (relationName.equals(""))
return null;
FeatureRelation preExistedRelation = getFeatureRelation(relationName, start, end);
if (preExistedRelation != null)
return preExistedRelation;
Map child = (Map) allRelations.get(relationName);
if (child == null) {
child = new TreeMap();
allRelations.put(relationName, child);
}
FeatureRelation relation = new FeatureRelationImplementation(relationName, start, end);
child.put(relation.getID(), relation);
propertyChangeSupport.firePropertyChange(FeatureModelProperties.RELATION_ADDED, null, relation);
return relation;
}
public FeatureRelation addRelation(String relationName, String relationID, Feature start, Feature end) {
if ((relationName == null) || (start == null) || (end == null)) {
return null;
}
relationName = relationName.trim();
if (relationName.equals(""))
return null;
FeatureRelation preExistedRelation = getFeatureRelation(relationName, start, end);
if (preExistedRelation != null)
return preExistedRelation;
Map child = (Map) allRelations.get(relationName);
if (child == null) {
child = new TreeMap();
allRelations.put(relationName, child);
}
FeatureRelation relation = new FeatureRelationImplementation(relationName, relationID, start, end);
child.put(relation.getID(), relation);
propertyChangeSupport.firePropertyChange(FeatureModelProperties.RELATION_ADDED, null, relation);
return relation;
}
public FeatureRelation addRelation(String relationName, String startFID, String endFID) {
Feature start = getFeature(startFID);
Feature end = getFeature(endFID);
return addRelation(relationName, start, end);
}
public FeatureRelation addRelation(String relationName, String relationID, String startFID, String endFID) {
Feature start = getFeature(startFID);
Feature end = getFeature(endFID);
return addRelation(relationName, relationID, start, end);
}
public void removeRelation(String id) {
removeRelation(getFeatureRelation(id));
}
public void removeRelation(FeatureRelation relation) {
removeRelation(relation.getName(), relation.getStartFeature(), relation.getEndFeature());
}
public void removeRelation(String relationName, Feature start, Feature end) {
if ((relationName == null) || (start == null) || (end == null)) {
return;
}
relationName = relationName.trim();
if (relationName.equals(""))
return;
if (!contains(relationName, start, end))
return;
boolean isSymmetric = featureRelationManager.isSymmetric(relationName);
Map child = (Map) allRelations.get(relationName);
FeatureRelation traget = null;
Iterator iterator = child.values().iterator();
while (iterator.hasNext()) {
FeatureRelation relation = (FeatureRelation) iterator.next();
if (!isSymmetric) {
if ((relation.getStartFeature() == start) && (relation.getEndFeature() == end)) {
traget = relation;
break;
}
} else {
if (((relation.getStartFeature() == start) && (relation.getEndFeature() == end))
|| ((relation.getStartFeature() == end) && (relation.getEndFeature() == start))) {
traget = relation;
break;
}
}
}
child.remove(traget.getID());
propertyChangeSupport.firePropertyChange(FeatureModelProperties.RELATION_REMOVED, traget, null);
if (child.isEmpty()) {
allRelations.remove(relationName);
}
}
public void removeRelation(String relationName, String startFID, String endFID) {
Feature start = getFeature(startFID);
Feature end = getFeature(endFID);
removeRelation(relationName, start, end);
}
}
}