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
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
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);
232 keepAttributes.addAll(tempAttributes);
233 }
234 request.getPortletSession().setAttribute(name,keepAttributes);
235 }
236 else if (tempAttributes.size() > 0)
237 {
238 tempAttributes.add(0,null);
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
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 }