1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.components.portletentity;
18
19 import java.io.IOException;
20 import java.security.Principal;
21 import java.util.Arrays;
22 import java.util.HashMap;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.ArrayList;
26 import java.util.Locale;
27 import java.util.Map;
28 import java.util.Set;
29 import java.util.prefs.BackingStoreException;
30 import java.util.prefs.Preferences;
31
32 import javax.portlet.PortletMode;
33
34 import org.apache.jetspeed.JetspeedActions;
35 import org.apache.jetspeed.aggregator.RenderTrackable;
36 import org.apache.jetspeed.components.persistence.store.PersistenceStore;
37 import org.apache.jetspeed.components.persistence.store.PersistenceStoreRuntimeExcpetion;
38 import org.apache.jetspeed.components.persistence.store.RemovalAware;
39 import org.apache.jetspeed.components.portletregistry.PortletRegistry;
40 import org.apache.jetspeed.om.common.portlet.MutablePortletApplication;
41 import org.apache.jetspeed.om.common.portlet.MutablePortletEntity;
42 import org.apache.jetspeed.om.common.portlet.PortletDefinitionComposite;
43 import org.apache.jetspeed.om.common.portlet.PrincipalAware;
44 import org.apache.jetspeed.om.page.Fragment;
45 import org.apache.jetspeed.om.portlet.impl.FragmentPortletDefinition;
46 import org.apache.jetspeed.om.preference.FragmentPreference;
47 import org.apache.jetspeed.om.preference.impl.PrefsPreference;
48 import org.apache.jetspeed.om.preference.impl.PrefsPreferenceSetImpl;
49 import org.apache.jetspeed.om.window.impl.PortletWindowListImpl;
50 import org.apache.jetspeed.page.PageManager;
51 import org.apache.jetspeed.request.RequestContext;
52 import org.apache.jetspeed.request.RequestContextComponent;
53 import org.apache.jetspeed.util.JetspeedObjectID;
54 import org.apache.pluto.om.common.Description;
55 import org.apache.pluto.om.common.ObjectID;
56 import org.apache.pluto.om.common.Preference;
57 import org.apache.pluto.om.common.PreferenceSet;
58 import org.apache.pluto.om.entity.PortletApplicationEntity;
59 import org.apache.pluto.om.portlet.PortletDefinition;
60 import org.apache.pluto.om.window.PortletWindow;
61 import org.apache.pluto.om.window.PortletWindowList;
62 import org.apache.pluto.util.StringUtils;
63
64 /***
65 * Portlet Entity default implementation.
66 *
67 * @author <a href="mailto:taylor@apache.org">David Sean Taylor </a>
68 * @author <a href="mailto:weaver@apache.org">Scott T. Weaver </a>
69 * @version $Id: PortletEntityImpl.java,v 1.9 2005/04/29 13:59:08 weaver Exp $
70 */
71 public class PortletEntityImpl implements MutablePortletEntity, PrincipalAware, RemovalAware, RenderTrackable
72 {
73 private long oid;
74 private JetspeedObjectID id;
75 protected static PortletEntityAccessComponent pac;
76 protected static PortletRegistry registry;
77 protected static RequestContextComponent rcc;
78 protected static PageManager pm;
79
80 protected PrefsPreferenceSetImpl pagePreferenceSet;
81 protected Map perPrincipalPrefs = new HashMap();
82 protected Map originalValues;
83 private PortletApplicationEntity applicationEntity = null;
84 private PortletWindowList portletWindows = new PortletWindowListImpl();
85 private PortletDefinitionComposite portletDefinition = null;
86 protected String portletName;
87 protected String appName;
88 private boolean dirty = false;
89 private Fragment fragment;
90 private ThreadLocal fragmentPortletDefinition = new ThreadLocal();
91
92 protected transient int timeoutCount = 0;
93 protected transient long expiration = 0;
94
95 public PortletEntityImpl(Fragment fragment)
96 {
97 setFragment(fragment);
98 }
99
100 public PortletEntityImpl()
101 {
102 super();
103 }
104
105 public static final String NO_PRINCIPAL = "no-principal";
106 public static final String ENTITY_DEFAULT_PRINCIPAL = "entity-default";
107
108 public ObjectID getId()
109 {
110 return id;
111 }
112
113 public long getOid()
114 {
115 return oid;
116 }
117
118 public void setId( String id )
119 {
120 this.id = JetspeedObjectID.createFromString(id);
121 }
122
123 /***
124 *
125 * <p>
126 * getPreferenceSet
127 * </p>
128 *
129 * @see org.apache.pluto.om.entity.PortletEntity#getPreferenceSet()
130 * @return
131 */
132 public PreferenceSet getPreferenceSet()
133 {
134 if (isEditDefaultsMode())
135 {
136 return getPreferenceSetFromPage();
137 }
138 else
139 {
140 Principal currentUser = getPrincipal();
141 return getPreferenceSet(currentUser);
142 }
143 }
144
145 public PreferenceSet getPreferenceSet(Principal principal)
146 {
147 PrefsPreferenceSetImpl preferenceSet = (PrefsPreferenceSetImpl) perPrincipalPrefs.get(principal);
148 try
149 {
150 if (preferenceSet == null || !dirty)
151 {
152 String prefNodePath = MutablePortletEntity.PORTLET_ENTITY_ROOT + "/" + getId() +"/"+ principal.getName() +"/"
153 + PrefsPreference.PORTLET_PREFERENCES_ROOT;
154 Preferences prefNode = Preferences.userRoot().node(prefNodePath);
155 preferenceSet = new PrefsPreferenceSetImpl(prefNode);
156 perPrincipalPrefs.put(principal, preferenceSet);
157 if (pac.isMergeSharedPreferences())
158 {
159 mergePreferencesSet(preferenceSet);
160 }
161 backupValues(preferenceSet);
162 dirty = true;
163 }
164 }
165 catch (BackingStoreException e)
166 {
167 String msg = "Preference backing store failed: " + e.toString();
168 IllegalStateException ise = new IllegalStateException(msg);
169 ise.initCause(e);
170 throw ise;
171 }
172 return preferenceSet;
173 }
174
175 private PreferenceSet getPreferenceSetFromPage()
176 {
177 PrefsPreferenceSetImpl preferenceSet = this.pagePreferenceSet;
178
179 try
180 {
181 if (preferenceSet == null || !dirty)
182 {
183 String prefNodePath = MutablePortletEntity.PORTLET_ENTITY_ROOT + "/" +
184 getId() +"/"+ PrefsPreference.PORTLET_PREFERENCES_ROOT;
185
186 Preferences prefNode = Preferences.systemRoot().node(prefNodePath);
187 preferenceSet = new PrefsPreferenceSetImpl(prefNode);
188 this.pagePreferenceSet = preferenceSet;
189
190 List fragmentPreferences = this.fragment.getPreferences();
191
192 if (fragmentPreferences != null)
193 {
194 for (Iterator it = fragmentPreferences.iterator(); it.hasNext(); )
195 {
196 FragmentPreference preference = (FragmentPreference) it.next();
197 List preferenceValues = preference.getValueList();
198 preferenceSet.add(preference.getName(), preferenceValues);
199 }
200 }
201
202 backupValues(preferenceSet);
203 dirty = true;
204 }
205 }
206 catch (BackingStoreException e)
207 {
208 String msg = "Preference backing store failed: " + e.toString();
209 IllegalStateException ise = new IllegalStateException(msg);
210 ise.initCause(e);
211 throw ise;
212 }
213 return preferenceSet;
214 }
215
216 private void mergePreferencesSet(PrefsPreferenceSetImpl userPrefSet)
217 throws BackingStoreException
218 {
219 String sharedNodePath = MutablePortletEntity.PORTLET_ENTITY_ROOT + "/" +
220 getId() +"/"+ NO_PRINCIPAL +"/" +
221 PrefsPreference.PORTLET_PREFERENCES_ROOT;
222 Preferences sharedNode = Preferences.userRoot().node(sharedNodePath);
223 if (sharedNode == null)
224 return;
225 PrefsPreferenceSetImpl sharedSet = new PrefsPreferenceSetImpl(sharedNode);
226 if (sharedSet.size() == 0)
227 return;
228 Set names = userPrefSet.getNames();
229 Iterator sharedPrefs = sharedSet.iterator();
230 int index = 0;
231 while (sharedPrefs.hasNext())
232 {
233 PrefsPreference sharedPref = (PrefsPreference) sharedPrefs.next();
234
235 List prefs = Arrays.asList(sharedPref.getValueArray());
236 userPrefSet.add(sharedPref.getName(), prefs);
237 index++;
238 }
239 }
240
241 /***
242 * <p>
243 * backupValues
244 * </p>
245 *
246 *
247 */
248 protected void backupValues( PreferenceSet preferenceSet )
249 {
250 originalValues = new HashMap();
251 Iterator itr = preferenceSet.iterator();
252 while (itr.hasNext())
253 {
254 PrefsPreference pref = (PrefsPreference) itr.next();
255
256 String[] currentValues = pref.getValueArray();
257 String[] backUp = new String[currentValues.length];
258 System.arraycopy(currentValues, 0, backUp, 0, currentValues.length);
259 originalValues.put(pref.getName(), backUp);
260
261 }
262 }
263
264 public PortletDefinition getPortletDefinition()
265 {
266
267
268
269
270
271 if(this.portletDefinition == null)
272 {
273 PortletDefinition pd = registry.getPortletDefinitionByIdentifier(getPortletUniqueName());
274 if ( pd != null )
275 {
276
277
278 setPortletDefinition(pd);
279 }
280 else
281 {
282 return null;
283 }
284 }
285
286
287 PortletDefinition fpd = (PortletDefinition)fragmentPortletDefinition.get();
288 if (fpd == null)
289 {
290 fpd = new FragmentPortletDefinition(this.portletDefinition, fragment);
291 fragmentPortletDefinition.set(fpd);
292 }
293 return fpd;
294 }
295
296 public PortletApplicationEntity getPortletApplicationEntity()
297 {
298 return applicationEntity;
299 }
300
301 public PortletWindowList getPortletWindowList()
302 {
303 return portletWindows;
304 }
305
306 /***
307 *
308 * <p>
309 * store
310 * </p>
311 *
312 */
313 public void store() throws IOException
314 {
315 if (isEditDefaultsMode())
316 {
317 storeToPage();
318 }
319 else
320 {
321 Principal currentUser = getPrincipal();
322 store(currentUser);
323 }
324 }
325
326 public void store(Principal principal) throws IOException
327 {
328 if (pac == null)
329 {
330 throw new IllegalStateException("You must call PortletEntityImpl.setPorteltEntityDao() before "
331 + "invoking PortletEntityImpl.store().");
332 }
333
334 PreferenceSet preferenceSet = (PreferenceSet)perPrincipalPrefs.get(principal);
335 pac.storePreferenceSet(preferenceSet, this);
336 dirty = false;
337 if (preferenceSet != null)
338 {
339 backupValues(preferenceSet);
340 }
341 }
342
343 private void storeToPage() throws IOException
344 {
345 if (pm == null)
346 {
347 throw new IllegalStateException("You must set pageManager before "
348 + "invoking PortletEntityImpl.store().");
349 }
350
351 PreferenceSet preferenceSet = this.pagePreferenceSet;
352 List preferences = new ArrayList();
353
354 for (Iterator it = preferenceSet.iterator(); it.hasNext(); )
355 {
356 Preference pref = (Preference) it.next();
357
358 FragmentPreference preference = pm.newFragmentPreference();
359 preference.setName(pref.getName());
360 List preferenceValues = new ArrayList();
361
362 for (Iterator iterVals = pref.getValues(); iterVals.hasNext(); )
363 {
364 preferenceValues.add(iterVals.next());
365 }
366
367 preference.setValueList(preferenceValues);
368 preferences.add(preference);
369 }
370
371 this.fragment.setPreferences(preferences);
372
373 try
374 {
375 pm.updatePage(rcc.getRequestContext().getPage());
376 }
377 catch (Exception e)
378 {
379 }
380
381 dirty = false;
382 if (preferenceSet != null)
383 {
384 backupValues(preferenceSet);
385 }
386 }
387
388 /***
389 *
390 * <p>
391 * reset
392 * </p>
393 *
394 */
395
396 public void reset() throws IOException
397 {
398 PrefsPreferenceSetImpl preferenceSet = (PrefsPreferenceSetImpl) perPrincipalPrefs.get(getPrincipal());
399 try
400 {
401 if (originalValues != null && preferenceSet != null)
402 {
403 Iterator prefs = preferenceSet.iterator();
404
405 while (prefs.hasNext())
406 {
407 PrefsPreference pref = (PrefsPreference) prefs.next();
408 if (originalValues.containsKey(pref.getName()))
409 {
410 pref.setValues((String[]) originalValues.get(pref.getName()));
411 }
412 else
413 {
414 preferenceSet.remove(pref);
415 }
416 preferenceSet.flush();
417 }
418
419 Iterator keys = originalValues.keySet().iterator();
420 while (keys.hasNext())
421 {
422 String key = (String) keys.next();
423 if (preferenceSet.get(key) == null)
424 {
425 preferenceSet.add(key, Arrays.asList((String[]) originalValues.get(key)));
426 }
427 }
428 }
429 dirty = false;
430 backupValues(preferenceSet);
431 }
432 catch (BackingStoreException e)
433 {
434 String msg = "Preference backing store failed: " + e.toString();
435 IOException ioe = new IOException(msg);
436 ioe.initCause(e);
437 throw ioe;
438 }
439
440 }
441
442
443
444 public String toString()
445 {
446 return toString(0);
447 }
448
449 public String toString( int indent )
450 {
451 StringBuffer buffer = new StringBuffer(1000);
452 StringUtils.newLine(buffer, indent);
453 buffer.append(getClass().toString());
454 buffer.append(":");
455 StringUtils.newLine(buffer, indent);
456 buffer.append("{");
457 StringUtils.newLine(buffer, indent);
458 buffer.append("id='");
459 buffer.append(oid);
460 buffer.append("'");
461 StringUtils.newLine(buffer, indent);
462 buffer.append("definition-id='");
463 if(portletDefinition != null)
464 {
465 buffer.append(portletDefinition.getId().toString());
466 }
467 else
468 {
469 buffer.append("null");
470 }
471 buffer.append("'");
472
473 StringUtils.newLine(buffer, indent);
474
475
476 StringUtils.newLine(buffer, indent);
477 buffer.append("}");
478 return buffer.toString();
479 }
480
481 /***
482 * @see org.apache.pluto.om.entity.PortletEntity#getDescription(java.util.Locale)
483 */
484 public Description getDescription( Locale arg0 )
485 {
486 return portletDefinition.getDescription(arg0);
487 }
488
489 /***
490 * <p>
491 * setPortletDefinition
492 * </p>
493 *
494 * @param composite
495 *
496 */
497 public void setPortletDefinition( PortletDefinition composite )
498 {
499 if(composite != null)
500 {
501 portletDefinition = (PortletDefinitionComposite) composite;
502
503 fragmentPortletDefinition.set(null);
504 this.appName = ((MutablePortletApplication)portletDefinition.getPortletApplicationDefinition()).getName();
505 this.portletName = portletDefinition.getName();
506 }
507 else
508 {
509 throw new IllegalArgumentException("Cannot pass a null PortletDefinition to a PortletEntity.");
510 }
511 }
512
513 /***
514 * @return Returns the principal.
515 */
516 public Principal getPrincipal()
517 {
518 if (rcc == null)
519 {
520 return new PortletEntityUserPrincipal(NO_PRINCIPAL);
521 }
522 RequestContext rc = rcc.getRequestContext();
523 Principal principal = rc.getUserPrincipal();
524 if (principal == null)
525 {
526 principal = new PortletEntityUserPrincipal(NO_PRINCIPAL);
527 }
528 return principal;
529 }
530
531 class PortletEntityUserPrincipal implements Principal
532 {
533 String name;
534
535 protected PortletEntityUserPrincipal( String name )
536 {
537 this.name = name;
538 }
539
540 /***
541 * <p>
542 * getName
543 * </p>
544 *
545 * @see java.security.Principal#getName()
546 * @return
547 */
548 public String getName()
549 {
550 return name;
551 }
552
553 /***
554 * <p>
555 * equals
556 * </p>
557 *
558 * @see java.lang.Object#equals(java.lang.Object)
559 * @param obj
560 * @return
561 */
562 public boolean equals( Object obj )
563 {
564 if (obj != null && obj instanceof Principal)
565 {
566 Principal p = (Principal) obj;
567 return name != null && p.getName() != null && name.equals(p.getName());
568 }
569 else
570 {
571 return false;
572 }
573 }
574
575 /***
576 * <p>
577 * hashCode
578 * </p>
579 *
580 * @see java.lang.Object#hashCode()
581 * @return
582 */
583 public int hashCode()
584 {
585 if (name != null)
586 {
587 return (getClass().getName()+ ":" + name).hashCode();
588 }
589 else
590 {
591 return -1;
592 }
593 }
594
595 /***
596 * <p>
597 * toString
598 * </p>
599 *
600 * @see java.lang.Object#toString()
601 * @return
602 */
603 public String toString()
604 {
605 return name;
606 }
607 }
608 /***
609 * <p>
610 * postRemoval
611 * </p>
612 *
613 * @see org.apache.jetspeed.components.persistence.store.RemovalAware#postRemoval(org.apache.jetspeed.components.persistence.store.PersistenceStore)
614 * @param store
615 * @throws {@link org.apache.jetspeed.persistence.store.PersistenceStoreRuntimeExcpetion}
616 * if the removal of the {@link java.util.prefs.Preference} related to this entity fails
617 */
618 public void postRemoval( PersistenceStore store )
619 {
620
621
622 }
623 /***
624 * <p>
625 * preRemoval
626 * </p>
627 * not implemented.
628 *
629 * @see org.apache.jetspeed.components.persistence.store.RemovalAware#preRemoval(org.apache.jetspeed.components.persistence.store.PersistenceStore)
630 * @param store
631 */
632 public void preRemoval( PersistenceStore store )
633 {
634 String rootForEntity = MutablePortletEntity.PORTLET_ENTITY_ROOT + "/" + getId();
635 try
636 {
637 if(Preferences.userRoot().nodeExists(rootForEntity))
638 {
639 Preferences.userRoot().node(rootForEntity).removeNode();
640 }
641 }
642 catch (BackingStoreException e)
643 {
644 throw new PersistenceStoreRuntimeExcpetion(e.toString(), e);
645 }
646
647 }
648 public String getPortletUniqueName()
649 {
650 if(this.appName != null && this.portletName != null)
651 {
652 return this.appName+"::"+this.portletName;
653 }
654 else if(fragment != null)
655 {
656 return fragment.getName();
657 }
658 else
659 {
660 return null;
661 }
662 }
663
664 public void setFragment(Fragment fragment)
665 {
666 this.fragment = fragment;
667
668 fragmentPortletDefinition.set(null);
669 }
670
671 public int getRenderTimeoutCount()
672 {
673 return timeoutCount;
674 }
675
676 public synchronized void incrementRenderTimeoutCount()
677 {
678 timeoutCount++;
679 }
680
681 public synchronized void setExpiration(long expiration)
682 {
683 this.expiration = expiration;
684 }
685
686 public long getExpiration()
687 {
688 return this.expiration;
689 }
690
691 public void success()
692 {
693 timeoutCount = 0;
694 }
695
696 public void setRenderTimeoutCount(int timeoutCount)
697 {
698 this.timeoutCount = timeoutCount;
699 }
700
701 private boolean isEditDefaultsMode()
702 {
703 boolean editDefaultsMode = false;
704
705 PortletWindow curWindow = null;
706
707 if (this.portletWindows != null)
708 {
709 try
710 {
711 curWindow = (PortletWindow) this.portletWindows.iterator().next();
712 }
713 catch (Exception e)
714 {
715 }
716 }
717
718 if (rcc != null)
719 {
720 RequestContext context = rcc.getRequestContext();
721
722 try
723 {
724 PortletMode curMode = context.getPortalURL().getNavigationalState().getMode(curWindow);
725 editDefaultsMode = (JetspeedActions.EDIT_DEFAULTS_MODE.equals(curMode));
726 }
727 catch (Exception e)
728 {
729 }
730 }
731
732 return editDefaultsMode;
733 }
734 }