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