package de.FeatureModellingTool.PLModelChecker.RelationAnalysis;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import de.FeatureModellingTool.FeatureModel.ConstraintModel;
import de.FeatureModellingTool.FeatureModel.Feature;
import de.FeatureModellingTool.FeatureModel.FeatureModel;
import de.FeatureModellingTool.PLModelChecker.RelationAnalysis.ConstraintRelationDiagram.NGraph;
import de.FeatureModellingTool.PLModelChecker.RelationAnalysis.ConstraintRelationDiagram.NNode;
public class FeatureReorder {
public FeatureReorder(FeatureModel fm , ConstraintModel cm) {
this.fm = fm;
this.cm = cm;
this.crd = new ConstraintRelationDiagram(fm , cm , null);
}
protected FeatureModel fm = null;
protected ConstraintModel cm = null;
protected ConstraintRelationDiagram crd = null;
public List<Feature> getFeatureOrder() {
List<Feature> result = new ArrayList<Feature>();
Set<NGraph> graphs = this.crd.getGraph().getConnectedGraph();
getFeatureOrder(graphs , result);
return result;
}
protected void getFeatureOrder(Set<NGraph> graphs , List<Feature> result) {
if (graphs.size()==0) {
return;
}
for (Iterator<NGraph> itGraph=graphs.iterator() ; itGraph.hasNext() ; ) {
getFeatureOrder(itGraph.next() , result);
}
}
protected void getFeatureOrder(NGraph graph , List<Feature> result) {
int graphSize = graph.nodes.size();
if (graphSize==0) {
return;
}
if (graphSize<=40) {
addNodeDepth(graph , result);
return;
}
ConstraintRelationDiagram.Bridge bridge = graph.getBestBridge(20 , 0.6);
if (bridge==null) {
addNodeDepth(graph , result);
return;
}
int bridgeSize = ConstraintRelationDiagram.getConnectedGraphMaxSize(bridge.connectedGraph);
if (bridgeSize>graphSize-20 || bridgeSize>graphSize*0.6) {
addNodeDepth(graph , result);
return;
}
getFeatureOrder(graph , bridge.node , result);
}
protected void getFeatureOrder(NGraph graph , NNode node , List<Feature> result) {
result.add(node.feature);
node.setEnabled(false);
Set<NGraph> connectedGraphs = graph.getConnectedGraph();
this.getFeatureOrder(connectedGraphs , result);
}
protected void addNodeDepth(NGraph graph , List<Feature> result) {
HashSet<Feature> roots = new HashSet<Feature>();
for (Iterator<NNode> itNode=graph.nodes.values().iterator() ; itNode.hasNext() ; ) {
Feature f = itNode.next().feature;
Feature father = this.fm.getParentFeature(f.getID());
while (father!=null && graph.nodes.containsKey(father)) {
f = father;
father = this.fm.getParentFeature(f.getID());
}
if (!roots.contains(f)) {
roots.add(f);
}
}
for (Iterator<Feature> itFeature=roots.iterator() ; itFeature.hasNext() ; ) {
Feature root = itFeature.next();
addNodeDepth(root , graph.nodes.keySet() , result);
}
}
protected void addNodeDepth(Feature father , Set<Feature> permitFeatures , List<Feature> result) {
result.add(father);
List<Feature> children = this.fm.getChildrenFeature(father.getID());
for (int i=0 ; i<children.size() ; i++) {
Feature child = children.get(i);
if (permitFeatures.contains(child)) {
addNodeDepth(child , permitFeatures , result);
}
}
}
}