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.struts.config;
    18
    19  import java.io.Serializable;
    20  import java.util.ArrayList;
    21  import java.util.Enumeration;
    22  import java.util.List;
    23
    24  import javax.portlet.PortletRequest;
    25  import javax.portlet.PortletSession;
    26
    27  import org.apache.commons.digester.Digester;
    28  import org.apache.struts.taglib.tiles.ComponentConstants;
    29
    30  public class RenderContextAttributes extends AbstractConfigComponent
    31  {
    32      private static class AttributeValue implements Serializable
    33      {
    34          private String  name;
    35          private Object  value;
    36
    37          public AttributeValue(String name, Object value)
    38          {
    39              super();
    40              this.name = name;
    41              this.value = value;
    42          }
    43
    44          public String getName()
    45          {
    46              return name;
    47          }
    48
    49          public Object getValue()
    50          {
    51              return value;
    52          }
    53      }
    54
    55      public static class Attribute
    56      {
    57          private String value;
    58          private boolean prefix;
    59          private boolean keep;
    60
    61          public Attribute()
    62          {
    63          }
    64
    65          public boolean isKeep()
    66          {
    67              return keep;
    68          }
    69
    70          public void setKeep(boolean keep)
    71          {
    72              this.keep = keep;
    73          }
    74
    75          public boolean isPrefixAttr()
    76          {
    77              return prefix;
    78          }
    79
    80          public String getValue()
    81          {
    82              return value;
    83          }
    84
    85          public void setName(String value)
    86          {
    87              this.value = value;
    88              this.prefix = false;
    89          }
    90
    91          public void setPrefix(String value)
    92          {
    93              this.value = value;
    94              this.prefix = true;
    95          }
    96      }
    97
    98      private String name = this.getClass().getName();
    99      private Attribute[] namedAttributes;
    100     private Attribute[] prefixAttributes;
    101     private ArrayList namedAttributesList;
    102     private ArrayList prefixAttributesList;
    103
    104     public RenderContextAttributes()
    105     {
    106         namedAttributesList = new ArrayList();
    107         prefixAttributesList = new ArrayList();
    108     }
    109
    110     private static boolean isNotEmpty(String str)
    111     {
    112         return str != null && str.length() > 0;
    113     }
    114
    115     private Attribute[] createArray(List attributes)
    116     {
    117         Attribute[] array = null;
    118         if ( attributes != null && attributes.size() > 0 )
    119         {
    120             array = new Attribute[attributes.size()];
    121             for ( int i = 0; i < array.length; i++ )
    122             {
    123                 array[i] = (Attribute)attributes.get(i);
    124             }
    125         }
    126         return array;
    127     }
    128
    129     public void addAttribute(Attribute attribute)
    130     {
    131         checkLoaded();
    132
    133         if (attribute.isPrefixAttr())
    134         {
    135             prefixAttributesList.add(attribute);
    136         }
    137         else
    138         {
    139             namedAttributesList.add(attribute);
    140         }
    141     }
    142
    143     public void setName(String name)
    144     {
    145         checkLoaded();
    146         this.name = name;
    147     }
    148
    149     public void configure(Digester digester)
    150     {
    151         digester.addRule("config/render-context", new SetParentRule(this));
    152         digester.addSetProperties("config/render-context");
    153         digester.addObjectCreate("config/render-context/attribute", Attribute.class);
    154         digester.addSetProperties("config/render-context/attribute");
    155         digester.addSetNext("config/render-context/attribute", "addAttribute");
    156         digester.addCallMethod("config/render-context", "afterLoad");
    157
    158     }
    159
    160     public void afterLoad()
    161     {
    162         super.afterLoad();
    163
    164         // special handling for Tiles support, see PB-41
    165         boolean found = false;
    166         for ( int i = 0, size = namedAttributesList.size(); i < size; i++ )
    167         {
    168             Attribute attr = (Attribute)namedAttributesList.get(i);
    169             if ( ComponentConstants.COMPONENT_CONTEXT.equals(attr.getValue()) )
    170             {
    171                 found = true;
    172                 break;
    173             }
    174         }
    175         if ( !found )
    176         {
    177             // Add Tiles COMPONENT_CONTEXT to named Attributes list
    178             Attribute tilesContextAttribute = new Attribute();
    179             tilesContextAttribute.setName(ComponentConstants.COMPONENT_CONTEXT);
    180             namedAttributesList.add(tilesContextAttribute);
    181         }
    182         namedAttributes = createArray(namedAttributesList);
    183         prefixAttributes = createArray(prefixAttributesList);
    184
    185         namedAttributesList = null;
    186         prefixAttributesList = null;
    187     }
    188
    189     /***
    190      * Save attributes in the PortletSession. This will ensure
    191      * that each portlet instance will have its own render attributes.
    192      * @param request The PortletRequest
    193      */
    194     public void saveAttributes(PortletRequest request)
    195     {
    196         ArrayList keepAttributes = new ArrayList();
    197         ArrayList tempAttributes = new ArrayList();
    198         ArrayList savedNames = new ArrayList();
    199         if ( namedAttributes != null )
    200         {
    201             for ( int i = 0; i < namedAttributes.length; i++ )
    202             {
    203                 Object value = request.getAttribute(namedAttributes[i].getValue());
    204                 if ( value != null )
    205                 {
    206                     AttributeValue attributeValue = new AttributeValue(namedAttributes[i].getValue(), value);
    207                     savedNames.add(attributeValue.getName());
    208                     if ( namedAttributes[i].isKeep() )
    209                     {
    210                         keepAttributes.add(attributeValue);
    211                     }
    212                     else
    213                     {
    214                         tempAttributes.add(attributeValue);
    215                     }
    216                 }
    217             }
    218         }
    219         if ( prefixAttributes != null )
    220         {
    221             Enumeration names = request.getAttributeNames();
    222             while ( names.hasMoreElements() )
    223             {
    224                 String name = (String)names.nextElement();
    225                 for ( int i = 0; i < prefixAttributes.length; i++ )
    226                 {
    227                     if (!savedNames.contains(name) && name.startsWith(prefixAttributes[i].getValue()))
    228                     {
    229                         AttributeValue attributeValue = new AttributeValue(name, request.getAttribute(name));
    230                         savedNames.add(name);
    231                         if (prefixAttributes[i].isKeep())
    232                         {
    233                             keepAttributes.add(attributeValue);
    234                         }
    235                         else
    236                         {
    237                             tempAttributes.add(attributeValue);
    238                         }
    239                     }
    240                 }
    241             }
    242         }
    243         if (keepAttributes.size() > 0)
    244         {
    245             if (tempAttributes.size() > 0)
    246             {
    247                 keepAttributes.add(null); // indicating subsequent attributeValues are temporarily
    248                 keepAttributes.addAll(tempAttributes);
    249             }
    250             request.getPortletSession().setAttribute(name,keepAttributes);
    251         }
    252         else if (tempAttributes.size() > 0)
    253         {
    254             tempAttributes.add(0,null); // indicating subsequent attributeValues are temporarily
    255             request.getPortletSession().setAttribute(name,tempAttributes);
    256         }
    257     }
    258
    259     /***
    260      * Remove attributes from the PortletSession
    261      * @param session The PortletSession
    262      */
    263     public void clearAttributes(PortletSession session)
    264     {
    265         session.removeAttribute(name);
    266     }
    267
    268     /***
    269      * Restore attributes from the PortletSession.
    270      * @param request The portletRequest
    271      */
    272     public void restoreAttributes(PortletRequest request)
    273     {
    274         PortletSession portletSession = request.getPortletSession();
    275         ArrayList attributes = (ArrayList)portletSession.getAttribute(name);
    276         if ( attributes != null )
    277         {
    278             for ( int size = attributes.size(), i = size - 1 ; i > -1; i-- )
    279             {
    280                 AttributeValue attributeValue = (AttributeValue)attributes.get(i);
    281                 if ( attributeValue == null )
    282                 {
    283                     if ( i == 0 )
    284                     {
    285                         portletSession.removeAttribute(name);
    286                     }
    287                     else
    288                     {
    289                         // remove this and previously retrieved attributeValues as being temporarily
    290                         while (size > i )
    291                         {
    292                             attributes.remove(--size);
    293                         }
    294                     }
    295                 }
    296                 else
    297                 {
    298                     request.setAttribute(attributeValue.getName(), attributeValue.getValue());
    299                 }
    300             }
    301         }
    302     }
    303 }