KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > bridge > jsp > taglib > typehandler > AbstractTypeHandler


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

10 package org.mmbase.bridge.jsp.taglib.typehandler;
11
12 import javax.servlet.jsp.JspTagException JavaDoc;
13 import java.util.*;
14
15 import org.mmbase.bridge.jsp.taglib.edit.FormTag;
16 import org.mmbase.util.*;
17 import org.mmbase.util.transformers.Xml;
18 import org.mmbase.bridge.*;
19 import org.mmbase.bridge.util.Queries;
20 import org.mmbase.bridge.jsp.taglib.*;
21 import org.mmbase.storage.search.*;
22 import org.mmbase.datatypes.*;
23 import org.mmbase.util.logging.Logger;
24 import org.mmbase.util.logging.Logging;
25
26 /**
27  * @javadoc
28  *
29  * @author Gerard van de Looi
30  * @author Michiel Meeuwissen
31  * @since MMBase-1.6
32  * @version $Id: AbstractTypeHandler.java,v 1.48 2006/04/27 17:35:59 michiel Exp $
33  */

34
35 public abstract class AbstractTypeHandler implements TypeHandler {
36     private static final Logger log = Logging.getLoggerInstance(AbstractTypeHandler.class);
37
38     protected FieldInfoTag tag;
39     protected EnumHandler eh;
40     protected boolean gotEnumHandler = false;
41
42     /**
43      * Constructor for AbstractTypeHandler.
44      */

45     public AbstractTypeHandler(FieldInfoTag tag) {
46         super();
47         this.tag = tag;
48
49     }
50     public void init() {
51         eh = null;
52         gotEnumHandler = false;
53     }
54
55
56     protected EnumHandler getEnumHandler(Node node, Field field) throws JspTagException JavaDoc {
57         if (gotEnumHandler) return eh;
58         gotEnumHandler = true;
59         DataType dt = field.getDataType();
60
61         if (dt.getEnumerationValues(tag.getLocale(), tag.getCloudVar(), node, field) != null) {
62             return new EnumHandler(tag, node, field);
63         }
64
65         // XXX: todo the following stuff may peraps be somehow wrapped to IntegerDataType itself;
66
// but what to do with 200L??
67
if (dt instanceof IntegerDataType) {
68             IntegerDataType idt = (IntegerDataType) dt;
69             final int min = idt.getMin() + (idt.isMinInclusive() ? 0 : 1);
70             final int max = idt.getMax() - (idt.isMaxInclusive() ? 0 : 1);
71             if ((long) max - min < 200L) {
72                 return new EnumHandler(tag, node, field) {
73                         int i = min;
74                         protected Iterator getIterator(Node node, Field field) {
75                             return new Iterator() {
76                                     public boolean hasNext() {
77                                         return i <= max;
78                                     }
79                                     public Object JavaDoc next() {
80                                         Integer JavaDoc value = new Integer JavaDoc(i++);
81                                         return new Entry(value, value);
82                                     }
83                                     public void remove() {
84                                         throw new UnsupportedOperationException JavaDoc();
85                                     }
86                                 };
87                         }
88                     };
89             }
90         }
91         if (dt instanceof LongDataType) {
92             LongDataType ldt = (LongDataType) dt;
93             final long min = ldt.getMin() + (ldt.isMinInclusive() ? 0 : 1);
94             final long max = ldt.getMax() - (ldt.isMaxInclusive() ? 0 : 1);
95             if ((double) max - min < 200.0) {
96                 return new EnumHandler(tag, node, field) {
97                         long i = min;
98                         protected Iterator getIterator(Node node, Field field) {
99                             return new Iterator() {
100                                     public boolean hasNext() {
101                                         return i <= max;
102                                     }
103                                     public Object JavaDoc next() {
104                                         Long JavaDoc value = new Long JavaDoc(i++);
105                                         return new Entry(value, value);
106                                     }
107                                     public void remove() {
108                                         throw new UnsupportedOperationException JavaDoc();
109                                     }
110                                 };
111                         }
112                     };
113             }
114         }
115
116         return null;
117     }
118
119     protected StringBuffer JavaDoc addExtraAttributes(StringBuffer JavaDoc buf) throws JspTagException JavaDoc {
120         String JavaDoc options = tag.getOptions();
121         if (options != null) {
122             int i = options.indexOf("extra:");
123             if (i > -1) {
124                 buf.append(" " + options.substring(i + 6) + " ");
125             }
126         }
127         return buf;
128     }
129
130     /**
131      * @since MMBase-1.8
132      */

133     protected String JavaDoc getClasses(Field field) {
134         return "mm_validate mm_f_" + field.getName() + " mm_nm_" + field.getNodeManager().getName();
135     }
136
137     /**
138      * @see TypeHandler#htmlInput(Node, Field, boolean)
139      */

140     public String JavaDoc htmlInput(Node node, Field field, boolean search) throws JspTagException JavaDoc {
141         eh = getEnumHandler(node, field);
142         if (eh != null) {
143             return eh.htmlInput(node, field, search);
144         }
145         // default implementation.
146
StringBuffer JavaDoc show = new StringBuffer JavaDoc("<input type=\"text\" class=\"small " + getClasses(field) + "\" size=\"80\" ");
147         addExtraAttributes(show);
148         Object JavaDoc value = getFieldValue(node, field, ! search);
149         show.append("name=\"").append(prefix(field.getName())).append("\" ");
150         show.append("id=\"").append(prefixID(field.getName())).append("\" ");
151         show.append("value=\"");
152         show.append((value == null ? "" : Casting.toString(value)));
153         show.append("\" />");
154         return show.toString();
155     }
156
157     /**
158      * Returns the field value as specified by the client's post.
159      */

160     protected Object JavaDoc getFieldValue(Field field) throws JspTagException JavaDoc {
161         Object JavaDoc found = tag.getContextProvider().getContextContainer().find(tag.getPageContext(), prefix(field.getName()));
162         return found;
163     }
164     protected boolean interpretEmptyAsNull(Field field) {
165         return true;
166     }
167
168     protected Object JavaDoc cast(Object JavaDoc value, Node node, Field field) {
169         return field.getDataType().cast(value, node, field);
170     }
171
172     /**
173      * Returns the field value to be used in the page.
174      */

175     protected Object JavaDoc getFieldValue(Node node, Field field, boolean useDefault) throws JspTagException JavaDoc {
176         Object JavaDoc value = getFieldValue(field);
177         if (value == null) {
178             String JavaDoc fieldName = field.getName();
179             if (node != null) {
180                 value = node.isNull(fieldName) ? null : node.getValue(fieldName);
181             } else if (useDefault) {
182                 value = field.getDataType().getDefaultValue();
183             }
184         }
185         return value;
186     }
187
188     public String JavaDoc checkHtmlInput(Node node, Field field, boolean errors) throws JspTagException JavaDoc {
189         eh = getEnumHandler(node, field);
190         if (eh != null) {
191             return eh.checkHtmlInput(node, field, errors);
192         }
193         Object JavaDoc fieldValue = getFieldValue(field);
194         DataType dt = field.getDataType();
195         if (fieldValue == null) {
196             log.debug("Field value not found in context, using existing value ");
197             fieldValue = getFieldValue(node, field, node == null);
198         } else if (fieldValue.equals("") && ! field.isRequired()) {
199             log.debug("Field value found in context is empty, interpreting as null");
200             fieldValue = null;
201         }
202         if (log.isDebugEnabled()) {
203             log.debug("Value for field " + field + ": " + fieldValue);
204         }
205         Collection col = dt.validate(fieldValue, node, field);
206         if (col.size() == 0) {
207             // do actually set the field, because some datatypes need cross-field checking
208
// also in an mm:form, you can simply commit.
209
if (node != null && ! field.isReadOnly()) {
210                 String JavaDoc fieldName = field.getName();
211                 Object JavaDoc oldValue = node.getValue(fieldName);
212                 if (fieldValue == null ? oldValue != null : ! fieldValue.equals(oldValue)) {
213                     try {
214                         if(log.isDebugEnabled()) {
215                             log.debug("Setting " + fieldName + " to " + fieldValue);
216                         }
217                         if ("".equals(fieldValue) && interpretEmptyAsNull(field)) {
218                             node.setValue(fieldName, null);
219                         } else {
220                             node.setValue(fieldName, fieldValue);
221                         }
222                     } catch (Throwable JavaDoc t) {
223                         // may throw exception like 'You cannot change the field"
224
}
225                 } else {
226                     if (log.isDebugEnabled()) {
227                         log.debug("not Setting " + fieldName + " to " + fieldValue + " because already has that value");
228                     }
229                 }
230             }
231             if (errors) {
232                 return "<div id=\"" + prefixError(field.getName()) + "\" class=\"mm_check_noerror\"> </div>";
233             } else {
234                 return "";
235             }
236         } else {
237             FormTag form = (FormTag) tag.findParentTag(FormTag.class, null, false);
238             if (form != null) {
239                 form.setValid(false);
240             }
241             if (errors) {
242                 StringBuffer JavaDoc show = new StringBuffer JavaDoc("<div id=\"");
243                 show.append(prefixError(field.getName()));
244                 show.append("\" class=\"mm_check_error\">");
245                 Locale locale = tag.getLocale();
246                 Iterator i = col.iterator();
247                 while (i.hasNext()) {
248                     LocalizedString error = (LocalizedString) i.next();
249                     show.append("<span>");
250                     Xml.XMLEscape(error.get(locale), show);
251                     show.append("</span>");
252                 }
253                 show.append("</div>");
254                 return show.toString();
255             } else {
256                 return "";
257             }
258         }
259     }
260
261     /**
262      * @see TypeHandler#useHtmlInput(Node, Field)
263      */

264     public boolean useHtmlInput(Node node, Field field) throws JspTagException JavaDoc {
265         String JavaDoc fieldName = field.getName();
266         Object JavaDoc fieldValue = getFieldValue(node, field, false);
267         Object JavaDoc oldValue = node.getValue(fieldName);
268         if (fieldValue == null ? oldValue == null : fieldValue.equals(oldValue)) {
269             return false;
270         } else {
271             if ("".equals(fieldValue) && interpretEmptyAsNull(field)) {
272                 node.setValue(fieldName, null);
273             } else {
274                 node.setValue(fieldName, fieldValue);
275             }
276             return true;
277         }
278     }
279
280
281
282     /**
283      * @see TypeHandler#whereHtmlInput(Field)
284      */

285     public String JavaDoc whereHtmlInput(Field field) throws JspTagException JavaDoc {
286         eh = getEnumHandler(null, field);
287         if (eh != null) {
288             return eh.whereHtmlInput(field);
289         }
290         String JavaDoc string = findString(field);
291         if (string == null) return null;
292         return "( [" + field.getName() + "] =" + getSearchValue(string) + ")";
293     }
294
295     /**
296      * The operator to be used by whereHtmlInput(field, query)
297      * @since MMBase-1.7
298      */

299     protected int getOperator() {
300         return FieldCompareConstraint.EQUAL;
301     }
302     /**
303      * Converts the value to the actual value to be searched. (mainly targeted at StringHandler).
304      * @since MMBase-1.7
305      */

306     protected String JavaDoc getSearchValue(String JavaDoc string) {
307         return string;
308     }
309
310     /**
311      * @since MMBase-1.7
312      */

313     final protected String JavaDoc findString(Field field) throws JspTagException JavaDoc {
314         String JavaDoc fieldName = field.getName();
315         String JavaDoc search = (String JavaDoc) tag.getContextProvider().getContextContainer().find(tag.getPageContext(), prefix(fieldName));
316         if (search == null || "".equals(search)) {
317             return null;
318         }
319         return search;
320     }
321
322
323     public void paramHtmlInput(ParamHandler handler, Field field) throws JspTagException JavaDoc {
324         eh = getEnumHandler(null, field);
325         if (eh != null) {
326             eh.paramHtmlInput(handler, field);
327             return;
328         }
329         handler.addParameter(prefix(field.getName()), findString(field));
330     }
331
332
333     /**
334      * Adds search constraint to Query object.
335      * @return null if nothing to be searched, the constraint if constraint added
336      */

337
338     public Constraint whereHtmlInput(Field field, Query query) throws JspTagException JavaDoc {
339         eh = getEnumHandler(null, field);
340         if (eh != null) {
341             return eh.whereHtmlInput(field, query);
342         }
343         String JavaDoc value = findString(field);
344         if (value != null) {
345             String JavaDoc fieldName = field.getName();
346             if (query.getSteps().size() > 1) {
347                 fieldName = field.getNodeManager().getName()+"."+fieldName;
348             }
349             Constraint con = Queries.createConstraint(query, fieldName, getOperator(), getSearchValue(value));
350             Queries.addConstraint(query, con);
351             return con;
352         } else {
353             return null;
354         }
355     }
356
357     /**
358      * Puts a prefix before a name. This is used in htmlInput and
359      * useHtmlInput, they need it to get a reasonably unique value for
360      * the name attribute of form elements.
361      *
362      */

363     protected String JavaDoc prefix(String JavaDoc s) throws JspTagException JavaDoc {
364         return tag.getPrefix() + "_" + s;
365     }
366
367     /**
368      * Puts a prefix 'mm_' before an id in form fields. To be used in ccs etc..
369      *
370      * @param s Fieldname
371      * @return String with the id, like f.e. 'mm_title'
372      */

373     protected String JavaDoc prefixID(String JavaDoc s) throws JspTagException JavaDoc {
374         String JavaDoc prefix = tag.getPrefix();
375         if (! prefix.equals("")) prefix += "_";
376         return "mm_" + prefix + s;
377     }
378
379     protected String JavaDoc prefixError(String JavaDoc s) throws JspTagException JavaDoc {
380         String JavaDoc prefix = tag.getPrefix();
381         if (! prefix.equals("")) prefix += "_";
382         return "mm_check_" + prefix + s;
383     }
384
385
386
387 }
388
Popular Tags