1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.layout.impl;
18
19 import java.util.HashMap;
20 import java.util.Iterator;
21 import java.util.Map;
22
23 import javax.portlet.PortletMode;
24 import javax.portlet.WindowState;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.jetspeed.JetspeedActions;
29 import org.apache.jetspeed.PortalReservedParameters;
30 import org.apache.jetspeed.ajax.AJAXException;
31 import org.apache.jetspeed.ajax.AjaxAction;
32 import org.apache.jetspeed.ajax.AjaxBuilder;
33 import org.apache.jetspeed.container.state.MutableNavigationalState;
34 import org.apache.jetspeed.container.window.PortletWindowAccessor;
35 import org.apache.jetspeed.decoration.PageActionAccess;
36 import org.apache.jetspeed.layout.PortletActionSecurityBehavior;
37 import org.apache.jetspeed.om.page.ContentFragment;
38 import org.apache.jetspeed.om.page.ContentPage;
39 import org.apache.jetspeed.page.PageManager;
40 import org.apache.jetspeed.request.RequestContext;
41 import org.apache.pluto.om.window.PortletWindow;
42
43 /***
44 * Changes the window state or portlet mode for a given portlet window
45 *
46 * AJAX Parameters:
47 * id = the fragment id of the portlet to move
48 * page = (implied in the URL)
49 * state = the new window state
50 * mode = the new portlet mode
51 *
52 * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
53 * @version $Id: $
54 */
55 public class ChangePortletAction
56 extends BasePortletAction
57 implements AjaxAction, AjaxBuilder, Constants
58 {
59 protected static final Log log = LogFactory.getLog(ChangePortletAction.class);
60 protected String action;
61 protected Map validWindowStates = new HashMap();
62 protected Map validPortletModes = new HashMap();
63 protected PortletWindowAccessor windowAccessor;
64
65 public ChangePortletAction(String template,
66 String errorTemplate,
67 String action,
68 PortletWindowAccessor windowAccessor)
69 throws AJAXException
70 {
71 this(template, errorTemplate, action, null, windowAccessor, null);
72 }
73
74 public ChangePortletAction(String template,
75 String errorTemplate,
76 String action,
77 PageManager pageManager,
78 PortletWindowAccessor windowAccessor,
79 PortletActionSecurityBehavior securityBehavior)
80 throws AJAXException
81 {
82 super(template, errorTemplate, pageManager, securityBehavior);
83 this.action = action;
84 this.windowAccessor = windowAccessor;
85
86
87 Iterator modes = JetspeedActions.getStandardPortletModes().iterator();
88 while (modes.hasNext())
89 {
90 String mode = modes.next().toString();
91 this.validPortletModes.put(mode, mode);
92 }
93 modes = JetspeedActions.getExtendedPortletModes().iterator();
94 while (modes.hasNext())
95 {
96 String mode = modes.next().toString();
97 this.validPortletModes.put(mode, mode);
98 }
99 Iterator states = JetspeedActions.getStandardWindowStates().iterator();
100 while (states.hasNext())
101 {
102 String state = states.next().toString();
103 this.validWindowStates.put(state, state);
104 }
105 states = JetspeedActions.getExtendedWindowStates().iterator();
106 while (states.hasNext())
107 {
108 String state = states.next().toString();
109 this.validWindowStates.put(state, state);
110 }
111 }
112
113 public boolean runBatch(RequestContext requestContext, Map resultMap) throws AJAXException
114 {
115 return runAction(requestContext, resultMap, true);
116 }
117
118 public boolean run(RequestContext requestContext, Map resultMap)
119 throws AJAXException
120 {
121 return runAction(requestContext, resultMap, false);
122 }
123
124 public boolean runAction(RequestContext requestContext, Map resultMap, boolean batch)
125 {
126 boolean success = true;
127 String status = "success";
128 try
129 {
130 resultMap.put(ACTION, action);
131
132 String fragmentId = getActionParameter(requestContext, FRAGMENTID);
133 if (fragmentId == null)
134 {
135 throw new Exception("fragment id not provided");
136 }
137 resultMap.put(FRAGMENTID, fragmentId);
138
139 ContentPage page = requestContext.getPage();
140 ContentFragment fragment = page.getContentFragmentById(fragmentId);
141
142 if ( fragment == null )
143 {
144 throw new Exception( "fragment specified by id cannot be found" );
145 }
146 String requestedState = getActionParameter(requestContext, WINDOW_STATE);
147 String requestedMode = getActionParameter(requestContext, PORTLET_MODE);
148 if ( "layout".equals( fragment.getType() ) )
149 {
150 if ( ! fragment.getId().equals( page.getRootFragment().getId() ) )
151 {
152 throw new Exception( "for layout fragments, change action applies to only to the root layout fragment (i.e. it does not apply to nested layout fragments)" );
153 }
154 PageActionAccess pageActionAccess = (PageActionAccess)requestContext.getAttribute( PortalReservedParameters.PAGE_EDIT_ACCESS_ATTRIBUTE );
155 if ( pageActionAccess == null )
156 {
157 throw new Exception( "cannot change action for root layout fragment due to null PageActionAccess object" );
158 }
159
160 PortletWindow window = windowAccessor.getPortletWindow(fragment);
161 PortletMode currentMode = requestContext.getPortalURL().getNavigationalState().getMode( window );
162 WindowState currentState = requestContext.getPortalURL().getNavigationalState().getState( window );
163
164 boolean requestedModeAlreadySet = false;
165 if ( requestedMode == null )
166 requestedModeAlreadySet = true;
167 else
168 {
169 if ( requestedMode.equals( PortletMode.EDIT.toString() ) )
170 {
171 if( pageActionAccess.isEditing() )
172 requestedModeAlreadySet = true;
173 else
174 {
175 if ( pageActionAccess.isEditAllowed())
176 {
177 pageActionAccess.setEditing( true );
178 resultMap.put(STATUS, status);
179 resultMap.put(OLD_PORTLET_MODE, currentMode.toString());
180 resultMap.put(PORTLET_MODE, requestedMode);
181 }
182 else
183 {
184 throw new Exception( "permissions do no allow page edit" );
185 }
186 }
187 }
188 else if ( requestedMode.equals( PortletMode.VIEW.toString() ) )
189 {
190 pageActionAccess.setEditing( false );
191
192 resultMap.put(STATUS, status);
193 resultMap.put(OLD_PORTLET_MODE, currentMode.toString());
194 resultMap.put(PORTLET_MODE, requestedMode);
195 }
196 else
197 {
198 requestedModeAlreadySet = true;
199 }
200 }
201 if ( requestedModeAlreadySet )
202 {
203 resultMap.put(STATUS, status);
204 resultMap.put(OLD_PORTLET_MODE, currentMode.toString());
205 resultMap.put(PORTLET_MODE, currentMode.toString());
206 }
207 }
208 else
209 {
210 if (requestedState == null && requestedMode == null)
211 {
212 throw new Exception("portlet window state or mode not provided");
213 }
214 if (requestedState != null && !isValidWindowState(requestedState))
215 {
216 throw new Exception("portlet window state " + requestedState + " is not supported");
217 }
218 if (requestedMode != null && !isValidPortletMode(requestedMode))
219 {
220 throw new Exception("portlet mode " + requestedMode + " is not supported");
221 }
222
223
224 String oldState = fragment.getState();
225 String oldMode = fragment.getMode();
226
227
228 MutableNavigationalState navState = (MutableNavigationalState)requestContext.getPortalURL().getNavigationalState();
229 PortletWindow portletWindow = windowAccessor.getPortletWindow(fragment);
230 if (portletWindow != null)
231 {
232 oldState = navState.getState(portletWindow).toString();
233 oldMode = navState.getMode(portletWindow).toString();
234 if (requestedState != null)
235 {
236 navState.setState(portletWindow, new WindowState(requestedState));
237 }
238 if (requestedMode != null)
239 {
240 navState.setMode(portletWindow, new PortletMode(requestedMode));
241 }
242 navState.sync(requestContext);
243 }
244
245
246 if (checkAccess(requestContext, JetspeedActions.EDIT))
247 {
248 if (requestedState != null)
249 fragment.setState(requestedState);
250 if (requestedMode != null)
251 fragment.setMode(requestedMode);
252
253 if (pageManager != null && !batch)
254 {
255 pageManager.updatePage(page);
256 }
257 }
258
259
260 resultMap.put(STATUS, status);
261
262 if (requestedState != null)
263 {
264 resultMap.put(OLD_WINDOW_STATE, oldState);
265 resultMap.put(WINDOW_STATE, requestedState);
266 }
267
268 if (requestedMode != null)
269 {
270 resultMap.put(OLD_PORTLET_MODE, oldMode);
271 resultMap.put(PORTLET_MODE, requestedMode);
272 }
273 }
274 }
275 catch (Exception e)
276 {
277
278 log.error("exception while changing portlet/page action", e);
279 resultMap.put(REASON, e.toString());
280
281 success = false;
282 }
283
284 return success;
285 }
286
287
288
289
290
291
292
293
294
295
296 protected boolean isValidWindowState(String windowState)
297 {
298 return this.validWindowStates.containsKey(windowState);
299 }
300 protected boolean isValidPortletMode(String portletMode)
301 {
302 return this.validPortletModes.containsKey(portletMode);
303 }
304
305 }