KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > fr > improve > struts > taglib > layout > field > OptionsDependentTag


1 /*
2  * Created on 2 avr. 2004
3  *
4  * Copyright Improve SA 2004.
5  * All rights reserved.
6  */

7 package fr.improve.struts.taglib.layout.field;
8
9 import java.util.HashMap JavaDoc;
10 import java.util.Iterator JavaDoc;
11 import java.util.Map JavaDoc;
12
13 import javax.servlet.jsp.JspException JavaDoc;
14 import javax.servlet.jsp.PageContext JavaDoc;
15 import javax.servlet.jsp.tagext.TagSupport JavaDoc;
16
17 import fr.improve.struts.taglib.layout.util.LayoutUtils;
18 import fr.improve.struts.taglib.layout.util.TagUtils;
19
20 /**
21  * The optionsDependent tag allows to make interdependent combo box.
22  *
23  * @author jnribette
24  */

25 public class OptionsDependentTag extends TagSupport JavaDoc {
26     /**
27      * Helper data object holding all the required information to make 2 combos interdependent.
28      */

29     static class DependentInfo {
30         /**
31          * Name of the bean holding the main collection in the request.
32          */

33         String JavaDoc mainCollectionName;
34         /**
35          * Property of the bean holding the main collection in the request.
36          */

37         String JavaDoc mainCollectionProperty;
38         
39         /**
40          * Property of the bean in the main collection holding the value.
41          */

42         String JavaDoc mainCollectionBeanProperty;
43                 
44         /**
45          * Property of the form bean holding the main property.
46          */

47         String JavaDoc mainProperty;
48         
49         /**
50          * Property of the form bean holding the dependent property.
51          */

52         String JavaDoc dependentProperty;
53         
54         /**
55          * Property of the main select elements holding the nested property.
56          */

57         String JavaDoc dependentCollectionProperty;
58         
59         String JavaDoc dependentCollectionLabel;
60         String JavaDoc dependentCollectionValue;
61     }
62     
63     /**
64      * The property of the beans of the main combo that holds the nested collection.
65      */

66     protected String JavaDoc collection;
67     
68     /**
69      * The property this combo depends from.
70      */

71     protected String JavaDoc dependsFrom;
72     
73     /**
74      * The label property.
75      */

76     protected String JavaDoc labelProperty;
77     
78     /**
79      * The value property.
80      */

81     protected String JavaDoc property;
82     
83     /**
84      * Key of the map holding the DependentInfo objects in the pageContext.
85      */

86     protected static final String JavaDoc DEPENDENT_INFO_KEY = "fr.improve.struts.taglib.layout.field.OptionsDependentTag.DEPENDENT_INFO_KEY";
87     
88     /**
89      * Do many things
90      */

91     public int doStartTag() throws JspException JavaDoc {
92         // Find DependentInfo based on the dependsForm attribute.
93
DependentInfo lc_info = getDependentInfo(dependsFrom, pageContext);
94         
95         // Initialize the DependentInfo.
96
initializeChildDependentInfo(lc_info);
97         
98         // Make the combo interdependent.
99
makeDependentCombo(lc_info);
100         
101         return SKIP_BODY;
102     }
103         
104     protected void initializeChildDependentInfo(DependentInfo lc_info) {
105         SelectTag lc_selectTag = (SelectTag) findAncestorWithClass(this, SelectTag.class);
106         lc_info.dependentProperty = lc_selectTag.getProperty();
107         lc_info.dependentCollectionProperty = collection;
108         lc_info.dependentCollectionLabel = labelProperty;
109         lc_info.dependentCollectionValue = property;
110     }
111
112     protected static DependentInfo getDependentInfo(String JavaDoc in_dependsFrom, PageContext JavaDoc in_pg) {
113         // Get the DependentInfo map.
114
Map JavaDoc lc_map = (Map JavaDoc) in_pg.findAttribute(DEPENDENT_INFO_KEY);
115         if (lc_map==null) {
116             lc_map = new HashMap JavaDoc();
117             in_pg.setAttribute(DEPENDENT_INFO_KEY, lc_map);
118         }
119         
120         // Get the specified DependentInfo.
121
DependentInfo lc_info = (DependentInfo) lc_map.get(in_dependsFrom);
122         if (lc_info==null) {
123             lc_info = new DependentInfo();
124             lc_info.mainProperty = in_dependsFrom;
125             lc_map.put(in_dependsFrom, lc_info);
126         }
127         
128         // Return the DependentInfo.
129
return lc_info;
130     }
131
132     /**
133      * Init the dependent combo this tag is a datasource from.
134      */

135     protected void makeDependentCombo(DependentInfo in_dependentInfo) throws JspException JavaDoc {
136         // 1 : generate js data.
137
generateDependentComboData(in_dependentInfo);
138         
139         // 2 : register a Javascript handler for the parent select tag.
140
registerDependentComboHandler(in_dependentInfo);
141     }
142     
143     /**
144      * Build JS array name.
145      */

146     protected String JavaDoc buildCollectionName(DependentInfo in_info) {
147         StringBuffer JavaDoc lc_collection = new StringBuffer JavaDoc();
148         lc_collection.append(in_info.mainCollectionProperty==null ? in_info.mainCollectionName : in_info.mainCollectionProperty);
149         lc_collection.append("_");
150         lc_collection.append(in_info.dependentCollectionProperty);
151         return lc_collection.toString();
152     }
153     
154     /**
155      * Generate js data for dependent combos.
156      */

157     protected void generateDependentComboData(DependentInfo in_info) throws JspException JavaDoc {
158         String JavaDoc lc_collection = buildCollectionName(in_info);
159         TagUtils.write(pageContext, "<script>var ");
160         TagUtils.write(pageContext, lc_collection);
161         TagUtils.write(pageContext, " = new Array();\n");
162         
163         Iterator JavaDoc lc_it = LayoutUtils.getIterator(pageContext, in_info.mainCollectionName, in_info.mainCollectionProperty);
164         generateDependentComboData(in_info, lc_it, lc_collection);
165         TagUtils.write(pageContext, "</script>\n");
166     }
167     
168     protected void generateDependentComboData(DependentInfo in_info, Iterator JavaDoc in_it, String JavaDoc in_collection) throws JspException JavaDoc {
169         String JavaDoc collection = in_collection;
170         String JavaDoc nestedCollection = in_info.dependentCollectionProperty;
171         
172         int i = 0;
173         while (in_it.hasNext()) {
174             Object JavaDoc lc_bean = in_it.next();
175             // Define the js bean.
176
TagUtils.write(pageContext, collection);
177             TagUtils.write(pageContext, "[");
178             TagUtils.write(pageContext, String.valueOf(i));
179             TagUtils.write(pageContext, "] = new Object();\n");
180             
181             // Define the js bean value.
182
TagUtils.write(pageContext, collection);
183             TagUtils.write(pageContext, "[");
184             TagUtils.write(pageContext, String.valueOf(i));
185             TagUtils.write(pageContext, "].value = \"");
186             TagUtils.write(pageContext, filter(LayoutUtils.getProperty(lc_bean, in_info.mainCollectionBeanProperty)));
187             TagUtils.write(pageContext, "\";\n");
188             
189             // Define the js bean nested collection.
190
TagUtils.write(pageContext, collection);
191             TagUtils.write(pageContext, "[");
192             TagUtils.write(pageContext, String.valueOf(i));
193             TagUtils.write(pageContext, "].");
194             TagUtils.write(pageContext, nestedCollection);
195             TagUtils.write(pageContext, " = new Array();\n");
196             
197             // Initalize the nested collection
198
Object JavaDoc lc_nestedCollection = LayoutUtils.getProperty(lc_bean, nestedCollection);
199             Iterator JavaDoc lc_nestedIterator = LayoutUtils.getIterator(lc_nestedCollection);
200             int j = 0;
201             while (lc_nestedIterator.hasNext()) {
202                 Object JavaDoc lc_nestedBean = lc_nestedIterator.next();
203                 TagUtils.write(pageContext, collection);
204                 TagUtils.write(pageContext, "[");
205                 TagUtils.write(pageContext, String.valueOf(i));
206                 TagUtils.write(pageContext, "].");
207                 TagUtils.write(pageContext, nestedCollection);
208                 TagUtils.write(pageContext, "[");
209                 TagUtils.write(pageContext, String.valueOf(j));
210                 TagUtils.write(pageContext, "] = new Object();\n");
211                 
212                 TagUtils.write(pageContext, collection);
213                 TagUtils.write(pageContext, "[");
214                 TagUtils.write(pageContext, String.valueOf(i));
215                 TagUtils.write(pageContext, "].");
216                 TagUtils.write(pageContext, nestedCollection);
217                 TagUtils.write(pageContext, "[");
218                 TagUtils.write(pageContext, String.valueOf(j));
219                 TagUtils.write(pageContext, "].value = \"");
220                 TagUtils.write(pageContext, filter(LayoutUtils.getProperty(lc_nestedBean, in_info.dependentCollectionValue)));
221                 TagUtils.write(pageContext, "\";\n");
222                 
223                 TagUtils.write(pageContext, collection);
224                 TagUtils.write(pageContext, "[");
225                 TagUtils.write(pageContext, String.valueOf(i));
226                 TagUtils.write(pageContext, "].");
227                 TagUtils.write(pageContext, nestedCollection);
228                 TagUtils.write(pageContext, "[");
229                 TagUtils.write(pageContext, String.valueOf(j));
230                 TagUtils.write(pageContext, "].label = \"");
231                 TagUtils.write(pageContext, filter(LayoutUtils.getProperty(lc_nestedBean, in_info.dependentCollectionLabel)));
232                 TagUtils.write(pageContext, "\";\n");
233                 
234                 j++;
235             }
236             
237             i++;
238         }
239         
240     }
241     
242     /**
243      * Filter sensitive js and html character
244      */

245     protected String JavaDoc filter(Object JavaDoc in_string) {
246         if (in_string==null) {
247             return "";
248         }
249         String JavaDoc lc_string = in_string.toString();
250         if (lc_string.length()==0) {
251             return "";
252         }
253         StringBuffer JavaDoc lc_buffer = new StringBuffer JavaDoc(lc_string.length());
254         int i;
255         for (i = 0; i < lc_string.length(); i++) {
256             char c = lc_string.charAt(i);
257             switch (c) {
258                 case '<':
259                     lc_buffer.append("&lt;");
260                     break;
261                 case '>':
262                     lc_buffer.append("&gt;");
263                 case '"':
264                     lc_buffer.append("\"");
265                 default:
266                     lc_buffer.append(c);
267             }
268         }
269         return lc_buffer.toString();
270     }
271
272     /**
273      * Register a Javascript handler to initialize the dependent combos when a value is selected.
274      */

275     protected void registerDependentComboHandler(DependentInfo in_info) throws JspException JavaDoc {
276         // Find the selected value.
277
SelectTag lc_selectTag = (SelectTag) findAncestorWithClass(this, SelectTag.class);
278         Object JavaDoc lc_selectedValue = lc_selectTag.getFieldValue();
279         if (lc_selectedValue!=null && lc_selectedValue.getClass().isArray()) {
280             Object JavaDoc[] lc_temp = (Object JavaDoc[]) lc_selectedValue;
281             if (lc_temp.length>0) {
282                 lc_selectedValue = lc_temp[0];
283             }
284         }
285         if (lc_selectedValue!=null) {
286             lc_selectedValue = lc_selectedValue.toString();
287         }
288         
289         // Easy, do it with Javascript.
290
String JavaDoc lc_collection = buildCollectionName(in_info);
291         TagUtils.write(pageContext, "<script>initDependentComboHandler(\"");
292         TagUtils.write(pageContext, in_info.mainProperty);
293         TagUtils.write(pageContext, "\",\"");
294         TagUtils.write(pageContext, in_info.dependentProperty);
295         TagUtils.write(pageContext, "\",\"");
296         TagUtils.write(pageContext, lc_collection);
297         TagUtils.write(pageContext, "\",\"");
298         TagUtils.write(pageContext, in_info.dependentCollectionProperty);
299         TagUtils.write(pageContext, "\",\"");
300         TagUtils.write(pageContext, (String JavaDoc)lc_selectedValue);
301         TagUtils.write(pageContext, "\");</script>\n");
302     }
303
304     
305     public void release() {
306         collection = null;
307         dependsFrom = null;
308         labelProperty = null;
309         property = null;
310     }
311     
312     public void setCollection(String JavaDoc in_collection) {
313         collection = in_collection;
314     }
315     
316     public void setDependsFrom(String JavaDoc in_dependsFrom) {
317         dependsFrom = in_dependsFrom;
318     }
319     
320     public void setLabelProperty(String JavaDoc in_labelProperty) {
321         labelProperty = in_labelProperty;
322     }
323     
324     public void setProperty(String JavaDoc in_property) {
325         property = in_property;
326     }
327 }
328
Popular Tags