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