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.container.window.impl;
18  
19  import java.util.ArrayList;
20  import java.util.Collections;
21  import java.util.HashMap;
22  import java.util.List;
23  import java.util.Map;
24  import java.util.Set;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  import org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent;
29  import org.apache.jetspeed.components.portletentity.PortletEntityNotGeneratedException;
30  import org.apache.jetspeed.components.portletentity.PortletEntityNotStoredException;
31  import org.apache.jetspeed.components.portletregistry.PortletRegistry;
32  import org.apache.jetspeed.components.portletregistry.RegistryEventListener;
33  import org.apache.jetspeed.container.window.FailedToCreateWindowException;
34  import org.apache.jetspeed.container.window.FailedToRetrievePortletWindow;
35  import org.apache.jetspeed.container.window.PortletWindowAccessor;
36  import org.apache.jetspeed.factory.PortletFactory;
37  import org.apache.jetspeed.om.common.portlet.MutablePortletApplication;
38  import org.apache.jetspeed.om.common.portlet.MutablePortletEntity;
39  import org.apache.jetspeed.om.common.portlet.PortletApplication;
40  import org.apache.jetspeed.om.common.portlet.PortletDefinitionComposite;
41  import org.apache.jetspeed.om.page.ContentFragment;
42  import org.apache.jetspeed.om.window.impl.PortletWindowImpl;
43  import org.apache.jetspeed.util.ArgUtil;
44  import org.apache.pluto.om.entity.PortletEntity;
45  import org.apache.pluto.om.window.PortletWindow;
46  import org.apache.pluto.om.window.PortletWindowCtrl;
47  
48  /***
49   * Portlet Window Accessor Implementation
50   *
51   * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
52   * @version $Id: PortletWindowAccessorImpl.java,v 1.12 2005/04/29 14:01:57 weaver Exp $
53   */
54  public class PortletWindowAccessorImpl implements PortletWindowAccessor, RegistryEventListener
55  {
56      protected final static Log log = LogFactory.getLog(PortletWindowAccessorImpl.class);
57     
58      private Map windows = Collections.synchronizedMap(new HashMap());    
59      private PortletEntityAccessComponent entityAccessor;
60      private PortletFactory portletFactory;
61      private boolean validateWindows = false;
62      
63  
64      public PortletWindowAccessorImpl(PortletEntityAccessComponent entityAccessor, PortletFactory portletFactory, boolean validateWindows)
65      {
66          this.entityAccessor = entityAccessor;
67          this.portletFactory = portletFactory;
68          this.validateWindows = validateWindows;
69      }
70  
71      public PortletWindowAccessorImpl(PortletEntityAccessComponent entityAccessor, 
72                                       PortletFactory portletFactory, 
73                                       PortletRegistry registry,
74                                       boolean validateWindows)
75      {
76          this.entityAccessor = entityAccessor;
77          this.portletFactory = portletFactory;
78          this.validateWindows = validateWindows;
79          registry.addRegistryListener(this);
80      }
81      
82      public PortletWindow createPortletWindow(PortletEntity entity, String windowId)
83      {
84          if(entity == null)
85          {
86              throw new IllegalArgumentException("cratePortletWindow requires a non-null PortletEntity");
87          }
88          
89          PortletWindow found = getWindowFromCache(windowId);
90          if (found != null)
91          {
92              // remove from cache if invalid entity
93              checkPortletWindowEntity(found);
94              ((PortletWindowCtrl)found).setPortletEntity(entity);
95              return found;
96          }
97          
98          PortletWindowImpl window = new PortletWindowImpl(windowId);
99          window.setPortletEntity(entity);
100         if ( isValidPortletEntity(entity))
101         {
102             windows.put(windowId, window);
103         }
104         return window;        
105     }
106 
107     public PortletWindow createPortletWindow(String windowId)
108     {
109         PortletWindow found = getWindowFromCache(windowId);
110         if (found != null)
111         {
112             // remove from cache if invalid entity
113             checkPortletWindowEntity(found);
114             return found;
115         }        
116         PortletWindowImpl window = new PortletWindowImpl(windowId);
117         return window;                
118     }
119     
120     public PortletWindow getPortletWindow(String windowId)
121     {
122         PortletWindow window = getWindowFromCache(windowId);
123         if (window != null)
124         {
125             // remove from cache if invalid entity
126             checkPortletWindowEntity(window);
127         }        
128         return window;
129     }
130     
131     public PortletWindow getPortletWindow(ContentFragment fragment) throws FailedToRetrievePortletWindow, PortletEntityNotStoredException
132     {
133         ArgUtil.assertNotNull(ContentFragment.class, fragment, this, "getPortletWindow(Fragment fragment)");
134         PortletWindow portletWindow = getWindowFromCache(fragment);        
135         if (portletWindow == null || !checkPortletWindowEntity(portletWindow))
136         {
137             try
138             {
139                 return createPortletWindow(fragment);
140             }
141             catch (FailedToCreateWindowException e)
142             {
143                 throw new FailedToRetrievePortletWindow(e.toString(), e);
144             }
145         }
146         else
147         {
148             if (validateWindows)
149             {
150                 validateWindow(fragment, portletWindow);
151             }
152         }
153         
154         return portletWindow;
155     }
156     
157     /***
158      * <p>
159      * validateWindow
160      * </p>
161      *
162      * @param fragment
163      * @param portletWindow
164      * @throws PortletEntityNotStoredException 
165      * @throws InconsistentWindowStateException
166      */
167     protected void validateWindow( ContentFragment fragment, PortletWindow portletWindow ) throws FailedToRetrievePortletWindow, PortletEntityNotStoredException
168     {
169         // make sure the window has the most up-to-date portlet entity
170         PortletEntity portletEntity = entityAccessor.getPortletEntityForFragment(fragment);
171         if(portletEntity != null)
172         {
173             ((PortletWindowCtrl) portletWindow).setPortletEntity(portletEntity);
174             // if not a valid entity, remove window from cache
175             checkPortletWindowEntity(portletWindow);
176         }
177         else
178         {
179             removeWindow(portletWindow);  
180             throw new FailedToRetrievePortletWindow("No PortletEntity exists for for id "+fragment.getId()+" removing window from cache.");
181         }
182     }
183 
184     public PortletWindow getPortletWindow(ContentFragment fragment, String principal) throws FailedToRetrievePortletWindow, FailedToCreateWindowException, PortletEntityNotStoredException
185     {
186         ArgUtil.assertNotNull(ContentFragment.class, fragment, this, "getPortletWindow(Fragment fragment, String principal)");
187         ArgUtil.assertNotNull(String.class, principal, this, "getPortletWindow(Fragment fragment, String principal)");
188         PortletWindow portletWindow = getWindowFromCache(fragment);
189         if (portletWindow == null)
190         {
191             return createPortletWindow(fragment, principal);
192         }        
193         else
194         {
195             // make sure the window has the most up-to-date portlet entity
196             validateWindow(fragment, portletWindow);
197         }
198         return portletWindow;
199     }
200 
201     private PortletWindow createPortletWindow(ContentFragment fragment) throws FailedToCreateWindowException, PortletEntityNotStoredException
202     {
203         return createPortletWindow(fragment, null);
204     }
205     
206     private PortletWindow createPortletWindow(ContentFragment fragment, String principal) throws FailedToCreateWindowException, PortletEntityNotStoredException
207     {        
208         PortletWindow portletWindow = new PortletWindowImpl(fragment.getId());
209         boolean temporaryWindow = false;
210                 
211         MutablePortletEntity portletEntity = entityAccessor.getPortletEntityForFragment(fragment, principal);
212         if (portletEntity == null)
213         {
214             log.info("No portlet entity defined for fragment ID "+fragment.getId()+" attempting to auto-generate...");
215             try
216             {
217                 portletEntity = entityAccessor.generateEntityFromFragment(fragment, principal);
218                 // not portlet definition most likely means that the portlet has not been deployed so dont worry about storing off the entity
219                 if(isValidPortletEntity(portletEntity))
220                 {
221                     entityAccessor.storePortletEntity(portletEntity);
222                 }
223                 else
224                 {
225                     // don't cache the incomplete window
226                     temporaryWindow = true;
227                 }
228             }
229             catch (PortletEntityNotGeneratedException e)
230             {
231                 throw new FailedToCreateWindowException("Error generating new PortletEntity: "+e.toString(), e);                
232             }
233             catch (PortletEntityNotStoredException e)
234             {
235                 throw new FailedToCreateWindowException("Error storing new PortletEntity: "+e.toString(), e);
236             }
237             
238             if(portletEntity == null)
239             {
240                 throw new FailedToCreateWindowException("Unable to generate portlet entity.");
241             }
242             
243         }
244         ((PortletWindowCtrl) portletWindow).setPortletEntity(portletEntity);
245         
246         if ( !temporaryWindow )
247         {
248             windows.put(fragment.getId(), portletWindow);   
249         }
250         
251         return portletWindow;
252     }
253     
254 
255     public void removeWindows(PortletEntity portletEntity)
256     {
257         List tmpWindows = new ArrayList(windows.entrySet());
258         for(int i = 0; i < tmpWindows.size(); i++)
259         {
260             PortletWindow window = (PortletWindow)((Map.Entry)tmpWindows.get(i)).getValue();
261             if (portletEntity.getId().equals(window.getPortletEntity().getId()))
262             {
263                 removeWindow(window);
264             }
265         }        
266         tmpWindows.clear();
267 
268     }
269     
270     public void removeWindow(PortletWindow window)
271     {
272         windows.remove(window.getId().toString());
273     }
274     
275     private PortletWindow getWindowFromCache(ContentFragment fragment)
276     {
277         return (PortletWindow)windows.get(fragment.getId());
278     }
279     
280     private PortletWindow getWindowFromCache(String id)
281     {
282         return (PortletWindow)windows.get(id);
283     }
284 
285     private boolean checkPortletWindowEntity(PortletWindow window)
286     {
287         if (!isValidPortletEntity(window.getPortletEntity()))
288         {
289             removeWindow(window);
290             return false;
291         }
292         return true;
293     }
294     
295     private boolean isValidPortletEntity(PortletEntity pe)
296     {
297         return pe != null
298                 && pe.getPortletDefinition() != null
299                 && pe.getPortletDefinition().getPortletApplicationDefinition() != null
300                 && portletFactory.isPortletApplicationRegistered((PortletApplication) pe.getPortletDefinition()
301                         .getPortletApplicationDefinition());
302     }
303     
304     public Set getPortletWindows()
305     {
306         return this.windows.entrySet();
307     }
308 
309     protected void removeForPortletDefinition(PortletDefinitionComposite def)
310     {
311         List tmpWindows = new ArrayList(windows.entrySet());
312         for (int i = 0; i < tmpWindows.size(); i++)
313         {
314             PortletWindow window = (PortletWindow)((Map.Entry)tmpWindows.get(i)).getValue();
315             PortletDefinitionComposite windowDef = (PortletDefinitionComposite)window.getPortletEntity().getPortletDefinition();            
316             if(def != null && windowDef != null && def.getUniqueName() != null && def.getUniqueName().equals(windowDef.getUniqueName()))
317             {
318                 removeWindow(window);
319             }
320         }        
321         tmpWindows.clear(); 
322         if (def != null)
323             portletFactory.updatePortletConfig(def);
324     }
325 
326     protected void removeForPortletApplication(MutablePortletApplication app)
327     {
328         List tmpWindows = new ArrayList(windows.entrySet());
329         for (int i = 0; i < tmpWindows.size(); i++)
330         {
331             PortletWindow window = (PortletWindow)((Map.Entry)tmpWindows.get(i)).getValue();
332             PortletDefinitionComposite pd =  (PortletDefinitionComposite)window.getPortletEntity().getPortletDefinition();
333             if (pd != null)
334             {
335                 MutablePortletApplication windowApp = (MutablePortletApplication)pd.getPortletApplicationDefinition();            
336                 if (app.getName().equals(windowApp.getName()))
337                 {
338                     removeWindow(window);
339                 }
340             }
341         }        
342         tmpWindows.clear();        
343     }
344     
345     public void applicationRemoved(MutablePortletApplication app)
346     {
347         if (app == null)
348         {
349             //System.out.println("@@@ receiving APP REMOVED message with NULL");
350             return;
351         }
352         //System.out.println("@@@ receiving APP REMOVED message: " + app.getName());
353         removeForPortletApplication(app);
354     }
355 
356  
357     public void applicationUpdated(MutablePortletApplication app)
358     {
359         if (app == null)
360         {
361             //System.out.println("@@@ receiving APP UPDATED message with NULL");
362             return;
363         }
364         //System.out.println("@@@ receiving APP UPDATED message: " + app.getName()); 
365         removeForPortletApplication(app);
366     }
367 
368     public void portletRemoved(PortletDefinitionComposite def)
369     {
370         if (def == null)
371         {
372             //System.out.println("@@@ receiving DEF REMOVED message with NULL");
373             return;
374         }
375         //System.out.println("@@@ receiving DEF REMOVED message: " + def.getName()); 
376         removeForPortletDefinition(def);
377     }
378  
379     public void portletUpdated(PortletDefinitionComposite def)
380     {
381         if (def == null)
382         {
383             //System.out.println("@@@ receiving DEF UPDATED message with NULL");
384             return;
385         }
386         //System.out.println("@@@ receiving DEF UPDATED message: " + def.getName());
387         removeForPortletDefinition(def);
388     }
389 }