View Javadoc

1   /*
2    * Copyright 2000-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.portals.bridges.frameworks.spring;
17  
18  import java.io.InputStream;
19  import java.util.HashMap;
20  import java.util.Iterator;
21  import java.util.Map;
22  import java.util.ResourceBundle;
23  
24  import javax.portlet.PortletConfig;
25  import javax.portlet.PortletException;
26  
27  import org.springframework.beans.PropertyValue;
28  import org.springframework.beans.factory.config.BeanDefinition;
29  import org.springframework.beans.factory.xml.XmlBeanFactory;
30  
31  import org.apache.commons.validator.Validator;
32  import org.apache.commons.validator.ValidatorException;
33  import org.apache.commons.validator.ValidatorResources;
34  import org.apache.commons.validator.ValidatorResults;
35  import org.apache.portals.bridges.frameworks.ExternalComponentSupport;
36  import org.apache.portals.bridges.frameworks.Lookup;
37  import org.apache.portals.bridges.frameworks.model.ModelBean;
38  import org.apache.portals.bridges.frameworks.model.PortletApplicationModel;
39  import org.apache.portals.bridges.frameworks.spring.ModelBeanImpl;
40  
41  
42  /***
43   * PortletApplicationModelImpl
44   * 
45   * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
46   * @version $Id: PortletApplicationModelImpl.java 216210 2005-07-13 20:28:18 +0200 (Wed, 13 Jul 2005) taylor $
47   */
48  public class PortletApplicationModelImpl implements PortletApplicationModel
49  {
50      /***
51       * Spring configuration: view to bean name map
52       */
53      private static final String PORTLET_VIEW_BEAN_MAP = "portlet-view-bean-map";
54      
55      /***
56       * Spring configuration: view to validator name map
57       */
58      private static final String PORTLET_VIEW_VALIDATOR_MAP = "portlet-view-validator-map";
59      
60      /***
61       * logical view to template map
62       */
63      private static final String PORTLET_LOGICAL_VIEW_MAP = "portlet-views";
64  
65      /***
66       * map for action forward definitions (success, failure)
67       */
68      private static final String PORTLET_ACTION_FORWARD_MAP = "portlet-action-forward-map";
69          
70      /***
71       * Spring Factory 
72       */
73      private XmlBeanFactory springFactory = null;
74  
75      /***
76       * View Bean Map
77       */
78      private Map viewBeanMap = null;
79      
80      /***
81       * Validation resources
82       */
83      private ValidatorResources validations = null;
84          
85      /***
86       * View Validation Map
87       */
88      private Map viewValidatorMap = null;
89  
90      /***
91       * Map from logical views to templates
92       */
93      private Map logicalViewMap = null;
94  
95      /***
96       * Map from view:status to view
97       */    
98      private Map actionForwardMap = null;
99      
100     private Map modelBeanMap = new HashMap();
101     
102     private Map externalSupportMap = new HashMap();
103     
104     private static Object semaphore = new Object();
105     
106     private String springConfig;
107     private String validatorConfig = null;
108     
109     public PortletApplicationModelImpl(String springConfig, String validatorConfig)
110     {
111         this.springConfig = springConfig;
112         this.validatorConfig = validatorConfig;
113     }
114     
115     public void setExternalSupport(Map map)
116     {
117         this.externalSupportMap = map;
118     }
119     
120     public void init(PortletConfig config)
121     throws PortletException
122     {
123         // load Spring
124         try 
125         {
126             synchronized (semaphore)
127             {
128                 if (null == springFactory)
129                 {
130                     InputStream is = config.getPortletContext().getResourceAsStream(springConfig);                    
131                     springFactory = new XmlBeanFactory(is);
132                     is.close();
133                 }
134             }
135          } 
136          catch (Exception e) 
137          {
138              throw new PortletException("Failed to load spring configuration.", e);
139          }   
140                            
141          // load validator
142          synchronized (semaphore)
143          {             
144              if (validatorConfig != null && null == validations)
145              {
146                  InputStream is = null;
147                  
148                  try
149                  {
150                      // TODO: support extensible user-defined validator resources
151                      //is = this.getClass().getResourceAsStream("/org/apache/portals/bridges/velocity/validation/default-portlet-validation.xml");
152                      is = config.getPortletContext().getResourceAsStream(validatorConfig);                    
153                      
154                      validations = new ValidatorResources(is);
155                  }
156                  catch (Exception e)
157                  {
158                      throw new PortletException("Failed to load validator configuration.", e);
159                  }
160                  finally 
161                  {
162                      // Make sure we close the input stream.
163                      if (is != null) 
164                      {
165                          try
166                          {
167                              is.close();
168                          }
169                          catch (Exception e)
170                          {}
171                      }
172                  }                     
173              }
174          }
175 
176          // Logical Views to templates
177          synchronized (semaphore)
178          {
179              logicalViewMap = (Map)springFactory.getBean(PORTLET_LOGICAL_VIEW_MAP);
180              if (logicalViewMap == null)
181              {
182                  logicalViewMap = new HashMap(); 
183              }
184          }
185          
186          // View to Validator Map
187          synchronized (semaphore)
188          {             
189              viewValidatorMap = (Map)springFactory.getBean(PORTLET_VIEW_VALIDATOR_MAP);
190              if (viewValidatorMap == null)
191              {
192                  viewValidatorMap = new HashMap(); 
193              }
194          }
195          
196          // View to Bean Map
197          synchronized (semaphore)
198          {
199              viewBeanMap = (Map)springFactory.getBean(PORTLET_VIEW_BEAN_MAP);
200              if (viewBeanMap == null)
201              {
202                  viewBeanMap = new HashMap();              
203              }
204          }        
205 
206          // Action Forward map
207          synchronized (semaphore)
208          {
209              actionForwardMap = (Map)springFactory.getBean(PORTLET_ACTION_FORWARD_MAP);
210              if (actionForwardMap == null)
211              {
212                  actionForwardMap = new HashMap();              
213              }
214          }
215          
216          
217     }
218     
219     public ModelBean getModelBean(String view)
220     {
221         ModelBean modelBean;
222         String beanName = (String)viewBeanMap.get(view);
223         if (beanName != null)
224         {
225             modelBean = (ModelBean)modelBeanMap.get(beanName);
226             if (modelBean == null)
227             {
228                 BeanDefinition bd = springFactory.getBeanDefinition(beanName);
229                 Object bean = springFactory.getBean(beanName);
230                 if (bd == null || bean == null)
231                 {
232                     return new ModelBeanImpl(beanName, ModelBean.POJO);
233                 }                   
234                 String lookup = null;
235                 boolean requiresExternalSupport = false;
236                 PropertyValue value = bd.getPropertyValues().getPropertyValue("lookupKey");
237                 if (value != null)
238                 {
239                     lookup = (String)value.getValue();
240                 }                
241                 if (bean instanceof ExternalComponentSupport)
242                 {
243                     requiresExternalSupport = true;
244                 }
245                 modelBean = new ModelBeanImpl(beanName, ModelBean.POJO, lookup, requiresExternalSupport);
246                 modelBeanMap.put(beanName, modelBean);
247             }
248         }
249         else
250         {
251             modelBean = new ModelBeanImpl(beanName, ModelBean.PREFS_MAP);
252         }        
253         return modelBean;
254     }
255     
256     public String getTemplate(String view)
257     {
258         return (String)logicalViewMap.get(view);
259     }
260     
261     public Object lookupBean(ModelBean mb, String key)
262     {
263         Object bean = springFactory.getBean(mb.getBeanName());
264         if (bean != null)
265         {
266             if (mb.isRequiresExternalSupport())
267             {
268                 ExternalComponentSupport ecs = (ExternalComponentSupport)bean;
269                 ecs.setExternalSupport(externalSupportMap.get(mb.getBeanName()));
270             }
271             if (mb.isRequiresLookup())
272             {
273                 ((Lookup)bean).lookup(key);
274             }
275         }
276         return bean;
277     }
278 
279     public Object createBean(ModelBean mb)
280     {
281         Object bean = springFactory.getBean(mb.getBeanName());
282         if (bean != null)
283         {
284             if (mb.isRequiresExternalSupport())
285             {
286                 ExternalComponentSupport ecs = (ExternalComponentSupport)bean;
287                 ecs.setExternalSupport(externalSupportMap.get(mb.getBeanName()));
288             }
289         }
290         return bean;
291     }
292     
293     public Map createPrefsBean(ModelBean mb, Map original)
294     {
295         Map prefs = new HashMap();
296         Iterator it = original.entrySet().iterator();
297         while (it.hasNext())
298         {
299             Map.Entry entry = (Map.Entry)it.next();
300             String key = (String)entry.getKey();
301             Object value = entry.getValue();
302             if (value instanceof String)
303             {
304                 prefs.put(key, value);
305             }
306             else if (value instanceof String[])
307             {
308                 prefs.put(key, ((String[])value)[0]);
309             }
310         }
311         return prefs;        
312     }
313 
314     public Map validate(Object bean, String view, ResourceBundle bundle)
315     throws PortletException
316     {
317         Map result = new HashMap();
318         if (validations == null)
319         {
320             return result; // no validation configured
321         }
322         // Get the bean name from the bean-view map
323         String validatorFormName = (String)viewValidatorMap.get(view);
324         if (validatorFormName == null)
325         {
326             return result; // no validation for this bean
327         }
328 
329         Validator validator = new Validator(validations, validatorFormName);
330 
331         // Tell the validator which bean to validate against.
332         validator.setParameter(Validator.BEAN_PARAM, bean);
333         
334         // Parameters used by our validators
335         validator.setParameter("java.util.Map", result);
336         validator.setParameter("java.util.ResourceBundle", bundle);
337         
338         ValidatorResults results = null;
339                 
340         try
341         {
342             validator.setOnlyReturnErrors(true);
343             results = validator.validate();
344             if (results.isEmpty())
345             {
346                 return result;
347             }
348         }
349         catch (ValidatorException e)
350         {
351             throw new PortletException("Error in processing validation: ", e);            
352         }
353         
354         return result;        
355     }
356     
357     public String getForward(String view, String status)
358     {
359         return (String)actionForwardMap.get(view + ":" + status);
360     }
361 
362     public String getForward(String view)
363     {
364         return (String)actionForwardMap.get(view);
365     }
366     
367 }