001: package org.swingml.event;
002:
003: import java.awt.*;
004: import java.util.*;
005:
006: import javax.swing.*;
007:
008: import org.swingml.*;
009: import org.swingml.event.*;
010: import org.swingml.model.*;
011: import org.swingml.registry.*;
012: import org.swingml.server.SwingMLServerResponse;
013: import org.swingml.system.*;
014:
015: /**
016: * @author David Pitt
017: * This event handler invokes a URL address with specified key value parameter pairs.
018: * Response XML is rendered in a specified SwingML container.
019: *
020: * Parameters
021: *
022: * OPEN = <OPEN|OPEN-MODEL|REFRESH|NORENDER>
023: * COMPONENT = <Container Name>
024: * URL = URL to post specified param values and container component Name Value pairs
025: * if not specified, the URL property defined in the SwingMLProperties object will be used
026: *
027: *
028: *
029: */
030: public class ControllerActionEventHandler extends EventUtil {
031:
032: private Component component;
033: private String panel;
034: private Map actionParameters;
035: private Container parent;
036: private ControllerActionModel model = null;
037:
038: public ControllerActionEventHandler() {
039: }
040:
041: public ControllerActionEventHandler(Component aComponent, Map aMap) {
042: setActionParameters(aMap);
043: setComponent(aComponent);
044:
045: if (aComponent instanceof Container) {
046: setParent((Container) aComponent);
047: }
048: }
049:
050: public void destroy() {
051: }
052:
053: protected ActionParamModel getActionParamModel(String key) {
054: ActionParamModel result = null;
055: Object value = getActionParameters().get(key);
056: if (value != null) {
057: result = (ActionParamModel) value;
058: }
059: return result;
060: }
061:
062: public Component getComponent() {
063: return this .component;
064: }
065:
066: private String getEventSource() {
067: return "&" + Constants.EVENT_SOURCE + "="
068: + getParameterValue(Constants.EVENT_SOURCE);
069: }
070:
071: private String getModalParameterString() {
072: StringBuffer ps = new StringBuffer();
073: Iterator keys = getActionParameters().keySet().iterator();
074: while (keys.hasNext()) {
075: String key = (String) keys.next();
076: if (!"EVENT-SOURCE".equals(key)) {
077: ps.append(key);
078: ps.append("=");
079: ps.append(getParameterValue(key));
080: ps.append("&");
081: }
082: }
083: return ps.toString();
084: }
085:
086: protected String getPanel() {
087: return this .panel;
088: }
089:
090: protected String getParameterValue(String key) {
091: String result = null;
092: if (getActionParameters() == null) {
093: return result;
094: }
095: Object value = getActionParameters().get(key);
096: if (value != null) {
097: result = ((ActionParamModel) value).getValue();
098: }
099: return result;
100: }
101:
102: protected Map getActionParameters() {
103: return this .actionParameters;
104: }
105:
106: protected String getParameterString() {
107: StringBuffer ps = new StringBuffer();
108: if (getActionParameters() == null) {
109: return "";
110: }
111: Iterator keys = getActionParameters().keySet().iterator();
112: while (keys.hasNext()) {
113: String key = (String) keys.next();
114: ps.append(key);
115: ps.append("=");
116: ps.append(getParameterValue(key));
117:
118: if (keys.hasNext()) {
119: ps.append("&");
120: }
121: }
122: return ps.toString();
123: }
124:
125: public Container getParent() {
126: return this .parent;
127: }
128:
129: /**
130: * This method expects the objects in the params argument to be instances of
131: * the ActionParamModel object. And will replace tokendized map values with values
132: * looked up from the SwingMLProperties singleton. If a tokenized key is not found, and error
133: * is reported
134: *
135: * @param params
136: * A reference to an array of Object instances.
137: *
138: *
139: *
140: * @return void
141: * @see com.crosslogic.swingml.model.ActionParamModel
142: */
143: protected void replaceTokens(Object[] aParams) {
144:
145: ActionParamModel theParam = null;
146: if (aParams != null && aParams.length > 0) {
147: for (int i = 0; i < aParams.length; i++) {
148: if (aParams[i] instanceof ActionParamModel) {
149: theParam = (ActionParamModel) aParams[i];
150: int index = 0;
151: if ((index = theParam.getValue().indexOf("@")) > -1) {
152:
153: String key = theParam.getValue().substring(
154: index + 1);
155: String replaceWith = SwingMLProperties.sole()
156: .get(key);
157: if (replaceWith == null) {
158:
159: throw new RuntimeException(
160: "Token "
161: + theParam.getValue()
162: + " not found in SwingMLProperties instance, make sure it has been initialized somewhere...");
163: }
164:
165: // replace with new looked up value
166: theParam.setValue(replaceWith);
167:
168: }
169:
170: }
171: }
172: }
173: return;
174: }
175:
176: public void initialize(Component aComponent, Object[] parameters,
177: ControllerActionModel model) {
178:
179: setModel(model);
180: replaceTokens(parameters);
181: setActionParameters(buildActionParametersMap(parameters));
182: setComponent(aComponent);
183:
184: if (aComponent instanceof Container) {
185: setParent((Container) aComponent);
186: }
187: }
188:
189: public void invoke() {
190: try {
191:
192: // setPanel(getParameterValue(Constants.OPEN_MODAL));
193:
194: if (getModel().getOperation().equalsIgnoreCase(
195: Constants.OPEN)) {
196: open(parent, getParameterString(), shouldShowProgress());
197:
198: } else if (getModel().getOperation().equalsIgnoreCase(
199: Constants.REFRESH)) {
200: refresh(parent, getParameterString());
201: } else if (getModel().getOperation().equalsIgnoreCase(
202: Constants.NORENDER)) {
203: noRender(parent, getParameterString());
204:
205: }
206:
207: } catch (InvalidTargetLocationException e) {
208: // tried to connect to an invalid location
209: // log the error
210: SwingMLLogger.getInstance().log(SwingMLLogger.ERROR, e);
211:
212: // notify the user
213: SwingMLRenderer.getRenderer().render(
214: HttpSubmitController.getInvalidTargetErrorSpec(),
215: null);
216: }
217:
218: }
219:
220: public void setComponent(Component component) {
221: this .component = component;
222: }
223:
224: protected void setPanel(String panel) {
225: this .panel = panel;
226: }
227:
228: protected void setActionParameters(Map params) {
229: this .actionParameters = params;
230: }
231:
232: public void setParent(Container parentContainer) {
233: this .parent = parentContainer;
234: }
235:
236: /**
237: * Looks for the INDICATE-PROGRESS parameter. If found, and equal to 'false'
238: * then returns FALSE, else this defaults to return TRUE.
239: *
240: * @return
241: */
242: private boolean shouldShowProgress() {
243: boolean result = true;
244: if (getParameterValue(Constants.INDICATE_PROGRESS) != null
245: && "false"
246: .equals((getParameterValue(Constants.INDICATE_PROGRESS))
247: .toLowerCase())) {
248: result = false;
249: }
250: return result;
251: }
252:
253: public void open(Container parentContainer, String params,
254: boolean showProgress) {
255: SwingMLServerResponse response = null;
256:
257: String url = null;
258:
259: url = computeURL();
260: if (url != null) {
261: response = HttpSubmitController.submit(url,
262: parentContainer, params, showProgress);
263: } else {
264: throw new InvalidTargetLocationException(
265: "Error accessing URL, make sure URL Property entry is defined...");
266: }
267:
268: SwingMLRenderer renderer = SwingMLRenderer.getRenderer();
269: if (response != null) {
270: renderer.render(response.getSwingMLSpec(), parentContainer);
271: if (response.hasErrors()) {
272: SwingMLModel model = (SwingMLModel) SwingMLModelToContainerRegistry
273: .getModel(parentContainer);
274: // TODO - Edit Substitute
275: model.handle(response.getErrors());
276: }
277: } else {
278: renderer.render(HttpSubmitController
279: .getConnectionErrorSpec(), parentContainer);
280: }
281: }
282:
283: public String computeURL() {
284:
285: // if URL is specified in action parameters us this, otherwise use default.
286: String URL = null;
287: URL = getModel().getUrl();
288:
289: if (URL == null) {
290: URL = SwingMLProperties.sole().get("URL");
291: }
292:
293: return URL;
294:
295: }
296:
297: /**
298: * Refresh the given container.
299: *
300: * @param container
301: */
302: public void refresh(Container container, String params) {
303:
304: disableComponents(container);
305: String theHttpRequest = HttpSubmitController
306: .buildHttpRequest(container);
307: String url = computeURL();
308: if (url != null) {
309: SwingMLServerResponse response = HttpSubmitController
310: .submit(url, params + "&" + theHttpRequest,
311: container);
312: SwingMLRenderer renderer = SwingMLRenderer.getRenderer();
313: if (response != null) {
314: renderer.processAndRender(response.getSwingMLSpec(),
315: container, true, true);
316: if (response.hasErrors()) {
317: SwingMLModel model = (SwingMLModel) SwingMLModelToContainerRegistry
318: .getModel(container);
319: model.handle(response.getErrors());
320: }
321: } else {
322: renderer.render(HttpSubmitController
323: .getConnectionErrorSpec(), container);
324: }
325: } else {
326: throw new InvalidTargetLocationException(container
327: .getName());
328: }
329: }
330:
331: /**
332: * Invoke the specified URL, No result expected, therefore XML will not be rendered...
333: *
334: * @param container
335: */
336: public void noRender(Container container, String params) {
337:
338: String theHttpRequest = HttpSubmitController
339: .buildHttpRequest(container);
340: String url = computeURL();
341: if (url != null) {
342: SwingMLServerResponse response = HttpSubmitController
343: .submit(url, params + "&" + theHttpRequest,
344: container);
345:
346: } else {
347: throw new InvalidTargetLocationException(container
348: .getName());
349: }
350: }
351:
352: private void disableComponents(Component component) {
353: component.setEnabled(false);
354: // recurse children?
355: if (component instanceof Container) {
356: Container container = (Container) component;
357: Component[] children = container.getComponents();
358: for (int x = 0; x < children.length; x++) {
359: disableComponents(children[x]);
360: }
361: }
362: }
363:
364: public ControllerActionModel getModel() {
365: return model;
366: }
367:
368: public void setModel(ControllerActionModel model) {
369: this.model = model;
370: }
371:
372: }
|