KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jetspeed > modules > actions > portlets > CustomizeAction


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.portlets;
18
19 // Jetspeed Stuff
20
import org.apache.jetspeed.modules.actions.portlets.CustomizeSetAction;
21 import org.apache.jetspeed.portal.Portlet;
22 import org.apache.jetspeed.portal.PortletConfig;
23 import org.apache.jetspeed.portal.PortletException;
24 import org.apache.jetspeed.portal.PortletSkin;
25 import org.apache.jetspeed.portal.portlets.VelocityPortlet;
26 import org.apache.jetspeed.services.persistence.PersistenceManager;
27 import org.apache.jetspeed.services.Registry;
28 import org.apache.jetspeed.services.rundata.JetspeedRunData;
29 import org.apache.jetspeed.om.BaseSecurityReference;
30 import org.apache.jetspeed.om.profile.Entry;
31 import org.apache.jetspeed.om.profile.Profile;
32 import org.apache.jetspeed.om.profile.Skin;
33 import org.apache.jetspeed.om.profile.psml.PsmlSkin;
34 import org.apache.jetspeed.om.SecurityReference;
35 import org.apache.jetspeed.om.registry.PortletEntry;
36 import org.apache.jetspeed.om.registry.Parameter;
37 import org.apache.jetspeed.om.registry.base.BaseParameter;
38 import org.apache.jetspeed.om.security.JetspeedUser;
39 import org.apache.jetspeed.services.JetspeedSecurity;
40 import org.apache.jetspeed.services.PortalToolkit;
41 import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
42 import org.apache.jetspeed.services.logging.JetspeedLogger;
43 import org.apache.jetspeed.services.security.PortalResource;
44 import org.apache.jetspeed.portal.PortletInstance;
45 import org.apache.jetspeed.util.MetaData;
46 import org.apache.jetspeed.services.statemanager.SessionState;
47
48 // Turbine stuff
49
import org.apache.turbine.util.RunData;
50 import org.apache.turbine.modules.ActionLoader;
51
52 // Velocity Stuff
53
import org.apache.velocity.context.Context;
54
55 import java.util.Vector JavaDoc;
56 import java.util.Iterator JavaDoc;
57
58 /**
59  * This action implements the default portlet behavior customizer
60  *
61  * <p>Don't call it from the URL, the Portlet and the Action are automatically
62  * associated through the registry PortletName
63  *
64  * @author <a HREF="mailto:raphael@apache.org">Raphaël Luta</a>
65  */

66 public class CustomizeAction extends VelocityPortletAction
67 {
68
69     public static final String JavaDoc PARAM_NAMESPACE = "_param_";
70
71     /**
72      * Static initialization of the logger for this class
73      */

74     private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(CustomizeAction.class.getName());
75     
76     /**
77      * Subclasses must override this method to provide default behavior
78      * for the portlet action
79      *
80      * <table>
81      * <tr><th>Context </th><th> Description</th></tr>
82      * <!-- --------- ------------------------- -->
83      * <tr><td>action </td><td> Action to use</td></tr>
84      * <tr><td>current_skin </td><td> Current skin for this portlet INSTANCE</td></tr>
85      * <tr><td>params </td><td> List of configurable parameters from the REGISTRY entry.</td></tr>
86      * <tr><td>portlet </td><td> Portlet, not the Portlet Instance!</td></tr>
87      * <tr><td>skins </td><td> List of skins</td></tr>
88      * <tr><td>security </td><td> List of security ref</td></tr>
89      * <tr><td>security_ref </td><td> Current securityRef for this portlet INSTANCE</td></tr>
90      * </table>
91      */

92     protected void buildNormalContext( VelocityPortlet portlet,
93                                        Context context,
94                                        RunData rundata )
95     {
96
97         // generic context stuff
98
context.put("skins", CustomizeSetAction.buildList(rundata, Registry.SKIN));
99         context.put("securitys", CustomizeSetAction.buildList(rundata, Registry.SECURITY));
100
101         // we should first retrieve the portlet to customize
102
Portlet p = ((JetspeedRunData)rundata).getCustomized();
103
104         context.put("action", "portlets.CustomizeAction");
105
106         PortletInstance instance = PersistenceManager.getInstance(p, rundata);
107         context.put("portlet_instance", PersistenceManager.getInstance(p, rundata));
108
109         if (p==null) return;
110
111         // retrieve the portlet parameters
112
PortletEntry entry = (PortletEntry)Registry.getEntry(Registry.PORTLET,p.getName());
113         // save the entry in the session
114
Vector JavaDoc params = new Vector JavaDoc();
115         Iterator JavaDoc i = entry.getParameterNames();
116
117         //System.out.println("==========================================");
118
while(i.hasNext())
119         {
120             String JavaDoc name = (String JavaDoc)i.next();
121             Parameter param = entry.getParameter(name);
122
123             // filter some "system" and hidden parameters
124
if ( (!param.isHidden()) && (name.charAt(0)!='_') )
125             {
126                 // check the user role
127
if (JetspeedSecurity.checkPermission((JetspeedUser)rundata.getUser(), new PortalResource( entry, param), JetspeedSecurity.PERMISSION_CUSTOMIZE))
128                 {
129                     // Implementation of clone() is missing so we have do it "by hand"
130
Parameter clone = new BaseParameter();
131                     clone.setName(param.getName());
132                     clone.setTitle(param.getTitle());
133                     clone.setDescription(param.getDescription());
134                     clone.setType(param.getType());
135                     if (instance.getAttribute(name, null) != null)
136                     {
137                         clone.setValue(instance.getAttribute(name));
138                         //System.out.println("Adding value from instance [" + name + "] = [" + clone.getValue() + "]");
139
}
140                     else if (p.getPortletConfig().getInitParameter(name) != null)
141                     {
142                         clone.setValue(p.getPortletConfig().getInitParameter(name));
143                         //System.out.println("Adding value from init [" + name + "] = [" + clone.getValue() + "]");
144
}
145                     else
146                     {
147                         clone.setValue(param.getValue());
148                         //System.out.println("Adding value from registry [" + name + "] = [" + clone.getValue() + "]");
149
}
150                     params.add(clone);
151                 }
152             }
153         }
154
155         // get the customization state for this page
156
SessionState customizationState = ((JetspeedRunData)rundata).getPageSessionState();
157         customizationState.setAttribute("customize-parameters", params);
158
159         // populate the customizer context
160
context.put("parameters", params);
161         context.put("portlet", p);
162         context.put("customizer", portlet);
163
164         if (p.getPortletConfig().getSecurityRef() != null)
165           context.put("security_ref", p.getPortletConfig().getSecurityRef().getParent());
166         if (p.getPortletConfig().getSkin() != null)
167             context.put("current_skin", p.getPortletConfig().getPortletSkin().getName());
168
169         Profile profile = ((JetspeedRunData)rundata).getCustomizedProfile();
170         String JavaDoc currentTitle = profile.getDocument().getEntryById(p.getID()).getTitle();
171         if (currentTitle == null && p.getPortletConfig().getMetainfo() != null)
172         {
173             currentTitle = p.getPortletConfig().getMetainfo().getTitle();
174         }
175         context.put("current_title", currentTitle);
176
177     }
178
179     /** Clean up the customization state */
180     public void doCancel(RunData rundata, Context context)
181     {
182         ((JetspeedRunData)rundata).setCustomized(null);
183         if (((JetspeedRunData)rundata).getCustomized()==null)
184         {
185             try
186             {
187                 ActionLoader.getInstance().exec( rundata, "controls.EndCustomize" );
188             }
189             catch (Exception JavaDoc e)
190             {
191                 logger.error("Unable to load action controls.EndCustomize ",e);
192             }
193         }
194     }
195
196     /**
197      * Resets the portlet settings to default
198      *
199      * @param rundata
200      * @param context
201      */

202     public void doDefault(RunData rundata, Context context)
203     {
204         // we should first retrieve the portlet to customize and its parameters
205
// definition
206
Portlet p = ((JetspeedRunData) rundata).getCustomized();
207
208         // Update paramaters
209
try
210         {
211             PortletInstance instance = PersistenceManager.getInstance(p, rundata);
212
213             instance.removeAllAttributes();
214
215             try
216             {
217                 ((JetspeedRunData) rundata).getCustomizedProfile().store();
218             }
219             catch (Exception JavaDoc e)
220             {
221                 logger.error("Unable to save profile ",e);
222             }
223
224             //FIXME: this hack is due to the corrupted lifecycle of the portlet in the
225
//current API when caching is activated
226
try
227             {
228                 org.apache.jetspeed.util.PortletSessionState.setPortletConfigChanged(p, rundata);
229                 p.init();
230             }
231             catch (PortletException e)
232             {
233                 logger.error("Customizer failed to reinitialize the portlet "+p.getName(), e);
234             }
235
236             // we're done, make sure clean up the
237
// session
238
doCancel(rundata, context);
239         }
240         catch (Exception JavaDoc e)
241         {
242             logger.error("Exception", e);
243         }
244     }
245
246
247     /** Updates the customized portlet entry */
248     public void doUpdate(RunData rundata, Context context)
249     {
250         // get the customization state for this page
251
SessionState customizationState = ((JetspeedRunData)rundata).getPageSessionState();
252
253         // we should first retrieve the portlet to customize and its parameters
254
// definition
255
Portlet p = ((JetspeedRunData)rundata).getCustomized();
256         Vector JavaDoc params = (Vector JavaDoc) customizationState.getAttribute("customize-parameters");
257         String JavaDoc newSecurityParent = rundata.getParameters().getString("_security_ref");
258         String JavaDoc newSkinName = (String JavaDoc) rundata.getParameters().getString("_skin");
259         String JavaDoc newTitle = (String JavaDoc) rundata.getParameters().getString("current_title");
260
261         boolean changeRequested = ( (params != null) || (newSkinName != null) || (newSecurityParent != null) || (newTitle != null));
262         boolean madePsChange = false;
263         boolean madePcChange = false;
264
265         if ((p==null) || (changeRequested == false ))
266         {
267             doCancel(rundata, context);
268             return;
269         }
270         PortletConfig pc = p.getPortletConfig();
271         Profile profile = ((JetspeedRunData)rundata).getCustomizedProfile();
272         Entry entry = profile.getDocument().getEntryById(p.getID());
273
274         // Only update the security ref if the parent changed
275
if ((newSecurityParent != null))
276         {
277             boolean securityChanged = false;
278             SecurityReference currentSecurityRef = pc.getSecurityRef();
279             if (currentSecurityRef != null)
280             {
281                 securityChanged = (newSecurityParent.equals(currentSecurityRef.getParent()) == false);
282             }
283             else
284             {
285                 securityChanged = (newSecurityParent.trim().length() > 0);
286             }
287             if (securityChanged == true)
288             {
289                 SecurityReference securityRef = null;
290                 if ((newSecurityParent.trim().length() > 0))
291                 {
292                     securityRef = new BaseSecurityReference();
293                     securityRef.setParent( newSecurityParent);
294                 }
295                 // Note: setting the portlet's config may not be a good idea -
296
// it might be used as the Portlet for other PSMLDocument Entries that
297
// have a different idea of security - and the caching of Portlets does
298
// NOT include security -ggolden.
299
pc.setSecurityRef(securityRef);
300                 entry.setSecurityRef(securityRef);
301                 madePcChange = true;
302             }
303         }
304
305         // Only update the skin if the name changed
306
if (newSkinName != null)
307         {
308             boolean skinChanged = false;
309             String JavaDoc currentSkinName = null;
310
311             if (pc.getSkin() != null)
312                 currentSkinName = pc.getPortletSkin().getName();
313
314             if (currentSkinName != null)
315             {
316                 skinChanged = (newSkinName.equals(currentSkinName) == false);
317             }
318             else
319             {
320                 skinChanged = (newSkinName.trim().length() > 0);
321             }
322
323             if (skinChanged == true)
324             {
325                 PortletSkin skin = null;
326                 if ((newSkinName.trim().length() > 0))
327                 {
328                     skin = PortalToolkit.getSkin(newSkinName);
329                     if (skin != null)
330                     {
331                         // Note: setting the portlet's config may not be a good idea -
332
// it might be used as the Portlet for other PSMLDocument Entries that
333
// have a different idea of skin - and the caching of Portlets does
334
// NOT include skin -ggolden.
335
pc.setPortletSkin(skin);
336
337                         Skin psmlSkin = entry.getSkin();
338                         if (psmlSkin == null)
339                         {
340                             entry.setSkin(new PsmlSkin());
341                         }
342                         entry.getSkin().setName(newSkinName);
343                     }
344                     else
345                     {
346                         logger.warn( "Unable to update skin for portlet entry " + entry.getId() + " because skin " + skin + " does not exist.");
347                     }
348                 }
349                 else
350                 {
351                     // Note: setting the portlet's config may not be a good idea -
352
// it might be used as the Portlet for other PSMLDocument Entries that
353
// have a different idea of skin - and the caching of Portlets does
354
// NOT include skin -ggolden.
355
pc.setPortletSkin( null);
356                     entry.setSkin(null);
357                 }
358                 madePcChange = true;
359             }
360         }
361
362         // Only update the title if the title changed
363
if (newTitle != null)
364         {
365             boolean titleChanged = false;
366             String JavaDoc currentTitle = entry.getTitle();
367
368             MetaData md = pc.getMetainfo();
369             if (currentTitle == null && md != null && md.getTitle() != null)
370                 currentTitle = md.getTitle();
371
372             if (currentTitle != null)
373             {
374                 titleChanged = (newTitle.equals(currentTitle) == false);
375             }
376             else
377             {
378                 titleChanged = (newTitle.trim().length() > 0);
379             }
380
381             if (titleChanged == true)
382             {
383
384                 if ((newTitle.trim().length() > 0))
385                 {
386                     // Note: setting the portlet's config may not be a good idea -
387
// it might be used as the Portlet for other PSMLDocument Entries that
388
// have a different idea of title - and the caching of Portlets does
389
// NOT include title -ggolden.
390
if (md == null) {
391                         md = new MetaData();
392                         pc.setMetainfo(md);
393                     }
394                     md.setTitle(newTitle);
395                     entry.setTitle(newTitle);
396                     madePcChange = true;
397                 }
398             }
399         }
400
401         // Update paramaters
402
try
403         {
404             PortletInstance instance = PersistenceManager.getInstance(p, rundata);
405             PortletEntry regEntry = (PortletEntry) Registry.getEntry(Registry.PORTLET, p.getName());
406
407             Iterator JavaDoc i = params.iterator();
408
409             //System.out.println("==========================================");
410
while(i.hasNext())
411             {
412                 Parameter param = (Parameter)i.next();
413                 String JavaDoc name = param.getName();
414                 String JavaDoc newValue = null;
415                 String JavaDoc[] testArray = rundata.getParameters().getStrings(name);
416                 if (testArray != null && testArray.length > 1)
417                 {
418                     newValue = org.apache.jetspeed.util.StringUtils.arrayToString(testArray, ",");
419                 }
420                 else
421                 {
422                     newValue = rundata.getParameters().getString(name);
423                     if (newValue == null)
424                     {
425                         newValue = "";
426                     }
427                 }
428                 String JavaDoc regValue = regEntry.getParameter(name).getValue(); //param.getValue();
429
String JavaDoc psmlValue = instance.getAttribute(name);
430
431                 //System.out.println(name + "= [" + psmlValue + "] in psml");
432
//System.out.println(name + "= [" + regValue + "] in registry");
433

434                 // New value for this parameter exists
435
if (newValue != null)
436                 {
437                     //System.out.println(name + "= [" + newValue + "] in request");
438
// New value differs from registry - record it in psml
439
if (!regValue.equals(newValue) || !psmlValue.equals(newValue))
440                     {
441                         instance.setAttribute(name, newValue);
442                         psmlValue = newValue;
443                         //System.out.println("setting attribute for [" + name + "] to [" + newValue + "]");
444
}
445                     madePsChange = true;
446                 }
447                 // Remove duplicate parameters from psml
448
if (psmlValue != null && psmlValue.equals(regValue))
449                 {
450                     //System.out.println("removing attribute for [" + name + "]");
451
instance.removeAttribute(name);
452                     madePsChange = true;
453                 }
454
455             }
456
457             // save all the changes
458
if ((madePsChange == true) || (madePcChange == true))
459             {
460                 try
461                 {
462                     JetspeedRunData jdata = (JetspeedRunData) rundata;
463                     profile.store();
464                     //FIXME: this hack is due to the corrupted lifecycle of the portlet in the
465
//current API when caching is activated
466
p.init();
467                     org.apache.jetspeed.util.PortletSessionState.setPortletConfigChanged(p, rundata);
468                 }
469                 catch (PortletException e)
470                 {
471                     logger.error("Customizer failed to reinitialize the portlet "+p.getName(), e);
472                 }
473                 catch (Exception JavaDoc e)
474                 {
475                     logger.error("Unable to save profile ",e);
476                 }
477             }
478
479             // we're done, make sure clean up the
480
// session
481
doCancel(rundata, context);
482         }
483         catch (Exception JavaDoc e)
484         {
485             logger.error("Exception", e);
486         }
487     }
488 }
489
Popular Tags