Source code: nextapp/echoservlet/WindowUI.java
1 /*
2 * This file is part of the Echo Web Application Framework (hereinafter "Echo").
3 * Copyright (C) 2002-2004 NextApp, Inc.
4 *
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * Alternatively, the contents of this file may be used under the terms of
18 * either the GNU General Public License Version 2 or later (the "GPL"), or
19 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
20 * in which case the provisions of the GPL or the LGPL are applicable instead
21 * of those above. If you wish to allow use of your version of this file only
22 * under the terms of either the GPL or the LGPL, and not to allow others to
23 * use your version of this file under the terms of the MPL, indicate your
24 * decision by deleting the provisions above and replace them with the notice
25 * and other provisions required by the GPL or the LGPL. If you do not delete
26 * the provisions above, a recipient may use your version of this file under
27 * the terms of any one of the MPL, the GPL or the LGPL.
28 */
29
30 package nextapp.echoservlet;
31
32 import java.beans.PropertyChangeEvent;
33 import java.beans.PropertyChangeListener;
34 import java.io.IOException;
35 import java.io.PrintWriter;
36
37 import nextapp.echo.Window;
38
39 import nextapp.echoservlet.html.Element;
40 import nextapp.echoservlet.html.ElementNames;
41 import nextapp.echoservlet.resource.ResourceNames;
42 import nextapp.echoservlet.util.ContentType;
43
44 /**
45 * A peer object for <code>Window</code>s. This class is responsible for
46 * rendering the root document of each browser window, which contains a
47 * <frameset> that references the window's content and the
48 * <code>Controller</code> document. Windows also contain the
49 * client model object script and additional JavaScript functions for
50 * maintaining application state.
51 */
52 public class WindowUI extends ComponentPeer
53 implements PropertyChangeListener, Service {
54
55 public static final int MENU_BAR = 0x4;
56 public static final int STATUS_BAR = 0x8;
57 public static final int TOOL_BAR = 0x2;
58
59 /**
60 * The service containing the ClientModel script.
61 */
62 private static final Service SERVICE_CLIENT_MODEL_SCRIPT
63 = StaticText.createFromResource(ClientObjects.STD_PREFIX + "cmodel", ResourceNames.CLIENT_MODEL_SCRIPT);
64
65 /**
66 * The service containing the window's built-in JavaScript functions.
67 */
68 private static final Service SERVICE_WINDOW_SCRIPT
69 = StaticText.createFromResource(ClientObjects.STD_PREFIX + "win", ResourceNames.WINDOW_SCRIPT);
70
71 static {
72 EchoServer.addGlobalService(SERVICE_CLIENT_MODEL_SCRIPT);
73 EchoServer.addGlobalService(SERVICE_WINDOW_SCRIPT);
74 }
75
76 /**
77 * Returns a line of JavaScript code that will invoke the window unload
78 * handler.
79 *
80 * @return A line of JavaScript code that will invoke the window unload
81 * handler.
82 */
83 public static String getScriptHandleUnload() {
84 return ClientObjects.STD_PREFIX + "handleUnload();";
85 }
86
87 private int flags = 0;
88
89 /**
90 * Returns the PaneUI of the WindowUI's content.
91 *
92 * @return The PaneUI of the WindowUI's content.
93 */
94 public PaneUI getRootPaneUI() {
95 Window window = (Window) getComponent();
96 PaneUI paneUI;
97 if (window.getContent() == null || !window.getContent().isVisible()) {
98 paneUI = null;
99 } else {
100 paneUI = (PaneUI) getPeer(window.getContent());
101 if (paneUI instanceof ContainerPaneUI) {
102 // Display forwarded container pane if container pane is empty.
103 paneUI = ((ContainerPaneUI) paneUI).getForwardingPane();
104 }
105 }
106 return paneUI;
107 }
108
109 /**
110 * Returns the script necessary to initialize the "ClientModel"
111 * JavaScript object.
112 *
113 * @return The script necessary to initialize the "ClientModel"
114 * JavaScript object.
115 */
116 private String getScriptInitClientModel() {
117 return "E_initClientModel(\'" + getId() + "\');";
118 }
119
120 /**
121 * Returns the flags enabled on this window.
122 *
123 * @return The flags enabled on this window, which can consist of zero or
124 * more of the following values ORed together:
125 * <ul>
126 * <li>MENU_BAR</li>
127 * <li>STATUS_BAR</li>
128 * <li>TOOL_BAR</li>
129 * </ul>
130 */
131 public int getFlags() {
132 return flags;
133 }
134
135 /**
136 * @see java.beans.PropertyChangeListener#propertyChange(PropertyChangeEvent)
137 */
138 public void propertyChange(PropertyChangeEvent e) {
139 if (Window.TITLE_CHANGED_PROPERTY.equals(e.getPropertyName())) {
140 getInstancePeer().setTitle(this);
141 } else if (Window.Z_INDEX_CHANGED_PROPERTY.equals(e.getPropertyName())) {
142 if (((Integer)e.getNewValue()).intValue() > 0) {
143 getInstancePeer().raiseWindow(this);
144 } else {
145 getInstancePeer().lowerWindow(this);
146 }
147 } else {
148 redraw();
149 }
150 }
151
152 /**
153 * @see nextapp.echoservlet.ComponentPeer#registered()
154 */
155 public void registered() {
156 getComponent().addPropertyChangeListener(this);
157 }
158
159 /**
160 * @see nextapp.echoservlet.Service#service(Connection)
161 */
162 public void service(Connection conn)
163 throws IOException {
164 Window window = (Window) getComponent();
165
166 HtmlDocument doc = HtmlDocument.createFrameSet(conn);
167 doc.addScriptInclude(EchoServer.SERVICE_COLLECTIONS_SCRIPT);
168 doc.addScriptInclude(SERVICE_CLIENT_MODEL_SCRIPT);
169 doc.addScriptInclude(SERVICE_WINDOW_SCRIPT);
170 doc.addScript(getScriptInitClientModel(), HtmlDocument.EVENT_INITIALIZE);
171 if (!conn.getServer().getApplicationProperties().getBoolean(ApplicationProperties.DISABLE_ONUNLOAD)) {
172 doc.addScript(getScriptHandleUnload(), HtmlDocument.EVENT_ONUNLOAD);
173 }
174
175 // Add Title.
176 Element title = new Element(ElementNames.TITLE, true);
177 title.setWhitespaceRelevant(true);
178 if (window.getTitle() != null) {
179 title.addText(window.getTitle());
180 }
181 doc.getHeadElement().add(title);
182
183 Element frameSet = doc.getBodyElement();
184 if (conn.isDebugInteractiveControllerEnabled()) {
185 // The interactive controller is visible.
186 frameSet.addAttribute("rows", "*,40");
187 } else {
188 frameSet.addAttribute("rows", "100%,*");
189 }
190 frameSet.addAttribute("id", ClientObjects.getObjectName(getId()));
191 frameSet.addAttribute("frameborder", 0);
192 frameSet.addAttribute("framespacing", 0);
193 frameSet.addAttribute("border", 0);
194
195 // Add the window's content.
196 PaneUI paneUI;
197 if (window.getContent() == null || !window.getContent().isVisible()) {
198 paneUI = null;
199 } else {
200 paneUI = (PaneUI) getPeer(window.getContent());
201 }
202
203 frameSet.add(ContainerPaneUI.createFrameElement(conn, paneUI));
204
205 // Add Controller Frame.
206 Element controlFrame = new Element(ElementNames.FRAME, false);
207 controlFrame.addAttribute("src", ClientObjects.getServiceUri(conn, getInstancePeer().getController()));
208 controlFrame.addAttribute("name", ClientObjects.CONTROLLER_FRAME_NAME);
209 controlFrame.addAttribute("scrolling", "no");
210 controlFrame.addAttribute("frameborder", 0);
211 controlFrame.addAttribute("marginwidth", 0);
212 controlFrame.addAttribute("marginheight", 0);
213 controlFrame.addAttribute("noresize");
214 frameSet.add(controlFrame);
215
216 conn.setContentType(ContentType.TEXT_HTML);
217 PrintWriter pw = conn.getWriter();
218 doc.render(pw);
219 pw.close();
220 }
221
222 /**
223 * Sets the flags enabled on this window.
224 *
225 * @param flags The flags enabled on this window, which can consist of zero or
226 * more of the following values ORed together:
227 * <ul>
228 * <li>MENU_BAR</li>
229 * <li>STATUS_BAR</li>
230 * <li>TOOL_BAR</li>
231 * </ul>
232 */
233 public void setFlags(int flags) {
234 this.flags = flags;
235 }
236
237 /**
238 * @see nextapp.echoservlet.ComponentPeer#unregistered()
239 */
240 public void unregistered() {
241 getComponent().removePropertyChangeListener(this);
242 }
243 }