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.components.portletentity;
18  
19  import java.io.IOException;
20  import java.rmi.server.UID;
21  import java.util.Collection;
22  import java.util.Iterator;
23  import java.util.prefs.BackingStoreException;
24  
25  import org.apache.jetspeed.components.portletregistry.PortletRegistry;
26  import org.apache.jetspeed.container.window.PortletWindowAccessor;
27  import org.apache.jetspeed.om.common.portlet.MutablePortletApplication;
28  import org.apache.jetspeed.om.common.portlet.MutablePortletEntity;
29  import org.apache.jetspeed.om.common.portlet.PortletDefinitionComposite;
30  import org.apache.jetspeed.om.page.ContentFragment;
31  import org.apache.jetspeed.om.page.Fragment;
32  import org.apache.jetspeed.om.preference.impl.PrefsPreferenceSetImpl;
33  import org.apache.jetspeed.page.PageManager;
34  import org.apache.jetspeed.request.RequestContextComponent;
35  import org.apache.jetspeed.util.JetspeedObjectID;
36  import org.apache.ojb.broker.query.Criteria;
37  import org.apache.ojb.broker.query.Query;
38  import org.apache.ojb.broker.query.QueryFactory;
39  import org.apache.pluto.om.common.ObjectID;
40  import org.apache.pluto.om.common.PreferenceSet;
41  import org.apache.pluto.om.entity.PortletEntity;
42  import org.apache.pluto.om.entity.PortletEntityCtrl;
43  import org.apache.pluto.om.portlet.PortletDefinition;
44  import org.apache.pluto.om.window.PortletWindow;
45  import org.springframework.orm.ojb.support.PersistenceBrokerDaoSupport;
46  
47  /***
48   * <p>
49   * PersistenceStorePortletEntityAccess
50   * </p>
51   * <p>
52   * 
53   * </p>
54   * 
55   * @author <a href="mailto:weaver@apache.org">Scott T. Weaver </a>
56   * @version $Id: PersistenceBrokerPortletEntityAccess.java,v 1.5 2005/04/29 13:59:08 weaver Exp $
57   *  
58   */
59  public class PersistenceBrokerPortletEntityAccess extends PersistenceBrokerDaoSupport
60          implements
61              PortletEntityAccessComponent
62  {
63      private PortletRegistry registry;
64      private PortletWindowAccessor windowAccessor = null;
65      
66      // 2006-08-22: by default, do not merge preferences from the shared preferences area 
67      // up until this point, all preferences were shared. With JS2-449, preferences are now
68      // stored 'per user'. The username is stored in the preferences FULL_PATH
69      // To turn on mergeSharedPreferences configure this property to true 
70      // in your Spring configuration
71      boolean mergeSharedPreferences = false;
72      
73      /***
74       * 
75       * @param registry
76       */
77      public PersistenceBrokerPortletEntityAccess( PortletRegistry registry )
78      {
79          super();
80          this.registry = registry;        
81          PortletEntityImpl.registry = registry;
82      }
83  
84      public PersistenceBrokerPortletEntityAccess(PortletRegistry registry, RequestContextComponent rcc)
85      {
86          super();
87          this.registry = registry;        
88          PortletEntityImpl.registry = registry;
89          PortletEntityImpl.rcc = rcc;
90      }
91  
92      public PersistenceBrokerPortletEntityAccess(PortletRegistry registry, RequestContextComponent rcc, PageManager pageManager)
93      {
94          super();
95          this.registry = registry;        
96          PortletEntityImpl.registry = registry;
97          PortletEntityImpl.rcc = rcc;
98          PortletEntityImpl.pm = pageManager;
99      }
100     
101     public PersistenceBrokerPortletEntityAccess(PortletRegistry registry, RequestContextComponent rcc, PageManager pageManager, boolean mergeSharedPreferences)
102     {
103         super();
104         this.registry = registry;        
105         PortletEntityImpl.registry = registry;
106         PortletEntityImpl.rcc = rcc;
107         PortletEntityImpl.pm = pageManager;
108         this.mergeSharedPreferences = mergeSharedPreferences;
109     }
110     
111     public void setEntityAccessProxy(PortletEntityAccessComponent proxy)
112     {
113         PortletEntityImpl.pac = proxy;
114     }
115     
116     public void setPageManager(PageManager pageManager)
117     {
118         PortletEntityImpl.pm = pageManager;
119     }
120     
121     /***
122      * 
123      * <p>
124      * generateEntityFromFragment
125      * </p>
126      * 
127      * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#generateEntityFromFragment(org.apache.jetspeed.om.page.Fragment,
128      *      java.lang.String)
129      * @param fragment
130      * @param principal
131      * @return @throws
132      *         PortletEntityNotGeneratedException
133      */
134     public MutablePortletEntity generateEntityFromFragment( ContentFragment fragment, String principal )
135             throws PortletEntityNotGeneratedException
136     {
137         PortletDefinition pd = registry.getPortletDefinitionByUniqueName(fragment.getName());
138         ObjectID entityKey = generateEntityKey(fragment, principal);
139         MutablePortletEntity portletEntity = null;
140 
141         if (pd != null)
142         {
143             portletEntity = newPortletEntityInstance(pd);
144             if (portletEntity == null)
145             {
146                 throw new PortletEntityNotGeneratedException("Failed to create Portlet Entity for "
147                         + fragment.getName());
148             }
149         }
150         else
151         {
152             String msg = "Failed to retrieve Portlet Definition for " + fragment.getName();
153             logger.warn(msg);
154             portletEntity = new PortletEntityImpl(fragment);
155             fragment.overrideRenderedContent(msg);
156         }
157 
158         portletEntity.setId(entityKey.toString());
159 
160         return portletEntity;
161     }
162 
163     /***
164      * 
165      * <p>
166      * generateEntityFromFragment
167      * </p>
168      * 
169      * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#generateEntityFromFragment(org.apache.jetspeed.om.page.Fragment)
170      * @param fragment
171      * @return @throws
172      *         PortletEntityNotGeneratedException
173      */
174     public MutablePortletEntity generateEntityFromFragment( ContentFragment fragment )
175             throws PortletEntityNotGeneratedException
176     {
177         return generateEntityFromFragment(fragment, null);
178     }
179 
180     /***
181      * 
182      * <p>
183      * generateEntityKey
184      * </p>
185      * 
186      * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#generateEntityKey(org.apache.jetspeed.om.page.Fragment,
187      *      java.lang.String)
188      * @param fragment
189      * @param principal
190      * @return
191      */
192     public ObjectID generateEntityKey( Fragment fragment, String principal )
193     {
194         StringBuffer key = new StringBuffer();
195         if (principal != null && principal.length() > 0)
196         {
197             key.append(principal);
198             key.append("/");
199         }
200         key.append(fragment.getId());
201         return JetspeedObjectID.createFromString(key.toString());
202     }
203 
204     /***
205      * 
206      * <p>
207      * getPortletEntities
208      * </p>
209      * 
210      * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#getPortletEntities(org.apache.pluto.om.portlet.PortletDefinition)
211      * @param portletDefinition
212      * @return
213      */
214     public Collection getPortletEntities( PortletDefinition portletDefinition )
215     {
216         Criteria c = new Criteria();
217         String appName = ((MutablePortletApplication) portletDefinition.getPortletApplicationDefinition()).getName();
218         String portletName = portletDefinition.getName();
219         c.addEqualTo("appName", appName);
220         c.addEqualTo("portletName", portletName);
221 
222         return getPersistenceBrokerTemplate().getCollectionByQuery(QueryFactory.newQuery(PortletEntityImpl.class, c));
223     }
224     
225     public Collection getPortletEntities( String portletUniqueName )
226     {        
227         String[] split = portletUniqueName.split("::");
228         String appName = split[0];
229         String portletName = split[1];
230         Criteria c = new Criteria();
231         c.addEqualTo("appName", appName);
232         c.addEqualTo("portletName", portletName);
233 
234         return getPersistenceBrokerTemplate().getCollectionByQuery(QueryFactory.newQuery(PortletEntityImpl.class, c));
235     }
236 
237     public MutablePortletEntity getPortletEntity( ObjectID id )
238     {
239         try
240         {
241             return getPortletEntity(id, null);
242         }
243         // This exception is only thrown if a Fragment has been passed into the
244         // getPortletEntity() method.  This should never happen.
245         catch (PortletEntityNotStoredException e)
246         {
247             IllegalStateException ise = new IllegalStateException("Unexepected error while retrieving portlet entity "+id);
248             ise.initCause(e);
249             throw ise;
250         }
251     }
252 
253     protected MutablePortletEntity getPortletEntity(ObjectID id, ContentFragment fragment) throws PortletEntityNotStoredException
254     {
255         Criteria c = new Criteria();
256         c.addEqualTo("id", id.toString());
257         Query q = QueryFactory.newQuery(PortletEntityImpl.class, c);
258         MutablePortletEntity portletEntity = (MutablePortletEntity) getPersistenceBrokerTemplate().getObjectByQuery(q);
259         if (portletEntity == null)
260         {
261             return null;
262         }
263         else
264         {
265             String portletUniqueName = portletEntity.getPortletUniqueName();
266             PortletDefinitionComposite parentPortletDef = registry.getPortletDefinitionByUniqueName(portletUniqueName);
267             if(parentPortletDef != null)
268             {
269                 //Indication that the fragment has changed the portlet it references.
270                 if(fragment != null && !portletUniqueName.equals(fragment.getName()))
271                 {
272                     parentPortletDef = registry.getPortletDefinitionByUniqueName(fragment.getName());
273                     ((PortletEntityCtrl)portletEntity).setPortletDefinition(parentPortletDef);
274                     storePortletEntity(portletEntity);
275                 }
276                 else
277                 {
278                     ((PortletEntityCtrl)portletEntity).setPortletDefinition(parentPortletDef);
279                 }
280             }
281             else if(fragment != null && parentPortletDef == null)
282             {
283                 // If we have no porlet definition but have a fragment, we see if the
284                 // unique name has changed and access the portlet definition
285                 // using that unique name.
286                 parentPortletDef = registry.getPortletDefinitionByUniqueName(fragment.getName());
287                 if ( parentPortletDef != null)
288                 {
289                     ((PortletEntityCtrl)portletEntity).setPortletDefinition(parentPortletDef);
290                     storePortletEntity(portletEntity);
291                 }
292             }
293             
294             if(parentPortletDef == null)
295             {
296                 final String msg = "Portlet "+portletUniqueName+" not found";
297                 String content = fragment.getOverriddenContent();
298                 if (content == null || !content.equals(msg))
299                 {
300                     fragment.overrideRenderedContent(msg);
301                     logger.error(msg);
302                 }
303             }           
304             
305             return portletEntity;                
306         }
307     }
308 
309     public MutablePortletEntity getPortletEntity( String id )
310     {
311         ObjectID oid = JetspeedObjectID.createFromString(id);
312         return getPortletEntity(oid);
313     }
314 
315     public MutablePortletEntity getPortletEntityForFragment( ContentFragment fragment, String principal ) throws PortletEntityNotStoredException
316     {
317         return getPortletEntity(generateEntityKey(fragment, principal), fragment);
318     }
319 
320     public MutablePortletEntity getPortletEntityForFragment( ContentFragment fragment ) throws PortletEntityNotStoredException
321     {
322         return getPortletEntity(generateEntityKey(fragment, null), fragment);
323     }
324 
325     public MutablePortletEntity newPortletEntityInstance( PortletDefinition portletDefinition )
326     {
327         return newPortletEntityInstance(portletDefinition, autoGenerateID(portletDefinition));
328     }
329 
330     public MutablePortletEntity newPortletEntityInstance(PortletDefinition portletDefinition, String id)
331     {
332         PortletEntityImpl portletEntity = new PortletEntityImpl();
333         portletEntity.setPortletDefinition(portletDefinition);
334         portletEntity.setId(id);
335         return portletEntity;
336     }
337     
338     
339     public void removeFromCache(PortletEntity entity)
340     {
341         if (windowAccessor != null)
342         {
343             String windowId = entity.getId().toString();
344             PortletWindow window = windowAccessor.getPortletWindow(windowId);
345             if (window != null)
346             {
347                 windowAccessor.removeWindow(window);
348             }
349         }
350     }
351 
352     public void removePortletEntities( PortletDefinition portletDefinition ) throws PortletEntityNotDeletedException
353     {
354         Iterator entities = getPortletEntities(portletDefinition).iterator();
355         while (entities.hasNext())
356         {
357             PortletEntity entity = (PortletEntity) entities.next();
358             removePortletEntity(entity);
359         }
360 
361     }
362 
363     public void removePortletEntity( PortletEntity portletEntity ) throws PortletEntityNotDeletedException
364     {
365         PreferenceSet prefsSet  = portletEntity.getPreferenceSet();
366         getPersistenceBrokerTemplate().delete(portletEntity);
367         
368         if(prefsSet instanceof PrefsPreferenceSetImpl)
369         {
370             try
371             {
372                 ((PrefsPreferenceSetImpl)prefsSet).clear();
373                 removeFromCache(portletEntity);
374             }
375             catch (BackingStoreException e)
376             {
377                 throw new PortletEntityNotDeletedException("Failed to remove preferences for portlet entity "+portletEntity.getId()+".  "+e.getMessage(), e);
378             }
379         }
380     }
381 
382     /***
383      * <p>
384      * updatePortletEntity
385      * </p>
386      *
387      * Updates portlet definition associated with the portlet
388      * entity to match the fragment configuration 
389      *
390      * @param portletEntity
391 	 * @param fragment
392 	 * @throws PortletEntityNotStoredException 
393      */
394     public void updatePortletEntity(PortletEntity portletEntity, ContentFragment fragment) throws PortletEntityNotStoredException
395     {
396         // validate portlet entity id
397         if (!fragment.getId().equals(portletEntity.getId().toString()))
398         {
399             throw new PortletEntityNotStoredException("Fragment and PortletEntity ids do not match, update skipped: " + fragment.getId() + " != " + portletEntity.getId() );
400         }
401 
402         // update portlet definition from fragment
403         PortletDefinition pd = registry.getPortletDefinitionByUniqueName(fragment.getName());
404         if (pd != null)
405         {
406             ((PortletEntityImpl)portletEntity).setPortletDefinition(pd);
407         }
408         else
409         {
410             throw new PortletEntityNotStoredException("Fragment PortletDefinition not found: " + fragment.getName() );
411         }
412     }
413 
414     public void storePortletEntity( PortletEntity portletEntity ) throws PortletEntityNotStoredException
415     {
416         try
417         {
418             ((PortletEntityCtrl) portletEntity).store();
419         }
420         catch (Exception e)
421         {
422             throw new PortletEntityNotStoredException(e.toString(), e);
423         }
424 
425     }
426 
427     /***
428      * <p>
429      * storePreferenceSet
430      * </p>
431      * 
432      * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#storePreferenceSet(org.apache.pluto.om.common.PreferenceSet)
433      * @param prefSet
434      * @throws IOException
435      */
436     public void storePreferenceSet( PreferenceSet prefSet, PortletEntity entity ) throws IOException
437     {
438         try
439         {            
440             getPersistenceBrokerTemplate().store(entity);
441             if (prefSet != null && prefSet instanceof PrefsPreferenceSetImpl)
442             {
443                 ((PrefsPreferenceSetImpl)prefSet).flush();
444             }            
445 
446         }
447         catch (Exception e)
448         {
449             String msg = "Failed to store portlet entity:" + e.toString();
450             IOException ioe = new IOException(msg);
451             ioe.initCause(e);            
452             throw ioe;
453         }
454 
455     }
456     
457     protected String autoGenerateID(PortletDefinition pd)
458     {
459         String appName = ((MutablePortletApplication)pd.getPortletApplicationDefinition()).getName();
460         String portletName = pd.getName();
461         return appName+"::"+portletName+"::"+new UID().toString();
462     }
463 
464     /* (non-Javadoc)
465      * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#isMergeSharedPreferences()
466      */
467     public boolean isMergeSharedPreferences()
468     {
469         return this.mergeSharedPreferences;
470     }
471 
472     
473 }