001: /*
002: * This file is part of the Echo Web Application Framework (hereinafter "Echo").
003: * Copyright (C) 2002-2005 NextApp, Inc.
004: *
005: * Version: MPL 1.1/GPL 2.0/LGPL 2.1
006: *
007: * The contents of this file are subject to the Mozilla Public License Version
008: * 1.1 (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: * http://www.mozilla.org/MPL/
011: *
012: * Software distributed under the License is distributed on an "AS IS" basis,
013: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
014: * for the specific language governing rights and limitations under the
015: * License.
016: *
017: * Alternatively, the contents of this file may be used under the terms of
018: * either the GNU General Public License Version 2 or later (the "GPL"), or
019: * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
020: * in which case the provisions of the GPL or the LGPL are applicable instead
021: * of those above. If you wish to allow use of your version of this file only
022: * under the terms of either the GPL or the LGPL, and not to allow others to
023: * use your version of this file under the terms of the MPL, indicate your
024: * decision by deleting the provisions above and replace them with the notice
025: * and other provisions required by the GPL or the LGPL. If you do not delete
026: * the provisions above, a recipient may use your version of this file under
027: * the terms of any one of the MPL, the GPL or the LGPL.
028: */
029:
030: package nextapp.echo2.app.update;
031:
032: import java.io.Serializable;
033: import java.util.HashMap;
034: import java.util.Iterator;
035: import java.util.Map;
036:
037: import nextapp.echo2.app.ApplicationInstance;
038: import nextapp.echo2.app.Component;
039:
040: /**
041: * Stores inputs received from the application container and notifies
042: * components about them via the <code>Component.processInput()</code> method.
043: *
044: * @see nextapp.echo2.app.Component#processInput(java.lang.String, java.lang.Object)
045: */
046: public class ClientUpdateManager implements Serializable {
047:
048: private Map clientComponentUpdateMap = new HashMap();
049: private Map applicationUpdateMap = new HashMap();
050: private Component actionComponent;
051: private String actionName;
052: private Object actionValue;
053: private ApplicationInstance applicationInstance;
054:
055: /**
056: * Creates a new <Code>ClientUpdateManager</code>.
057: *
058: * @param applicationInstance the <code>ApplicationInstance</code> being supported
059: */
060: ClientUpdateManager(ApplicationInstance applicationInstance) {
061: this .applicationInstance = applicationInstance;
062: }
063:
064: /**
065: * Retrieves the <code>ClientComponentUpdate</code> object representing
066: * the specified <code>Component</code>, or null, if no client updates
067: * have been made to the <code>Component</code>.
068: *
069: * @param component the <code>Component</code>
070: * @return the representing <code>ClientComponentUpdate</code>
071: */
072: ClientComponentUpdate getComponentUpdate(Component component) {
073: return (ClientComponentUpdate) clientComponentUpdateMap
074: .get(component);
075: }
076:
077: /**
078: * Retrieves the value of the application-level property update with the
079: * specified name.
080: *
081: * @param propertyName the name of the property update
082: * @return the value of the property update, or null if none exists
083: */
084: Object getApplicationUpdatePropertyValue(String propertyName) {
085: return applicationUpdateMap.get(propertyName);
086: }
087:
088: /**
089: * Notifies components of input from the client via the
090: * <code>Component.processInput()</code> method.
091: *
092: * @see nextapp.echo2.app.Component#processInput(java.lang.String, java.lang.Object)
093: */
094: void process() {
095: // Process application-level property updates.
096: Iterator applicationUpdateIt = applicationUpdateMap.keySet()
097: .iterator();
098: while (applicationUpdateIt.hasNext()) {
099: String propertyName = (String) applicationUpdateIt.next();
100: Object propertyValue = applicationUpdateMap
101: .get(propertyName);
102: applicationInstance.processInput(propertyName,
103: propertyValue);
104: }
105:
106: // Process property updates.
107: Iterator componentUpdateIt = clientComponentUpdateMap.values()
108: .iterator();
109: while (componentUpdateIt.hasNext()) {
110: ClientComponentUpdate update = (ClientComponentUpdate) componentUpdateIt
111: .next();
112: Iterator inputNameIt = update.getInputNames();
113: while (inputNameIt.hasNext()) {
114: String inputName = (String) inputNameIt.next();
115: update.getComponent().processInput(inputName,
116: update.getInputValue(inputName));
117: }
118: }
119:
120: // Process action.
121: if (actionComponent != null) {
122: actionComponent.processInput(actionName, actionValue);
123: }
124: }
125:
126: /**
127: * Purges all updates from the <code>ClientUpdateManager</code>.
128: */
129: void purge() {
130: clientComponentUpdateMap.clear();
131: applicationUpdateMap.clear();
132: actionComponent = null;
133: actionName = null;
134: actionValue = null;
135: }
136:
137: /**
138: * Sets an application-level property received from the client.
139: *
140: * @param propertyName the name of the property
141: * @param propertyValue the value of the property
142: */
143: public void setApplicationProperty(String propertyName,
144: Object propertyValue) {
145: applicationUpdateMap.put(propertyName, propertyValue);
146: }
147:
148: /**
149: * Sets the action received from the client. The 'action' describes the
150: * client-side update which necessitated the occurrence of this
151: * client-server interaction. The application will be notified of the
152: * action AFTER it has been notified of all other property updates.
153: *
154: * @param actionComponent the action-producing component
155: * @param actionName the name of the action
156: * @param actionValue the value of the action
157: */
158: public void setComponentAction(Component actionComponent,
159: String actionName, Object actionValue) {
160: if (!actionComponent.verifyInput(actionName, actionValue)) {
161: // Invalid input.
162: return;
163: }
164:
165: this .actionComponent = actionComponent;
166: this .actionName = actionName;
167: this .actionValue = actionValue;
168: }
169:
170: /**
171: * Adds a property update received from the client.
172: *
173: * @param component the updated component
174: * @param inputName the name of the input property
175: * @param inputValue the value of the input property
176: */
177: public void setComponentProperty(Component component,
178: String inputName, Object inputValue) {
179: if (!component.verifyInput(inputName, inputValue)) {
180: // Invalid input.
181: return;
182: }
183:
184: ClientComponentUpdate clientUpdate = (ClientComponentUpdate) clientComponentUpdateMap
185: .get(component);
186: if (clientUpdate == null) {
187: clientUpdate = new ClientComponentUpdate(component);
188: clientComponentUpdateMap.put(component, clientUpdate);
189: }
190: clientUpdate.addInput(inputName, inputValue);
191: }
192:
193: }
|