001: /***************************************************************
002: * This file is part of the [fleXive](R) project.
003: *
004: * Copyright (c) 1999-2007
005: * UCS - unique computing solutions gmbh (http://www.ucs.at)
006: * All rights reserved
007: *
008: * The [fleXive](R) project is free software; you can redistribute
009: * it and/or modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation;
011: * either version 2 of the License, or (at your option) any
012: * later version.
013: *
014: * The GNU General Public License can be found at
015: * http://www.gnu.org/copyleft/gpl.html.
016: * A copy is found in the textfile GPL.txt and important notices to the
017: * license from the author are found in LICENSE.txt distributed with
018: * these libraries.
019: *
020: * This library is distributed in the hope that it will be useful,
021: * but WITHOUT ANY WARRANTY; without even the implied warranty of
022: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
023: * GNU General Public License for more details.
024: *
025: * For further information about UCS - unique computing solutions gmbh,
026: * please see the company website: http://www.ucs.at
027: *
028: * For further information about [fleXive](R), please see the
029: * project website: http://www.flexive.org
030: *
031: *
032: * This copyright notice MUST APPEAR in all copies of the file!
033: ***************************************************************/package com.flexive.faces.javascript.menu;
034:
035: import com.flexive.faces.javascript.RelativeUriMapper;
036: import com.flexive.shared.FxFormatUtils;
037: import com.flexive.war.JsonWriter;
038: import org.apache.commons.lang.StringUtils;
039:
040: import java.io.IOException;
041: import java.io.Writer;
042: import java.util.HashMap;
043: import java.util.Map;
044:
045: /**
046: * A writer for Dojo menu objects in JSON notation.
047: *
048: * @author Daniel Lichtenberger (daniel.lichtenberger@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
049: * @version $Rev: 1 $
050: */
051: public class MenuWriter {
052: public static final String ICON_PATH = "adm/images/menu";
053:
054: private JsonWriter out;
055: private final RelativeUriMapper uriMapper;
056: private boolean standAlone = false;
057: private Map<String, String> engageSubscriptions = new HashMap<String, String>();
058: private int itemIdCounter = 0;
059: private final String menuId;
060:
061: /**
062: * Create a new menu writer using the given JSON writer.
063: *
064: * @param out an existing JsonWriter
065: * @throws java.io.IOException if an output error occured
066: */
067: public MenuWriter(JsonWriter out, String widgetId,
068: RelativeUriMapper uriMapper) throws IOException {
069: this .out = out;
070: this .menuId = widgetId;
071: this .uriMapper = uriMapper;
072: out.startArray();
073: }
074:
075: /**
076: * Create a menu writer that writes directly to the given
077: * output writer.
078: *
079: * @param writer the output writer
080: * @throws java.io.IOException if an output error occured
081: */
082: public MenuWriter(Writer writer, String widgetId,
083: RelativeUriMapper uriMapper) throws IOException {
084: this (new JsonWriter(writer), widgetId, uriMapper);
085: this .standAlone = true;
086: }
087:
088: /**
089: * Render the JSON representation for the given menu.
090: *
091: * @param menuName name of the JS variable where the menu widget is stored
092: * @param menuClass widget class of the menu widget, e.g. TreeContextMenuV3
093: * @param itemClass widget class of the menu items, e.g. TreeMenuItemV3
094: * @param container the menu container
095: * @param contextMenuTarget target element if this menu should be attached as a context menu
096: * @param showHandler an optional javascript handler to be called when the menu is opened
097: * @throws IOException if an output error occured @param writer the output writer @param widgetId the widget ID (set to null to use an auto-generated ID)
098: */
099: public static void writeMenu(Writer writer, String widgetId,
100: String menuName, String menuClass, String itemClass,
101: MenuItemContainer container, RelativeUriMapper uriMapper,
102: String contextMenuTarget, String showHandler)
103: throws IOException {
104: writer.write("var "
105: + menuName
106: + " = makeMenu("
107: + (widgetId != null ? "'"
108: + FxFormatUtils.escapeForJavaScript(widgetId)
109: + "'" : "null") + ", '" + menuClass + "', '"
110: + itemClass + "', ");
111: // render menu-items in method call
112: MenuWriter menuWriter = new MenuWriter(writer, widgetId,
113: uriMapper);
114: for (MenuItem item : container.getMenuItems()) {
115: menuWriter.writeItem(item);
116: }
117: menuWriter.finishResponse();
118: writer.write(", false, "
119: + (StringUtils.isNotBlank(contextMenuTarget) ? "'"
120: + contextMenuTarget + "'" : "null") + ");\n");
121: // add event subscriptions
122: menuWriter.writeEventSubscriptions(writer);
123: if (StringUtils.isNotBlank(showHandler)) {
124: writer
125: .write(menuName + ".show_ = " + menuName
126: + ".show;\n");
127: writer.write(menuName + ".show = " + showHandler + ";\n");
128: }
129: }
130:
131: /**
132: * Ends the response.
133: *
134: * @throws java.io.IOException if an I/O error occured
135: */
136: public void finishResponse() throws IOException {
137: out.closeArray();
138: if (this .standAlone) {
139: // finish JSON response
140: out.finishResponse();
141: }
142: }
143:
144: public void startItem(MenuItem item) throws IOException {
145: out.startMap();
146: final String widgetId = item.getId();
147: itemIdCounter++;
148: item.renderItemAttributes(out, uriMapper, engageSubscriptions,
149: widgetId);
150: if (item.getMenuItems().size() > 0) {
151: // add nested menu items
152: out.startAttribute("submenu");
153: out.startArray();
154: for (MenuItem child : item.getMenuItems()) {
155: writeItem(child);
156: }
157: out.closeArray();
158: }
159: }
160:
161: public void startSubMenu() throws IOException {
162: out.startAttribute("submenu");
163: out.startArray();
164: }
165:
166: public void closeSubMenu() throws IOException {
167: out.closeArray();
168: }
169:
170: public void closeItem() throws IOException {
171: out.closeMap();
172: }
173:
174: public void writeItem(MenuItem item) throws IOException {
175: startItem(item);
176: closeItem();
177: }
178:
179: /**
180: * Render the event subscriptions accumulated while rendering the JSON code.
181: *
182: * @param out the output writer to be used. The JSON code must have been finished when
183: * this method is called!
184: * @throws java.io.IOException if an I/O error occured
185: */
186: public void writeEventSubscriptions(Writer out) throws IOException {
187: for (Map.Entry<String, String> entry : engageSubscriptions
188: .entrySet()) {
189: out.write("dojo.event.topic.subscribe(dojo.widget.byId('"
190: + entry.getKey() + "').eventNames.engage, "
191: + entry.getValue() + ");\n");
192: // out.write("dojo.widget.byId('" + entry.getKey() + "').onClick = " + entry.getValue() + ";\n");
193: }
194: }
195:
196: public Map<String, String> getEngageSubscriptions() {
197: return engageSubscriptions;
198: }
199:
200: public void setEngageSubscriptions(
201: Map<String, String> engageSubscriptions) {
202: this.engageSubscriptions = engageSubscriptions;
203: }
204: }
|