001: /**
002: * Copyright 2007 Webmedia Group Ltd.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: **/package org.araneaframework.uilib.menu;
016:
017: import java.io.Serializable;
018: import java.util.Iterator;
019: import java.util.Map;
020: import org.apache.commons.collections.map.LinkedMap;
021: import org.araneaframework.Component;
022: import org.araneaframework.Widget;
023: import org.araneaframework.http.util.JsonArray;
024: import org.araneaframework.http.util.JsonObject;
025:
026: /**
027: * Represents web application context menu (right-click menu) hierarchy.
028: *
029: * @see org.araneaframework.uilib.menu.ContextMenuWidget
030: *
031: * @author Taimo Peelo (taimo@araneaframework.org)
032: * @since 1.1
033: */
034: public class ContextMenuItem implements Serializable {
035: /** Submenu of this <code>MenuItem</code>. */
036: private Map subMenu;
037:
038: /** Name for this menu item. */
039: private String label;
040:
041: private ContextMenuEntry menuEntry;
042:
043: /**
044: * Creates a top-level context menu which has no
045: * <code>label</code> and does not represent any menu entry.
046: */
047: public ContextMenuItem() {
048: }
049:
050: /**
051: * Creates a context menu item which has just <code>label</code>.
052: */
053: public ContextMenuItem(String label) {
054: this .label = label;
055: }
056:
057: /**
058: * Creates context menu with both <code>label</code> and associated menu entry.
059: */
060: public ContextMenuItem(String label, ContextMenuEntry menuEntry) {
061: this (label);
062: this .menuEntry = menuEntry;
063: }
064:
065: /**
066: * Adds {@link ContextMenuItem} <code>item</code> as submenu of this {@link ContextMenuItem}.
067: * @return this {@link ContextMenuItem}
068: */
069: public ContextMenuItem addMenuItem(ContextMenuItem item) {
070: if (subMenu == null)
071: subMenu = new LinkedMap();
072: subMenu.put(item.getLabel(), item);
073: return item;
074: }
075:
076: /**
077: * Returns <code>label</code> of this {@link ContextMenuItem}.
078: */
079: public String getLabel() {
080: return label;
081: }
082:
083: /**
084: * Returns submenu of this {@link ContextMenuItem} as <code>Map<String, ContextMenuItem></code>.
085: */
086: public Map getSubMenu() {
087: return subMenu;
088: }
089:
090: /**
091: * Returns JSON representation of this context menu hierarchy.
092: */
093: public JsonObject toJSON() {
094: JsonObject jsonObject = new JsonObject();
095: if (label != null)
096: jsonObject.setStringProperty("label", label);
097: if (menuEntry != null) {
098: jsonObject.setStringProperty("target", menuEntry
099: .getTarget() != null ? menuEntry.getTarget()
100: .getScope().toString() : "null");
101: jsonObject.setStringProperty("type", menuEntry
102: .getEventType());
103: jsonObject.setStringProperty("id", menuEntry.getEventId()
104: .toString());
105: jsonObject.setProperty("param", menuEntry
106: .getEventParamDetector());
107: }
108: if (subMenu != null) {
109: jsonObject.setProperty("submenu", menuMapToJsonArray(
110: subMenu).toString());
111: }
112:
113: return jsonObject;
114: }
115:
116: protected JsonArray menuMapToJsonArray(Map map) {
117: JsonArray result = new JsonArray();
118: for (Iterator i = map.values().iterator(); i.hasNext();) {
119: ContextMenuItem item = (ContextMenuItem) i.next();
120: result.append(item.toJSON().toString());
121: }
122:
123: return result;
124: }
125:
126: /**
127: * This class describes the menu entry corresponding to some {@link ContextMenuItem}.
128: * It contains information about {@link Component} that is notified when entry is selected from menu,
129: * the event type (<code>action</code> or <code>event</code>) which should be triggered and
130: * event parameter detector. It cannot be instantiated directly, rather its subclasses
131: * {@link ContextMenuActionEntry} or {@link ContextMenuEventEntry} should be used.
132: *
133: * @author Taimo Peelo (taimo@araneaframework.org)
134: * @since 1.1
135: */
136: public static class ContextMenuEntry implements Serializable {
137: /** Default event parameter detector (leaves event parameter undefined). */
138: public static final String NULL_EVENT_PARAM_DETECTOR = "function() { return null; }";
139: /** Constant corresponding to Aranea <code>action</code> triggering by this {@link ContextMenuEntry}. */
140: public static final String ACTION = "action";
141: /** Constant corresponding to Aranea <code>event</code> triggering by this {@link ContextMenuEntry}. */
142: public static final String EVENT = "event";
143:
144: private Widget target = null;
145: protected Object eventId = null;
146: protected String eventType = null;
147: protected String eventParamDetector = NULL_EVENT_PARAM_DETECTOR;
148:
149: protected ContextMenuEntry(Object eventId, String eventType) {
150: this .eventId = eventId;
151: this .eventType = eventType;
152: }
153:
154: protected ContextMenuEntry(Object eventId, String eventType,
155: Widget target) {
156: this (eventId, eventType);
157: this .target = target;
158: }
159:
160: protected ContextMenuEntry(Object eventId, String eventType,
161: Widget target, String eventParamDetector) {
162: this (eventId, eventType);
163: this .target = target;
164: this .eventParamDetector = eventParamDetector;
165: }
166:
167: /**
168: * Returns the event id generated when entry is selected.
169: */
170: public Object getEventId() {
171: return eventId;
172: }
173:
174: /**
175: * Returns the event type of this {@link ContextMenuEntry}, either {@link ContextMenuEntry#ACTION}
176: * or {@link ContextMenuEntry#EVENT}.
177: */
178: public String getEventType() {
179: return eventType;
180: }
181:
182: /**
183: * Returns {@link Widget} that receives the event when entry is selected.
184: */
185: public Widget getTarget() {
186: return target;
187: }
188:
189: /**
190: * Returns the event parameter detector which detects the event parameter supplied along with event id.
191: * If left unspecified, this returns {@link ContextMenuEntry#NULL_EVENT_PARAM_DETECTOR} which returns
192: * null. Otherwise it returns custom Javascript function defined by developer.
193: */
194: public String getEventParamDetector() {
195: return eventParamDetector;
196: }
197: }
198:
199: /**
200: * Context menu entry which generates Aranea <code>action</code> when entry is selected.
201: *
202: * @author Taimo Peelo (taimo@araneaframework.org)
203: * @since 1.1
204: */
205: public static class ContextMenuActionEntry extends ContextMenuEntry {
206: public ContextMenuActionEntry(Object actionId, Widget target) {
207: super (actionId, ACTION, target);
208: }
209:
210: public ContextMenuActionEntry(Object actionId, Widget target,
211: String eventParamDetector) {
212: super (actionId, ACTION, target, eventParamDetector);
213: }
214: }
215:
216: /**
217: * Context menu entry which generates Aranea <code>event</code> when entry is selected.
218: *
219: * @author Taimo Peelo (taimo@araneaframework.org)
220: * @since 1.1
221: */
222: public static class ContextMenuEventEntry extends ContextMenuEntry {
223: public ContextMenuEventEntry(Object eventId, Widget target) {
224: super (eventId, EVENT, target);
225: }
226:
227: public ContextMenuEventEntry(Object eventId, Widget target,
228: String eventParamDetector) {
229: super(eventId, EVENT, target, eventParamDetector);
230: }
231: }
232: }
|