📄 attributetablemodel.java
字号:
package com.ca.directory.jxplorer.viewer.tableviewer;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.event.*;
import javax.naming.*;
import javax.naming.directory.*;
import com.ca.commons.naming.*;
public class AttributeTableModel extends AbstractTableModel
{
protected boolean dataChanged = false; // whether the user has modified the data.
int noRows = 0;
DXEntry oldEntry; // the original, unedited data
Vector attributeTypes = new Vector(); // vector of string IDs
Vector attributeValues = new Vector(); // vector of attributeValues
/**
* The number of naming values (e.g. the length of the
* namingTypes/namingRawValues vectors).
*/
int numberNamingValues;
/**
* <p>The ordered list of naming types (e.g. ['cn', 'id']) </p>
* <p>The namingTypes and namingRawValues arrays are set from
* the RDN. They are then used to identify the corresponding
* naming AttributeValues, which are used to recreate the RDN
* later (as required).</p>
* <p>So the logic goes RDN -> string arrays -> array of naming
* attributes -> RDN
*/
String[] namingTypes;
/**
* The ordered list of naming values (e.g. ['Joe Bloggs', '7670001'])
*/
String[] namingRawValues;
/**
* Returns the size of the naming RDN.
*/
public int getRDNSize()
{
return numberNamingValues;
}
/**
* Returns the class of the objects in the different columns:
* AttributeType.class for col 0, AttributeValue.class for col 1.
*/
public Class getColumnClass(int c)
{
return (c==1)?AttributeValue.class: AttributeType.class;
}
/**
* Returns number of columns (=2)
*/
public int getColumnCount() { return 2; }
/**
* Returns number of rows (varies dynamically)
*/
public int getRowCount() { return noRows;}
/**
* Allows a cell value to be set (should only ever be the
* second column, col=1).
*/
public void setValueAt(Object aValue,int row,int col)
{
dataChanged = true;
if (col == 1) // which it jolly well should...
{
if (aValue instanceof AttributeValue) // replace an attributeValues
{
attributeValues.set(row, aValue);
}
else // ... or update it.
{
((AttributeValue)attributeValues.elementAt(row)).update(aValue);
}
fireTableCellUpdated(row, col);
}
}
/**
* Returns a value as a string. Null and zero length string are
* made 1 character blank strings, so that the joke called swing
* printing can be kludged to work.
*/
public String getStringValueAt(int row, int col)
{
String s = getValueAt(row,col).toString();
if ((s == null) || (s.length()==0))
s = " ";
return s;
}
/**
* Return the object at a given position.
*/
public Object getValueAt(int row, int col)
{
return (col==0)?attributeTypes.elementAt(row):attributeValues.elementAt(row);
}
/**
* Whether a particular column is editable (yes if col!=0)
*/
public boolean isCellEditable(int row, int col)
{
if (col == 0) return false; // can't edit attribute names
if (col > 1) return false; // should never happen.
if (attributeTypes.elementAt(row).toString().equalsIgnoreCase("objectclass"))
return false; // can't edit object classes (this way)
return true;
}
/**
* Gets column header names.
*/
public String getColumnName(int columnIndex)
{
return (columnIndex == 0)?("attribute type"):("value");
}
/**
* 'Resets' the value of all attribute Value cells back to their original value.
*/
public void reset()
{
dataChanged = false;
/*
* Return each attribute to the original value.
*/
for (int i=0; i<attributeValues.size(); i++)
((AttributeValue)attributeValues.elementAt(i)).reset();
/*
* Return the naming attribute list to the original
* (if necessary)
*/
RDN rdn = oldEntry.getRDN();
if (rdn.equals(getRDN()) == false)
setRDN(rdn);
/*
* All done - and the data has probably changed!
*/
fireChange();
}
/**
* Removes all data leaving an empty table.
*/
public void clear()
{
dataChanged = false; // well, it sorta has I guess, but this is only done when
// we're starting from scratch.
noRows = 0;
attributeTypes.clear();
attributeValues.clear();
fireChange();
}
/**
* Insert a set of attributes into the table.
*/
public void insertAttributes(DXEntry entry)
{
/*
* Check that we've got data to edit.
*/
if (entry==null) return;
/*
* Clear the decks for the new entry.
*/
oldEntry = entry;
noRows = 0;
attributeTypes.clear();
attributeValues.clear();
/*
* work through the attributes, adding each attribute to the
* table model.
*/
try
{
/*
* First, figure out the naming attibutes. setRDN sets
* the string array of naming types/values. Once set, these
* are used by insertAttribute to mark them as special values.
*/
RDN rdn = entry.getRDN();
setRDN(rdn);
/*
* First, get the mandatory attributes which every entry 'MUST' contain.
*/
DXNamingEnumeration mandatory = (DXNamingEnumeration)entry.getMandatory();
while (mandatory.hasMore())
insertAttribute(((DXAttribute)mandatory.next()), AttributeType.MANDATORY);
/*
* Then add the 'MAY' contain optional attributes.
*/
DXNamingEnumeration active = (DXNamingEnumeration)entry.getAllNonNull();
active.sort();
while (active.hasMore())
{
DXAttribute temp = (DXAttribute) active.next();
if (mandatory.contains(temp)==false && (temp.size()>0) && (temp.get() != null))
{
temp.sort();
insertAttribute(temp, AttributeType.NORMAL);
}
}
// finally add attributes without values (i.e. ones that the user could add)
// XXX need special code for null Binary attributes...
DXNamingEnumeration possible = (DXNamingEnumeration)entry.getAll();
possible.sort();
while (possible.hasMore())
{
DXAttribute temp = (DXAttribute) possible.next();
if (mandatory.contains(temp)==false && ((temp.size()==0) || (temp.get() == null)))
{
insertAttribute(temp, AttributeType.NORMAL);
}
}
fireChange();
// This particular action we ignore, since it is the one that initially
// sets up the table.
dataChanged = false;
}
catch (NamingException e)
{
System.err.println("Naming Exception in AttributeTableModel: " + e);
}
catch (Exception e2)
{
System.err.println("Unexpected Exception in AttributeTableModel: " + e2);
e2.printStackTrace();
}
}
/**
* Sets up the list of naming attribute types - values pairs.
* (usually there is only ONE naming value, but sometimes an
* entry is multi valued).
* @param rdn the RDN to extract the naming information from.
*/
protected void setRDN(RDN rdn)
{
numberNamingValues = rdn.size(); // almost always 1, but sometimes...
namingTypes = new String[numberNamingValues];
namingRawValues = new String[numberNamingValues];
for (int i=0; i<numberNamingValues; i++)
{
namingTypes[i] = rdn.getAtt(i);
namingRawValues[i] = rdn.getRawVal(i);
}
}
/**
* Adds a single attribute, and (possibly multiple, or blank) values
* to the table.
*/
public void insertAttribute(DXAttribute att, int type)
throws NamingException
{
//boolean addingNamingValue = false;
String namingValue = null; // the exact naming value for this attribute (if any)
String ID = att.getID();
NamingEnumeration values = att.getAll();
//shiba modified to enable list selection
AttributeValue newAV = new AttributeValue(ID, ""); ;
/*
* Add the Attribute to the internal data vectors.
*/
if (att.size() == 0) // the attribute has no data (although the user may enter some later)
{
newAV = new AttributeValue(ID, "");
if (att.isString() == false)
{
newAV.setBinary(true);
}
addAttribute(ID, newAV, type);
}
else // The attribute already has one or more data values.
{
/*
* Check if we're adding a naming value - returns null if not...
*/
namingValue = getAnyNamingValue(ID);
// XXX If we want to support binary naming attributes, we would need to do some
// nifty base-64 encoding comparison stuff here...
if (namingValue != null && att.isString() == false)
throw new NamingException("Binary naming attributes not supported in JXplorer: can't use attribute " + ID + " to name an entry");
while (values.hasMore())
{
newAV = new AttributeValue(ID, values.next());
/*
* Set a Binary Attribute
*/
if (att.isString()==false)
{
newAV.setBinary(true);
}
/*
* Checks (and possibly Flags) that an AttributeValue
* is a Naming Value.
*/
if (namingValue != null && newAV.getStringValue().equalsIgnoreCase(namingValue))
newAV.setNamingStatus(true);
/*
* Adds the attribute to the table.
*/
addAttribute(ID, newAV, type);
}
}
//shiba modified to enable list selection
if (att instanceof DXAttribute)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -