732 lines
31 KiB
Java
732 lines
31 KiB
Java
|
|
/*
|
||
|
|
* Copyright (c) 2003,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 java.io.File;
|
||
|
|
import java.io.FileInputStream;
|
||
|
|
import java.io.IOException;
|
||
|
|
import java.io.FileNotFoundException;
|
||
|
|
import com.common.debug.*;
|
||
|
|
import com.common.util.optimized.ObjectIntHashMap;
|
||
|
|
import com.foundation.view.*;
|
||
|
|
import com.foundation.view.resource.AbstractResourceService;
|
||
|
|
import com.foundation.controller.AbstractViewController;
|
||
|
|
import com.foundation.controller.DecorationManager;
|
||
|
|
import com.foundation.event.*;
|
||
|
|
import com.foundation.tcv.server.controller.*;
|
||
|
|
import com.foundation.tcv.view.*;
|
||
|
|
|
||
|
|
public abstract class AbstractComponent implements com.foundation.tcv.swt.IAbstractComponent, IAbstractComponent, IAbstractRemoteViewComponent, IEventHandler {
|
||
|
|
/** Identifies the controller for the client session that this component interacts over. */
|
||
|
|
private SessionViewController sessionViewController = null;
|
||
|
|
/** The component's number. This allows lookup of components in the view by the number. */
|
||
|
|
private int number = -1;
|
||
|
|
/** The handler for all requests. All requests should pass through this handler so they are handled on the proper thread in the proper order. */
|
||
|
|
private IViewRequestHandler requestHandler = null;
|
||
|
|
/** Flags the component to suppress all updates to the view. This is useful for hidden components that will be explicitly refreshed. */
|
||
|
|
private boolean suppressUpdates = false;
|
||
|
|
/** Whether the component has already been initialized. This is useful when setting attributes which require initialization after or durring the component's initialization. */
|
||
|
|
private boolean isInitialized = false;
|
||
|
|
/** The last used decoration identifier number. */
|
||
|
|
private int lastDecorationNumber = 0;
|
||
|
|
/** A mapping of decoration identifier numbers by the decoration. */
|
||
|
|
private ObjectIntHashMap decorationMap = new ObjectIntHashMap(5);
|
||
|
|
/**
|
||
|
|
* AbstractComponent default constructor.
|
||
|
|
*/
|
||
|
|
public AbstractComponent() {
|
||
|
|
}//AbstractComponent()//
|
||
|
|
/**
|
||
|
|
* AbstractComponent constructor.
|
||
|
|
* @param sessionViewController The view component's session controller.
|
||
|
|
*/
|
||
|
|
public AbstractComponent(SessionViewController sessionViewController) {
|
||
|
|
super();
|
||
|
|
String clientClassName = getClientClassName();
|
||
|
|
|
||
|
|
this.sessionViewController = sessionViewController;
|
||
|
|
|
||
|
|
requestHandler = sessionViewController.getViewRequestHandler();
|
||
|
|
|
||
|
|
//Notify the client to create the control if the control has a client side part.//
|
||
|
|
if((clientClassName != null) && (clientClassName.length() > 0)) {
|
||
|
|
number = sessionViewController.registerComponent(this);
|
||
|
|
sessionViewController.sendMessage(new ViewMessage(0, MESSAGE_CREATE_COMPONENT, getClientClassName(), null, number, 0, true), false);
|
||
|
|
}//if//
|
||
|
|
else if(clientClassName == null) {
|
||
|
|
Debug.log("Error: Must implement the getClientClassName() method and return a non-null value from the class: " + getClass().getName());
|
||
|
|
}//else if//
|
||
|
|
}//AbstractComponent()//
|
||
|
|
/**
|
||
|
|
* Suspends all layouts and packing while the view is getting setup.
|
||
|
|
*/
|
||
|
|
public void suspendLayouts() {
|
||
|
|
sendMessage(MESSAGE_SUSPEND_LAYOUTS, null, null, 1, -1);
|
||
|
|
}//suspendLayouts()//
|
||
|
|
/**
|
||
|
|
* Resumes processing of requests to layout or pack components.
|
||
|
|
*/
|
||
|
|
public void resumeLayouts() {
|
||
|
|
sendMessage(MESSAGE_SUSPEND_LAYOUTS, null);
|
||
|
|
}//resumeLayouts()//
|
||
|
|
/**
|
||
|
|
* Whether the component is suspending all layouts and packing while the view is getting setup.
|
||
|
|
* @return Whether the component should not layout or pack.
|
||
|
|
*/
|
||
|
|
public boolean isSuspendingLayouts() {
|
||
|
|
return false;
|
||
|
|
}//isSuspendingLayouts()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.IView#getViewContext()
|
||
|
|
*/
|
||
|
|
public IViewContext getViewContext() {
|
||
|
|
return getSessionViewController().getSessionController();
|
||
|
|
}//getViewContext()//
|
||
|
|
/**
|
||
|
|
* Gets the session view controller for the component.
|
||
|
|
* @return The component's session view controller.
|
||
|
|
*/
|
||
|
|
public SessionViewController getSessionViewController() {
|
||
|
|
return sessionViewController;
|
||
|
|
}//getSessionViewController()//
|
||
|
|
/**
|
||
|
|
* Gets the event loop used to queue outside requests so that the internals are mostly single threaded.
|
||
|
|
* @return The request handler that single threads external requests (from the application). Internal requests from the remote process will be handled on a different thread.
|
||
|
|
*/
|
||
|
|
protected IViewRequestHandler getEventLoop() {
|
||
|
|
return requestHandler;
|
||
|
|
}//getEventLoop()//
|
||
|
|
/**
|
||
|
|
* Sets the menu for the component.
|
||
|
|
* @param menu The menu optionally used by the component.
|
||
|
|
*/
|
||
|
|
public void setMenu(Menu menu) {
|
||
|
|
//Does nothing.//
|
||
|
|
}//setMenu()//
|
||
|
|
/**
|
||
|
|
* Determines whether the calling thread is the view's event thread.
|
||
|
|
* @return Whether the view's event thread and the calling thread are one and the same.
|
||
|
|
* @link com.foundation.view.IView.isViewThread()
|
||
|
|
*/
|
||
|
|
public boolean isViewThread() {
|
||
|
|
return getEventLoop().isRequestThread();
|
||
|
|
}//isViewThread()//
|
||
|
|
/**
|
||
|
|
* Verifies that the calling thread is allowed access to the view components.
|
||
|
|
* <p>Note: This is really a debug only operation and should be turned off for production applications.</p>
|
||
|
|
*/
|
||
|
|
public void verifyThread() {
|
||
|
|
if(!isViewThread()) {
|
||
|
|
Debug.log(new RuntimeException("Error: Invalid thread."));
|
||
|
|
}//if//
|
||
|
|
}//verifyThread()//
|
||
|
|
/**
|
||
|
|
* Determines whether updates to the view should be suppressed.
|
||
|
|
* @return Whether update suppression is requested.
|
||
|
|
*/
|
||
|
|
public boolean suppressUpdates() {
|
||
|
|
return suppressUpdates;
|
||
|
|
}//suppressUpdates()//
|
||
|
|
/**
|
||
|
|
* Determines whether updates to the view should be suppressed.
|
||
|
|
* @param suppressUpdates Whether update suppression is requested.
|
||
|
|
*/
|
||
|
|
public void suppressUpdates(boolean suppressUpdates) {
|
||
|
|
this.suppressUpdates = suppressUpdates;
|
||
|
|
}//suppressUpdates()//
|
||
|
|
/**
|
||
|
|
* Determines whether the component has already been initialized. This is useful when setting attributes which require initialization after or during the component's initialization.
|
||
|
|
* @return Whether the component's internalViewInitalize method has been or is being run.
|
||
|
|
*/
|
||
|
|
protected boolean isInitialized() {
|
||
|
|
return isInitialized;
|
||
|
|
}//isInitialized()//
|
||
|
|
/**
|
||
|
|
* Determines whether the component has already been initialized.
|
||
|
|
* @param isInitialized Whether the component's internalViewInitalize method has been or is being run.
|
||
|
|
*/
|
||
|
|
protected void isInitialized(boolean isInitialized) {
|
||
|
|
this.isInitialized = isInitialized;
|
||
|
|
}//isInitialized()//
|
||
|
|
/**
|
||
|
|
* Gets the component's number which identifies this component in the view.
|
||
|
|
* @return The view unique number for this component.
|
||
|
|
*/
|
||
|
|
public int getNumber() {
|
||
|
|
return number;
|
||
|
|
}//getNumber()//
|
||
|
|
/**
|
||
|
|
* Gets the component's set of numbers that identifies it uniquely within the session.
|
||
|
|
* @return The identity of the component within the session.
|
||
|
|
*/
|
||
|
|
public long[] getIdentity() {
|
||
|
|
return new long[] {getSessionViewController().getNumber(), (long) number};
|
||
|
|
}//getIdentity()//
|
||
|
|
/**
|
||
|
|
* Increments the hold count on the message queue so that messages will be queued up until the count reaches zero.
|
||
|
|
*/
|
||
|
|
public void addMessageHold() {
|
||
|
|
//TODO: Remove this method.
|
||
|
|
suspendMessages();
|
||
|
|
}//addMessageHold()//
|
||
|
|
/**
|
||
|
|
* Decrements the hold count on the message queue so that messages will be queued up until the count reaches zero.
|
||
|
|
*/
|
||
|
|
public void removeMessageHold() {
|
||
|
|
//TODO: Remove this method.
|
||
|
|
resumeMessages();
|
||
|
|
}//removeMessageHold()//
|
||
|
|
/**
|
||
|
|
* Increments the hold count on the message queue so that messages will be queued up until the count reaches zero.
|
||
|
|
*/
|
||
|
|
public void suspendMessages() {
|
||
|
|
sessionViewController.incrementMessageHoldCount();
|
||
|
|
}//suspendMessages()//
|
||
|
|
/**
|
||
|
|
* Decrements the hold count on the message queue so that messages will be queued up until the count reaches zero.
|
||
|
|
*/
|
||
|
|
public void resumeMessages() {
|
||
|
|
sessionViewController.decrementMessageHoldCount();
|
||
|
|
}//resumeMessages()//
|
||
|
|
/**
|
||
|
|
* Suspends all drawing on the client.
|
||
|
|
*/
|
||
|
|
public void suspendRedraw() {
|
||
|
|
sendMessage(MESSAGE_SUSPEND_REDRAW, null);
|
||
|
|
}//suspendRedraw()//
|
||
|
|
/**
|
||
|
|
* Resumes all drawing on the client.
|
||
|
|
*/
|
||
|
|
public void resumeRedraw() {
|
||
|
|
sendMessage(MESSAGE_RESUME_REDRAW, null);
|
||
|
|
}//resumeRedraw()//
|
||
|
|
/**
|
||
|
|
* Tries to load an image from the file system.
|
||
|
|
* @param imageName The image name and path. If a path is not provided the application path will be used.
|
||
|
|
* @return The image bytes, or null if the image was not found.
|
||
|
|
*/
|
||
|
|
protected byte[] loadImage(String imageName) {
|
||
|
|
File file = new File(imageName);
|
||
|
|
byte[] result = null;
|
||
|
|
|
||
|
|
if((file.exists()) && (file.isFile())) {
|
||
|
|
FileInputStream in = null;
|
||
|
|
|
||
|
|
try {
|
||
|
|
in = new FileInputStream(file);
|
||
|
|
result = new byte[in.available()];
|
||
|
|
in.read(result);
|
||
|
|
}//try//
|
||
|
|
catch(FileNotFoundException e) {
|
||
|
|
Debug.log(e, "Unable to load the image: " + imageName);
|
||
|
|
result = null;
|
||
|
|
}//catch//
|
||
|
|
catch(IOException e) {
|
||
|
|
Debug.log(e, "Unable to load the image: " + imageName);
|
||
|
|
result = null;
|
||
|
|
}//catch//
|
||
|
|
finally {
|
||
|
|
try {
|
||
|
|
in.close();
|
||
|
|
}//try//
|
||
|
|
catch(Throwable e) {
|
||
|
|
Debug.handle(e);
|
||
|
|
}//catch//
|
||
|
|
}//finally//
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}//loadImage()//
|
||
|
|
/**
|
||
|
|
* Gets the container containing this component.
|
||
|
|
* @return The containing container, or null if this component is a root level window.
|
||
|
|
*/
|
||
|
|
public abstract IAbstractContainer getContainer();
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.IMultiResourceAssociationChangeListener#getResourceService()
|
||
|
|
*/
|
||
|
|
public AbstractResourceService getResourceService() {
|
||
|
|
return getContainer().getResourceService();
|
||
|
|
}//getResourceService()//
|
||
|
|
/**
|
||
|
|
* Gets the component in the view given the component's view unique number.
|
||
|
|
* @return The view component assigned the component number.
|
||
|
|
*/
|
||
|
|
protected AbstractComponent getComponent(int componentNumber) {
|
||
|
|
return (AbstractComponent) getSessionViewController().getComponent(componentNumber);
|
||
|
|
}//getComponent()//
|
||
|
|
/**
|
||
|
|
* Creates a new view message with the given message number and message data.
|
||
|
|
* @param messageNumber The component specific number indicating the message type.
|
||
|
|
* @param messageData The data specific to the message type.
|
||
|
|
* @param secondaryMessageData The optional secondary message data reference.
|
||
|
|
* @param messageInteger The numeric data associated with the message.
|
||
|
|
* @param secondaryMessageInteger The secondary numeric data associated with the message.
|
||
|
|
* @param isOneWay Whether the message doesn't require a return value.
|
||
|
|
* @return The view message object representing the message.
|
||
|
|
*/
|
||
|
|
private ViewMessage createViewMessage(int messageNumber, Object messageData, Object secondaryMessageData, int messageInteger, int secondaryMessageInteger, boolean isOneWay) {
|
||
|
|
ViewMessage result = null;
|
||
|
|
|
||
|
|
if(number != -1) {
|
||
|
|
result = new ViewMessage(number, messageNumber, messageData, secondaryMessageData, messageInteger, secondaryMessageInteger, !isOneWay);
|
||
|
|
}//if//
|
||
|
|
else {
|
||
|
|
Debug.log("Error: Cannot send a message to the client from a component that has an invalid number.");
|
||
|
|
}//else//
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}//createViewMessage()//
|
||
|
|
/**
|
||
|
|
* Sends a message to the client component.
|
||
|
|
* @param messageNumber The message number which will be used by the client component to handle the message and interperate the parameters.
|
||
|
|
* @param messageData The data associated with the message.
|
||
|
|
*/
|
||
|
|
public void sendMessage(int messageNumber, Object messageData) {
|
||
|
|
sendMessage(messageNumber, messageData, null, 0, 0);
|
||
|
|
}//sendMessage()//
|
||
|
|
/**
|
||
|
|
* Sends a message to the client component.
|
||
|
|
* @param messageNumber The message number which will be used by the client component to handle the message and interperate the parameters.
|
||
|
|
* @param messageData The data associated with the message.
|
||
|
|
* @param secondaryMessageData The optional secondary message data reference.
|
||
|
|
* @param messageInteger The numeric data associated with the message.
|
||
|
|
* @param secondaryMessageInteger The secondary numeric data associated with the message.
|
||
|
|
*/
|
||
|
|
public void sendMessage(int messageNumber, Object messageData, Object secondaryMessageData, int messageInteger, int secondaryMessageInteger) {
|
||
|
|
sessionViewController.sendMessage(createViewMessage(messageNumber, messageData, secondaryMessageData, messageInteger, secondaryMessageInteger, true), false);
|
||
|
|
}//sendMessage()//
|
||
|
|
/**
|
||
|
|
* Sends a round trip message to the client, waiting until the message result comes back.
|
||
|
|
* @param messageNumber The control's number for the message (as defined in the control's interface shared between the client and server).
|
||
|
|
* @param messageData The data specific to the message.
|
||
|
|
* @return The result of the message.
|
||
|
|
*/
|
||
|
|
public Object sendRoundTripMessage(int messageNumber, Object messageData) {
|
||
|
|
return sendRoundTripMessage(messageNumber, messageData, null, 0, 0);
|
||
|
|
}//sendRoundTripMessage()//
|
||
|
|
/**
|
||
|
|
* Sends a round trip message to the client, waiting until the message result comes back.
|
||
|
|
* @param messageNumber The control's number for the message (as defined in the control's interface shared between the client and server).
|
||
|
|
* @param messageData The data specific to the message.
|
||
|
|
* @param secondaryMessageData The optional secondary message data reference.
|
||
|
|
* @param messageInteger The numeric data associated with the message.
|
||
|
|
* @param secondaryMessageInteger The secondary numeric data associated with the message.
|
||
|
|
* @return The result of the message.
|
||
|
|
*/
|
||
|
|
public Object sendRoundTripMessage(int messageNumber, Object messageData, Object secondaryMessageData, int messageInteger, int secondaryMessageInteger) {
|
||
|
|
return sessionViewController.sendMessage(createViewMessage(messageNumber, messageData, secondaryMessageData, messageInteger, secondaryMessageInteger, false), true);
|
||
|
|
}//sendRoundTripMessage()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.tcv.view.IAbstractRemoteViewComponent#processMessage(com.foundation.tcv.view.ViewMessage)
|
||
|
|
*/
|
||
|
|
public Object processMessage(ViewMessage viewMessage) {
|
||
|
|
Object result = null;
|
||
|
|
|
||
|
|
switch(viewMessage.getMessageNumber()) {
|
||
|
|
default: {
|
||
|
|
Debug.log("Error: processMessage(ViewMessage) is not implemented.");
|
||
|
|
break;
|
||
|
|
}//default//
|
||
|
|
}//switch//
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}//processMessage()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.event.IHandler#evaluate(int, java.lang.Object[], int)
|
||
|
|
*/
|
||
|
|
public final void evaluate(int eventNumber, Object[] arguments, int flags) {
|
||
|
|
Debug.log("Error: evaluate(int, Object[]) should never be called.");
|
||
|
|
}//evaluate()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.event.IEventHandler#evaluate(com.foundation.event.IEventEmitter, int, java.lang.Object[], int)
|
||
|
|
*/
|
||
|
|
public final void evaluate(final IEventEmitter eventEmitter, final int eventNumber, final Object[] arguments, int flags) {
|
||
|
|
if(EventSupport.isStandardEvent(flags)) {
|
||
|
|
verifyThread();
|
||
|
|
internalEvaluate(eventEmitter, eventNumber, arguments);
|
||
|
|
}//if//
|
||
|
|
}//evaluate()//
|
||
|
|
/**
|
||
|
|
* A default handler for events received by the component.
|
||
|
|
* @param eventEmitter The object which fired the event.
|
||
|
|
* @param eventNumber The unique number for the event.
|
||
|
|
* @param arguments The event arguments which may be null if there are none.
|
||
|
|
*/
|
||
|
|
protected void internalEvaluate(IEventEmitter eventEmitter, int eventNumber, Object[] arguments) {
|
||
|
|
//Subclasses should override this and provide an implementation.//
|
||
|
|
//Subclasses would only need an implementation if they had IEventAssociation or IAttributeAssociation attributes.//
|
||
|
|
internalEvaluate(eventEmitter, EventSupport.getEventName(eventEmitter.getClass(), eventNumber), arguments);
|
||
|
|
}//internalEvaluate()//
|
||
|
|
/**
|
||
|
|
* A default handler for events received by the component.
|
||
|
|
* @param eventEmitter The object which fired the event.
|
||
|
|
* @param eventNumber The unique name for the event.
|
||
|
|
* @param arguments The event arguments which may be null if there are none.
|
||
|
|
*/
|
||
|
|
protected void internalEvaluate(IEventEmitter eventEmitter, String eventName, Object[] arguments) {
|
||
|
|
//Subclasses should override this and provide an implementation.//
|
||
|
|
//Subclasses would only need an implementation if they had IEventAssociation or IAttributeAssociation attributes.//
|
||
|
|
}//internalEvaluate()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.IAttributeAssociationChangeListener#onValueChanged(com.foundation.view.IAttributeAssociation)
|
||
|
|
*/
|
||
|
|
public void onValueChanged(IAttributeAssociation attributeAssociation) {
|
||
|
|
verifyThread();
|
||
|
|
internalOnValueChanged(attributeAssociation);
|
||
|
|
}//onValueChanged()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.ISingleResourceAssociationChangeListener#onValueChanged(com.foundation.view.ResourceAssociation, int)
|
||
|
|
*/
|
||
|
|
public final void onValueChanged(ResourceAssociation resourceAssociation, int flags) {
|
||
|
|
verifyThread();
|
||
|
|
|
||
|
|
if(isInitialized()) {
|
||
|
|
if(resourceAssociation instanceof SingleResourceAssociation) {
|
||
|
|
internalOnValueChanged((SingleResourceAssociation) resourceAssociation, flags);
|
||
|
|
}//if//
|
||
|
|
else if(resourceAssociation instanceof CollectingSingleResourceAssociation) {
|
||
|
|
internalOnValueChanged((CollectingSingleResourceAssociation) resourceAssociation);
|
||
|
|
}//else if//
|
||
|
|
}//if//
|
||
|
|
}//onValueChanged()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.IMultiResourceAssociationChangeListener#onValueChanged(com.foundation.view.ResourceAssociation, java.lang.Object, java.lang.Object, boolean)
|
||
|
|
*/
|
||
|
|
public final void onValueChanged(ResourceAssociation resourceAssociation, Object alteredItem, Object data, boolean isUpdate) {
|
||
|
|
verifyThread();
|
||
|
|
|
||
|
|
if(isInitialized()) {
|
||
|
|
if(resourceAssociation instanceof MultiResourceAssociation) {
|
||
|
|
internalOnValueChanged((MultiResourceAssociation) resourceAssociation, alteredItem, data, isUpdate);
|
||
|
|
}//else if//
|
||
|
|
else if(resourceAssociation instanceof CollectingMultiResourceAssociation) {
|
||
|
|
internalOnValueChanged((CollectingMultiResourceAssociation) resourceAssociation, alteredItem, data);
|
||
|
|
}//else if//
|
||
|
|
}//if//
|
||
|
|
}//onValueChanged()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.ISingleResourceAssociationChangeListener#onModelExternallyChanged(com.foundation.view.ResourceAssociation, boolean, java.lang.Object)
|
||
|
|
*/
|
||
|
|
public void onModelExternallyChanged(ResourceAssociation resourceAssociation, boolean isCleared, Object originalValue) {
|
||
|
|
verifyThread();
|
||
|
|
|
||
|
|
if(isInitialized()) {
|
||
|
|
internalOnModelExternallyChanged((SingleResourceAssociation) resourceAssociation, isCleared, originalValue);
|
||
|
|
}//if//
|
||
|
|
}//onModelExternallyChanged()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.IMultiResourceAssociationChangeListener#onModelExternallyChanged(com.foundation.view.ResourceAssociation, java.lang.Object, java.lang.Object, boolean, java.lang.Object)
|
||
|
|
*/
|
||
|
|
public void onModelExternallyChanged(ResourceAssociation resourceAssociation, Object alteredItem, Object data, boolean isCleared, Object originalValue) {
|
||
|
|
verifyThread();
|
||
|
|
|
||
|
|
if(isInitialized()) {
|
||
|
|
internalOnModelExternallyChanged((MultiResourceAssociation) resourceAssociation, alteredItem, data, isCleared, originalValue);
|
||
|
|
}//if//
|
||
|
|
}//onModelExternallyChanged()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.IAbstractComponent#onEventFired(com.foundation.view.IEventAssociation, java.lang.Object[])
|
||
|
|
*/
|
||
|
|
public void onEventFired(IEventAssociation eventAssociation, Object[] eventArguments) {
|
||
|
|
verifyThread();
|
||
|
|
addMessageHold();
|
||
|
|
|
||
|
|
try {
|
||
|
|
internalOnEventFired(eventAssociation, eventArguments);
|
||
|
|
}//try//
|
||
|
|
finally {
|
||
|
|
removeMessageHold();
|
||
|
|
}//finally//
|
||
|
|
}//onEventFired()//
|
||
|
|
/**
|
||
|
|
* Called by the value holders when a registered attribute changes value or the value containing the attribute changes.
|
||
|
|
* @param attributeAssociation The attribute association used to register with the attribute.
|
||
|
|
*/
|
||
|
|
protected void internalOnValueChanged(IAttributeAssociation attributeAssociation) {
|
||
|
|
Debug.log(new RuntimeException("Error: Unexpected (unhandled by AbstractComponent) attribute association found. AttributeName: " + attributeAssociation.getAttributeName()));
|
||
|
|
}//internalOnValueChanged()//
|
||
|
|
/**
|
||
|
|
* Called by the resource association when a resource changes value.
|
||
|
|
* <p>The change in value will be because the resource context altered its set of current resources and the associated resources was in the set that was altered.</p>
|
||
|
|
* @param resourceAssociation The resource association used to register with the resource.
|
||
|
|
* @param isUpdate Whether the alteration was due to the object's reflected object updating it, in which case the user might want to be warned.
|
||
|
|
*/
|
||
|
|
protected void internalOnValueChanged(SingleResourceAssociation resourceAssociation, int flags) {
|
||
|
|
Debug.log(new RuntimeException("Error: Unexpected (unhandled by AbstractComponent) resource association found. Resource URL: " + resourceAssociation.toString()));
|
||
|
|
}//internalOnValueChanged()//
|
||
|
|
/**
|
||
|
|
* Called by the resource association when a resource changes value.
|
||
|
|
* <p>The change in value will be because the resource context altered its set of current resources and the associated resources was in the set that was altered.</p>
|
||
|
|
* @param resourceAssociation The resource association used to register with the resource.
|
||
|
|
* @param alteredItem The item whose value has been altered.
|
||
|
|
* @param data The data passed when the item was registered with the resource association.
|
||
|
|
* @param isUpdate Whether the alteration was due to the object's reflected object updating it, in which case the user might want to be warned.
|
||
|
|
*/
|
||
|
|
protected void internalOnValueChanged(MultiResourceAssociation resourceAssociation, Object alteredItem, Object data, boolean isUpdate) {
|
||
|
|
Debug.log(new RuntimeException("Error: Unexpected (unhandled by AbstractComponent) resource association found. Resource URL: " + resourceAssociation.toString()));
|
||
|
|
}//internalOnValueChanged()//
|
||
|
|
/**
|
||
|
|
* Called by the resource association when a resource changes value.
|
||
|
|
* <p>The change in value will be because the resource context altered its set of current resources and the associated resources was in the set that was altered.</p>
|
||
|
|
* @param resourceAssociation The resource association used to register with the resource.
|
||
|
|
* @param alteredItem The item whose value has been altered.
|
||
|
|
* @param data The data passed when the item was registered with the resource association.
|
||
|
|
*/
|
||
|
|
protected void internalOnValueChanged(CollectingMultiResourceAssociation resourceAssociation, Object alteredItem, Object data) {
|
||
|
|
Debug.log(new RuntimeException("Error: Unexpected (unhandled by AbstractComponent) resource association found. Resource URL: " + resourceAssociation.toString()));
|
||
|
|
}//internalOnValueChanged()//
|
||
|
|
/**
|
||
|
|
* Called by the resource association when a resource changes value.
|
||
|
|
* <p>The change in value will be because the resource context altered its set of current resources and the associated resources was in the set that was altered.</p>
|
||
|
|
* @param resourceAssociation The resource association used to register with the resource.
|
||
|
|
*/
|
||
|
|
protected void internalOnValueChanged(CollectingSingleResourceAssociation resourceAssociation) {
|
||
|
|
Debug.log(new RuntimeException("Error: Unexpected (unhandled by AbstractComponent) resource association found. Resource URL: " + resourceAssociation.toString()));
|
||
|
|
}//internalOnValueChanged()//
|
||
|
|
/**
|
||
|
|
* Called by the resource association when a resource changes value.
|
||
|
|
* <p>The change in value will be because the resource context altered its set of current resources and the associated resources was in the set that was altered.</p>
|
||
|
|
* @param resourceAssociation The resource association used to register with the resource.
|
||
|
|
* @param isCleared Whether the original value was cleared, in which case the original value parameter should be ignored.
|
||
|
|
* @param originalValue The model value unaltered by the view's user.
|
||
|
|
*/
|
||
|
|
protected void internalOnModelExternallyChanged(SingleResourceAssociation resourceAssociation, boolean isCleared, Object originalValue) {
|
||
|
|
//Debug.log(new RuntimeException("Error: Unexpected (unhandled by AbstractComponent) resource association found. Resource URL: " + resourceAssociation.toString()));
|
||
|
|
}//internalOnModelExternallyChanged()//
|
||
|
|
/**
|
||
|
|
* Called by the resource association when a resource changes value.
|
||
|
|
* <p>The change in value will be because the resource context altered its set of current resources and the associated resources was in the set that was altered.</p>
|
||
|
|
* @param resourceAssociation The resource association used to register with the resource.
|
||
|
|
* @param alteredItem The item whose value has been altered.
|
||
|
|
* @param data TODO
|
||
|
|
* @param isCleared Whether the original value was cleared, in which case the original value parameter should be ignored.
|
||
|
|
* @param originalValue The model value unaltered by the view's user.
|
||
|
|
*/
|
||
|
|
protected void internalOnModelExternallyChanged(MultiResourceAssociation resourceAssociation, Object alteredItem, Object data, boolean isCleared, Object originalValue) {
|
||
|
|
//Debug.log(new RuntimeException("Error: Unexpected (unhandled by AbstractComponent) resource association found. Resource URL: " + resourceAssociation.toString()));
|
||
|
|
}//internalOnModelExternallyChanged()//
|
||
|
|
/**
|
||
|
|
* Called when any event association connected with this component is notified that the event has fired.
|
||
|
|
* @param eventAssociation The event association for the event that was fired.
|
||
|
|
* @param eventArguments The non-null event arguments as received by the event association.
|
||
|
|
*/
|
||
|
|
protected void internalOnEventFired(IEventAssociation eventAssociation, Object[] eventArguments) {
|
||
|
|
Debug.log(new RuntimeException("Error: Unexpected (unhandled by AbstractComponent) event association found. Event Number: " + eventAssociation.getEventNumber()));
|
||
|
|
}//internalOnEventFired()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.IView#viewInitializeAll()
|
||
|
|
*/
|
||
|
|
public final void viewInitializeAll() {
|
||
|
|
verifyThread();
|
||
|
|
// suspendMessages();
|
||
|
|
// suspendRedraw();
|
||
|
|
|
||
|
|
try {
|
||
|
|
internalViewInitializeAll();
|
||
|
|
sendMessage(MESSAGE_VIEW_INITIALIZE_ALL, null);
|
||
|
|
internalViewRefreshAll();
|
||
|
|
sendMessage(MESSAGE_VIEW_INITIALIZATION_COMPLETE, null);
|
||
|
|
}//try//
|
||
|
|
finally {
|
||
|
|
// resumeRedraw();
|
||
|
|
// resumeMessages();
|
||
|
|
}//finally//
|
||
|
|
}//viewInitializeAll()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.IView#viewReleaseAll()
|
||
|
|
*/
|
||
|
|
public final void viewReleaseAll() {
|
||
|
|
verifyThread();
|
||
|
|
suspendMessages();
|
||
|
|
//suspendRedraw();
|
||
|
|
|
||
|
|
try {
|
||
|
|
internalViewReleaseAll();
|
||
|
|
sendMessage(MESSAGE_VIEW_RELEASE_ALL, null);
|
||
|
|
}//try//
|
||
|
|
finally {
|
||
|
|
//resumeRedraw();
|
||
|
|
resumeMessages();
|
||
|
|
}//finally//
|
||
|
|
}//viewReleaseAll()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.IView#viewRefreshAll()
|
||
|
|
*/
|
||
|
|
public final void viewRefreshAll() {
|
||
|
|
verifyThread();
|
||
|
|
addMessageHold();
|
||
|
|
|
||
|
|
try {
|
||
|
|
//Don't send any message to the client. Each control will send what ever refresh messages are necessary.//
|
||
|
|
internalViewRefreshAll();
|
||
|
|
}//try//
|
||
|
|
finally {
|
||
|
|
removeMessageHold();
|
||
|
|
}//finally//
|
||
|
|
}//viewRefreshAll()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.IView#viewSynchronizeAll()
|
||
|
|
*/
|
||
|
|
public final void viewSynchronizeAll() {
|
||
|
|
verifyThread();
|
||
|
|
|
||
|
|
try {
|
||
|
|
internalViewSynchronizeAll();
|
||
|
|
}//try//
|
||
|
|
catch(Throwable e) {
|
||
|
|
Debug.handle(e);
|
||
|
|
}//catch//
|
||
|
|
}//viewSynchronizeAll()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.IView#viewRefreshAll()
|
||
|
|
*/
|
||
|
|
public final void viewRefresh() {
|
||
|
|
verifyThread();
|
||
|
|
addMessageHold();
|
||
|
|
|
||
|
|
try {
|
||
|
|
//Don't send any message to the client. Each control will send what ever refresh messages are necessary.//
|
||
|
|
internalViewRefresh();
|
||
|
|
}//try//
|
||
|
|
finally {
|
||
|
|
removeMessageHold();
|
||
|
|
}//finally//
|
||
|
|
}//viewRefresh()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.IView#viewSynchronize()
|
||
|
|
*/
|
||
|
|
public final void viewSynchronize() {
|
||
|
|
verifyThread();
|
||
|
|
|
||
|
|
try {
|
||
|
|
sendRoundTripMessage(MESSAGE_VIEW_SYNCHRONIZE, null);
|
||
|
|
}//try//
|
||
|
|
catch(Throwable e) {
|
||
|
|
Debug.handle(e);
|
||
|
|
}//catch//
|
||
|
|
}//viewSynchronize()//
|
||
|
|
/**
|
||
|
|
* Initializes this view and all its' contained components.
|
||
|
|
*/
|
||
|
|
protected void internalViewInitializeAll() {
|
||
|
|
try {
|
||
|
|
//Initialize this component.//
|
||
|
|
internalViewInitialize();
|
||
|
|
}//try//
|
||
|
|
catch(Throwable e) {
|
||
|
|
Debug.log(e);
|
||
|
|
Debug.halt();
|
||
|
|
}//catch//
|
||
|
|
}//internalViewInitializeAll()//
|
||
|
|
/**
|
||
|
|
* Releases this view and all its' contained components.
|
||
|
|
*/
|
||
|
|
protected void internalViewReleaseAll() {
|
||
|
|
try {
|
||
|
|
//Release this component.//
|
||
|
|
internalViewRelease();
|
||
|
|
}//try//
|
||
|
|
catch(Throwable e) {
|
||
|
|
Debug.log(e);
|
||
|
|
}//catch//
|
||
|
|
}//internalViewReleaseAll()//
|
||
|
|
/**
|
||
|
|
* Refreshes this view and all its' contained components.
|
||
|
|
*/
|
||
|
|
protected void internalViewRefreshAll() {
|
||
|
|
try {
|
||
|
|
//Refresh this component.//
|
||
|
|
internalViewRefresh();
|
||
|
|
}//try//
|
||
|
|
catch(Throwable e) {
|
||
|
|
Debug.log(e);
|
||
|
|
}//catch//
|
||
|
|
}//internalViewRefreshAll()//
|
||
|
|
/**
|
||
|
|
* Initializes this component only.
|
||
|
|
* @see #internalViewInitializeAll()
|
||
|
|
*/
|
||
|
|
protected void internalViewInitialize() {
|
||
|
|
this.isInitialized = true;
|
||
|
|
}//internalViewInitialize()//
|
||
|
|
/**
|
||
|
|
* Releases this component only.
|
||
|
|
* @see #internalViewReleaseAll()
|
||
|
|
*/
|
||
|
|
protected void internalViewRelease() {
|
||
|
|
}//internalViewRelease()//
|
||
|
|
/**
|
||
|
|
* Refreshes this component only.
|
||
|
|
* @see #internalViewRefreshAll()
|
||
|
|
*/
|
||
|
|
protected void internalViewRefresh() {
|
||
|
|
}//internalViewRefresh()//
|
||
|
|
/**
|
||
|
|
* Synchronize this component only.
|
||
|
|
* @see #internalViewSynchronizeAll()
|
||
|
|
*/
|
||
|
|
protected final void internalViewSynchronize() {
|
||
|
|
sendRoundTripMessage(MESSAGE_VIEW_SYNCHRONIZE, null);
|
||
|
|
}//internalViewSynchronize()//
|
||
|
|
/**
|
||
|
|
* Synchronizes this view and all its' contained components.
|
||
|
|
*/
|
||
|
|
protected void internalViewSynchronizeAll() {
|
||
|
|
sendRoundTripMessage(MESSAGE_VIEW_SYNCHRONIZE_ALL, null);
|
||
|
|
}//internalViewSynchronizeAll()//
|
||
|
|
/**
|
||
|
|
* Gets the qualified class name for the client side class that mirrors the server side component.
|
||
|
|
* @return The client side class name for this component.
|
||
|
|
*/
|
||
|
|
protected abstract String getClientClassName();
|
||
|
|
/**
|
||
|
|
* Gets the controller for the view component.
|
||
|
|
* @return The view's controller.
|
||
|
|
*/
|
||
|
|
public AbstractViewController getController() {
|
||
|
|
return getContainer().getController();
|
||
|
|
}//getController()//
|
||
|
|
/**
|
||
|
|
* Notifies the view controller that it should validate.
|
||
|
|
*/
|
||
|
|
protected void postSynchronizeValidate() {
|
||
|
|
getController().validate();
|
||
|
|
}//postSynchronizeValidate()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.ISingleResourceAssociationChangeListener#getDecorationManager()
|
||
|
|
*/
|
||
|
|
public DecorationManager getDecorationManager() {
|
||
|
|
return getController().getDecorationManager();
|
||
|
|
}//getDecorationManager()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.ISingleResourceAssociationChangeListener#addDecoration(com.foundation.view.AbstractDecoration)
|
||
|
|
*/
|
||
|
|
public void addDecoration(AbstractDecoration decoration) {
|
||
|
|
decorationMap.put(decoration, ++lastDecorationNumber);
|
||
|
|
sendMessage(MESSAGE_ADD_DECORATION, decoration, null, lastDecorationNumber, -1);
|
||
|
|
}//addDecoration()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.ISingleResourceAssociationChangeListener#removeDecoration(com.foundation.view.AbstractDecoration)
|
||
|
|
*/
|
||
|
|
public void removeDecoration(AbstractDecoration decoration) {
|
||
|
|
if(decoration != null) {
|
||
|
|
sendMessage(MESSAGE_REMOVE_DECORATION, null, null, decorationMap.remove(decoration), -1);
|
||
|
|
}//if//
|
||
|
|
}//removeDecoration()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.IMultiResourceAssociationChangeListener#addDecoration(com.foundation.view.ResourceAssociation, java.lang.Object, java.lang.Object, com.foundation.view.AbstractDecoration)
|
||
|
|
*/
|
||
|
|
public void addDecoration(ResourceAssociation association, Object row, Object data, AbstractDecoration decoration) {
|
||
|
|
}//addDecoration()//
|
||
|
|
/* (non-Javadoc)
|
||
|
|
* @see com.foundation.view.IMultiResourceAssociationChangeListener#removeDecoration(com.foundation.view.ResourceAssociation, java.lang.Object, java.lang.Object, com.foundation.view.AbstractDecoration)
|
||
|
|
*/
|
||
|
|
public void removeDecoration(ResourceAssociation association, Object row, Object data, AbstractDecoration decoration) {
|
||
|
|
}//removeDecoration()//
|
||
|
|
}//AbstractComponent//
|