KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > portal > core > invocation > StrategyInterceptor


1 /*
2  * JBoss, the OpenSource J2EE webOS
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7
8 package org.jboss.portal.core.invocation;
9
10 import org.apache.log4j.Logger;
11 import org.jboss.portal.common.MediaType;
12 import org.jboss.portal.core.CoreConstants;
13 import org.jboss.portal.core.metadata.PageMetaData;
14 import org.jboss.portal.core.plugins.page.Page;
15 import org.jboss.portal.core.plugins.page.WindowLocation;
16 import org.jboss.portal.core.theme.strategy.StrategyFactory;
17 import org.jboss.portal.server.LayoutServer;
18 import org.jboss.portal.server.Portal;
19 import org.jboss.portal.server.PortalRequest;
20 import org.jboss.portal.server.PortalResponse;
21 import org.jboss.portal.server.ServerObject;
22 import org.jboss.portal.server.Window;
23 import org.jboss.portal.server.WindowContext;
24 import org.jboss.portal.server.invocation.AttachmentKey;
25 import org.jboss.portal.server.invocation.Interceptor;
26 import org.jboss.portal.server.invocation.Invocation;
27 import org.jboss.portal.server.plugins.windowstate.WindowState;
28 import org.jboss.portal.server.theme.LayoutConstants;
29 import org.jboss.portal.server.theme.PortalLayout;
30 import org.jboss.portal.server.theme.strategy.LayoutStrategy;
31 import org.jboss.portal.server.theme.strategy.PortletContext;
32 import org.jboss.portal.server.theme.strategy.StrategyContext;
33 import org.jboss.portal.server.theme.strategy.StrategyException;
34 import org.jboss.portal.server.theme.strategy.StrategyResponse;
35 import org.jboss.portal.server.user.UserContext;
36
37 import javax.activation.MimeTypeParseException JavaDoc;
38 import javax.servlet.http.HttpServletRequest JavaDoc;
39 import java.util.ArrayList JavaDoc;
40 import java.util.HashMap JavaDoc;
41 import java.util.Iterator JavaDoc;
42 import java.util.List JavaDoc;
43 import java.util.Map JavaDoc;
44
45 /**
46  * Interceptor to handle layout behavior.
47  * <p>This interceptor works together with the StrategyFactory to invoke and evaluate
48  * the layout strategy. The strategy can be defined for each portal as property (pointing to a
49  * named strategy, that can be defined in portal-strategies.xml). It can also be overwritten
50  * in individual layouts (see portal-layouts.xml). This implementation handles maximized portlets,
51  * and makes sure that there is always only one maximized portlet at a time. It also takes care of
52  * all the portlets that don't need to be rendered, since they won't get a chance to appear on
53  * the page (since the maximized portlet takes over).</p>
54  *
55  * @author <a HREF="mailto:mholzner@novell.com">Martin Holzner</a>.
56  * @version <tt>$Revision: 1.14 $</tt>
57  * @see StrategyFactory
58  * @see org.jboss.portal.server.theme.strategy.LayoutStrategy
59  */

60 public final class StrategyInterceptor implements Interceptor
61 {
62    private static final Logger log = Logger.getLogger(StrategyInterceptor.class);
63
64    /**
65     * Perform the invocation.
66     *
67     * @param invocation
68     * @return the returned object
69     */

70    public Object JavaDoc invoke(Invocation invocation)
71    {
72       log.debug("analyzing layout strategy....");
73
74       Portal portal = (Portal)invocation.getAttachment(AttachmentKey.PORTAL);
75       Page page = (Page)invocation.getAttachment(CoreAttachmentKey.PAGE);
76       PortalRequest request = (PortalRequest)invocation.getAttachment(AttachmentKey.PORTAL_REQUEST);
77
78       try
79       {
80          String JavaDoc layoutURI = null;
81          StrategyResponse strategyResponse = null;
82          LayoutStrategy layoutStrategy = null;
83          String JavaDoc state = null;
84
85          publishLayoutServerToRequest(request);
86
87          PortalLayout layout = getLayout(portal, page, request);
88
89          // get the requested media type
90
MediaType mediaType = getRequestedMediaType(invocation);
91
92          log.debug("looking for a layout strategy [" + portal.getName() + "] [" + page.getName() + "] ["
93             + (layout != null ? layout.getName() : "<no layout>") + "] [" + mediaType + "]");
94
95          LayoutServer layoutServer = request.getServer().getManager().getLayoutServer();
96
97          if (layout != null)
98          {
99             // get the layout strategy for this layout
100
log.debug("got a layout: trying to get the strategy from it...");
101             layoutStrategy = layoutServer.getStrategy(layout, mediaType);
102          }
103
104          if (layoutStrategy == null)
105          {
106             log.debug("no strategy from the layoutlayout: trying to get named strategy...");
107             // if the layout doesn't define a strategy, then use the one defined for the portal
108
String JavaDoc strategyName = (String JavaDoc)portal.getProperties().get(CoreConstants.PORTAL_PROP_STRATEGY);
109             if (strategyName == null)
110             {
111                log.warn("No strategy name found, using 'default'");
112                // default to the 'default' strategy
113
strategyName = "default";
114             }
115             log.debug("looking for strategy with name: " + strategyName);
116             layoutStrategy = layoutServer.getStrategy(strategyName, mediaType);
117          }
118
119          // if a strategy is defined, call it
120
if (layoutStrategy == null)
121          {
122             log.warn("No Layout Strategy found");
123          }
124          else
125          {
126             log.debug("found strategy to use: " + layoutStrategy);
127
128             UserContext userContext = (UserContext)invocation.getAttachment(AttachmentKey.USER_CONTEXT);
129
130             // get the names of all regions on the requested page
131
String JavaDoc[] regionNames = getRegionNames(page);
132
133             // get a map of portlet context to window
134
List JavaDoc windows = (List JavaDoc)invocation.getAttachment(AttachmentKey.VIEW);
135             Map JavaDoc portlets = getPortletList(windows, userContext);
136
137             // check if the request is targeted at a particular portlet
138
PortletContext targetPortlet = getTarget(request, userContext);
139
140             // now create a context, and evaluate the strategy
141
StrategyContext strategyContext = StrategyFactory.createStrategyContext((HttpServletRequest JavaDoc)request,
142                layout, portlets.keySet(), targetPortlet, portal.getName(), page.getName(), regionNames);
143
144             strategyResponse = layoutStrategy.evaluate(strategyContext);
145
146             // to end this: evaluate the response
147
// handle excluded portlets
148
handleExcludedPortlets(strategyResponse, windows, portlets);
149             // handle changes in window state of one or more portlets
150
handleWindowStateChanges(strategyResponse, portlets, userContext);
151             // handle changes in the region and order
152
// handleModifiedPortletContexts(page, strategyResponse, portlets);
153
//
154
portlets.clear();
155
156             invocation.setAttachment(AttachmentKey.VIEW, windows);
157             state = strategyResponse.getState();
158             request.setAttribute(LayoutConstants.PARAM_LAYOUT_STATE, state);
159          }
160
161          if (layout != null)
162          {
163             // handle the layout URI
164
layoutURI = handleLayoutURI(strategyResponse, state, layout);
165
166             invocation.setAttachment(AttachmentKey.LAYOUT, layout);
167             invocation.setAttachment(AttachmentKey.LAYOUT_URI, layoutURI);
168             request.setAttribute(LayoutConstants.PARAM_LAYOUT, layout);
169             request.setAttribute(LayoutConstants.PARAM_LAYOUT_URI, layoutURI);
170          }
171       }
172       catch (StrategyException e)
173       {
174          log.error(e);
175       }
176       catch (MimeTypeParseException JavaDoc e)
177       {
178          log.error(e);
179       }
180
181       log.debug("done analyzing layout strategy");
182
183       // call the next interceptor in the chain
184
return invocation.invokeNext();
185    }
186
187    private void publishLayoutServerToRequest(PortalRequest request)
188    {
189       LayoutServer server = request.getServer().getManager().getLayoutServer();
190       if (server != null)
191       {
192          request.setAttribute(LayoutConstants.ATTR_LAYOUTSERVER, server);
193       }
194    }
195
196    private PortletContext getTarget(PortalRequest request, UserContext userContext)
197    {
198       ServerObject target = request.getTarget();
199       if (target instanceof Window)
200       {
201          return StrategyFactory.createPortletContext((Window)target, userContext);
202       }
203
204       return null;
205    }
206
207    private static String JavaDoc handleLayoutURI(StrategyResponse strategyResponse, String JavaDoc state, PortalLayout layout)
208    {
209       if (strategyResponse == null && layout != null)
210       {
211          return layout.getURI();
212       }
213
214       String JavaDoc layoutURI = null;
215       if (state != null)
216       {
217          layoutURI = layout.getURI(state);
218       }
219       if (layoutURI == null && strategyResponse.getLayoutURI() != null)
220       {
221          layoutURI = strategyResponse.getLayoutURI();
222       }
223       if (layoutURI == null)
224       {
225          layoutURI = layout.getURI();
226       }
227
228       log.debug("setting layout URI: " + layoutURI);
229
230       return layoutURI;
231    }
232
233    /*
234    // handle changes to the region and order the portlet is in
235    private static void handleModifiedPortletContexts(Page page, StrategyResponse strategyResponse, Map portlets)
236    {
237       if (!strategyResponse.getModifiedPortletContextList().isEmpty())
238       {
239          log.debug("analyze modified portlets...");
240          for (Iterator i = strategyResponse.getModifiedPortletContextList().iterator(); i.hasNext();)
241          {
242             PortletContext portletContext = (PortletContext)i.next();
243             Window window = (Window)portlets.get(portletContext);
244             WindowLocation ref = (WindowLocation)page.getLocation(window.getID());
245             //+++TODO: needs the page mode to allow for this
246          }
247       }
248    }
249    */

250
251    private static void handleWindowStateChanges(StrategyResponse strategyResponse, Map JavaDoc portlets, UserContext userContext)
252    {
253       if (strategyResponse != null && !strategyResponse.getWindowStateChangeMap().isEmpty())
254       {
255          log.debug("analyze portlets to change window state...");
256          for (Iterator JavaDoc i = strategyResponse.getWindowStateChangeMap().keySet().iterator(); i.hasNext();)
257          {
258             PortletContext portletContext = (PortletContext)i.next();
259             Window window = (Window)portlets.get(portletContext);
260             // the window might have been removed from the list (getExcludedList())
261
if (window != null)
262             {
263                WindowState newWindowState = (WindowState)strategyResponse.getWindowStateChangeMap().get(portletContext);
264                if (window.getSupportedWindowStates().contains(newWindowState))
265                {
266                   log.debug("change window state for: " + portletContext.getPortletName() + " to " + newWindowState);
267                   WindowContext windowContext = (WindowContext)userContext.getContext(window);
268                   windowContext.setWindowState(newWindowState);
269                }
270                else
271                {
272                   log.error("attempt to change to invalid window state for: " + portletContext.getPortletName() + " to " + newWindowState);
273                }
274             }
275          }
276       }
277    }
278
279    private static void handleExcludedPortlets(StrategyResponse strategyResponse, List JavaDoc windows, Map JavaDoc portlets)
280    {
281       if (strategyResponse != null && !strategyResponse.getExcludedList().isEmpty())
282       {
283          log.debug("analyze portlets to exlude...");
284
285          for (Iterator JavaDoc i = strategyResponse.getExcludedList().iterator(); i.hasNext();)
286          {
287             PortletContext portletContext = (PortletContext)i.next();
288             log.debug("exlude portlet : " + portletContext.getPortletName());
289             windows.remove(portlets.get(portletContext));
290          }
291       }
292    }
293
294    private static MediaType getRequestedMediaType(Invocation invocation)
295       throws MimeTypeParseException JavaDoc
296    {
297       PortalResponse response = (PortalResponse)invocation.getAttachment(AttachmentKey.PORTAL_RESPONSE);
298       return MediaType.parseMimeType(response.getContentType());
299    }
300
301    /**
302     * Create a map of portletContext to window, so that we can provide the portlet context list
303     * to the strategy, and find our way back after the strategy returns
304     *
305     * @param windows the windows that will be rendered
306     * @param userContext
307     * @return
308     */

309    private static Map JavaDoc getPortletList(List JavaDoc windows, UserContext userContext)
310    {
311       Map JavaDoc portlets = new HashMap JavaDoc();
312       for (Iterator JavaDoc i = windows.iterator(); i.hasNext();)
313       {
314          Window window = (Window)i.next();
315          portlets.put(StrategyFactory.createPortletContext(window, userContext), window);
316       }
317       return portlets;
318    }
319
320    private static String JavaDoc[] getRegionNames(Page page)
321    {
322       String JavaDoc[] regionNames;
323       List JavaDoc regions = new ArrayList JavaDoc();
324       for (Iterator JavaDoc pi = page.getLocations().iterator(); pi.hasNext();)
325       {
326          WindowLocation location = (WindowLocation)pi.next();
327          if (!regions.contains(location.getRegion()))
328          {
329             log.debug("adding region: " + location.getRegion());
330             regions.add(location.getRegion());
331          }
332       }
333       if (!regions.isEmpty())
334       {
335          regionNames = new String JavaDoc[regions.size()];
336          regions.toArray(regionNames);
337       }
338       else
339       {
340          regionNames = new String JavaDoc[0];
341       }
342       return regionNames;
343    }
344
345    private static PortalLayout getLayout(Portal portal, Page page, PortalRequest request)
346    {
347       // sequence: request, over page, over portal
348
String JavaDoc layoutName = request.getParameter(LayoutConstants.PARAM_LAYOUT);
349       if (layoutName == null)
350       {
351          layoutName = ((PageMetaData)page.getMetaData()).getLayoutName();
352       }
353       if (layoutName == null)
354       {
355          layoutName = (String JavaDoc)portal.getProperties().get(CoreConstants.PORTAL_PROP_LAYOUT);
356       }
357       // we haven't set a default layout , so we need to handle it here
358
if (layoutName == null)
359       {
360          layoutName = "nodesk";
361       }
362       return request.getServer().getManager().getLayoutServer().getLayout(layoutName, true);
363    }
364 }
365
Popular Tags