001: package nextapp.echo2.testapp.interactive.testscreen;
002:
003: import org.w3c.dom.Document;
004: import org.w3c.dom.DocumentFragment;
005: import org.w3c.dom.Element;
006: import org.w3c.dom.Node;
007:
008: import nextapp.echo2.app.Button;
009: import nextapp.echo2.app.Column;
010: import nextapp.echo2.app.Component;
011: import nextapp.echo2.app.Insets;
012: import nextapp.echo2.app.event.ActionEvent;
013: import nextapp.echo2.app.event.ActionListener;
014: import nextapp.echo2.app.layout.SplitPaneLayoutData;
015: import nextapp.echo2.app.update.ServerComponentUpdate;
016: import nextapp.echo2.app.util.DomUtil;
017: import nextapp.echo2.webcontainer.ComponentSynchronizePeer;
018: import nextapp.echo2.webcontainer.ContainerInstance;
019: import nextapp.echo2.webcontainer.DomUpdateSupport;
020: import nextapp.echo2.webcontainer.RenderContext;
021: import nextapp.echo2.webrender.ServerMessage;
022: import nextapp.echo2.webrender.Service;
023: import nextapp.echo2.webrender.WebRenderServlet;
024: import nextapp.echo2.webrender.servermessage.DomUpdate;
025: import nextapp.echo2.webrender.service.JavaScriptService;
026:
027: /**
028: * A test to examine failure behavior with client script exceptions.
029: */
030: public class ClientExceptionTest extends Column {
031:
032: /**
033: * Component that can be configured to throw JavaScript
034: * exception on client/server sync.
035: */
036: public static class ExComponent extends Component {
037:
038: public static final int MODE_WORKING = 0;
039: public static final int MODE_FAIL_ON_RENDER_ONCE = 1;
040: public static final int MODE_FAIL_ON_RENDER_EVERY_TIME = 2;
041: public static final int MODE_LOAD_BROKEN_JS_ONCE = 3;
042: public static final int MODE_LOAD_BROKEN_JS_EVERY_TIME = 4;
043:
044: private int mode;
045:
046: public ExComponent(int mode) {
047: super ();
048: this .mode = mode;
049: }
050:
051: public int getMode() {
052: return mode;
053: }
054:
055: public void setMode(int mode) {
056: this .mode = mode;
057: }
058: }
059:
060: /**
061: * Peer class for <code>ExComponent</code> that will throw a JavaScript
062: * error depending on component state.
063: */
064: public static class ExPeer implements ComponentSynchronizePeer,
065: DomUpdateSupport {
066:
067: /**
068: * Service to provide supporting JavaScript library.
069: */
070: private static final Service EXCOMPONENT_SERVICE = JavaScriptService
071: .forResource("EchoTestApp.ExComponent",
072: "/nextapp/echo2/testapp/interactive/resource/js/ExComponent.js");
073:
074: /**
075: * Service to provide supporting JavaScript library.
076: */
077: private static final Service EXCOMPONENT_BROKEN_SERVICE = JavaScriptService
078: .forResource("EchoTestApp.ExComponentBroken",
079: "/nextapp/echo2/testapp/interactive/resource/js/ExComponentBroken.js");
080:
081: static {
082: WebRenderServlet.getServiceRegistry().add(
083: EXCOMPONENT_SERVICE);
084: WebRenderServlet.getServiceRegistry().add(
085: EXCOMPONENT_BROKEN_SERVICE);
086: }
087:
088: /**
089: * @see nextapp.echo2.webcontainer.ComponentSynchronizePeer#getContainerId(nextapp.echo2.app.Component)
090: */
091: public String getContainerId(Component child) {
092: throw new UnsupportedOperationException(
093: "Component does not support children.");
094: }
095:
096: /**
097: * @see nextapp.echo2.webcontainer.ComponentSynchronizePeer#renderAdd(nextapp.echo2.webcontainer.RenderContext,
098: * nextapp.echo2.app.update.ServerComponentUpdate, java.lang.String, nextapp.echo2.app.Component)
099: */
100: public void renderAdd(RenderContext rc,
101: ServerComponentUpdate update, String targetId,
102: Component component) {
103: Element domAddElement = DomUpdate.renderElementAdd(rc
104: .getServerMessage());
105: DocumentFragment htmlFragment = rc.getServerMessage()
106: .getDocument().createDocumentFragment();
107: renderHtml(rc, update, htmlFragment, component);
108: DomUpdate.renderElementAddContent(rc.getServerMessage(),
109: domAddElement, targetId, htmlFragment);
110: }
111:
112: /**
113: * Renders a directive to dynamically load a broken script module.
114: *
115: * @param rc the relevant <code>RenderContext</code>
116: */
117: private void renderBrokenScriptModule(RenderContext rc) {
118: rc.getServerMessage().addLibrary(
119: EXCOMPONENT_BROKEN_SERVICE.getId());
120: }
121:
122: /**
123: * @see nextapp.echo2.webcontainer.ComponentSynchronizePeer#renderDispose(
124: * nextapp.echo2.webcontainer.RenderContext, nextapp.echo2.app.update.ServerComponentUpdate,
125: * nextapp.echo2.app.Component)
126: */
127: public void renderDispose(RenderContext rc,
128: ServerComponentUpdate update, Component component) {
129: }
130:
131: /**
132: * Renders a directive that will fail during processing.
133: *
134: * @param rc the relevant <code>RenderContext</code>
135: */
136: private void renderFailDirective(RenderContext rc) {
137: rc.getServerMessage().addLibrary(
138: EXCOMPONENT_SERVICE.getId());
139: rc.getServerMessage().appendPartDirective(
140: ServerMessage.GROUP_ID_POSTUPDATE,
141: "ExComponent.MessageProcessor", "fail");
142: }
143:
144: /**
145: * @see nextapp.echo2.webcontainer.DomUpdateSupport#renderHtml(nextapp.echo2.webcontainer.RenderContext,
146: * nextapp.echo2.app.update.ServerComponentUpdate,
147: * org.w3c.dom.Node, nextapp.echo2.app.Component)
148: */
149: public void renderHtml(RenderContext rc,
150: ServerComponentUpdate update, Node parentNode,
151: Component component) {
152: ExComponent exComponent = (ExComponent) component;
153: Document document = rc.getServerMessage().getDocument();
154: Element spanElement = document.createElement("span");
155: spanElement.setAttribute("id", ContainerInstance
156: .getElementId(component));
157: parentNode.appendChild(spanElement);
158:
159: switch (exComponent.getMode()) {
160: case ExComponent.MODE_FAIL_ON_RENDER_ONCE:
161: DomUtil.setElementText(spanElement,
162: "[fail on render once]");
163: renderFailDirective(rc);
164: exComponent.setMode(ExComponent.MODE_WORKING);
165: break;
166: case ExComponent.MODE_FAIL_ON_RENDER_EVERY_TIME:
167: DomUtil.setElementText(spanElement,
168: "[fail on render every time]");
169: renderFailDirective(rc);
170: break;
171: case ExComponent.MODE_LOAD_BROKEN_JS_ONCE:
172: DomUtil.setElementText(spanElement,
173: "[load broken script module]");
174: renderBrokenScriptModule(rc);
175: exComponent.setMode(ExComponent.MODE_WORKING);
176: break;
177: case ExComponent.MODE_LOAD_BROKEN_JS_EVERY_TIME:
178: DomUtil.setElementText(spanElement,
179: "[load broken script module]");
180: renderBrokenScriptModule(rc);
181: break;
182: default:
183: DomUtil.setElementText(spanElement, "[non-broken]");
184: }
185: }
186:
187: /**
188: * @see nextapp.echo2.webcontainer.ComponentSynchronizePeer#renderUpdate(
189: * nextapp.echo2.webcontainer.RenderContext, nextapp.echo2.app.update.ServerComponentUpdate,
190: * java.lang.String)
191: */
192: public boolean renderUpdate(RenderContext rc,
193: ServerComponentUpdate update, String targetId) {
194: String parentId = ContainerInstance.getElementId(update
195: .getParent());
196: DomUpdate.renderElementRemove(rc.getServerMessage(),
197: parentId);
198: renderAdd(rc, update, targetId, update.getParent());
199: return true;
200: }
201: }
202:
203: /**
204: * Creates a new <code>ClientExceptionTest</code>.
205: */
206: public ClientExceptionTest() {
207: super ();
208:
209: SplitPaneLayoutData splitPaneLayoutData = new SplitPaneLayoutData();
210: splitPaneLayoutData.setInsets(new Insets(10));
211: setLayoutData(splitPaneLayoutData);
212:
213: Button button;
214:
215: button = new Button("Add working component (Control Case)");
216: button.setStyleName("Default");
217: button.addActionListener(new ActionListener() {
218: public void actionPerformed(ActionEvent e) {
219: add(new ExComponent(ExComponent.MODE_WORKING));
220: }
221: });
222: add(button);
223:
224: button = new Button(
225: "Add broken component that fails to render (ONCE).");
226: button.setStyleName("Default");
227: button.addActionListener(new ActionListener() {
228: public void actionPerformed(ActionEvent e) {
229: add(new ExComponent(
230: ExComponent.MODE_FAIL_ON_RENDER_ONCE));
231: }
232: });
233: add(button);
234:
235: button = new Button(
236: "Add broken component that will dynamically load broken JavaScript module (ONCE).");
237: button.setStyleName("Default");
238: button.addActionListener(new ActionListener() {
239: public void actionPerformed(ActionEvent e) {
240: add(new ExComponent(
241: ExComponent.MODE_LOAD_BROKEN_JS_ONCE));
242: }
243: });
244: add(button);
245:
246: button = new Button(
247: "Add broken component that fails to render (EVERY TIME).");
248: button.setStyleName("Default");
249: button.addActionListener(new ActionListener() {
250: public void actionPerformed(ActionEvent e) {
251: add(new ExComponent(
252: ExComponent.MODE_FAIL_ON_RENDER_EVERY_TIME));
253: }
254: });
255: add(button);
256:
257: button = new Button(
258: "Add broken component that will dynamically load broken JavaScript module (EVERY TIME).");
259: button.setStyleName("Default");
260: button.addActionListener(new ActionListener() {
261: public void actionPerformed(ActionEvent e) {
262: add(new ExComponent(
263: ExComponent.MODE_LOAD_BROKEN_JS_EVERY_TIME));
264: }
265: });
266: add(button);
267: }
268: }
|