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 }