View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.jetspeed.portlets.layout;
18  
19  import java.io.IOException;
20  import java.io.UnsupportedEncodingException;
21  import java.net.URLEncoder;
22  import java.util.ArrayList;
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.StringTokenizer;
26  
27  import javax.portlet.ActionRequest;
28  import javax.portlet.ActionResponse;
29  import javax.portlet.PortletConfig;
30  import javax.portlet.PortletException;
31  import javax.portlet.PortletMode;
32  import javax.portlet.RenderRequest;
33  import javax.portlet.RenderResponse;
34  
35  import org.apache.commons.logging.Log;
36  import org.apache.commons.logging.LogFactory;
37  import org.apache.jetspeed.CommonPortletServices;
38  import org.apache.jetspeed.PortalReservedParameters;
39  import org.apache.jetspeed.cache.JetspeedContentCache;
40  import org.apache.jetspeed.decoration.DecorationFactory;
41  import org.apache.jetspeed.decoration.PageEditAccess;
42  import org.apache.jetspeed.desktop.JetspeedDesktop;
43  import org.apache.jetspeed.om.folder.Folder;
44  import org.apache.jetspeed.om.page.ContentFragment;
45  import org.apache.jetspeed.om.page.ContentPage;
46  import org.apache.jetspeed.om.page.Fragment;
47  import org.apache.jetspeed.om.page.Page;
48  import org.apache.jetspeed.page.FolderNotUpdatedException;
49  import org.apache.jetspeed.page.document.NodeException;
50  import org.apache.jetspeed.request.RequestContext;
51  import org.apache.pluto.om.window.PortletWindow;
52  
53  /***
54   */
55  public class MultiColumnPortlet extends LayoutPortlet
56  {
57      /*** Commons logging */
58      protected final static Log log = LogFactory.getLog(MultiColumnPortlet.class);
59  
60      protected final static String PARAM_NUM_COLUMN = "columns";
61      protected final static int DEFAULT_NUM_COLUMN = 2;
62      protected final static String PARAM_COLUMN_SIZES = "sizes";
63      protected final static String DEFAULT_ONE_COLUMN_SIZES = "100%";
64      protected final static String DEFAULT_TWO_COLUMN_SIZES = "50%,50%";
65      protected final static String DEFAULT_THREE_COLUMN_SIZES = "34%,33%,33%";
66  
67      private int numColumns = 0;
68      private String columnSizes = null;
69      private String portletName = null;
70      private String layoutType;
71      private String editorType = null;
72      protected DecorationFactory decorators;
73      protected JetspeedDesktop desktop;
74      protected JetspeedContentCache decoratorCache;
75  
76      public void init( PortletConfig config ) throws PortletException
77      {
78          super.init(config);
79          this.portletName = config.getPortletName();
80          this.layoutType = config.getInitParameter("layoutType");
81          this.editorType = config.getInitParameter("editorType");
82          if (this.layoutType == null)
83          {
84              throw new PortletException("Layout type not specified for " + this.portletName);
85          }
86          this.numColumns = Integer.parseInt(config.getInitParameter(PARAM_NUM_COLUMN));
87          if (this.numColumns < 1)
88          {
89              this.numColumns = 1;
90          }
91          this.columnSizes = config.getInitParameter(PARAM_COLUMN_SIZES);
92          if ((this.columnSizes == null) || (this.columnSizes.trim().length() == 0))
93          {
94              switch (this.numColumns)
95              {
96              case 1: this.columnSizes = DEFAULT_ONE_COLUMN_SIZES; break;
97              case 2: this.columnSizes = DEFAULT_TWO_COLUMN_SIZES; break;
98              case 3: this.columnSizes = DEFAULT_THREE_COLUMN_SIZES; break;
99              default: this.columnSizes = null; break;
100             }
101         }
102         if (this.columnSizes == null)
103         {
104             throw new PortletException("Column sizes cannot be defaulted for " + this.numColumns + " columns and are not specified for " + this.portletName);
105         }
106        
107         this.decorators = (DecorationFactory)getPortletContext().getAttribute(CommonPortletServices.CPS_DECORATION_FACTORY);
108         if (null == this.decorators)
109         {
110             throw new PortletException("Failed to find the Decoration Factory on portlet initialization");
111         }
112         
113         this.desktop = (JetspeedDesktop)getPortletContext().getAttribute(CommonPortletServices.CPS_DESKTOP);
114         
115         this.decoratorCache = (JetspeedContentCache)getPortletContext().getAttribute(CommonPortletServices.CPS_DECORATOR_CACHE);
116     }
117 
118     public void doView( RenderRequest request, RenderResponse response ) throws PortletException, IOException
119     {
120         RequestContext context = getRequestContext(request);
121 
122         ContentPage requestPage = context.getPage();       
123         PageEditAccess pageEditAccess = (PageEditAccess)context.getAttribute(PortalReservedParameters.PAGE_EDIT_ACCESS_ATTRIBUTE);
124         if ( requestPage == null)
125         {
126             // Targetting this portlet REQUIRES that the ProfilerValve has been invoked!
127             throw new PortletException("Current request page not available.");
128         }
129         if (pageEditAccess == null)
130         {
131             // Targetting this portlet REQUIRES that the ProfilerValve has been invoked!
132             throw new PortletException("Current PageEditAccess not available.");            
133         }
134         
135         Boolean editing = ( pageEditAccess.isEditing() && 
136                             PortletMode.VIEW.equals(request.getPortletMode()) && 
137                             request.isPortletModeAllowed(PortletMode.EDIT))
138                           ? Boolean.TRUE : Boolean.FALSE;
139                                          
140         PortletWindow window = context.getPortalURL().getNavigationalState().getMaximizedWindow();
141         if (window != null)
142         {
143             super.doView(request, response);
144             return;
145         }
146         
147         // get fragment column sizes
148         Fragment f = getFragment(request, false);
149         String fragmentColumnSizes = columnSizes;
150         String fragmentColumnSizesProperty = f.getProperty(Fragment.SIZES_PROPERTY_NAME);
151         if (fragmentColumnSizesProperty != null)
152         {
153             fragmentColumnSizes = fragmentColumnSizesProperty;
154         }
155         String [] fragmentColumnSizesArray = fragmentColumnSizes.split("//,");
156         List fragmentColumnSizesList = new ArrayList(fragmentColumnSizesArray.length);
157         for (int i = 0; (i < fragmentColumnSizesArray.length); i++)
158         {
159             fragmentColumnSizesList.add(fragmentColumnSizesArray[i]);
160         }
161 
162         // construct layout object
163         ColumnLayout layout;
164         try
165         {
166             layout = new ColumnLayout(numColumns, layoutType, f.getFragments(), fragmentColumnSizesArray);
167             layout.addLayoutEventListener(new PageManagerLayoutEventListener(pageManager, context.getPage(), layoutType));
168         }
169         catch (LayoutEventException e1)
170         {
171             throw new PortletException("Failed to build ColumnLayout "+e1.getMessage(), e1);
172         }
173 
174         // invoke the JSP associated with this portlet
175         request.setAttribute("columnLayout", layout);
176         request.setAttribute("numberOfColumns", new Integer(numColumns));
177         request.setAttribute("decorationFactory", this.decorators);
178         request.setAttribute("columnSizes", fragmentColumnSizesList);
179         request.setAttribute("editing",editing);
180         request.setAttribute("fragmentNestingLevel",new Integer(getFragmentNestingLevel(requestPage,f.getId())));
181         super.doView(request, response);
182         request.removeAttribute("decorationFactory");
183         request.removeAttribute("columnLayout");
184         request.removeAttribute("numberOfColumns");
185         request.removeAttribute("columnSizes");
186         request.removeAttribute("editing");
187         request.removeAttribute(("fragmentNestingLevel"));
188     }
189 
190     public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException
191     {
192         RequestContext requestContext = (RequestContext)request.getAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE);
193         
194         ContentPage requestPage = requestContext.getPage();       
195         PageEditAccess pageEditAccess = (PageEditAccess)requestContext.getAttribute(PortalReservedParameters.PAGE_EDIT_ACCESS_ATTRIBUTE);
196         if ( requestPage == null || pageEditAccess == null )
197         {
198             // Targetting this portlet with an ActionRequest REQUIRES that the ProfilerValve has been invoked!
199             throw new PortletException("Current request page or PageEditAccess not available.");
200         }
201 
202         decoratorCache.invalidate(requestContext);
203         
204         String pageMode = request.getParameter("pageMode");
205         if ( pageMode != null )
206         {
207             if ( "view".equals(pageMode) )
208             {
209                 pageEditAccess.setEditing(false);
210             }
211             else if ( "edit".equals(pageMode) && pageEditAccess.isEditAllowed() )
212             {
213                 if ( this.editorType != null && this.editorType.equals( "desktop" ) )
214                 {
215                     String redirectUrl = this.desktop.getPortalUrl( requestContext, requestContext.getPath() );
216                     redirectUrl += "?editPage=true&portal=true";
217                     response.sendRedirect( redirectUrl );
218                 }
219                 else
220                 {
221                     pageEditAccess.setEditing(true);
222                 }
223             }
224             return;
225         }
226         
227         if ( pageEditAccess.isEditAllowed() && request.isPortletModeAllowed(PortletMode.EDIT) )
228         {
229             String layout = null;
230             
231             boolean addLayout = request.getParameter("jsAddLayout") != null;
232             if ( addLayout || request.getParameter("jsChangeLayout") != null )
233             {
234                 layout = request.getParameter("layout");
235                 if ( layout != null && layout.length() > 0 )
236                 {
237                     PortletWindow window = requestContext.getActionWindow();
238                     ContentFragment targetFragment = requestPage.getContentFragmentById(window.getId().toString());
239                     
240                     if ( targetFragment == null )
241                     {
242                         // ignore no longer consistent page definition
243                         return;
244                     }
245                     
246                     if ( addLayout )
247                     {
248                         try
249                         {
250                             Fragment fragment = pageManager.newFragment();
251                             fragment.setType(Fragment.LAYOUT);
252                             fragment.setName(layout);                            
253                             targetFragment.getFragments().add(fragment);
254                             pageManager.updatePage(requestPage);
255                             clearLayoutAttributes(request);                            
256                         }
257                         catch (Exception e)
258                         {
259                             throw new PortletException("failed to add portlet " + layout + " to page: " + requestPage+": "+e.getMessage(), e);
260                         }
261                     }
262                     else if ( !layout.equals(targetFragment.getName()) )
263                     {
264                         try
265                         {
266                             // layout portlet change
267                             targetFragment.setName(layout);
268                             pageManager.updatePage(requestPage);
269                             entityAccess.updatePortletEntity(window.getPortletEntity(), targetFragment);
270                             entityAccess.storePortletEntity(window.getPortletEntity());
271                             windowAccess.createPortletWindow(window.getPortletEntity(), targetFragment.getId());
272                             clearLayoutAttributes(request);
273                             return;
274                         }
275                         catch (Exception e)
276                         {
277                             throw new PortletException("Unable to update page: "+e.getMessage(), e);
278                         }
279                     }
280                 }
281                 return;
282             }
283 
284             if ( request.getParameter("jsSubmitPage" ) != null )
285             {
286                 String jsPageName = request.getParameter("jsPageName");
287                 String jsPageTitle = request.getParameter("jsPageTitle");
288                 String jsPageShortTitle = request.getParameter("jsPageShortTitle");
289                 if ( jsPageName != null && jsPageName.length() > 0 && jsPageName.indexOf(Folder.PATH_SEPARATOR) == -1 )
290                 {
291                     try
292                     {                
293                         Folder parent = (Folder)requestPage.getParent();
294                         if (parent != null)
295                         {
296                             String path = parent.getPath();
297                             if (path.endsWith(Folder.PATH_SEPARATOR))
298                             {
299                                 path = path + getEscapedName(jsPageName);
300                             }
301                             else
302                             {
303                                 path = path + Folder.PATH_SEPARATOR
304                                         + getEscapedName(jsPageName);
305                             }
306                             Page page = pageManager.newPage(path);
307                             if ( layout == null || layout.length() == 0 )
308                             {
309                                 layout = requestPage.getRootFragment().getName();
310                             }
311                             page.getRootFragment().setName(layout);
312                             page.setDefaultDecorator(requestPage.getDefaultDecorator(Fragment.LAYOUT), Fragment.LAYOUT);
313                             page.setDefaultDecorator(requestPage.getDefaultDecorator(Fragment.PORTLET), Fragment.PORTLET);
314                             page.setTitle(jsPageTitle != null && !jsPageTitle.equals("") ? jsPageTitle : jsPageName);
315                             page.setShortTitle(jsPageShortTitle != null
316                                             && !jsPageShortTitle.equals("") ? jsPageShortTitle
317                                             : jsPageName);
318                             pageManager.updatePage(page);
319                             clearLayoutAttributes(request);                            
320                             List orderList = parent.getDocumentOrder();
321                             if (orderList != null)
322                             {
323                                 String name = page.getName();
324                                 if (orderList.indexOf(name) < 0)
325                                 {
326                                     orderList.add(name);
327                                     parent.setDocumentOrder(orderList);
328                                     pageManager.updateFolder(parent);
329                                 }
330                             }
331                         }
332                     }
333                     catch (Exception e)
334                     {
335                         throw new PortletException("Unable to access page for editing: "+e.getMessage(), e);
336                     }                        
337                 }
338                 return;
339             }
340 
341             if (request.getParameter("jsChangePageName") != null)
342             {
343                 String jsPageTitle = request.getParameter("jsPageTitle");
344                 String jsPageShortTitle = request
345                         .getParameter("jsPageShortTitle");
346                 try
347                 {
348                     if (jsPageTitle != null && !jsPageTitle.equals(""))
349                     {
350                         requestPage.setTitle(jsPageTitle);
351                     }
352                     if (jsPageShortTitle != null
353                             && !jsPageShortTitle.equals(""))
354                     {
355                         requestPage.setShortTitle(jsPageShortTitle);
356                     }
357                     pageManager.updatePage(requestPage);
358                 }
359                 catch (Exception e)
360                 {
361                     throw new PortletException(
362                             "Unable to access page for editing: "
363                                     + e.getMessage(), e);
364                 }
365                 return;
366             }
367 
368             if ( request.getParameter("jsDeletePage" ) != null )
369             {
370                 try
371                 {
372                     Folder parent = (Folder)requestPage.getParent();
373                     if (parent != null)
374                     {
375                         List orderList = parent.getDocumentOrder();
376                         if (orderList != null)
377                         {
378                             String name = requestPage.getName();
379                             if (orderList.indexOf(name) > -1)
380                             {
381                                 orderList.remove(name);
382                                 parent.setDocumentOrder(orderList);
383                                 pageManager.updateFolder(parent);
384                             }
385                         }
386                     }
387 
388                     pageManager.removePage(requestPage);
389                 }
390                 catch (Exception e)
391                 {
392                     throw new PortletException("Unable to access page for removing: "+e.getMessage(), e);
393                 }
394                 return;
395             }
396 
397             if (request.getParameter("jsMovePageLeft") != null)
398             {
399                 try
400                 {
401                     Folder parent = (Folder) requestPage.getParent();
402                     if (parent != null)
403                     {
404                         List orderList = parent.getDocumentOrder();
405                         String name = requestPage.getName();
406                         if (orderList != null)
407                         {
408                             int index = orderList.indexOf(name);
409                             if (index > -1)
410                             {
411                                 String type = requestPage.getType();
412                                 int i = index - 1;
413                                 while (i >= 0)
414                                 {
415                                     String value = (String) orderList.get(i);
416                                     if (value.endsWith(type))
417                                     {
418                                         orderList.remove(index);
419                                         orderList.add(i, name);
420                                         parent.setDocumentOrder(orderList);
421                                         pageManager.updateFolder(parent);
422                                         break;
423                                     }
424                                     i--;
425                                 }
426                             }
427                             else
428                             {
429                                 orderList.add(name);
430                                 parent.setDocumentOrder(orderList);
431                                 pageManager.updateFolder(parent);
432                             }
433                         }
434                         else
435                         {
436                             orderList = new ArrayList(4);
437                             orderList.add(name);
438                             parent.setDocumentOrder(orderList);
439                             pageManager.updateFolder(parent);
440                         }
441                     }
442                 }
443                 catch (Exception e)
444                 {
445                     throw new PortletException(
446                             "Unable to access page for changing the document order: "
447                                     + e.getMessage(), e);
448                 }
449                 return;
450             }
451 
452             if (request.getParameter("jsMovePageRight") != null)
453             {
454                 try
455                 {
456                     Folder parent = (Folder) requestPage.getParent();
457                     if (parent != null)
458                     {
459                         List orderList = parent.getDocumentOrder();
460                         String name = requestPage.getName();
461                         if (orderList != null)
462                         {
463                             int index = orderList.indexOf(name);
464                             if (index > -1)
465                             {
466                                 String type = requestPage.getType();
467                                 int i = index + 1;
468                                 while (i < orderList.size())
469                                 {
470                                     String value = (String) orderList.get(i);
471                                     if (value.endsWith(type))
472                                     {
473                                         orderList.remove(index);
474                                         orderList.add(i, name);
475                                         parent.setDocumentOrder(orderList);
476                                         pageManager.updateFolder(parent);
477                                         break;
478                                     }
479                                     i++;
480                                 }
481                             }
482                             else
483                             {
484                                 orderList.add(name);
485                                 parent.setDocumentOrder(orderList);
486                                 pageManager.updateFolder(parent);
487                             }
488                         }
489                         else
490                         {
491                             orderList = new ArrayList(4);
492                             orderList.add(name);
493                             parent.setDocumentOrder(orderList);
494                             pageManager.updateFolder(parent);
495                         }
496                     }
497                 }
498                 catch (Exception e)
499                 {
500                     throw new PortletException(
501                             "Unable to access page for changing the document order: "
502                                     + e.getMessage(), e);
503                 }
504                 return;
505             }            
506 
507             if (request.getParameter("jsSubmitFolder") != null)
508             {
509                 String jsFolderName = request.getParameter("jsFolderName");
510                 String jsFolderTitle = request.getParameter("jsFolderTitle");
511                 String jsFolderShortTitle = request.getParameter("jsFolderShortTitle");
512                 if (jsFolderName != null && jsFolderName.length() > 0
513                         && jsFolderName.indexOf(Folder.PATH_SEPARATOR) == -1)
514                 {
515                     try
516                     {
517                         Folder parent = (Folder) requestPage.getParent();
518                         if (parent != null)
519                         {
520                             String path = parent.getPath();
521                             if (path.endsWith(Folder.PATH_SEPARATOR))
522                             {
523                                 path = path + getEscapedName(jsFolderName);
524                             }
525                             else
526                             {
527                                 path = path + Folder.PATH_SEPARATOR
528                                         + getEscapedName(jsFolderName);
529                             }
530                             Folder folder = pageManager.newFolder(path);
531                             if (layout == null || layout.length() == 0)
532                             {
533                                 layout = requestPage.getRootFragment()
534                                         .getName();
535                             }
536                             folder.setDefaultDecorator(requestPage
537                                     .getDefaultDecorator(Fragment.LAYOUT),
538                                     Fragment.LAYOUT);
539                             folder.setDefaultDecorator(requestPage
540                                     .getDefaultDecorator(Fragment.PORTLET),
541                                     Fragment.PORTLET);
542                             folder
543                                     .setTitle(jsFolderTitle != null
544                                             && !jsFolderTitle.equals("") ? jsFolderTitle
545                                             : jsFolderName);
546                             folder
547                                     .setShortTitle(jsFolderShortTitle != null
548                                             && !jsFolderShortTitle.equals("") ? jsFolderShortTitle
549                                             : jsFolderName);
550                             pageManager.updateFolder(folder);
551 
552                             List orderList = parent.getDocumentOrder();
553                             if (orderList != null)
554                             {
555                                 String name = folder.getName();
556                                 if (orderList.indexOf(name) < 0)
557                                 {
558                                     orderList.add(name);
559                                     parent.setDocumentOrder(orderList);
560                                     pageManager.updateFolder(parent);
561                                 }
562                             }
563 
564                             // add default page
565                             path = folder.getPath();
566                             if (path.endsWith(Folder.PATH_SEPARATOR))
567                             {
568                                 path = path + getEscapedName("default-page");
569                             }
570                             else
571                             {
572                                 path = path + Folder.PATH_SEPARATOR
573                                         + getEscapedName("default-page");
574                             }
575                             Page page = pageManager.newPage(path);
576                             if (layout == null || layout.length() == 0)
577                             {
578                                 layout = requestPage.getRootFragment()
579                                         .getName();
580                             }
581                             page.getRootFragment().setName(layout);
582                             page.setDefaultDecorator(requestPage
583                                     .getDefaultDecorator(Fragment.LAYOUT),
584                                     Fragment.LAYOUT);
585                             page.setDefaultDecorator(requestPage
586                                     .getDefaultDecorator(Fragment.PORTLET),
587                                     Fragment.PORTLET);
588                             page.setTitle(jsFolderName);
589                             pageManager.updatePage(page);
590 
591                             orderList = folder.getDocumentOrder();
592                             if (orderList != null)
593                             {
594                                 String name = page.getName();
595                                 if (orderList.indexOf(name) < 0)
596                                 {
597                                     orderList.add(name);
598                                     folder.setDocumentOrder(orderList);
599                                     pageManager.updateFolder(folder);
600                                 }
601                             }
602                         }
603                     }
604                     catch (Exception e)
605                     {
606                         throw new PortletException(
607                                 "Unable to access folder for editing: "
608                                         + e.getMessage(), e);
609                     }
610                 }
611                 return;
612             }
613 
614             if (request.getParameter("jsChangeFolderName") != null)
615             {
616                 String jsFolderTitle = request.getParameter("jsFolderTitle");
617                 String jsFolderShortTitle = request
618                         .getParameter("jsFolderShortTitle");
619                 try
620                 {
621                     Folder parent = (Folder) requestPage.getParent();
622                     if (parent != null)
623                     {
624                         if (jsFolderTitle != null && !jsFolderTitle.equals(""))
625                         {
626                             parent.setTitle(jsFolderTitle);
627                         }
628                         if (jsFolderShortTitle != null
629                                 && !jsFolderShortTitle.equals(""))
630                         {
631                             parent.setShortTitle(jsFolderShortTitle);
632                         }
633                         pageManager.updateFolder(parent);
634                     }
635 
636                 }
637                 catch (Exception e)
638                 {
639                     throw new PortletException(
640                             "Unable to access folder for editing: "
641                                     + e.getMessage(), e);
642                 }
643                 return;
644             }
645             
646             if (request.getParameter("jsDeleteFolder") != null)
647             {
648                 try
649                 {
650                     Folder targetFolder = (Folder) requestPage.getParent();
651                     Folder parent = (Folder) targetFolder.getParent();
652                     if (parent != null)
653                     {
654                         List orderList = parent.getDocumentOrder();
655                         if (orderList != null)
656                         {
657                             String name = targetFolder.getName();
658                             if (orderList.indexOf(name) > -1)
659                             {
660                                 orderList.remove(name);
661                                 parent.setDocumentOrder(orderList);
662                                 pageManager.updateFolder(parent);
663                             }
664                         }
665 
666                         // do not remove if the folder is root.
667                         pageManager.removeFolder(targetFolder);
668                     }
669                 }
670                 catch (Exception e)
671                 {
672                     throw new PortletException(
673                             "Unable to access folder for removing: "
674                                     + e.getMessage(), e);
675                 }
676                 return;
677             }
678 
679             if (request.getParameter("jsMoveFolderLeft") != null)
680             {
681                 try
682                 {
683                     Folder targetFolder = (Folder) requestPage.getParent();
684                     Folder parent = (Folder) targetFolder.getParent();
685                     if (parent != null)
686                     {
687                         List orderList = parent.getDocumentOrder();
688                         String name = targetFolder.getName();
689                         if (orderList != null)
690                         {
691                             int index = orderList.indexOf(name);
692                             if (index > -1)
693                             {
694                                 int i = index - 1;
695                                 while (i >= 0)
696                                 {
697                                     String value = (String) orderList.get(i);
698                                     if (!value.endsWith(".psml")
699                                             && !value.endsWith(".link"))
700                                     {
701                                         orderList.remove(index);
702                                         orderList.add(i, name);
703                                         parent.setDocumentOrder(orderList);
704                                         pageManager.updateFolder(parent);
705                                         break;
706                                     }
707                                     i--;
708                                 }
709                             }
710                             else
711                             {
712                                 orderList.add(name);
713                                 parent.setDocumentOrder(orderList);
714                                 pageManager.updateFolder(parent);
715                             }
716                         }
717                         else
718                         {
719                             orderList = new ArrayList(4);
720                             orderList.add(name);
721                             parent.setDocumentOrder(orderList);
722                             pageManager.updateFolder(parent);
723                         }
724                     }
725                 }
726                 catch (Exception e)
727                 {
728                     throw new PortletException(
729                             "Unable to access folder for changing the document order: "
730                                     + e.getMessage(), e);
731                 }
732                 return;
733             }
734 
735             if (request.getParameter("jsMoveFolderRight") != null)
736             {
737                 try
738                 {
739                     Folder targetFolder = (Folder) requestPage.getParent();
740                     Folder parent = (Folder) targetFolder.getParent();
741                     if (parent != null)
742                     {
743                         List orderList = parent.getDocumentOrder();
744                         String name = targetFolder.getName();
745                         if (orderList != null)
746                         {
747                             int index = orderList.indexOf(name);
748                             if (index > -1)
749                             {
750                                 int i = index + 1;
751                                 while (i < orderList.size())
752                                 {
753                                     String value = (String) orderList.get(i);
754                                     if (!value.endsWith(".psml")
755                                             && !value.endsWith(".link"))
756                                     {
757                                         orderList.remove(index);
758                                         orderList.add(i, name);
759                                         parent.setDocumentOrder(orderList);
760                                         pageManager.updateFolder(parent);
761                                         break;
762                                     }
763                                     i++;
764                                 }
765                             }
766                             else
767                             {
768                                 orderList.add(name);
769                                 parent.setDocumentOrder(orderList);
770                                 pageManager.updateFolder(parent);
771                             }
772                         }
773                         else
774                         {
775                             orderList = new ArrayList(4);
776                             orderList.add(name);
777                             parent.setDocumentOrder(orderList);
778                             pageManager.updateFolder(parent);
779                         }
780                     }
781                 }
782                 catch (Exception e)
783                 {
784                     throw new PortletException(
785                             "Unable to access folder for changing the document order: "
786                                     + e.getMessage(), e);
787                 }
788                 return;
789             }
790 
791             String theme = request.getParameter("theme");
792             if ( theme != null && theme.length() > 0 && !theme.equals(requestPage.getDefaultDecorator(Fragment.LAYOUT)) )
793             {
794                 requestPage.setDefaultDecorator(theme, Fragment.LAYOUT);
795                 try
796                 {
797                     pageManager.updatePage(requestPage);
798                 }
799                 catch (Exception e)
800                 {
801                     throw new PortletException("Unable to update page: "+e.getMessage(), e);
802                 }
803                 return;
804             }
805             
806             String fragmentId = request.getParameter("fragment");
807             if ( fragmentId != null && fragmentId.length() > 0 )
808             {
809                 String move = request.getParameter("move");
810                 if ( move != null && move.length() > 0 )
811                 {
812                     int moveCode = Integer.parseInt(move);                    
813                     PortletWindow window = requestContext.getActionWindow();
814                     Fragment currentFragment = requestPage.getFragmentById(window.getId().toString());
815                     Fragment fragmentToMove = requestPage.getFragmentById(fragmentId);
816                     
817                     if ( currentFragment == null || fragmentToMove == null )
818                     {
819                         // ignore no longer consistent page definition
820                         return;
821                     }
822                     
823                     ColumnLayout columnLayout;
824                     try
825                     {
826                         columnLayout = new ColumnLayout(numColumns, layoutType, currentFragment.getFragments(), null);
827                         columnLayout.addLayoutEventListener(new PageManagerLayoutEventListener(pageManager, requestPage, layoutType));
828                     }
829                     catch (LayoutEventException e1)
830                     {
831                         throw new PortletException("Failed to build ColumnLayout "+e1.getMessage(), e1);
832                     }
833 
834                     try
835                     {                
836                         switch (moveCode)
837                         {
838                         case LayoutEvent.MOVED_UP:
839                             columnLayout.moveUp(fragmentToMove);
840                             break;
841                         case LayoutEvent.MOVED_DOWN:
842                             columnLayout.moveDown(fragmentToMove);
843                             break;
844                         case LayoutEvent.MOVED_RIGHT:
845                             columnLayout.moveRight(fragmentToMove);
846                             break;
847                         case LayoutEvent.MOVED_LEFT:
848                             columnLayout.moveLeft(fragmentToMove);
849                             break;
850                         default:
851                             throw new PortletException("Invalid movement code " + moveCode);
852                         }
853                        
854                     }
855                     catch (SecurityException se)
856                     {
857                         // ignore page security constraint violations, only
858                         // permitted users can edit managed pages; page
859                         // update will remain transient
860                         log.info("Unable to update page " + requestPage.getId() + " layout due to security permission/constraint.", se);
861                     }
862                     catch (Exception e)
863                     {
864                         if (e instanceof PortletException)
865                         {
866                             throw (PortletException)e;
867                         }
868                         else
869                         {
870                             throw new PortletException("Unable to process layout for page " + requestPage.getId() + " layout: " + e.toString(), e);
871                         }
872                     }
873                     return;
874                 }
875                 
876                 String remove = request.getParameter("remove");
877                 if ( remove != null && remove.length() > 0 )
878                 {
879                     Page page = null;
880                     try
881                     {
882                         // TODO: for now retrieve the real Page instead of ContentPage
883                         //       because removing fragments isn't working through the ContentFragment wrapping
884                         page = pageManager.getPage(requestPage.getPath());
885                     }
886                     catch (Exception e)
887                     {
888                         throw new PortletException("Unable to retrieve page "+requestPage.getId(),e);
889                     }
890 
891                     PortletWindow window = requestContext.getActionWindow();
892                     Fragment currentFragment = page.getFragmentById(window.getId().toString());
893 
894                     if ( currentFragment == null )
895                     {
896                         // ignore no longer consistent page definition
897                         return;
898                     }
899                     
900                     removeFragment(page, currentFragment, fragmentId);
901                     return;
902                 }
903                 
904                 String decorator = request.getParameter("decorator");
905                 if ( decorator != null )
906                 {
907                     Fragment fragment = requestPage.getFragmentById(fragmentId);
908 
909                     if ( fragment == null )
910                     {
911                         // ignore no longer consistent page definition
912                         return;
913                     }
914                     
915                     if (decorator.trim().length() == 0)
916                         fragment.setDecorator(null);
917                     else
918                         fragment.setDecorator(decorator);
919                     try
920                     {
921                         pageManager.updatePage(requestPage);
922                     }
923                     catch (Exception e)
924                     {
925                         throw new PortletException("Unable to update page for fragment decorator: "+e.getMessage(), e);
926                     }
927                     return;
928                 }
929             }
930             // change style for all pages in user folder 
931             String jsChangeUserPagesTheme = request.getParameter("jsChangeUserPagesTheme");
932             if ( jsChangeUserPagesTheme != null )
933             {
934                String user_pages_theme = request.getParameter("user_pages_theme");
935                try
936                 {
937                    Folder f = pageManager.getUserFolder(request.getRemoteUser());
938                    applyStyle(f,user_pages_theme,Fragment.LAYOUT);
939                 }
940                 catch (Exception e)
941                 {
942                    throw new PortletException("Unable to update folder for defUserLayoutDeco decorator: "+e.getMessage(), e);
943                 }
944                 return;
945             }                
946             String jsChangeUserPortletsDeco = request.getParameter("jsChangeUserPortletsDeco");
947             if ( jsChangeUserPortletsDeco != null )
948             {                  
949                String user_portlets_deco = request.getParameter("user_portlets_deco");
950                try
951                 {
952                    Folder f = pageManager.getUserFolder(request.getRemoteUser());
953                    applyStyle(f,user_portlets_deco,Fragment.PORTLET);
954                 }
955                catch (Exception e)
956                 {
957                     throw new PortletException("Unable to update folder for defUserPortletDeco decorator: "+e.getMessage(), e);
958                 }
959                return;
960             }                                
961             
962             String jsChangeThemeAll = request.getParameter("jsChangeThemeAll");
963             if (jsChangeThemeAll != null)
964             {
965                 String decorators = request.getParameter("decorators");                
966                 Iterator fragmentsIter = requestPage.getRootFragment().getFragments().iterator();
967                 while(fragmentsIter.hasNext())
968                 {
969                     Fragment fragment = (Fragment) fragmentsIter.next();
970                     if ( fragment == null )
971                     {
972                         // ignore no longer consistent page definition
973                         return;
974                     }
975                     
976                     if (decorators.trim().length() == 0)
977                         fragment.setDecorator(null);
978                     else
979                         fragment.setDecorator(decorators);
980                 }
981                 try
982                 {
983                     pageManager.updatePage(requestPage);
984                 }
985                 catch (Exception e)
986                 {
987                     throw new PortletException("Unable to update page for fragment decorator: "+e.getMessage(), e);
988                 }
989                 return;
990             }                
991             
992             String portlets = request.getParameter("portlets");
993             if ( portlets != null && portlets.length() > 0 )
994             {
995                 PortletWindow window = requestContext.getActionWindow();
996                 Fragment targetFragment = requestPage.getFragmentById(window.getId().toString());
997 
998                 if ( targetFragment == null )
999                 {
1000                     // ignore no longer consistent page definition
1001                     return;
1002                 }
1003                 
1004                 StringTokenizer tokenizer = new StringTokenizer(portlets, ",");            
1005                 while (tokenizer.hasMoreTokens())
1006                 {
1007                     String portlet = tokenizer.nextToken();
1008                     if (portlet.startsWith("box_"))
1009                     {
1010                         portlet = portlet.substring("box_".length());                        
1011                         addPortletToPage(requestPage, targetFragment, portlet);
1012                     }
1013                 }
1014                 return;
1015             }
1016         }
1017     }
1018         
1019     protected void clearLayoutAttributes(ActionRequest request)
1020     {
1021         request.getPortletSession().removeAttribute(PortalReservedParameters.PAGE_LAYOUT_VIEW);
1022         request.getPortletSession().removeAttribute(PortalReservedParameters.PAGE_LAYOUT_SOLO);
1023         request.getPortletSession().removeAttribute(PortalReservedParameters.PAGE_LAYOUT_MAX);        
1024         request.getPortletSession().removeAttribute(PortalReservedParameters.PAGE_LAYOUT_HELP);
1025     }
1026 
1027     protected int getFragmentNestingLevel(Page page, String fragmentId)
1028     {
1029         Fragment root = page.getRootFragment();
1030         if ( root.getId().equals(fragmentId) )
1031         {
1032             return 0;
1033         }
1034         else
1035         {
1036             return getFragmentNestingLevel(root, 1, fragmentId);
1037         }
1038     }
1039     
1040     protected int getFragmentNestingLevel(Fragment parent, int level, String fragmentId)
1041     {
1042         Iterator iter = parent.getFragments().iterator();
1043         Fragment child;
1044         int childLevel;
1045         while ( iter.hasNext() )
1046         {
1047             child = (Fragment)iter.next();
1048             if (child.getId().equals(fragmentId))
1049             {
1050                 return level;
1051             }
1052             else
1053             {
1054                 childLevel = getFragmentNestingLevel(child, level+1, fragmentId);
1055                 if ( childLevel != -1 )
1056                 {
1057                     return childLevel;
1058                 }
1059             }
1060         }
1061         return -1;
1062     }
1063 
1064     protected String getEscapedName(String pageName)
1065     {
1066         try
1067         {
1068             return URLEncoder.encode(pageName, "UTF-8").replace('%', '_');
1069         }
1070         catch (UnsupportedEncodingException e)
1071         {
1072             log.warn("Unsupported Encoding Exception.", e);
1073             return pageName;
1074         }
1075     }
1076     
1077     private void applyStyle(Folder f, String theme, String theme_type) throws FolderNotUpdatedException, NodeException 
1078     {
1079        f.setDefaultDecorator(theme, theme_type);
1080        pageManager.updateFolder(f);
1081        Iterator pagesIter = f.getPages().iterator();
1082        while(pagesIter.hasNext())
1083        {
1084            Page pp = (Page) pagesIter.next();
1085            pp.setDefaultDecorator(theme, theme_type);
1086            pageManager.updatePage(pp);
1087        }                       
1088        Iterator userFoldersIter = pageManager.getFolders(f).iterator();
1089        while(userFoldersIter.hasNext()) 
1090        {
1091            Folder ff = (Folder) userFoldersIter.next();
1092            applyStyle(ff,theme,theme_type);
1093        }
1094     }    
1095 }