1 /***
2 * Copyright (c) 2003 held jointly by the individual authors.
3 *
4 * This library is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License as published by the Free
6 * Software Foundation; either version 2.1 of the License, or (at your option)
7 * any later version.
8 *
9 * This library is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. >
17 * http://www.gnu.org/copyleft/lesser.html >
18 * http://www.opensource.org/licenses/lgpl-license.php
19 */
20 package net.mlw.vlh.web.tag;
21
22 import java.util.List;
23 import java.util.StringTokenizer;
24
25 import javax.servlet.http.HttpServletRequest;
26 import javax.servlet.jsp.JspException;
27 import javax.servlet.jsp.PageContext;
28 import javax.servlet.jsp.tagext.BodyTagSupport;
29
30 import net.mlw.vlh.DefaultListBackedValueList;
31 import net.mlw.vlh.ValueList;
32 import net.mlw.vlh.web.ValueListConfigBean;
33 import net.mlw.vlh.web.ValueListRequestUtil;
34 import net.mlw.vlh.web.tag.support.HtmlDisplayProvider;
35 import net.mlw.vlh.web.tag.support.ParamAddable;
36 import net.mlw.vlh.web.tag.support.ValueListNullSpacer;
37 import net.mlw.vlh.web.util.ImagesHomeDisplayHelper;
38 import net.mlw.vlh.web.util.JspUtils;
39
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42 import org.springframework.beans.BeansException;
43 import org.springframework.web.context.WebApplicationContext;
44 import org.springframework.web.context.support.WebApplicationContextUtils;
45
46 /***
47 * @author Matthew L. Wilson, Andrej Zachar, Luciano Cunha
48 * @version $Revision: 1.29 $ $Date: 2005/11/23 14:47:51 $
49 */
50 public class ValueListSpaceTag extends BodyTagSupport implements ParamAddable
51 {
52
53 private static final long serialVersionUID = 7795421339534088302L;
54
55 /*** Commons Logger */
56 private static final Log LOGGER = LogFactory.getFactory().getInstance(ValueListSpaceTag.class);
57
58 /***
59 * Parent root tag in case of nested valuelist
60 */
61 private ValueListSpaceTag parentRootTag;
62
63 protected ValueListConfigBean config;
64
65 protected ValueList valueList = null;
66
67 protected TableInfo tableInfo = new TableInfo(TableInfo.DEFAULT_ID);
68
69 protected String valueListName = null;
70
71 protected String valueListScope = null;
72
73 /***
74 * @author Luciano Cunha
75 */
76 protected String excludeParameters;
77
78 /***
79 * true - If is valueList set from mvc or from jsp via tag retrieve.
80 */
81 private boolean wasRetrieved = false;
82
83 /***
84 * Parent root tag in case of nested valuelist
85 *
86 * @return parent root tag
87 */
88 public ValueListSpaceTag getParentRootTag()
89 {
90 return parentRootTag;
91 }
92
93 /***
94 * @see javax.servlet.jsp.tagext.Tag#doStartTag()
95 */
96 public int doStartTag() throws JspException
97 {
98
99 parentRootTag = (ValueListSpaceTag) findAncestorWithClass(this, ValueListSpaceTag.class);
100
101 Object bean;
102
103 if ("session".equals(valueListScope))
104 {
105 bean = pageContext.getAttribute(valueListName, PageContext.SESSION_SCOPE);
106 }
107 else if ("application".equals(valueListScope))
108 {
109 bean = pageContext.getAttribute(valueListName, PageContext.APPLICATION_SCOPE);
110 }
111 else
112 {
113 bean = pageContext.getAttribute(valueListName, PageContext.REQUEST_SCOPE);
114 }
115
116 if (bean != null)
117 {
118 if (bean instanceof ValueList)
119 {
120 setValueList((ValueList) bean);
121 }
122 else if (bean instanceof List)
123 {
124 setValueList(new DefaultListBackedValueList((List) bean));
125 if (LOGGER.isDebugEnabled())
126 {
127 LOGGER.debug("List '" + valueListName + "' was wrapped with DefaultListBackedValueList.");
128 }
129 }
130 else
131 {
132 String msg = "ValueList '" + valueListName + "' of of unknown type " + bean.getClass().getName() + "!";
133 LOGGER.warn(msg);
134 }
135 }
136 else
137 {
138 LOGGER.error("ValueList '" + valueListName + "' was not found in the scope '"
139 + (valueListScope == null ? "request" : valueListScope) + "'!");
140 }
141
142 if (bean != null)
143 {
144 pageContext.setAttribute(valueListName, bean);
145 }
146
147 tableInfo.setName(valueListName);
148 tableInfo.setConfig(getConfig());
149 tableInfo.setPageContext(pageContext);
150
151 pageContext.setAttribute(ImagesHomeDisplayHelper.IMAGES_HOME_ATTRIBUTE_KEY, ((HtmlDisplayProvider) tableInfo.getConfig()
152 .getDisplayProvider("html")).getImageHome((HttpServletRequest) pageContext.getRequest()));
153 /***
154 * @author Luciano Cunha
155 */
156 excludeParameters();
157
158 return super.doStartTag();
159 }
160
161 /***
162 * Exclude parameters.
163 *
164 * @author Luciano Cunha
165 */
166 public void excludeParameters()
167 {
168 if (excludeParameters != null)
169
170 {
171 for (StringTokenizer st = new StringTokenizer(excludeParameters, "|"); st.hasMoreTokens();)
172 {
173 String key = st.nextToken();
174 if (tableInfo.getParameters() != null && tableInfo.getParameters().containsKey(key))
175 {
176 tableInfo.getParameters().remove(key);
177 }
178 }
179 }
180 }
181
182 /***
183 * Write the bodyContent.
184 *
185 * @see javax.servlet.jsp.tagext.IterationTag#doAfterBody()
186 */
187 public int doAfterBody() throws JspException
188 {
189 if (bodyContent != null)
190 {
191 JspUtils.writePrevious(pageContext, bodyContent.getString());
192 }
193 valueList = null;
194 valueListName = null;
195 valueListScope = null;
196 config = null;
197 wasRetrieved = false;
198 tableInfo = new TableInfo(TableInfo.DEFAULT_ID);
199 return SKIP_BODY;
200 }
201
202 /***
203 * @see javax.servlet.jsp.tagext.Tag#doEndTag()
204 */
205 public int doEndTag() throws JspException
206 {
207 int result = super.doEndTag();
208 reset();
209 return result;
210 }
211
212 /***
213 * Setter for the base URL.
214 *
215 * @param url New value of property url.
216 */
217 public void setUrl(String url)
218 {
219 tableInfo.setUrl(url);
220 }
221
222 /***
223 * Setter for the included properties
224 *
225 * @param forwardParams The included properties
226 */
227 public void setIncludeParameters(String forwardParams)
228 {
229 tableInfo.getParameters().clear();
230 tableInfo.getParameters().putAll(ValueListRequestUtil.getAllForwardParameters(pageContext, forwardParams, tableInfo.getId()));
231
232 }
233
234 /***
235 * Setter for the excluded properties
236 *
237 * @param excludedParameters The excluded properties
238 * @autor Luciano Cunha
239 */
240 public void setExcludeParameters(String excludedParameters)
241 {
242 this.excludeParameters = excludedParameters;
243 }
244
245 /***
246 * Sets the name of the ValueList
247 *
248 * @param name The name to set of the ValueList.
249 */
250 public void setValue(String name)
251 {
252 valueListName = name;
253 }
254
255 /***
256 * If is your retrieved ValueList null or you forgot to send a valueList it
257 * returns the ValueListNullSpacer.
258 *
259 * @return Returns the valueList. NEVER RETURN NULL
260 */
261 public ValueList getValueList()
262 {
263 if (valueList == null)
264 {
265 if (!wasRetrieved)
266 {
267 LOGGER
268 .error("Please set any valueList before use! \n A) Check if you have the tag <vlh:retrieve .../> before using data, if you are not using Controller! The most safe place is to put it after the root tag."
269 + "\n B) If you are using a Controller, check if you set in the scope '"
270 + (valueListScope == null ? "request" : valueListScope)
271 + "' any valueList with the name '"
272 + valueListName
273 + "' \n C) Someone could hack parameters, no valueList was found.");
274 }
275 else
276 {
277 LOGGER.warn("Retrieved valueList is null!");
278 }
279 LOGGER.warn("Returning singleton ValueListNullSpacer!");
280 valueList = ValueListNullSpacer.getInstance();
281 }
282 return valueList;
283
284 }
285
286 /***
287 * @param valueList The valueList to set.
288 *
289 */
290 public void setValueList(ValueList valueList)
291 {
292 this.valueList = valueList;
293 wasRetrieved = true;
294 }
295
296 /***
297 * @return Returns the tableInfo.
298 */
299 public TableInfo getTableInfo()
300 {
301 return tableInfo;
302 }
303
304 /***
305 * @param id The id to set.
306 */
307 public void setId(String id)
308 {
309 tableInfo.setId(id);
310 }
311
312 /***
313 * @return Returns the config.
314 */
315 public ValueListConfigBean getConfig()
316 {
317 if (config == null)
318 {
319 LOGGER.warn("No ValueListConfigBean defined, using the default configuration.");
320 config = new ValueListConfigBean();
321 }
322
323 return config;
324 }
325
326 /***
327 * @param configName The config to set.
328 */
329 public void setConfigName(String configName)
330 {
331 try
332 {
333 WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(pageContext.getServletContext());
334 config = (ValueListConfigBean) context.getBean(configName, ValueListConfigBean.class);
335 }
336 catch (BeansException e)
337 {
338 config = null;
339 LOGGER.error("Check spelling of the config='" + configName + "' Error: " + e.getMessage());
340 }
341 }
342
343 /***
344 * @param valueListScope The valueListScope to set.
345 */
346 public void setScope(String valueListScope)
347 {
348 this.valueListScope = valueListScope;
349 }
350
351 /***
352 * Add params to url.
353 *
354 * @see net.mlw.vlh.web.tag.support.ParamAddable#addParam(java.lang.String,
355 * java.lang.String)
356 */
357 public void addParam(String key, String value)
358 {
359 tableInfo.getParameters().put(key, value);
360 }
361
362 private void reset()
363 {
364 this.parentRootTag = null;
365 this.config = null;
366 this.excludeParameters = null;
367 this.tableInfo = new TableInfo(TableInfo.DEFAULT_ID);
368 this.valueList = null;
369 this.valueListName = null;
370 this.valueListScope = null;
371 this.wasRetrieved = false;
372 }
373
374 /***
375 * Called on a Tag handler to release state.
376 * The page compiler guarantees that JSP page implementation
377 * objects will invoke this method on all tag handlers,
378 * but there may be multiple invocations on doStartTag and doEndTag in between.
379 *
380 * @see javax.servlet.jsp.tagext.Tag#release()
381 */
382 public void release()
383 {
384 super.release();
385 reset();
386 }
387 }