Files
Brainstorm/Foundation TCV SWT Server/src/com/foundation/tcv/swt/server/ValueHolder.java

251 lines
9.9 KiB
Java
Raw Normal View History

2014-05-30 10:31:51 -07:00
/*
* 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//