View Javadoc

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