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