package org.osbl.agent.gui;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import org.osbl.agent.model.Rule;
import org.wingx.table.XTableModel;
/**
* The table-model for the table in the SidePanel showing the Rules.
*
* @author Sebastian Nozzi.
*/
abstract class SidePanelTableModel extends XTableModel {
/** The current user. */
private String currentUser;
/**
* Gets the current rules, taking the filters into account.
*
* @return the current rules
*/
abstract List<Rule> getCurrentRules();
/**
* Called when the Rules are updated.
*/
abstract void rulesUpdated();
/**
* Gets the current user.
*
* @return the current user
*/
public String getCurrentUser() {
return currentUser;
}
/**
* Sets the current user.
*
* @param currentUser the new current user
*/
public void setCurrentUser(String currentUser) {
this.currentUser = currentUser;
}
/*
* (non-Javadoc)
*
* @see javax.swing.table.AbstractTableModel#getColumnClass(int)
*/
public Class<?> getColumnClass(int columnIndex) {
// As the first column corresponds to the Rule name...
if (columnIndex == 0)
// ...class of column is String
return String.class;
// The second column corresponds to the public/non-public checkbox...
else
// ...which results in a Boolean value.
return Boolean.class;
}
/*
* (non-Javadoc)
*
* @see javax.swing.table.TableModel#getColumnCount()
*/
public int getColumnCount() {
// Columns are "name" and "public" (or not).
return 2;
}
/*
* (non-Javadoc)
*
* @see javax.swing.table.AbstractTableModel#getColumnName(int)
*/
public String getColumnName(int columnIndex) {
final String[] names = { DesignContext.getMsg("name"), DesignContext.getMsg("public") };
return names[columnIndex];
}
/*
* (non-Javadoc)
*
* @see javax.swing.table.TableModel#getRowCount()
*/
public int getRowCount() {
// There are as many rows as applicable (depending on selected
// process/activity pair) Rules.
int result = getCurrentRules().size();
return result;
}
/*
* (non-Javadoc)
*
* @see javax.swing.table.TableModel#getValueAt(int, int)
*/
public Object getValueAt(int rowIndex, int columnIndex) {
Object result = null;
// ...
Rule aRule = getCurrentRules().get(rowIndex);
// First column is Rules's name.
if (columnIndex == 0) {
result = aRule.getName();
// If the name is too long...
if (((String) result).length() > 16)
// ...truncate it.
result = ((String) result).substring(0, 16) + "...";
}
// Second column is the Rule's public state...
if (columnIndex == 1) {
// For Rules that the user owns, return the public state...
if (aRule.getCreatorUser().equals(currentUser))
// ...as a Boolean instance.
result = new Boolean(aRule.isPublic());
// For foreign Rules return the creator's user-id as a String.
else
result = aRule.getCreatorUser();
}
// Return the gathered result.
return result;
}
/*
* (non-Javadoc)
*
* @see javax.swing.table.AbstractTableModel#isCellEditable(int, int)
*/
public boolean isCellEditable(int rowIndex, int columnIndex) {
// Cell is not directly editable (which would allow the Rule's name to
// be editable after a double-click) but through custom renderers.
return false;
}
/*
* (non-Javadoc)
*
* @see javax.swing.table.AbstractTableModel#setValueAt(java.lang.Object,
* int, int)
*/
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
List<Rule> rules = getCurrentRules();
// Return immediately if there are no current Rules.
if (rules.size() == 0)
return;
// Get current Rule (from the RulesWithContext).
Rule aRule = rules.get(rowIndex);
// Return immediately if an attempt is being made to modify
// a foreign Rule (not from this user).
if (aRule.getCreatorUser().equals(currentUser) == false)
return;
// After this, the Rule is from the current user.
// Let the user change the public/non-public state of the Rule
if (columnIndex == 1) {
boolean oldPublicStatus = aRule.isPublic();
boolean newPublicStatus = ((Boolean) aValue).booleanValue();
if(oldPublicStatus!=newPublicStatus){
aRule.setPublic(newPublicStatus);
// Since the internal state of the Rule changed, we
// need to notify of this fact...
rulesUpdated();
}
}
}
/*
* (non-Javadoc)
*
* @see org.wingx.table.RefreshableModel#refresh()
*/
public void refresh() {
// Convert current RuleWithContext list to an array.
Rule[] rulesAsArray = getCurrentRules()
// Note that we can't call toArray() since we want a RuleWithContext[] and not
// an Object[], so we have to use the "too small array" trick.
.toArray(new Rule[0]);
// Sort our newly created array using a custom-defined criteria, which reflects
// the current column-sorting settings of the table...
Arrays.sort(rulesAsArray, new Comparator<Rule>() {
// Sorting setting for first column (name of Rule).
int nameSort = SidePanelTableModel.this.getSort(0);
// Sorting setting for second column (public state of Rule).
int publicSort = SidePanelTableModel.this.getSort(1);
// Compare two RuleWithContext...
public int compare(Rule left, Rule right) {
// This forces our own Rules to appear first on the table...
if (left.getCreatorUser().equals(currentUser)
&& right.getCreatorUser().equals(currentUser) == false)
// Own Rules (left) always win (are "less") over foreign Rules.
return -1;
// Take the opposite case (foreign, left vs. own, right) into account.
else if (left.getCreatorUser().equals(currentUser) == false
&& right.getCreatorUser().equals(currentUser))
return 1;
// At this point the Rules are either both our own, or both foreign.
// So, further comparison DOES depend on the table criteria from now on.
// Are we sorting by name?
if (nameSort != XTableModel.SORT_NONE) {
// Compare names with String's compareTo...
int nameComparison = (left.getName().compareTo(right
.getName()));
// If names are not equal
if (nameComparison != 0)
// Return the String comparison we did, taking into account
// the sorting order of the column.
return nameComparison
* ((nameSort == XTableModel.SORT_ASCENDING) ? 1
: -1);
else {
// Names WERE equal but we are we ALSO sorting by public-state?
if (publicSort != XTableModel.SORT_NONE) {
// Public-states are different?
if (left.isPublic() != right.isPublic()) {
// Return boolean comparison modified by
// sorting order
return (new Boolean(left.isPublic())
.compareTo(new Boolean(right
.isPublic())))
* ((publicSort == XTableModel.SORT_ASCENDING) ? 1
: -1);
}
}
}
// We are JUST sorting by public-state...
} else if (publicSort != XTableModel.SORT_NONE) {
// Public-states are different?
if (left.isPublic() != right.isPublic()) {
// Return boolean comparison modified by sorting
// order
return (new Boolean(left.isPublic())
.compareTo(new Boolean(right.isPublic())))
* ((publicSort == XTableModel.SORT_ASCENDING) ? 1
: -1);
}
}
// At this point no acceptable comparison criterum was found/met.
// Consider the Rules equal and finish the comparison.
return 0;
}
});
// Get the List of current RuleWithContext...
List<Rule> currentRules = getCurrentRules();
// ...empty it...
currentRules.clear();
// ... and re-fill it with the same RuleWithContext, but ordered...
for (Rule r : rulesAsArray) {
currentRules.add(r);
}
// ... force table to re-render...
fireTableDataChanged();
}
}
|