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.Map;
20 import java.util.Iterator;
21
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24 import org.apache.jetspeed.JetspeedActions;
25 import org.apache.jetspeed.ajax.AJAXException;
26 import org.apache.jetspeed.ajax.AjaxAction;
27 import org.apache.jetspeed.ajax.AjaxBuilder;
28 import org.apache.jetspeed.layout.Coordinate;
29 import org.apache.jetspeed.layout.PortletActionSecurityBehavior;
30 import org.apache.jetspeed.layout.PortletPlacementException;
31 import org.apache.jetspeed.layout.PortletPlacementContext;
32 import org.apache.jetspeed.om.page.Fragment;
33 import org.apache.jetspeed.om.page.Page;
34 import org.apache.jetspeed.page.PageManager;
35 import org.apache.jetspeed.page.document.NodeException;
36 import org.apache.jetspeed.request.RequestContext;
37
38 /***
39 * Move Portlet portlet placement action
40 *
41 * AJAX Parameters:
42 * id = the fragment id of the portlet to move
43 * page = (implied in the URL)
44 * Additional Absolute Parameters:
45 * row = the new row to move to
46 * col = the new column to move to
47 * Additional Relative Parameters: (move left, right, up, down)
48 * none
49 *
50 * @author <a>David Gurney</a>
51 * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
52 * @version $Id: $
53 */
54 public class MovePortletAction
55 extends BasePortletAction
56 implements AjaxAction, AjaxBuilder, Constants
57 {
58 protected static final Log log = LogFactory.getLog(MovePortletAction.class);
59 private int iMoveType = -1;
60 private String sMoveType = null;
61
62 public MovePortletAction(String template,
63 String errorTemplate,
64 String sMoveType)
65 throws AJAXException
66 {
67 this(template, errorTemplate, sMoveType, null, null);
68 }
69
70 public MovePortletAction(String template,
71 String errorTemplate,
72 PageManager pageManager,
73 PortletActionSecurityBehavior securityBehavior)
74 throws AJAXException
75 {
76 this( template, errorTemplate, "moveabs", pageManager, securityBehavior );
77 }
78
79 public MovePortletAction(String template,
80 String errorTemplate,
81 String sMoveType,
82 PageManager pageManager,
83 PortletActionSecurityBehavior securityBehavior)
84 throws AJAXException
85 {
86 super(template, errorTemplate, pageManager, securityBehavior);
87 setMoveType(sMoveType);
88 }
89
90
91 public void setMoveType(String p_sMoveType) throws AJAXException
92 {
93 sMoveType = p_sMoveType;
94
95 if (p_sMoveType.equalsIgnoreCase("moveabs"))
96 {
97 iMoveType = ABS;
98 }
99 else if (p_sMoveType.equalsIgnoreCase("moveup"))
100 {
101 iMoveType = UP;
102 }
103 else if (p_sMoveType.equalsIgnoreCase("movedown"))
104 {
105 iMoveType = DOWN;
106 }
107 else if (p_sMoveType.equalsIgnoreCase("moveleft"))
108 {
109 iMoveType = LEFT;
110 }
111 else if (p_sMoveType.equalsIgnoreCase("moveright"))
112 {
113 iMoveType = RIGHT;
114 }
115 else if (p_sMoveType.equalsIgnoreCase("move"))
116 {
117 iMoveType = CARTESIAN;
118 }
119 else
120 {
121 throw new AJAXException("invalid move type of:" + p_sMoveType);
122 }
123 }
124
125 public boolean runBatch(RequestContext requestContext, Map resultMap) throws AJAXException
126 {
127 return runAction(requestContext, resultMap, true);
128 }
129
130 public boolean run(RequestContext requestContext, Map resultMap)
131 throws AJAXException
132 {
133 return runAction(requestContext, resultMap, false);
134 }
135
136 protected boolean runAction( RequestContext requestContext, Map resultMap, boolean batch ) throws AJAXException
137 {
138 boolean success = true;
139 String status = "success";
140 try
141 {
142 resultMap.put(ACTION, sMoveType);
143
144 String moveFragmentId = getActionParameter(requestContext, FRAGMENTID);
145 String layoutId = getActionParameter(requestContext, LAYOUTID);
146 if ( moveFragmentId == null )
147 {
148 throw new Exception( FRAGMENTID + " not provided; must specify portlet or layout id" );
149 }
150 resultMap.put(FRAGMENTID, moveFragmentId);
151
152 Fragment currentLayoutFragment = null;
153 Fragment moveToLayoutFragment = null;
154
155 if ( layoutId != null && layoutId.length() > 0 && iMoveType != CARTESIAN )
156 {
157 Page page = requestContext.getPage();
158 currentLayoutFragment = page.getFragmentById( layoutId );
159 if ( currentLayoutFragment == null )
160 {
161 throw new Exception("layout id not found: " + layoutId );
162 }
163 else
164 {
165
166 moveToLayoutFragment = currentLayoutFragment;
167 Iterator layoutChildIter = moveToLayoutFragment.getFragments().iterator();
168 while ( layoutChildIter.hasNext() )
169 {
170 Fragment childFrag = (Fragment)layoutChildIter.next();
171 if ( childFrag != null )
172 {
173 if ( moveFragmentId.equals( childFrag.getId() ) )
174 {
175 moveToLayoutFragment = null;
176 break;
177 }
178 }
179 }
180 if ( moveToLayoutFragment != null )
181 {
182
183
184 Fragment root = requestContext.getPage().getRootFragment();
185 currentLayoutFragment = getParentFragmentById(moveFragmentId, root);
186 }
187 }
188 if ( currentLayoutFragment == null )
189 {
190
191 throw new Exception("parent layout id not found for portlet id:" + moveFragmentId );
192 }
193 }
194
195 if (false == checkAccess(requestContext, JetspeedActions.EDIT))
196 {
197 Page page = requestContext.getPage();
198 Fragment fragment = page.getFragmentById(moveFragmentId);
199 if (fragment == null)
200 {
201 success = false;
202 resultMap.put(REASON, "Fragment not found");
203 return success;
204 }
205
206
207 int column = fragment.getLayoutColumn();
208 int row = fragment.getLayoutRow();
209
210
211 int layoutColumn = -1, layoutRow = -1;
212 int moveToLayoutColumn = -1, moveToLayoutRow = -1;
213 if ( currentLayoutFragment != null )
214 {
215 layoutColumn = currentLayoutFragment.getLayoutColumn();
216 layoutRow = currentLayoutFragment.getLayoutRow();
217 if ( moveToLayoutFragment != null )
218 {
219 moveToLayoutColumn = moveToLayoutFragment.getLayoutColumn();
220 moveToLayoutRow = moveToLayoutFragment.getLayoutRow();
221 }
222 }
223
224 if (!createNewPageOnEdit(requestContext))
225 {
226 success = false;
227 resultMap.put(REASON, "Insufficient access to edit page");
228 return success;
229 }
230 status = "refresh";
231
232
233 Fragment newFragment = getFragmentIdFromLocation(row, column, requestContext.getPage());
234 if (newFragment == null)
235 {
236 success = false;
237 resultMap.put( REASON, "Failed to find new fragment for portlet id: " + moveFragmentId );
238 return success;
239 }
240 moveFragmentId = newFragment.getId();
241
242 if ( currentLayoutFragment != null )
243 {
244 newFragment = getFragmentIdFromLocation(layoutRow, layoutColumn, requestContext.getPage());
245 if (newFragment == null)
246 {
247 success = false;
248 resultMap.put( REASON, "Failed to find new parent layout fragment id: " + currentLayoutFragment.getId() + " for portlet id: " + moveFragmentId );
249 return success;
250 }
251 currentLayoutFragment = newFragment;
252 if ( moveToLayoutFragment != null )
253 {
254 newFragment = getFragmentIdFromLocation(moveToLayoutRow, moveToLayoutColumn, requestContext.getPage());
255 if (newFragment == null)
256 {
257 success = false;
258 resultMap.put( REASON, "Failed to find new move-to layout fragment id: " + moveToLayoutFragment.getId() + " for portlet id: " + moveFragmentId );
259 return success;
260 }
261 moveToLayoutFragment = newFragment;
262 }
263 }
264 }
265
266 if ( moveToLayoutFragment != null )
267 {
268 success = moveFragment( requestContext,
269 pageManager,
270 batch,
271 resultMap,
272 moveFragmentId,
273 moveToLayoutFragment,
274 currentLayoutFragment ) ;
275 }
276 else
277 {
278 PortletPlacementContext placement = null;
279 if ( currentLayoutFragment != null )
280 placement = new PortletPlacementContextImpl(requestContext, currentLayoutFragment, 1);
281 else
282 {
283 placement = new PortletPlacementContextImpl(requestContext);
284 }
285 Fragment fragment = placement.getFragmentById(moveFragmentId);
286 if (fragment == null)
287 {
288 success = false;
289 resultMap.put(REASON, "Failed to find fragment for portlet id: " + moveFragmentId );
290 return success;
291 }
292 Coordinate returnCoordinate = null;
293 float oldX = 0f, oldY = 0f, oldZ = 0f, oldWidth = 0f, oldHeight = 0f;
294 float x = -1f, y = -1f, z = -1f, width = -1f, height = -1f;
295 boolean absHeightChanged = false;
296
297 String posExtended = getActionParameter(requestContext, DESKTOP_EXTENDED);
298 if ( posExtended != null )
299 {
300 Map fragmentProperties = fragment.getProperties();
301 if ( fragmentProperties == null )
302 {
303 success = false;
304 resultMap.put(REASON, "Failed to acquire fragment properties map for portlet id: " + moveFragmentId );
305 return success;
306 }
307 String oldDeskExt = (String)fragmentProperties.get( DESKTOP_EXTENDED );
308 resultMap.put( OLD_DESKTOP_EXTENDED, ( (oldDeskExt != null) ? oldDeskExt : "" ) );
309 fragmentProperties.put( DESKTOP_EXTENDED, posExtended );
310 }
311
312
313 if (iMoveType == ABS)
314 {
315 Coordinate a_oCoordinate = getCoordinateFromParams(requestContext);
316 returnCoordinate = placement.moveAbsolute(fragment, a_oCoordinate);
317 String sHeight = getActionParameter(requestContext, HEIGHT);
318 if ( sHeight != null && sHeight.length() > 0 )
319 {
320 oldHeight = fragment.getLayoutHeight();
321 height = Float.parseFloat(sHeight);
322 fragment.setLayoutHeight(height);
323 absHeightChanged = true;
324 }
325 }
326 else if (iMoveType == LEFT)
327 {
328 returnCoordinate = placement.moveLeft(fragment);
329 }
330 else if (iMoveType == RIGHT)
331 {
332 returnCoordinate = placement.moveRight(fragment);
333 }
334 else if (iMoveType == UP)
335 {
336 returnCoordinate = placement.moveUp(fragment);
337 }
338 else if (iMoveType == DOWN)
339 {
340 returnCoordinate = placement.moveDown(fragment);
341 }
342 else if (iMoveType == CARTESIAN)
343 {
344 String sx = getActionParameter(requestContext, X);
345 String sy = getActionParameter(requestContext, Y);
346 String sz = getActionParameter(requestContext, Z);
347 String sWidth = getActionParameter(requestContext, WIDTH);
348 String sHeight = getActionParameter(requestContext, HEIGHT);
349 if (sx != null)
350 {
351 oldX = fragment.getLayoutX();
352 x = Float.parseFloat(sx);
353 fragment.setLayoutX(x);
354 }
355 if (sy != null)
356 {
357 oldY = fragment.getLayoutY();
358 y = Float.parseFloat(sy);
359 fragment.setLayoutY(y);
360 }
361 if (sz != null)
362 {
363 oldZ = fragment.getLayoutZ();
364 z = Float.parseFloat(sz);
365 fragment.setLayoutZ(z);
366 }
367 if (sWidth != null)
368 {
369 oldWidth = fragment.getLayoutWidth();
370 width = Float.parseFloat(sWidth);
371 fragment.setLayoutWidth(width);
372 }
373 if (sHeight != null)
374 {
375 oldHeight = fragment.getLayoutHeight();
376 height = Float.parseFloat(sHeight);
377 fragment.setLayoutHeight(height);
378 }
379 }
380
381 Page page = placement.syncPageFragments();
382
383 if (pageManager != null && !batch)
384 {
385 pageManager.updatePage(page);
386 }
387
388 if (iMoveType == CARTESIAN)
389 {
390 putCartesianResult(resultMap, x, oldX, X, OLD_X);
391 putCartesianResult(resultMap, y, oldY, Y, OLD_Y);
392 putCartesianResult(resultMap, z, oldZ, Z, OLD_Z);
393 putCartesianResult(resultMap, width, oldWidth, WIDTH, OLD_WIDTH);
394 putCartesianResult(resultMap, height, oldHeight, HEIGHT, OLD_HEIGHT);
395 }
396 else
397 {
398
399 resultMap.put(OLDCOL, String.valueOf(returnCoordinate
400 .getOldCol()));
401 resultMap.put(OLDROW, String.valueOf(returnCoordinate
402 .getOldRow()));
403
404 resultMap.put(NEWCOL, String.valueOf(returnCoordinate
405 .getNewCol()));
406 resultMap.put(NEWROW, String.valueOf(returnCoordinate
407 .getNewRow()));
408 if ( absHeightChanged )
409 {
410 putCartesianResult(resultMap, height, oldHeight, HEIGHT, OLD_HEIGHT);
411 }
412 }
413 }
414 resultMap.put(STATUS, status);
415 resultMap.put(FRAGMENTID, moveFragmentId);
416 }
417 catch (Exception e)
418 {
419
420 log.error("exception while moving a portlet", e);
421 resultMap.put(REASON, e.toString());
422
423 success = false;
424 }
425
426 return success;
427 }
428
429 protected boolean moveFragment( RequestContext requestContext,
430 PageManager pageManager,
431 boolean batch,
432 Map resultMap,
433 String moveFragmentId,
434 Fragment moveToLayoutFragment,
435 Fragment removeFromLayoutFragment )
436 throws PortletPlacementException, NodeException
437 {
438 boolean success = true;
439 Fragment placeFragment = null;
440 if ( removeFromLayoutFragment != null )
441 {
442 PortletPlacementContext placement = new PortletPlacementContextImpl( requestContext, removeFromLayoutFragment, 1 );
443
444 placeFragment = placement.getFragmentById( moveFragmentId );
445 if ( placeFragment == null )
446 {
447 success = false;
448 resultMap.put( REASON, "Failed to find fragment to move to another layout for fragment id: " + moveFragmentId );
449 return success;
450 }
451 placement.remove( placeFragment );
452 Page page = placement.syncPageFragments();
453 page.removeFragmentById( moveFragmentId );
454 }
455 if ( placeFragment != null )
456 {
457 return placeFragment( requestContext,
458 pageManager,
459 batch,
460 resultMap,
461 placeFragment,
462 moveToLayoutFragment );
463 }
464 return success;
465 }
466
467 protected boolean placeFragment( RequestContext requestContext,
468 PageManager pageManager,
469 boolean batch,
470 Map resultMap,
471 Fragment placeFragment,
472 Fragment placeInLayoutFragment )
473 throws PortletPlacementException, NodeException
474 {
475 boolean success = true;
476 if ( placeFragment == null )
477 {
478 success = false;
479 return success;
480 }
481
482
483 String posExtended = getActionParameter(requestContext, DESKTOP_EXTENDED);
484 if ( posExtended != null )
485 {
486 Map fragmentProperties = placeFragment.getProperties();
487 if ( fragmentProperties == null )
488 {
489 success = false;
490 resultMap.put(REASON, "Failed to acquire fragment properties map for fragment id: " + placeFragment.getId() );
491 return success;
492 }
493 String oldDeskExt = (String)fragmentProperties.get( DESKTOP_EXTENDED );
494 resultMap.put( OLD_DESKTOP_EXTENDED, ( (oldDeskExt != null) ? oldDeskExt : "" ) );
495 fragmentProperties.put( DESKTOP_EXTENDED, posExtended );
496 }
497
498
499 PortletPlacementContext placement = new PortletPlacementContextImpl( requestContext, placeInLayoutFragment, 1 );
500 Coordinate returnCoordinate = placement.add( placeFragment, getCoordinateFromParams( requestContext ) );
501 Page page = placement.syncPageFragments();
502
503 placeInLayoutFragment.getFragments().add( placeFragment );
504 if ( pageManager != null && ! batch )
505 {
506 pageManager.updatePage( page );
507 }
508
509
510 resultMap.put( OLDCOL, String.valueOf( returnCoordinate.getOldCol() ) );
511 resultMap.put( OLDROW, String.valueOf( returnCoordinate.getOldRow() ) );
512
513 resultMap.put( NEWCOL, String.valueOf( returnCoordinate.getNewCol() ) );
514 resultMap.put( NEWROW, String.valueOf( returnCoordinate.getNewRow() ) );
515
516 return success;
517 }
518
519 protected Coordinate getCoordinateFromParams(RequestContext requestContext)
520 {
521 String a_sCol = getActionParameter( requestContext, COL );
522 String a_sRow = getActionParameter( requestContext, ROW );
523
524 int a_iCol = 0;
525 int a_iRow = 0;
526
527
528 if ( a_sCol != null )
529 {
530 a_iCol = Integer.parseInt( a_sCol );
531 }
532 if ( a_sRow != null )
533 {
534 a_iRow = Integer.parseInt( a_sRow );
535 }
536
537 Coordinate a_oCoordinate = new CoordinateImpl( 0, 0, a_iCol, a_iRow );
538 return a_oCoordinate;
539 }
540
541 protected void putCartesianResult(Map resultMap, float value, float oldValue, String name, String oldName)
542 {
543 if (value != -1F)
544 {
545 resultMap.put(oldName, new Float(oldValue));
546 resultMap.put(name, new Float(value));
547 }
548 }
549 }