251 lines
9.9 KiB
Java
251 lines
9.9 KiB
Java
/*
|
|
* Copyright (c) 2002,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.*;
|
|
import com.common.debug.*;
|
|
import com.foundation.view.*;
|
|
import com.foundation.controller.IController;
|
|
import com.foundation.event.*;
|
|
|
|
/*
|
|
* Encapsulates an object reference used by the view system at runtime, and the class of the runtime reference to allow design type automation.
|
|
*/
|
|
public class ValueHolder extends Component implements IValueHolder {
|
|
/** The class of value held by this value holder. */
|
|
private Class heldType = null;
|
|
/** The current value held by this value holder. */
|
|
private IEventEmitter value = null;
|
|
/** The collection of listeners listening for held value events. */
|
|
private LiteHashSet eventListeners = new LiteHashSet(5);
|
|
/** The collection of listeners listening for held value events. */
|
|
private LiteHashSet valueHolderListeners = new LiteHashSet(5, LiteHashSet.DEFAULT_LOAD_FACTOR, LiteHashSet.DEFAULT_COMPARATOR, LiteHashSet.STYLE_COUNT_DUPLICATES);
|
|
/** The event support used by value holder related associations to listen for held value events. */
|
|
private EventSupport eventSupport = null;
|
|
/** The parent resource from which this holder's value is derived. */
|
|
private SingleResourceAssociation parent = new SingleResourceAssociation(this, this, getViewContext(), SingleResourceAssociation.TYPE_OBJECT, false, null);
|
|
/** Whether the value holder gets its value from a parent. */
|
|
private boolean hasParent = false;
|
|
/** Whether to not warn when an attempt is made to place a value that is not of the correct type. */
|
|
private boolean ignoreWarnings = false;
|
|
/**
|
|
* ValueHolder constructor.
|
|
* @param parent The parent container.
|
|
* @param name The view unqiue name of the component.
|
|
* @param heldType The type of object to be held by the value holder.
|
|
*/
|
|
public ValueHolder(IAbstractContainer parent, String name, Class heldType) {
|
|
super(parent, name, 0);
|
|
|
|
this.heldType = heldType;
|
|
}//ValueHolder()//
|
|
/**
|
|
* Sets whether the holder supresses warnings relating to attempts at setting the value to an invalid object type.
|
|
* @param ignoreWarnings Whether to not warn when an attempt is made to place a value that is not of the correct type.
|
|
*/
|
|
public void ignoreWarnings(boolean ignoreWarnings) {
|
|
this.ignoreWarnings = ignoreWarnings;
|
|
}//ignoreWarnings()//
|
|
/**
|
|
* Sets the association container used to access the parent value holder.
|
|
* @param container The parent association metadata.
|
|
*/
|
|
public void setParentAssociation(SingleAssociationContainer container) {
|
|
verifyThread();
|
|
this.parent.setAssociations(container);
|
|
this.hasParent = true;
|
|
}//setParentAssociation()//
|
|
/**
|
|
* Gets the support object that provides event listening functionality.
|
|
* @return Will be used to listen for events from IEventEmitter objects.
|
|
*/
|
|
protected EventSupport getEventSupport() {
|
|
if(eventSupport == null) {
|
|
eventSupport = new EventSupport(null);
|
|
}//if//
|
|
|
|
return eventSupport;
|
|
}//getEventSupport()//
|
|
/**
|
|
* Gets the value being held by this holder.
|
|
* @return The currently held value.
|
|
*/
|
|
public IEventEmitter getValue() {
|
|
return value;
|
|
}//getValue()//
|
|
/**
|
|
* Gets the class for the values held by this value holder.
|
|
* @return The held value type.
|
|
*/
|
|
public Class getHeldType() {
|
|
return heldType;
|
|
}//getHeldType()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.IValueHolder#registerListener(com.foundation.view.IEventCapableAssociation)
|
|
*/
|
|
public void registerListener(IEventCapableAssociation eventAssociation) {
|
|
IEventEmitter value = getValue();
|
|
|
|
if((value != null) && (eventAssociation.getEventNumber() != -1) && ((eventAssociation.getValueHolderHeldType() == null) || (eventAssociation.getValueHolderHeldType().isAssignableFrom(value.getClass())))) {
|
|
getEventSupport().register(value, eventAssociation.getEventNumber(), eventAssociation, true);
|
|
}//if//
|
|
|
|
eventListeners.add(eventAssociation);
|
|
}//registerListener()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.IValueHolder#unregisterListener(com.foundation.view.IEventCapableAssociation)
|
|
*/
|
|
public void unregisterListener(IEventCapableAssociation eventAssociation) {
|
|
IEventEmitter value = getValue();
|
|
|
|
if((value != null) && (eventAssociation.getEventNumber() != -1) && ((eventAssociation.getValueHolderHeldType() == null) || (eventAssociation.getValueHolderHeldType().isAssignableFrom(value.getClass())))) {
|
|
getEventSupport().unregister(value, eventAssociation.getEventNumber(), eventAssociation);
|
|
}//if//
|
|
|
|
eventListeners.remove(eventAssociation);
|
|
}//unregisterListener()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.IValueHolder#registerListener(com.foundation.view.IValueHolderListener)
|
|
*/
|
|
public void registerListener(IValueHolderListener listener) {
|
|
valueHolderListeners.add(listener);
|
|
}//registerListener()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.view.IValueHolder#unregisterListener(com.foundation.view.IValueHolderListener)
|
|
*/
|
|
public void unregisterListener(IValueHolderListener listener) {
|
|
valueHolderListeners.remove(listener);
|
|
}//unregisterListener()//
|
|
/**
|
|
* Updates the registered listeners so that they are registered with the new held value and are notified that their attributes may have changed.
|
|
* @param oldHeldValue The old value held by this value holder.
|
|
* @param newHeldValue The new value held by this value holder.
|
|
*/
|
|
public synchronized void updateRegisteredListeners(IEventEmitter oldHeldValue, IEventEmitter newHeldValue) {
|
|
IIterator iterator = new LiteHashSet(eventListeners).iterator();
|
|
|
|
//Unregister and reregister handlers.//
|
|
while(iterator.hasNext()) {
|
|
IEventCapableAssociation eventAssociation = (IEventCapableAssociation) iterator.next();
|
|
|
|
if((oldHeldValue != null) && ((eventAssociation.getValueHolderHeldType() == null) || (eventAssociation.getValueHolderHeldType().isAssignableFrom(value.getClass())))) {
|
|
getEventSupport().unregister(oldHeldValue, eventAssociation.getEventNumber(), eventAssociation);
|
|
}//if//
|
|
|
|
if((newHeldValue != null) && ((eventAssociation.getValueHolderHeldType() == null) || (eventAssociation.getValueHolderHeldType().isAssignableFrom(value.getClass())))) {
|
|
getEventSupport().register(newHeldValue, eventAssociation.getEventNumber(), eventAssociation, true);
|
|
}//if//
|
|
}//while//
|
|
|
|
iterator.resetToFront();
|
|
|
|
while(iterator.hasNext()) {
|
|
IEventCapableAssociation eventAssociation = (IEventCapableAssociation) iterator.next();
|
|
|
|
eventAssociation.evaluate(eventAssociation.getEventNumber(), null, 0);
|
|
}//while//
|
|
|
|
//Notify the listeners so their user can update.//
|
|
if(valueHolderListeners.getSize() > 0) {
|
|
Object[] listeners = valueHolderListeners.toArray();
|
|
|
|
for(int index = 0; index < listeners.length; index++) {
|
|
IValueHolderListener listener = (IValueHolderListener) listeners[index];
|
|
|
|
listener.heldValueChanged();
|
|
}//while//
|
|
}//if//
|
|
}//updateRegisteredListeners()//
|
|
/**
|
|
* Sets the value being held.
|
|
* @param value The held value.
|
|
*/
|
|
protected void setValue(IEventEmitter value) {
|
|
if(value != this.value) {
|
|
IEventEmitter oldValue = this.value;
|
|
|
|
this.value = value;
|
|
updateRegisteredListeners(oldValue, value);
|
|
}//if//
|
|
}//setValue()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.tcv.swt.server.AbstractComponent#internalViewInitialize()
|
|
*/
|
|
protected void internalViewInitialize() {
|
|
parent.initialize();
|
|
isInitialized(true);
|
|
}//internalViewInitialize()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.tcv.swt.server.AbstractComponent#internalViewRelease()
|
|
*/
|
|
public void internalViewRelease() {
|
|
parent.release();
|
|
|
|
if(getContainer() != null) {
|
|
getContainer().getComponents().remove(this);
|
|
}//if//
|
|
}//internalViewRelease()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.tcv.swt.server.AbstractComponent#internalViewRefresh()
|
|
*/
|
|
protected void internalViewRefresh() {
|
|
if(isInitialized()) {
|
|
if(hasParent) {
|
|
if(parent.refresh()) {
|
|
Object value = parent.getValue();
|
|
|
|
if((value == null) || (value instanceof IEventEmitter) && (heldType.isAssignableFrom(value.getClass()))) {
|
|
setValue((IEventEmitter) value);
|
|
}//if//
|
|
else if(!ignoreWarnings) {
|
|
if(value instanceof IEventEmitter) {
|
|
Debug.log("Invalid held object. Received a " + value.getClass().getName() + " and was expecting a " + heldType.getName() + " in the ValueHolder named " + getName() + ".");
|
|
}//if//
|
|
else {
|
|
Debug.log("Invalid held object. The class " + value.getClass().getName() + " does not implement " + IEventEmitter.class.getName() + " in the ValueHolder named " + getName() + ".");
|
|
}//else//
|
|
}//else if//
|
|
}//if//
|
|
}//if//
|
|
else {
|
|
IAbstractContainer parent = getContainer();
|
|
IController controller = null;
|
|
|
|
while((parent != null) && (controller == null)) {
|
|
if(parent instanceof IView) {
|
|
controller = ((IView) parent).getController();
|
|
}//if//
|
|
else {
|
|
parent = parent.getContainer();
|
|
}//else//
|
|
}//while//
|
|
|
|
if((controller != null) && (controller.getClass().isAssignableFrom(heldType))) {
|
|
setValue((IEventEmitter) controller);
|
|
}//if//
|
|
else if(!controller.getClass().isAssignableFrom(heldType)) {
|
|
Debug.log("Invalid controller object. Received a " + controller.getClass().getName() + " and was expecting a " + heldType.getName() + " in the ValueHolder named " + getName() + ".");
|
|
}//else if//
|
|
}//else//
|
|
}//if//
|
|
}//internalViewRefresh()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.tcv.swt.server.AbstractComponent#internalOnValueChanged(com.foundation.view.SingleResourceAssociation)
|
|
*/
|
|
protected void internalOnValueChanged(SingleResourceAssociation resourceAssociation, int flags) {
|
|
if(isInitialized()) {
|
|
internalViewRefresh();
|
|
}//if//
|
|
}//internalOnValueChanged()//
|
|
/* (non-Javadoc)
|
|
* @see com.foundation.tcv.swt.server.AbstractComponent#getClientClassName()
|
|
*/
|
|
protected String getClientClassName() {
|
|
return StringSupport.EMPTY_STRING;
|
|
}//getClientClassName()//
|
|
}//ValueHolder// |