package de.FeatureModellingTool.Customize.ui;
import java.awt.Component;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import javax.swing.tree.TreePath;
import org.jdesktop.swingx.treetable.DefaultTreeTableModel;
import de.FeatureModellingTool.Customize.ConstantDefinition;
import de.FeatureModellingTool.Customize.CustomizationVersion;
import de.FeatureModellingTool.Customize.ui.ConstraintExplorerCellRenderHelperManager.ConstraintExplorerCellRenderHelper;
import de.FeatureModellingTool.FeatureModel.Constraint;
import de.FeatureModellingTool.FeatureModel.ConstraintModel;
import de.FeatureModellingTool.FeatureModel.Feature;
import de.FeatureModellingTool.FeatureModel.FeatureModel;
import de.FeatureModellingTool.FeatureModel.FeatureRelation;
import de.FeatureModellingTool.FeatureModel.Variability;
import de.reuse.Context;
import de.reuse.ContextImplementation;
public class ConstraintExplorerTreeModel extends DefaultTreeTableModel {
public ConstraintExplorerTreeModel(ConstraintExplorerTreeNode root) {
super(root);
this.columnIndexConstraintTable = new Hashtable<Integer , Object>();
this.idNodeTable = new Hashtable<String , ConstraintExplorerTreeNode>();
this.context.addContextChangeListener(new ContextChangeListener());
}
protected final ContextImplementation context = new ContextImplementation();
public Context getContext() {
return this.context;
}
FeatureModel featureModel = null;
ConstraintModel constraintModel = null;
CustomizationVersion customizationVersion = null;
Hashtable<Integer , Object> columnIndexConstraintTable = null;
Hashtable<String , ConstraintExplorerTreeNode> idNodeTable = null;
protected class ContextChangeListener implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent e) {
String propertyName = e.getPropertyName();
if (ConstantDefinition.FEATURE_MODEL.equals(propertyName)) {
bindFeatureModel((FeatureModel) e.getNewValue());
}
if (ConstantDefinition.CONSTRAINT_MODEL.equals(propertyName)) {
bindConstraintModel((ConstraintModel) e.getNewValue());
}
if (ConstantDefinition.CUSTOMIZATION_VERSION.equals(propertyName)) {
bindCustomizationVersion((CustomizationVersion) e.getNewValue());
}
}
}
private void filterFeatures(FeatureModel fm , ConstraintModel cm , Set<Feature> fs) {
for(Iterator<Constraint> itc=cm.getAllConstraint().values().iterator() ; itc.hasNext() ; ) {
Constraint con = itc.next();
ConstraintExplorerCellRenderHelper helper = ConstraintExplorerCellRenderHelperManager.getInstance().getHelper(con);
fs.addAll(helper.getRelatedFeatures(con));
}
if (fm.getAllFeatureRelation()!=null) {
for (Iterator<FeatureRelation> itRelation=fm.getAllFeatureRelation().values().iterator() ; itRelation.hasNext() ; ) {
FeatureRelation relation = itRelation.next();
if (relation.getName().equals(FeatureRelation.REQUIRE) || relation.getName().equals(FeatureRelation.EXCLUDE)) {
fs.add(relation.getStartFeature());
fs.add(relation.getEndFeature());
}
}
}
for (Iterator<Feature> itFeature=fm.getAllFeature().values().iterator() ; itFeature.hasNext() ; ) {
Feature feature = itFeature.next();
if (feature.getVariability().getName().equals(Variability.Optional) && !fs.contains(feature)) {
fs.add(feature);
}
}
HashSet<Feature> parents = new HashSet<Feature>();
for (Iterator<Feature> itFeature=fs.iterator() ; itFeature.hasNext() ; ) {
filterFeatures(fm , itFeature.next() , parents);
}
fs.addAll(parents);
}
private void filterFeatures(FeatureModel fm , Feature feature , Set<Feature> parents) {
Feature fParent = fm.getParentFeature(feature.getID());
if (fParent!=null) {
parents.add(fParent);
filterFeatures(fm , fParent , parents);
}
}
private void bindFeatureModel(FeatureModel featureModel) {
this.featureModel = featureModel;
}
protected class FeatureComparator implements Comparator<Feature> {
public int compare(Feature f1 , Feature f2) {
return f2.getName().compareTo(f1.getName());
}
}
private void bindFeature(ConstraintExplorerTreeNode parent , Feature feature , FeatureModel featureModel , Set<Feature> allowFeatures) {
if (allowFeatures.contains(feature)) {
ConstraintExplorerTreeNode node = new ConstraintExplorerTreeNode();
node.getContext().putValue(ConstantDefinition.FEATURE , feature);
this.idNodeTable.put(feature.getID() , node);
parent.add(node);
List<Feature> children = featureModel.getChildrenFeature(feature.getID());
Collections.sort(children , new FeatureComparator());
for (int i=0 ; i<children.size() ; i++) {
Feature child = children.get(i);
this.bindFeature(node , child, featureModel , allowFeatures);
}
}
}
private void bindConstraintModel(ConstraintModel constraintModel) {
this.constraintModel = constraintModel;
HashSet<Feature> fs = new HashSet<Feature>();
filterFeatures(this.featureModel , this.constraintModel , fs);
ConstraintExplorerTreeNode root = (ConstraintExplorerTreeNode)this.getRoot();
List<Feature> featureList = new ArrayList<Feature>();
for (Iterator<Feature> it = (Iterator<Feature>)featureModel.getAllFeature().values().iterator() ; it.hasNext() ; ) {
Feature feature = it.next();
if (featureModel.getParentFeature(feature.getID())==null) {
featureList.add(feature);
}
}
Collections.sort(featureList , new FeatureComparator());
for (int i=0 ; i<featureList.size() ; i++) {
this.bindFeature(root , featureList.get(i) , featureModel , fs);
}
int i = 1;
if (this.featureModel.getAllFeatureRelation()!=null) {
for (Iterator<FeatureRelation> it = this.featureModel.getAllFeatureRelation().values().iterator() ; it.hasNext() ; ) {
FeatureRelation relation = it.next();
if (relation.getName().equals(FeatureRelation.REQUIRE) || relation.getName().equals(FeatureRelation.EXCLUDE)) {
this.columnIndexConstraintTable.put(i , relation);
i++;
}
}
}
if (this.constraintModel.getAllConstraint()!=null) {
for (Iterator<Constraint> it = this.constraintModel.getAllConstraint().values().iterator() ; it.hasNext() ; ) {
this.columnIndexConstraintTable.put(i , it.next());
i++;
}
}
}
private void bindCustomizationVersion(CustomizationVersion customizationVersion) {
this.customizationVersion = customizationVersion;
ConstraintExplorerTreeNode root = (ConstraintExplorerTreeNode)this.getRoot();
bindCustomizationVersion(customizationVersion , root);
}
private void bindCustomizationVersion(CustomizationVersion customizationVersion , ConstraintExplorerTreeNode node) {
node.getContext().putValue(ConstantDefinition.CUSTOMIZATION_VERSION , customizationVersion);
for (int i=0 ; i<node.getChildCount() ; i++) {
bindCustomizationVersion(customizationVersion , (ConstraintExplorerTreeNode)node.getChildAt(i));
}
}
@Override
public int getColumnCount() {
if (this.constraintModel==null) {
return 1;
}
return 1 + this.columnIndexConstraintTable.size();
}
public int getHierarchicalColumn() {
return 0;
}
protected class JTableCellRenderer extends DefaultTableCellRenderer implements TableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
JLabel result = (JLabel)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
result.setIcon(null);
result.setText("");
ConstraintExplorerTreeNode node = (ConstraintExplorerTreeNode)value;
if (node==null || node.getFeature()==null || node.getCustomizationVersion()==null) {
return this;
}
if (column==0) {
result.setText((String)value);
return this;
}
Object cons = columnIndexConstraintTable.get(column);
if (cons!=null) {
ConstraintExplorerCellRenderHelper helper = ConstraintExplorerCellRenderHelperManager
.getInstance().getHelper(cons);
if (helper != null) {
helper.setLabelStat(cons, node, result , this);
}
}
return this;
}
}
protected class JTableHeaderRenderer extends DefaultTableCellRenderer implements TableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
if (column==0) {
setIcon(null);
setText("����");
return this;
}
Object cons = columnIndexConstraintTable.get(column);
if (cons!=null) {
ConstraintExplorerCellRenderHelper helper = ConstraintExplorerCellRenderHelperManager
.getInstance().getHelper(cons);
if (helper != null) {
setHorizontalAlignment(SwingConstants.CENTER);
setIcon(helper.getConstraintIcon(cons , constraintModel , customizationVersion));
setText("");
}
}
return this;
}
}
private JTableCellRenderer cellRender = new JTableCellRenderer();
public TableCellRenderer getCellRenderer() {
return this.cellRender;
}
private JTableHeaderRenderer headerRender = new JTableHeaderRenderer();
public JTableHeaderRenderer getHeaderRender() {
return this.headerRender;
}
public boolean moveColumnByFeature(Feature feature) {
List<Object> targetList = new ArrayList<Object>();
List<Object> leftList = new ArrayList<Object>();
int conCount = this.columnIndexConstraintTable.size();
for (int i=1 ; i<=conCount ; i++) {
Object con = this.columnIndexConstraintTable.get(i);
ConstraintExplorerCellRenderHelper helper = ConstraintExplorerCellRenderHelperManager.getInstance().getHelper(con);
if (helper.isRelatedFeature(this.columnIndexConstraintTable.get(i) , feature)) {
targetList.add(this.columnIndexConstraintTable.get(i));
} else {
leftList.add(this.columnIndexConstraintTable.get(i));
}
}
if (targetList.size()>0) {
this.columnIndexConstraintTable.clear();
int columnIndex = 1;
for (int i=0 ; i<targetList.size() ; i++) {
this.columnIndexConstraintTable.put(columnIndex , targetList.get(i));
columnIndex++;
}
for (int i=0 ; i<leftList.size() ; i++) {
this.columnIndexConstraintTable.put(columnIndex , leftList.get(i));
columnIndex++;
}
return true;
}
return false;
}
private List<TreePath> getConstraintPathes(Object con) {
List<TreePath> result = new ArrayList<TreePath>();
ConstraintExplorerCellRenderHelper helper = ConstraintExplorerCellRenderHelperManager.getInstance().getHelper(con);
Set<Feature> sFeature = helper.getRelatedFeatures(con);
for (Iterator<Feature> itFeature = sFeature.iterator() ; itFeature.hasNext() ; ) {
Feature feature = itFeature.next();
ConstraintExplorerTreeNode node = this.idNodeTable.get(feature.getID());
List<ConstraintExplorerTreeNode> path = node.getPath(false);
if (path.size()>0) {
TreePath treePath = new TreePath(path.toArray());
result.add(treePath);
}
}
return result;
}
public List<TreePath> getConstraintPathes(int columnIndex) {
return this.getConstraintPathes(this.columnIndexConstraintTable.get(columnIndex));
}
}