KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jetspeed > modules > actions > controllers > RowColumnControllerAction


1 /*
2  * Copyright 2000-2001,2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.jetspeed.modules.actions.controllers;
18
19 //Jetspeed Stuff
20
import org.apache.jetspeed.om.profile.Profile;
21 import org.apache.jetspeed.om.registry.RegistryEntry;
22 import org.apache.jetspeed.om.profile.Portlets;
23 import org.apache.jetspeed.om.profile.Entry;
24 import org.apache.jetspeed.om.profile.Layout;
25 import org.apache.jetspeed.om.profile.psml.PsmlLayout;
26 import org.apache.jetspeed.portal.PortletSet;
27 import org.apache.jetspeed.portal.PortletController;
28 import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
29 import org.apache.jetspeed.services.logging.JetspeedLogger;
30 import org.apache.jetspeed.services.Registry;
31 import org.apache.jetspeed.services.rundata.JetspeedRunData;
32 import org.apache.jetspeed.util.AutoProfile;
33
34 // Turbine stuff
35
//import org.apache.turbine.util.DynamicURI;
36
import org.apache.turbine.util.RunData;
37 import org.apache.turbine.modules.ActionLoader;
38
39 // Velocity Stuff
40
import org.apache.velocity.context.Context;
41
42 // Java stuff
43
import java.util.Vector JavaDoc;
44 import java.util.List JavaDoc;
45 import java.util.StringTokenizer JavaDoc;
46 import java.util.Iterator JavaDoc;
47 import java.util.ArrayList JavaDoc;
48 import java.util.Map JavaDoc;
49 import java.util.HashMap JavaDoc;
50 import java.util.Collections JavaDoc;
51 import java.util.Comparator JavaDoc;
52
53 /**
54  * This action builds a context suitable for controllers handlings simple
55  * sorted lists of portlets
56  *
57  * @author <a HREF="mailto:raphael@apache.org">RaphaŽl Luta</a>
58  * @author <a HREF="mailto:paulsp@apache.org">Paul Spencer</a>
59  */

60 public class RowColumnControllerAction extends VelocityControllerAction
61 {
62
63     /**
64      * Static initialization of the logger for this class
65      */

66     private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(RowColumnControllerAction.class.getName());
67     
68     /**
69      * Subclasses must override this method to provide default behavior
70      * for the portlet action
71      */

72     protected void buildNormalContext( PortletController controller,
73                                        Context context,
74                                        RunData rundata )
75     {
76         //retrieve the size for each of the element
77
String JavaDoc sizes = controller.getConfig().getInitParameter("sizes");
78         context.put("sizes", getCellSizes(sizes));
79     }
80
81     /** Parses the size config info and returns a list of
82      * size values for the current set
83      *
84      * @param sizeList java.lang.String a comma separated string a values
85      * @return a List of values
86      */

87     public static List JavaDoc getCellSizes(String JavaDoc sizelist)
88     {
89         List JavaDoc list = new Vector JavaDoc();
90
91         if (sizelist!=null)
92         {
93             StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(sizelist,",");
94             while (st.hasMoreTokens())
95             {
96                 list.add(st.nextToken());
97             }
98         }
99
100         return list;
101     }
102
103     /**
104      * Adds a "pane" portlet object in the context which represents the
105      * currently selected pane
106      */

107     protected void buildCustomizeContext( PortletController controller,
108                                        Context context,
109                                        RunData rundata )
110     {
111         super.buildCustomizeContext(controller, context, rundata);
112
113         JetspeedRunData jdata = (JetspeedRunData)rundata;
114         PortletSet set = (PortletSet)jdata.getCustomized();
115
116         Portlets portlets = jdata.getCustomizedProfile()
117                                  .getDocument()
118                                  .getPortletsById(set.getID());
119
120         List JavaDoc plist = new ArrayList JavaDoc();
121         List JavaDoc work = new ArrayList JavaDoc();
122         List JavaDoc filler = Collections.nCopies(portlets.getPortletsCount()+portlets.getEntryCount(),null);
123         plist.addAll(filler);
124
125         for (int i=0; i < portlets.getPortletsCount(); i++)
126         {
127             Portlets p = portlets.getPortlets(i);
128             if (logger.isDebugEnabled())
129             {
130                 logger.debug("RowColumnControllerAction: processing portlet: " + p.getTitle());
131             }
132             Layout layout = p.getLayout();
133             if (layout == null)
134             {
135                 // Pane should always have a layout with correct position
136
if (logger.isDebugEnabled())
137                 {
138                     logger.debug("RowColumnControllerAction: no layout, creating a new one");
139                 }
140                 layout = new PsmlLayout();
141                 layout.setPosition(i);
142                 p.setLayout(layout);
143             }
144             if (layout!=null)
145             {
146                 try
147                 {
148                     int pos = (int)layout.getPosition();
149                     if (logger.isDebugEnabled())
150                     {
151                         logger.debug("RowColumnControllerAction: layout has position: " + pos);
152                     }
153                     if (pos >= 0 && pos < plist.size())
154                     {
155                         plist.set(pos,p);
156                     }
157                     else
158                     {
159                         work.add(p);
160                     }
161                 }
162                 catch (Exception JavaDoc e)
163                 {
164                     logger.error("Layout error", e);
165                     layout.setPosition(-1);
166                     work.add(p);
167                 }
168             }
169             else
170             {
171                 work.add(p);
172             }
173         }
174
175         for (int i=0; i < portlets.getEntryCount(); i++)
176         {
177             Entry p = portlets.getEntry(i);
178             Layout layout = p.getLayout();
179             if (layout!=null)
180             {
181                 try
182                 {
183                     int pos = (int)layout.getPosition();
184                     if (pos>=0)
185                     {
186                         plist.set(pos,p);
187                     }
188                     else
189                     {
190                         work.add(p);
191                     }
192                 }
193                 catch (Exception JavaDoc e)
194                 {
195                     layout.setPosition(-1);
196                     work.add(p);
197                 }
198             }
199             else
200             {
201                 work.add(p);
202             }
203         }
204
205         Iterator JavaDoc i = work.iterator();
206         for(int idx=0;idx < plist.size(); idx++)
207         {
208             if (plist.get(idx)==null)
209             {
210                 if (i.hasNext())
211                 {
212                     plist.set(idx,i.next());
213                 }
214                 else
215                 {
216                     plist.remove(idx);
217                 }
218             }
219         }
220
221         Map JavaDoc titles = new HashMap JavaDoc();
222         i = plist.iterator();
223         while(i.hasNext())
224         {
225             Object JavaDoc obj = i.next();
226
227             if (obj instanceof Portlets)
228             {
229                 Portlets entry = (Portlets)obj;
230                 if ((entry.getMetaInfo()!=null)&&(entry.getMetaInfo().getTitle()!=null))
231                 {
232                     titles.put(entry.getId(),entry.getMetaInfo().getTitle());
233                 }
234             }
235             else
236             {
237                 Entry entry = (Entry)obj;
238                 if ((entry.getMetaInfo()!=null)&&(entry.getMetaInfo().getTitle()!=null))
239                 {
240                    titles.put(entry.getId(), entry.getMetaInfo().getTitle());
241                 }
242                 else
243                 {
244                     RegistryEntry pentry = Registry.getEntry(Registry.PORTLET,entry.getParent());
245
246                     if (pentry!=null)
247                     {
248                         titles.put(entry.getId(), pentry.getTitle());
249                     }
250                 }
251             }
252         }
253
254
255         context.put("portlets",plist);
256         context.put("titles",titles);
257
258         /**
259          * Make a list of all used portlets available thru the 'runs' reference
260          * --------------------------------------------------------------------------
261          * last modified: 10/31/01
262          * Andreas Kempf, Siemens ICM S CP PE, Munich
263          * mailto: A.Kempf@web.de
264          */

265         context.put("runs", AutoProfile.getPortletList(rundata));
266         // --------------------------------------------------------------------------
267
}
268
269     /**
270      * Cancel the current customizations. If this was the last customization
271      * on the stack, then return the user to the home page.
272      */

273     public void doCancel(RunData data, Context context)
274     {
275          ((JetspeedRunData)data).setCustomized(null);
276
277         if (((JetspeedRunData)data).getCustomized() == null)
278         {
279             try
280             {
281                 ActionLoader.getInstance().exec( data, "controls.EndCustomize" );
282             }
283             catch (Exception JavaDoc e)
284             {
285                 logger.error("Unable to load action controls.EndCustomize ",e);
286             }
287         }
288     }
289
290     public void doSave(RunData data, Context context)
291     {
292         doApply(data, context);
293     }
294
295     public void doApply(RunData data, Context context)
296     {
297         // move one level back in customization
298
((JetspeedRunData) data).setCustomized(null);
299
300         // if we are all done customization
301
if (((JetspeedRunData) data).getCustomized() == null)
302         {
303             // save the edit profile and make it current
304
try
305             {
306                 ((JetspeedRunData) data).getCustomizedProfile().store();
307             }
308             catch (Exception JavaDoc e)
309             {
310                 logger.error("Unable to save profile ",e);
311             }
312
313             try
314             {
315                 ActionLoader.getInstance().exec( data, "controls.EndCustomize" );
316             }
317             catch (Exception JavaDoc e)
318             {
319                 logger.error("Unable to load action controls.EndCustomize ",e);
320             }
321         }
322     }
323
324     /** Remove a pane from the current set
325      * This method expects the following parameters
326      * - paneid: the id a the pane to modify within the current profile
327      * - position: the position of the component to delete
328      */

329     public void doDelete(RunData data, Context context) throws Exception JavaDoc
330     {
331       JetspeedRunData jdata = (JetspeedRunData)data;
332       PortletSet customizedSet = (PortletSet)jdata.getCustomized();
333       int position = data.getParameters().getInt("position",-1);
334       Profile profile = jdata.getCustomizedProfile();
335
336       // ADDED for WML
337
//boolean isWML = (profile.getMediaType().equalsIgnoreCase("wml"));
338

339
340         if (customizedSet == null) return;
341
342         if (position > -1)
343         {
344             Portlets set = profile.getDocument()
345                                   .getPortletsById(customizedSet.getID());
346             if (set != null)
347             {
348                 // first try explicit portlets position
349
for(int i=0; i < set.getPortletsCount(); i++)
350                 {
351                     Portlets p = set.getPortlets(i);
352                     Layout layout = p.getLayout();
353 //
354
// if (layout == null)
355
// {
356
// Layout nl = new Layout ();
357
// nl.setPosition (String.valueOf(i));
358
//
359
// }
360
if ((layout!=null) && (layout.getPosition() != -1))
361                     {
362
363                         int lpos = (int)layout.getPosition();
364                         if (lpos==position)
365                         {
366                             set.removePortlets(i);
367
368                             updateLayoutPositions(set);
369
370                             // MODIFIED: Save changes for wml profiles
371
//if (isWML)
372
// doSave(data, null);
373

374                             return;
375                         }
376                     }
377                 }
378
379                 // try explicit entry position
380
for(int i=0; i < set.getEntryCount(); i++)
381                 {
382                     Entry p = set.getEntry(i);
383                     Layout layout = p.getLayout();
384
385                     if ((layout!=null) && (layout.getPosition() != -1))
386                     {
387                         int lpos = (int)layout.getPosition();
388
389                         if (lpos==position)
390                         {
391                             set.removeEntry(i);
392
393                             // MODIFIED: Save changes for wml profiles
394
//if (isWML)
395
// doSave(data, null);
396
return;
397                         }
398                     }
399                 }
400
401                 //else use implicit position
402
if (position < set.getPortletsCount())
403                 {
404                     set.removePortlets(position);
405
406                     // MODIFIED: Save changes for wml profiles
407
//if (isWML)
408
// doSave(data, null);
409
return;
410                 }
411
412                 if (position < set.getEntryCount())
413                 {
414                     set.removeEntry(position);
415
416                     // MODIFIED: Save changes for wml profiles
417
//if (isWML)
418
// doSave(data, null);
419
return;
420                 }
421             }
422         }
423
424
425     }
426
427     /**
428      * Updates the layout position based on physical order within the resorted portlet list. Assures that
429      * layout position is always consecutive and within bounds.
430      *
431      * @param set
432      */

433     private void updateLayoutPositions(Portlets set)
434     {
435         // Load the panes into a list
436
List JavaDoc list = new ArrayList JavaDoc();
437         for(int i = 0; i < set.getPortletsCount(); i++)
438         {
439             Portlets pane = set.getPortlets(i);
440             list.add(pane);
441         }
442
443         // Sort list using the current layout position
444
Collections.sort(list,
445                          new Comparator JavaDoc()
446                          {
447                              public int compare(Object JavaDoc pane1, Object JavaDoc pane2)
448                              {
449                                  Long JavaDoc pos1 = new Long JavaDoc(((Portlets) pane1).getLayout().getPosition());
450                                  Long JavaDoc pos2 = new Long JavaDoc(((Portlets) pane2).getLayout().getPosition());
451                                  return pos1.compareTo(pos2);
452                              }
453                          });
454
455         // Update the layout position based on the physical order within the sorted list
456
int position = 0;
457         for (Iterator JavaDoc iter = list.iterator(); iter.hasNext();)
458         {
459             Portlets pane = (Portlets) iter.next();
460             Layout layout = pane.getLayout();
461             layout.setPosition(position++);
462         }
463     }
464
465     /** Move a component up within the pane
466      * This method expects the following parameters
467      * - paneid: the id a the pane to modify within the current profile
468      * - position: move the component which occupies this position
469      */

470     public void doUp(RunData data, Context context) throws Exception JavaDoc
471     {
472         doMove(data,context,true);
473     }
474
475     /** Move a component down within the pane
476      * This method expects the following parameters
477      * - paneid: the id a the pane to modify within the current profile
478      * - position: move the component which occupies this position
479      */

480     public void doDown(RunData data, Context context) throws Exception JavaDoc
481     {
482         doMove(data,context,false);
483     }
484
485     /** Move a component within the pane
486      * This method expects the following parameters
487      * - paneid: the id a the pane to modify within the current profile
488      * - position: move the component which occupies this position
489      * The moveUp boolean determines the direction of the move
490      */

491     public void doMove(RunData data, Context context, boolean moveUp) throws Exception JavaDoc
492     {
493         JetspeedRunData jdata = (JetspeedRunData)data;
494         PortletSet customizedSet = (PortletSet)jdata.getCustomized();
495         int position = data.getParameters().getInt("position",-1);
496         Profile profile = jdata.getCustomizedProfile();
497
498         // ADDED for WML
499
//boolean isWML = (profile.getMediaType().equalsIgnoreCase("wml"));
500

501
502         if (customizedSet == null) return;
503
504         if (position > -1)
505         {
506             int target = -1;
507
508             Portlets set = profile.getDocument()
509                                   .getPortletsById(customizedSet.getID());
510             Layout targetLayout = null;
511             Layout baseLayout = null;
512
513             if (set != null)
514             {
515                 // check if we can possibly move as requested and calculate
516
// target position
517
if ( moveUp )
518                 {
519                     if ( (position >= set.getPortletsCount())
520                          && (position >= set.getEntryCount()) ) return;
521                     target = position + 1;
522                 }
523                 else
524                 {
525                     if (position ==0) return;
526                     target = position - 1;
527                 }
528
529                 // first find objects at explicit portlets position
530
for(int i=0; i < set.getPortletsCount(); i++)
531                 {
532                     if ((targetLayout!=null) && (baseLayout!=null)) break;
533
534                     Portlets p = set.getPortlets(i);
535                     Layout layout = p.getLayout();
536                     if ((layout!=null)&&(layout.getPosition()!=-1))
537                     {
538                         int lpos = (int)layout.getPosition();
539                         if ((baseLayout == null) && (lpos==position))
540                         {
541                             baseLayout = layout;
542                         }
543
544                         if ((targetLayout == null) && (lpos==target))
545                         {
546                             targetLayout = layout;
547                         }
548                     }
549                 }
550
551                 // try explicit entry position
552
for(int i=0; i < set.getEntryCount(); i++)
553                 {
554                     if ((targetLayout!=null) && (baseLayout!=null)) break;
555
556                     Entry p = set.getEntry(i);
557                     Layout layout = p.getLayout();
558                     if ((layout!=null)&&(layout.getPosition()!=-1))
559                     {
560                         int lpos = (int)layout.getPosition();
561                         if ((baseLayout == null) && (lpos==position))
562                         {
563                             baseLayout = layout;
564                         }
565
566                         if ((targetLayout == null) && (lpos==target))
567                         {
568                             targetLayout = layout;
569                         }
570                     }
571                 }
572
573                 //else use implicit position
574
if (baseLayout == null)
575                 {
576                     if (position < set.getPortletsCount())
577                     {
578                         Portlets p = set.getPortlets(position);
579                         if (p.getLayout()==null)
580                         {
581                             p.setLayout(new PsmlLayout());
582                         }
583                         baseLayout=p.getLayout();
584                     }
585
586                     if (position < set.getEntryCount())
587                     {
588                         Entry p = set.getEntry(position);
589                         if (p.getLayout()==null)
590                         {
591                             p.setLayout(new PsmlLayout());
592                         }
593                         baseLayout=p.getLayout();
594                     }
595                 }
596
597                 if (targetLayout == null)
598                 {
599                     if (target < set.getPortletsCount())
600                     {
601                         Portlets p = set.getPortlets(target);
602                         if (p.getLayout()==null)
603                         {
604                             p.setLayout(new PsmlLayout());
605                         }
606                         targetLayout=p.getLayout();
607                     }
608
609                     if (target < set.getEntryCount())
610                     {
611                         Entry p = set.getEntry(target);
612                         if (p.getLayout()==null)
613                         {
614                             p.setLayout(new PsmlLayout());
615                         }
616                         targetLayout=p.getLayout();
617                     }
618                 }
619
620                 //we should now have found both baseLayout and targetLayout, swap
621
//their positions using explicit positioning
622

623                 if ((baseLayout == null) || (targetLayout == null)) return;
624
625                 baseLayout.setPosition(target);
626                 targetLayout.setPosition(position);
627             }
628         }
629
630
631     // MODIFIED: Save changes for wml profiles
632
//if (isWML)
633
// doSave(data, null);
634
}
635 }
636
Popular Tags