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