001: /******************************************************************************
002: * JBoss, a division of Red Hat *
003: * Copyright 2006, Red Hat Middleware, LLC, and individual *
004: * contributors as indicated by the @authors tag. See the *
005: * copyright.txt in the distribution for a full listing of *
006: * individual contributors. *
007: * *
008: * This is free software; you can redistribute it and/or modify it *
009: * under the terms of the GNU Lesser General Public License as *
010: * published by the Free Software Foundation; either version 2.1 of *
011: * the License, or (at your option) any later version. *
012: * *
013: * This software is distributed in the hope that it will be useful, *
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of *
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
016: * Lesser General Public License for more details. *
017: * *
018: * You should have received a copy of the GNU Lesser General Public *
019: * License along with this software; if not, write to the Free *
020: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
021: * 02110-1301 USA, or see the FSF site: http://www.fsf.org. *
022: ******************************************************************************/package org.jboss.portal.core.aspects.controller.node;
023:
024: import org.apache.log4j.Logger;
025: import org.jboss.portal.Mode;
026: import org.jboss.portal.WindowState;
027: import org.jboss.portal.api.PortalRuntimeContext;
028: import org.jboss.portal.api.node.PortalNode;
029: import org.jboss.portal.api.node.event.PageRenderEvent;
030: import org.jboss.portal.api.node.event.PortalNodeEvent;
031: import org.jboss.portal.api.node.event.WindowActionEvent;
032: import org.jboss.portal.api.node.event.WindowEvent;
033: import org.jboss.portal.api.node.event.WindowNavigationEvent;
034: import org.jboss.portal.api.node.event.WindowRenderEvent;
035: import org.jboss.portal.common.invocation.InvocationException;
036: import org.jboss.portal.common.util.LazyMap;
037: import org.jboss.portal.core.controller.CommandRedirectionException;
038: import org.jboss.portal.core.controller.ControllerCommand;
039: import org.jboss.portal.core.controller.ControllerInterceptor;
040: import org.jboss.portal.core.controller.ControllerResponse;
041: import org.jboss.portal.core.event.PortalEventListenerRegistry;
042: import org.jboss.portal.core.impl.api.node.PortalNodeEventContextImpl;
043: import org.jboss.portal.core.impl.api.node.PortalNodeImpl;
044: import org.jboss.portal.core.model.portal.PortalObjectId;
045: import org.jboss.portal.core.model.portal.command.WindowCommand;
046: import org.jboss.portal.core.model.portal.command.action.InvokePortletWindowActionCommand;
047: import org.jboss.portal.core.model.portal.command.action.InvokePortletWindowRenderCommand;
048: import org.jboss.portal.core.model.portal.command.render.RenderPageCommand;
049: import org.jboss.portal.core.model.portal.command.render.RenderWindowCommand;
050: import org.jboss.portal.core.model.portal.navstate.WindowNavigationalState;
051: import org.jboss.portal.core.navstate.NavigationalStateKey;
052: import org.jboss.portal.portlet.PortletParameters;
053: import org.jboss.portal.portlet.PortletParametersStateString;
054: import org.jboss.portal.portlet.StateString;
055:
056: import java.util.Map;
057:
058: /** @author <a href="mailto:julien@jboss.org">Julien Viet</a> */
059: public class EventBroadcasterInterceptor extends ControllerInterceptor {
060:
061: /** . */
062: private static Logger log = Logger
063: .getLogger(EventBroadcasterInterceptor.class);
064:
065: /** . */
066: private PortalEventListenerRegistry listenerRegistry;
067:
068: public PortalEventListenerRegistry getListenerRegistry() {
069: return listenerRegistry;
070: }
071:
072: public void setListenerRegistry(
073: PortalEventListenerRegistry listenerRegistry) {
074: this .listenerRegistry = listenerRegistry;
075: }
076:
077: public ControllerResponse invoke(ControllerCommand cmd)
078: throws Exception, InvocationException {
079: // Get the current node from the thread local
080: PortalNodeImpl node = Navigation.getCurrentNode();
081:
082: // The next event that will optionally replace this one
083: PortalNodeEvent nextEvent = null;
084:
085: // Create an event from the current node
086: PortalNodeEvent event = createEvent(cmd, node);
087:
088: //
089: if (event != null) {
090: try {
091: // Get runtime context from the thread local
092: PortalRuntimeContext runtimeContext = Navigation
093: .getPortalRuntimeContext();
094:
095: //
096: PortalNodeEventContextImpl nodeEventContext = new PortalNodeEventContextImpl(
097: listenerRegistry, node, event, runtimeContext);
098:
099: // Fire the event
100: nextEvent = nodeEventContext.dispatch();
101: } catch (Exception e) {
102: log.error("Error when dispatching pre event " + event,
103: e);
104: }
105: }
106:
107: //
108: if (nextEvent != null) {
109: ControllerCommand redirection = createCommand(nextEvent);
110:
111: //
112: if (redirection != null) {
113: throw new CommandRedirectionException(redirection);
114: }
115: }
116:
117: //
118: return (ControllerResponse) cmd.invokeNext();
119: }
120:
121: /**
122: * @param event
123: * @return
124: */
125: private ControllerCommand createCommand(PortalNodeEvent event) {
126: if (event instanceof WindowEvent) {
127: WindowEvent we = (WindowEvent) event;
128:
129: //
130: PortalNodeImpl nextNode = (PortalNodeImpl) we.getNode();
131: PortalObjectId nodeRef = nextNode.getObjectId();
132: Mode mode = we.getMode();
133: WindowState windowState = we.getWindowState();
134:
135: //
136: if (event instanceof WindowActionEvent) {
137: WindowActionEvent wae = (WindowActionEvent) event;
138: Map params = wae.getParameters();
139:
140: //
141: PortletParameters interactionParams;
142: if (params instanceof ActionParameterMap) {
143: interactionParams = (PortletParameters) ((ActionParameterMap) params)
144: .createDelegate();
145: } else {
146: interactionParams = asParameters(params);
147: }
148:
149: //
150: if (interactionParams != null) {
151: return new InvokePortletWindowActionCommand(
152: nodeRef, mode, windowState, null,
153: new PortletParametersStateString(
154: interactionParams), null);
155: }
156: } else if (event instanceof WindowNavigationEvent) {
157: WindowNavigationEvent wne = (WindowNavigationEvent) event;
158:
159: //
160: Map params = wne.getParameters();
161: PortletParameters navigationalParams = asParameters(params);
162: StateString state = navigationalParams != null ? new PortletParametersStateString(
163: navigationalParams)
164: : null;
165:
166: //
167: return new InvokePortletWindowRenderCommand(nodeRef,
168: mode, windowState, state);
169: }
170: }
171:
172: //
173: return null;
174: }
175:
176: /**
177: * Returns portal node event corresponding to the command or null.
178: *
179: * @param command
180: * @param node
181: * @return a portal node event
182: */
183: private PortalNodeEvent createEvent(ControllerCommand command,
184: PortalNode node) {
185: if (command instanceof WindowCommand) {
186: WindowCommand wc = (WindowCommand) command;
187:
188: //
189: if (command instanceof InvokePortletWindowActionCommand) {
190: InvokePortletWindowActionCommand iwac = (InvokePortletWindowActionCommand) wc;
191:
192: // Get form parameters
193: PortletParameters formParameters = iwac
194: .getFormParameters();
195:
196: // Get interaction parameters
197: PortletParameters interactionParameters = null;
198: if (iwac.getInteractionState() instanceof PortletParametersStateString) {
199: interactionParameters = ((PortletParametersStateString) iwac
200: .getInteractionState()).getParameters();
201: }
202:
203: // Build a map that represents the parameters of the action
204: Map actionParameters;
205: if (interactionParameters != null) {
206: if (formParameters != null) {
207: actionParameters = new ActionParameterMap(
208: interactionParameters, formParameters);
209: } else {
210: actionParameters = interactionParameters;
211: }
212: } else {
213: if (formParameters != null) {
214: actionParameters = formParameters;
215: } else {
216: actionParameters = new PortletParameters();
217: }
218: }
219:
220: // Populate and return the window action event
221: WindowActionEvent action = new WindowActionEvent(node);
222: action.setMode(iwac.getMode());
223: action.setWindowState(iwac.getWindowState());
224: action.setParameters(actionParameters);
225: return action;
226: } else if (command instanceof InvokePortletWindowRenderCommand) {
227: InvokePortletWindowRenderCommand iwrc = (InvokePortletWindowRenderCommand) wc;
228:
229: //
230: WindowNavigationEvent event = new WindowNavigationEvent(
231: node);
232: event.setMode(iwrc.getMode());
233: event.setWindowState(iwrc.getWindowState());
234:
235: //
236: StateString navigationalState = iwrc
237: .getNavigationalState();
238: if (navigationalState instanceof PortletParametersStateString) {
239: Map params = ((PortletParametersStateString) navigationalState)
240: .getParameters();
241: event.setParameters(params);
242: }
243:
244: //
245: return event;
246: } else if (command instanceof RenderWindowCommand) {
247: WindowRenderEvent event = new WindowRenderEvent(node);
248:
249: //
250: RenderWindowCommand rwc = (RenderWindowCommand) command;
251: NavigationalStateKey key = new NavigationalStateKey(
252: WindowNavigationalState.class, rwc
253: .getTargetId());
254: WindowNavigationalState navstate = (WindowNavigationalState) command
255: .getControllerContext()
256: .getAttribute(
257: ControllerCommand.NAVIGATIONAL_STATE_SCOPE,
258: key);
259: if (navstate != null) {
260: event.setMode(navstate.getMode());
261: event.setWindowState(navstate.getWindowState());
262:
263: StateString parametersState = navstate
264: .getContentState();
265: if (parametersState instanceof PortletParametersStateString) {
266: Map params = ((PortletParametersStateString) parametersState)
267: .getParameters();
268: event.setParameters(params);
269: }
270: }
271:
272: //
273: return event;
274: }
275: } else if (command instanceof RenderPageCommand) {
276: return new PageRenderEvent(node);
277: }
278:
279: //
280: return null;
281: }
282:
283: /**
284: * @param map
285: * @return
286: */
287: private PortletParameters asParameters(Map map) {
288: if (map == null) {
289: return null;
290: } else if (map instanceof PortletParameters) {
291: return (PortletParameters) map;
292: } else {
293: try {
294: return new PortletParameters(map);
295: } catch (IllegalArgumentException e) {
296: log
297: .error(
298: "Window action event received wrong parameter set",
299: e);
300:
301: //
302: return null;
303: }
304: }
305: }
306:
307: /**
308: *
309: */
310: private static class ActionParameterMap extends LazyMap {
311: /** . */
312: private PortletParameters formParams;
313:
314: /** . */
315: private PortletParameters interactionParams;
316:
317: /** . */
318: private PortletParameters params;
319:
320: public ActionParameterMap(PortletParameters interactionParams,
321: PortletParameters formParams) {
322: this .formParams = formParams;
323: this .interactionParams = interactionParams;
324: this .params = null;
325: }
326:
327: protected Map createDelegate() {
328: if (params == null) {
329: params = new PortletParameters(interactionParams);
330: params.append(formParams);
331: }
332: return params;
333: }
334: }
335: }
|