Initial commit from SVN.

This commit is contained in:
wcrisman
2014-05-30 10:31:51 -07:00
commit b45e56b890
1968 changed files with 370949 additions and 0 deletions

View File

@@ -0,0 +1,460 @@
/*
* Copyright (c) 2004,2009 Declarative Engineering LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Declarative Engineering LLC
* verson 1 which accompanies this distribution, and is available at
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
*/
package com.foundation.tcv.swt.server;
import com.common.util.ICollection;
import com.common.util.IIterator;
import com.common.util.IList;
import com.common.util.LiteList;
import com.common.util.optimized.IntArray;
import com.foundation.tcv.swt.ITreeComponent;
import com.foundation.tcv.swt.server.SimpleTreeTable.SimpleNodeData;
import com.foundation.tcv.view.IAbstractRemoteViewComponent;
import com.foundation.tcv.view.ViewMessage;
import com.foundation.view.IAbstractComponent;
/*
* Tries to push as much common tree component code down to a reusable base class.
*/
public abstract class TreeComponent extends CollectionComponent implements ITreeComponent {
/** The collection of columns (AbstractColumn) in server order. */
private IList tableColumns = new LiteList(16);
/**
* Encapsulates all the data pertaining to a single column in the table component.
*/
public static abstract class AbstractColumn implements IAbstractComponent, IAbstractRemoteViewComponent {
/**
* Registers an item in the collection with this column.
* <p>An item can be registered more than once, but must be unregistered just as many times.</p>
* @param rowObject The row to be registered.
*/
protected void registerItem(RowObject rowObject) {
}//registerItem()//
/**
* Unregisters an item that had been previously registered.
* @param rowObject The row to be unregistered.
*/
protected void unregisterItem(RowObject rowObject) {
}//unregisterItem()//
/**
* Unregisters all items that had been previously registered.
*/
protected void unregisterAllItems() {
}//unregisterAllItems()//
/**
* Refreshes the value for the cell(s) denoted by the item representing the row(s) and this column.
* @param item The item that represents the row(s).
* @return Whether the cell data was altered by the refresh.
*/
protected abstract boolean refreshCellData(Object item);
/**
* Gets the value for the cell(s) denoted by the item representing the row(s) and this column.
* @param item The item that represents the row(s).
* @return The cell value.
*/
protected abstract Object getCellData(Object item);
/**
* Gets the column's creation index.
* @return The index assigned to this column and used to facilitate communication with the actual column resource in the display.
*/
protected abstract int getIndex();
/**
* Sets the column's creation index.
* @param index The index assigned to this column and used to facilitate communication with the actual column resource in the display.
*/
protected abstract void setIndex(int index);
/**
* Initializes the column before the table component is initialized.
*/
protected abstract void initialize();
/**
* Refreshes the column.
*/
protected abstract void refresh();
/**
* Initializes the column before the table component is released.
*/
protected abstract void release();
/* (non-Javadoc)
* @see com.foundation.tcv.view.IAbstractViewComponent#processMessage(com.foundation.tcv.view.ViewMessage)
*/
public Object processMessage(ViewMessage viewMessage) {
return null;
}//processMessage()//
}//AbstractColumn//
/**
* TreeComponent constructor.
* @param parent The parent container for this component.
* @param name The name of the component.
*/
public TreeComponent(Container parent, String name, int style) {
super(parent, name, style);
}//TreeComponent()//
/**
* Adds a column to the component.
* @param column The column to be added.
*/
protected void addColumn(AbstractColumn column) {
tableColumns.add(column.getIndex(), column);
//Update the other column indices.//
for(int index = column.getIndex() + 1; index < tableColumns.getSize(); index++) {
((AbstractColumn) tableColumns.get(index)).setIndex(index);
}//for//
//Notify the client.//
sendMessage(MESSAGE_ADD_COLUMN, new Integer(column.getIndex()));
//TODO: Support columns added after the display is showing.//
if(isInitialized()) {
//Note: While it would be nice to send the header and cell data, we can't because the column hasn't been setup yet.//
//TODO: Send the initial header data.//
//TODO: Need to send the initial cell data.//
}//if//
}//addColumn()//
/**
* Gets the number of columns in the table.
* @return The count of columns.
*/
protected int getColumnCount() {
return tableColumns.getSize();
}//getColumnCount()//
/**
* Gets the column at the given index.
* @param index The zero based column index.
* @return The column at the given index.
*/
protected AbstractColumn getColumn(int index) {
return (AbstractColumn) tableColumns.get(index);
}//getColumn()//
/* (non-Javadoc)
* @see com.foundation.tcv.swt.server.CollectionComponent#internalViewRefreshCollection(com.common.util.ICollection, com.common.util.ICollection)
*/
protected void internalViewRefreshCollection(ICollection newCollection, ICollection oldCollection) {
sendMessage(MESSAGE_SAVE_VIEW_STATE, null);
//Clear the old data.//
primaryCollectionItemsRemoved();
//Rebuild the tree.//
if(newCollection != null) {
IIterator itemIterator = newCollection.iterator();
//Get the array of strings representing the list contents.//
while(itemIterator.hasNext()) {
Object item = itemIterator.next();
placeItem(null, item);
}//while//
}//if//
//If the selection was invalid previously then refresh the selection since it may no longer be invalid.//
if(isSelectionInvalid) {
internalViewRefreshSelection();
}//if//
sendMessage(MESSAGE_RESTORE_VIEW_STATE, null);
}//internalViewRefreshCollection()//
/* (non-Javadoc)
* @see com.foundation.tcv.swt.server.CollectionComponent#internalViewRefreshSelection(java.lang.Object)
*/
protected void internalViewRefreshSelection(Object selectedItem) {
if(selectedItem != null) {
RowObject rowObject = (RowObject) getRowObject(selectedItem);
if(rowObject == null) {
isSelectionInvalid = true;
sendMessage(MESSAGE_SET_SELECTION, null);
}//if//
else {
isSelectionInvalid = false;
sendMessage(MESSAGE_SET_SELECTION, new int[] {rowObject.objectId});
}//else//
}//if//
else {
//No selection.//
sendMessage(MESSAGE_SET_SELECTION, null);
}//else//
}//internalViewRefreshSelection()//
/* (non-Javadoc)
* @see com.foundation.tcv.swt.server.CollectionComponent#internalViewRefreshSelections(com.common.util.ICollection, com.common.util.ICollection)
*/
protected void internalViewRefreshSelections(ICollection newSelections, ICollection oldSelections) {
if(newSelections != null) {
IntArray selectionObjectIds = new IntArray(newSelections.getSize());
IIterator selectionIterator = newSelections.iterator();
//Apply differences between the selection collection and the control selection. Also remove all impossible selections.//
while(selectionIterator.hasNext()) {
Object selection = selectionIterator.next();
RowObject rowObject = (RowObject) getRowObject(selection);
if(rowObject == null) {
//An invalid selection because the selection is not in the collection of displayed values.//
selectionIterator.remove();
}//if//
else {
selectionObjectIds.add(rowObject.objectId);
}//else//
}//while//
sendMessage(MESSAGE_SET_SELECTION, selectionObjectIds.toArray());
}//if//
else {
//Remove all selections.//
sendMessage(MESSAGE_REMOVE_SELECTIONS, null);
}//else//
}//internalViewRefreshSelections()//
/* (non-Javadoc)
* @see com.foundation.tcv.swt.server.CollectionComponent#internalViewInitialize()
*/
protected void internalViewInitialize() {
//Initialize all the columns.//
for(int columnIndex = 0; columnIndex < tableColumns.getSize(); columnIndex++) {
((AbstractColumn) tableColumns.get(columnIndex)).initialize();
}//for//
super.internalViewInitialize();
}//internalViewInitialize()//
/* (non-Javadoc)
* @see com.foundation.tcv.swt.server.CollectionComponent#internalViewRefresh()
*/
protected void internalViewRefresh() {
super.internalViewRefresh();
//Refresh all the columns.//
for(int columnIndex = 0; columnIndex < tableColumns.getSize(); columnIndex++) {
((AbstractColumn) tableColumns.get(columnIndex)).refresh();
}//for//
}//internalViewRefresh()//
/* (non-Javadoc)
* @see com.foundation.view.swt.AbstractComponent#internalViewRelease()
*/
protected void internalViewRelease() {
//Release all the columns.//
for(int columnIndex = 0; columnIndex < tableColumns.getSize(); columnIndex++) {
((AbstractColumn) tableColumns.get(columnIndex)).release();
}//for//
super.internalViewRelease();
}//internalViewRelease()//
/* (non-Javadoc)
* @see com.foundation.tcv.swt.server.CollectionComponent#itemSorted(int[])
*/
protected void itemSorted(int[] mapping) {
//TODO: Should this be implemented?
//sendMessage(MESSAGE_ORDER_ROWS, mapping);
}//itemSorted()//
/* (non-Javadoc)
* @see com.foundation.tcv.swt.server.CollectionComponent#selectionAdded(java.lang.Object)
*/
protected void selectionAdded(Object value) {
RowObject rowObject = getRowObject(value);
if(rowObject != null) {
sendMessage(MESSAGE_ADD_SELECTION, null, null, rowObject.objectId, -1);
}//if//
}//selectionAdded()//
/* (non-Javadoc)
* @see com.foundation.tcv.swt.server.CollectionComponent#selectionRemoved(java.lang.Object)
*/
protected void selectionRemoved(Object value) {
RowObject rowObject = getRowObject(value);
if(rowObject != null) {
sendMessage(MESSAGE_REMOVE_SELECTION, null, null, rowObject.objectId, -1);
}//if//
}//selectionRemoved()//
/* (non-Javadoc)
* @see com.foundation.tcv.swt.server.CollectionComponent#selectionAllRemoved()
*/
protected void selectionAllRemoved() {
sendMessage(MESSAGE_REMOVE_ALL_SELECTIONS, null);
}//selectionAllRemoved()//
/* (non-Javadoc)
* @see com.foundation.tcv.swt.server.CollectionComponent#registerItem(com.foundation.tcv.swt.server.RowObject)
*/
protected void registerItem(RowObject rowObject) {
super.registerItem(rowObject);
//Add the item to each of the columns so we receive updates.//
for(int index = 0; index < tableColumns.getSize(); index++) {
((AbstractColumn) tableColumns.get(index)).registerItem(rowObject);
}//for//
}//registerItem()//
/* (non-Javadoc)
* @see com.foundation.tcv.swt.server.CollectionComponent#unregisterItem(com.foundation.tcv.swt.server.RowObject)
*/
protected void unregisterItem(RowObject rowObject) {
super.unregisterItem(rowObject);
//Unregister the value with the columns so we stop receiving updates.//
for(int index = 0; index < tableColumns.getSize(); index++) {
((AbstractColumn) tableColumns.get(index)).unregisterItem(rowObject);
}//for//
}//unregisterItem()//
/* (non-Javadoc)
* @see com.foundation.tcv.swt.server.CollectionComponent#unregisterItems()
*/
protected void unregisterItems() {
super.unregisterItems();
//Unregister the items from the columns so we stop recieving updates.//
for(int index = 0; index < tableColumns.getSize(); index++) {
((AbstractColumn) tableColumns.get(index)).unregisterAllItems();
}//for//
}//unregisterItems()//
/* (non-Javadoc)
* @see com.foundation.tcv.swt.server.CollectionComponent#getItemData(com.foundation.tcv.swt.server.RowObject)
*/
protected Object getItemData(RowObject rowObject) {
Object[] result = new Object[tableColumns.getSize() + 1];
refreshRowHeaderCellData(rowObject.value);
result[0] = getRowHeaderCellData(rowObject.value);
for(int index = 0; index < result.length; index++) {
AbstractColumn column = (AbstractColumn) tableColumns.get(index);
if(column != null) {
column.refreshCellData(rowObject.value);
result[index + 1] = column.getCellData(rowObject.value);
}//if//
}//for//
return result;
}//getItemData()//
protected void sendAddItemMessage(RowObject rowObject, int itemIndex) {
//Don't send duplicate messages since the client doesn't care.//
if(rowObject.isFirstReference()) {
//TODO: Figure out how to get whether the value can have children from the row object. Send 0 if no children, 1 if can have children.
sendMessage(MESSAGE_ADD_ITEM, getItemData(rowObject), getItemHiddenData(rowObject.value), rowObject.objectId, canHaveChildren(rowObject.value) ? 1 : 0);
}//if//
}//sendAddItemMessage()//
/* (non-Javadoc)
* @see com.foundation.tcv.swt.server.CollectionComponent#sendRemoveItemMessage(com.foundation.tcv.swt.server.CollectionComponent.RowObject, int, boolean)
*/
protected void sendRemoveItemMessage(RowObject rowObject, int itemIndex, boolean isRemovedEntirely) {
if(isRemovedEntirely) {
sendMessage(MESSAGE_REMOVE_ITEM, null, null, rowObject.objectId, itemIndex);
}//if//
}//sendRemoveItemMessage()//
/**
* Refreshes the row header cell data and determines whether there were substantial alterations.
* @param item The row item.
* @return Whether the cell data was changed.
*/
protected abstract boolean refreshRowHeaderCellData(Object item);
/**
* Gets the row header cell data.
* @param item The row item.
* @return The cell data for the row's row header.
*/
protected abstract Object getRowHeaderCellData(Object item);
/**
* Determines whether the passed item might have children.
* @param item The item to check.
* @return Whether the item could have children.
*/
protected abstract boolean canHaveChildren(Object item);
/**
* Places the item as a child of the given node. It may be grouped so that it is an indirect child of the given node.
* @param node The node that will have the item as a child. This may be null if the item is at the root of the tree.
* @param item The non-grouping item that is placed under the node.
*/
protected abstract void placeItem(SimpleNodeData node, Object item);
/* (non-Javadoc)
* @see com.foundation.tcv.view.IViewComponent#processMessage(com.foundation.tcv.model.ViewMessage)
*/
public Object processMessage(ViewMessage viewMessage) {
Object retVal = null;
switch(viewMessage.getMessageNumber()) {
case MESSAGE_VIEW_SYNCHRONIZE_SELECTION: { //Receive the selection information from the client.//
Object messageData = viewMessage.getMessageData();
if(getAllowMultiSelection()) {
int[] selectionObjectIds = (int[]) messageData;
boolean[] selectionMarks = new boolean[selectionObjectIds.length];
ICollection modelSelections = getModelSelections();
//Prevent the selection additions from causing a feedback loop.//
suspendSelectionHooks = true;
try {
if(modelSelections != null) {
IIterator iterator = modelSelections.iterator();
LiteList removed = new LiteList(modelSelections.getSize());
LiteList added = new LiteList(selectionObjectIds.length);
//Initialize the bit field.//
for(int index = 0; index < selectionMarks.length; index++) {
selectionMarks[index] = false;
}//for//
//For each previous selection, try to find a matching current selection, otherwise remove it. Mark all used current selections.//
while(iterator.hasNext()) {
Object next = iterator.next();
RowObject rowObject = getRowObject(next);
if(rowObject != null) {
int nextObjectId = rowObject.objectId;
boolean found = false;
for(int index = 0; (!found) && (index < selectionObjectIds.length); index++) {
if((selectionObjectIds[index] == nextObjectId) && (!selectionMarks[index])) {
selectionMarks[index] = true;
found = true;
}//if//
}//for//
//If the selection wasn't found in the view then remove it from the model.//
if(!found) {
removed.add(next);
}//if//
//Add the selections that were in the view but not in the model.//
for(int index = 0; index < selectionMarks.length; index++) {
if(!selectionMarks[index]) {
RowObject wrapper = (RowObject) getRowObject(selectionObjectIds[index]);
if(wrapper != null) {
added.add(wrapper.value);
}//if//
}//if//
}//for//
}//if//
}//while//
modelSelections.replaceAll(removed, added);
}//if//
}//try//
finally {
suspendSelectionHooks = false;
}//finally//
}//if//
else {
int selectedObjectId = messageData != null ? ((Integer) messageData).intValue() : -1;
RowObject selectedRowObject = (RowObject) (selectedObjectId >= 0 ? getRowObject(selectedObjectId) : null);
setModelSelection(selectedRowObject == null ? null : selectedRowObject.value);
}//else//
if(getAutoValidate()) {
postSynchronizeValidate();
}//if//
break;
}//case//
default: {
retVal = super.processMessage(viewMessage);
}//default//
}//switch//
return retVal;
}//processMessage()//
}//TreeComponent//