KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > bridge > jsp > taglib > FieldInfoTag


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;
11
12 import org.mmbase.bridge.jsp.taglib.util.Attribute;
13 import org.mmbase.bridge.jsp.taglib.containers.*;
14 import org.mmbase.bridge.jsp.taglib.edit.FormTag;
15
16 import javax.servlet.jsp.JspTagException JavaDoc;
17 import javax.servlet.jsp.JspException JavaDoc;
18
19 import java.util.*;
20 import org.mmbase.bridge.*;
21 import org.mmbase.datatypes.*;
22 import org.mmbase.util.Casting;
23
24 import org.mmbase.util.logging.Logger;
25 import org.mmbase.util.logging.Logging;
26 import org.mmbase.util.xml.DocumentReader;
27 import org.mmbase.util.functions.*;
28
29 import org.mmbase.core.util.Fields;
30
31
32 import org.mmbase.bridge.jsp.taglib.typehandler.TypeHandler;
33 import org.mmbase.bridge.jsp.taglib.typehandler.DefaultTypeHandler;
34 import org.xml.sax.InputSource JavaDoc;
35 import org.w3c.dom.Element JavaDoc;
36
37
38 /**
39  * The FieldInfoTag can be used as a child of a 'FieldProvider' to
40  * provide info about the field or fieldtype.
41  *
42  * @author Michiel Meeuwissen
43  * @author Jaco de Groot
44  * @author Gerard van de Looi
45  * @version $Id: FieldInfoTag.java,v 1.97.2.1 2006/10/03 21:12:52 michiel Exp $
46  */

47 public class FieldInfoTag extends FieldReferrerTag implements Writer {
48     private static Logger log;
49
50     private static Class JavaDoc defaultHandler = DefaultTypeHandler.class;
51     private static Map handlers = new HashMap(); // datatype-class --> handler Class
52

53     static {
54         try {
55             log = Logging.getLoggerInstance(FieldInfoTag.class);
56             initializeTypeHandlers();
57         } catch (Exception JavaDoc e) {
58             log.error(e.toString());
59         }
60     }
61
62     protected static final int TYPE_NAME = 0;
63     protected static final int TYPE_GUINAME = 1;
64     protected static final int TYPE_VALUE = 2;
65     protected static final int TYPE_GUIVALUE = 3;
66     protected static final int TYPE_TYPE = 4;
67     protected static final int TYPE_GUITYPE = 5;
68     protected static final int TYPE_DESCRIPTION = 6;
69     protected static final int TYPE_TYPEDESCRIPTION = 7;
70     protected static final int TYPE_DATATYPE = 8;
71     protected static final int TYPE_DATATYPEDESCRIPTION = 9;
72     protected static final int TYPE_DATATYPEXML = 10;
73
74     protected static final int TYPE_UNSET = 100;
75
76     // input and useinput produces pieces of HTML
77
// very handy if you're creating an editor, but well yes, not very elegant.
78
protected static final int TYPE_INPUT = 14;
79     protected static final int TYPE_CHECK = 15;
80     protected static final int TYPE_ERRORS = 16;
81     protected static final int TYPE_USEINPUT = 17;
82     protected static final int TYPE_SEARCHINPUT = 18;
83     protected static final int TYPE_USESEARCHINPUT = 19;
84     protected static final int TYPE_REUSESEARCHINPUT = 20;
85
86
87     private String JavaDoc sessionName = "cloud_mmbase";
88
89     public String JavaDoc getSessionName() {
90         return sessionName;
91     }
92
93     protected Attribute type = Attribute.NULL;
94
95     public void setType(String JavaDoc t) throws JspTagException JavaDoc {
96         type = getAttribute(t);
97     }
98
99     protected Attribute container = Attribute.NULL; // not implemented
100

101
102     // Must be protected because otherwise tomcat does not work
103
// public would be defendable because typehandlers perhaps could need it.
104
protected int getType() throws JspTagException JavaDoc {
105         String JavaDoc t = type.getString(this).toLowerCase();
106         if ("".equals(t)) {
107             return TYPE_UNSET;
108         } else if ("name".equals(t)) {
109             return TYPE_NAME;
110         } else if ("guiname".equals(t)) {
111             return TYPE_GUINAME;
112         } else if ("value".equals(t)) {
113             return TYPE_VALUE;
114         } else if ("guivalue".equals(t)) {
115             return TYPE_GUIVALUE;
116        } else if ("type".equals(t)) {
117             return TYPE_TYPE;
118        } else if ("typedescription".equals(t)) {
119             return TYPE_TYPEDESCRIPTION;
120        } else if ("guitype".equals(t)) {
121             return TYPE_GUITYPE;
122        } else if ("description".equals(t)) {
123             return TYPE_DESCRIPTION;
124        } else if ("datatype".equals(t)) {
125             return TYPE_DATATYPE;
126        } else if ("datatypedescription".equals(t)) {
127             return TYPE_DATATYPEDESCRIPTION;
128         } else if ("input".equals(t)) {
129             return TYPE_INPUT;
130         } else if ("check".equals(t)) {
131             return TYPE_CHECK;
132         } else if ("errors".equals(t)) {
133             return TYPE_ERRORS;
134         } else if ("useinput".equals(t)) {
135             return TYPE_USEINPUT;
136         } else if ("searchinput".equals(t)) {
137             return TYPE_SEARCHINPUT;
138         } else if ("usesearchinput".equals(t)) {
139             return TYPE_USESEARCHINPUT;
140         } else if ("reusesearchinput".equals(t)) {
141             return TYPE_REUSESEARCHINPUT;
142         } else {
143             throw new JspTagException JavaDoc("Unknown value for attribute type (" + t + ")");
144         }
145     }
146     private Attribute options = Attribute.NULL;
147     public void setOptions(String JavaDoc o) throws JspTagException JavaDoc {
148         options = getAttribute(o);
149     }
150
151     public String JavaDoc getOptions() throws JspTagException JavaDoc {
152         return (String JavaDoc) options.getValue(this);
153     }
154
155     private Attribute dataType = Attribute.NULL;
156     /**
157      * @since MMBase-1.8
158      */

159     public void setDatatype(String JavaDoc d) throws JspTagException JavaDoc {
160         dataType = getAttribute(d);
161     }
162     /**
163      * @since MMBase-1.8
164      */

165     public DataType getDataType() throws JspTagException JavaDoc {
166         String JavaDoc dataTypeName = dataType.getString(this);
167         if (dataTypeName.equals("")) {
168             return null;
169         }
170         return DataTypes.getDataType(dataTypeName);
171     }
172
173     /**
174      * Answer the type handler for the given type.
175      * The type handler is responsible for showing the html
176      */

177     protected TypeHandler getTypeHandler(Field field) {
178         DataType dataType = field.getDataType();
179         Class JavaDoc dataTypeClass = dataType.getClass();
180         Class JavaDoc handler = (Class JavaDoc) handlers.get(dataTypeClass);
181         log.debug("Looking for typehandler for " + dataTypeClass);
182         while (handler == null) {
183             log.debug("No handler found for " + dataTypeClass);
184             dataTypeClass = dataTypeClass.getSuperclass();
185             if(dataTypeClass == null) break;
186             handler = (Class JavaDoc) handlers.get(dataTypeClass);
187         }
188
189         if (handler == null) {
190             log.warn("Could not find typehandler for type " + field.getDataType() + " using default for type.");
191             handler = (Class JavaDoc) handlers.get(DataTypes.getDataType(Fields.getTypeDescription(field.getType())).getClass());
192         }
193         if (handler == null) {
194             log.error("Could not even find typehandler for type " + Fields.getTypeDescription(field.getType()) + " using default.");
195             handler = getDefaultTypeHandler();
196         }
197         if (log.isDebugEnabled()) {
198             log.debug("using handler " + handler);
199         }
200         try {
201             return (TypeHandler)handler.getConstructor(new Class JavaDoc[]{FieldInfoTag.class}).newInstance(new Object JavaDoc[]{this});
202         } catch (Exception JavaDoc e) {
203             log.warn("Could not find typehandler for type " + type + " using default. Reason: " + e.toString() );
204             return new DefaultTypeHandler(this);
205         }
206     }
207
208     /**
209      * Initialize the type handlers default supported by the system.
210      */

211     private static void initializeTypeHandlers() {
212         log.service("Reading taglib field-handlers");
213         handlers = new HashMap();
214
215         Class JavaDoc thisClass = FieldInfoTag.class;
216         InputSource JavaDoc fieldtypes = new InputSource JavaDoc(thisClass.getResourceAsStream("resources/fieldtypes.xml"));
217         DocumentReader reader = new DocumentReader(fieldtypes, thisClass);
218         Element JavaDoc fieldtypesElement = reader.getElementByPath("fieldtypes");
219
220         for (Iterator iter = reader.getChildElements(fieldtypesElement, "fieldtype"); iter.hasNext();) {
221             Element JavaDoc element = (Element JavaDoc) iter.next();
222             String JavaDoc type = element.getAttribute("id");
223             DataType dataType = DataTypes.getDataType(type);
224             Class JavaDoc dataTypeClass = dataType.getClass();
225             if (dataType == null) {
226                 log.warn("'" + type + "' is not a known datatype");
227             }
228             String JavaDoc claz = reader.getElementValue(reader.getElementByPath(element, "fieldtype.class"));
229             try {
230                 log.debug("Adding field handler " + claz + " for type " + type + "(" + dataTypeClass + ")");
231                 handlers.put(dataTypeClass, Class.forName(claz));
232             } catch (java.lang.ClassNotFoundException JavaDoc ex) {
233                 log.error("Class " + claz + " could not be found for type " + type + "(" + dataTypeClass + ")");
234                 handlers.put(dataTypeClass, defaultHandler);
235             }
236         }
237     }
238
239     /**
240      * Set the type handler for the given type.
241      */

242     private static Class JavaDoc getDefaultTypeHandler() {
243         return defaultHandler;
244     }
245
246
247
248     public int doStartTag() throws JspTagException JavaDoc{
249         findWriter(false); // just to call haveBody;
250

251         Node node = null;
252         FieldProvider fieldProvider = findFieldProvider();
253         Field field = fieldProvider.getFieldVar();
254         String JavaDoc fieldName = field.getName();
255
256         {
257             /* perhaps 'getSessionName' should be added to CloudProvider
258              * EXPERIMENTAL
259              */

260             CloudTag ct = null;
261             ct = (CloudTag) findParentTag(CloudTag.class, null, false);
262             if (ct != null) {
263                 sessionName = ct.getSessionName();
264             }
265
266         }
267         // found the field now. Now we can decide what must be shown:
268
String JavaDoc show = null;
269
270         int infoType = getType();
271
272         if (log.isDebugEnabled()) {
273             log.debug("infotype:" + type.getValue(this) + " -> " + infoType);
274         }
275         // set node if necessary:
276
switch(infoType) {
277         case TYPE_CHECK:
278         case TYPE_ERRORS:
279             if (node == null) { // try to find nodeProvider
280
node = fieldProvider.getNodeVar();
281             } // node can stay null.
282
break;
283         case TYPE_INPUT:
284             if (node == null) { // try to find nodeProvider
285
node = fieldProvider.getNodeVar();
286             } // node can stay null.
287
if (field.isReadOnly()) {
288                 // show gui
289
if (node != null) {
290                     infoType = TYPE_GUIVALUE;
291                 } else {
292                     infoType = TYPE_UNSET;
293                 }
294             }
295             break;
296             // these types do really need a NodeProvider somewhere:
297
// so 'node' may not stay null.
298
case TYPE_USEINPUT:
299             if (field.isReadOnly()) {
300                 // ignore useinput
301
infoType = TYPE_UNSET;
302                 break;
303             }
304         case TYPE_VALUE:
305         case TYPE_GUIVALUE:
306             if (node == null) {
307                 node = fieldProvider.getNodeVar();
308             }
309             if (node == null) {
310                 throw new JspTagException JavaDoc("Could not find surrounding NodeProvider, which is needed for type=" + type);
311             }
312             break;
313         default:
314         }
315
316         Locale locale = getLocale();;
317
318         switch(infoType) {
319         case TYPE_NAME:
320             show = fieldName;
321             break;
322         case TYPE_GUINAME:
323             show = field.getGUIName(locale);
324             break;
325         case TYPE_VALUE:
326             show = org.mmbase.util.transformers.Xml.XMLEscape(decode(node.getStringValue(fieldName), node));
327             break;
328         case TYPE_GUIVALUE: {
329             if (log.isDebugEnabled()) {
330                 log.debug("field " + fieldName + " --> " + node.getStringValue(field.getName()));
331             }
332             Function guiFunction = node.getFunction("gui");
333             Parameters args = guiFunction.createParameters();
334             if (args.containsParameter(Parameter.FIELD)) {
335                 args.set(Parameter.FIELD, field.getName());
336             }
337             if (args.containsParameter("session")) {
338                 args.set("session", sessionName);
339             }
340             fillStandardParameters(args);
341
342             show = decode(Casting.toString(guiFunction.getFunctionValue(args)), node);
343             if (show.trim().equals("")) {
344                 show = org.mmbase.util.transformers.Xml.XMLEscape(decode(node.getStringValue(fieldName), node));
345             }
346             break;
347         }
348         case TYPE_CHECK:
349             checkHtmlInput(node, field, false);
350             break;
351         case TYPE_ERRORS:
352             show = checkHtmlInput(node, field, true);
353             break;
354         case TYPE_INPUT:
355             show = htmlInput(node, field, false);
356             break;
357         case TYPE_USEINPUT:
358             useHtmlInput(node, field);
359             show = "";
360             break;
361         case TYPE_SEARCHINPUT:
362             show = htmlInput(node, field, true);
363             break;
364         case TYPE_USESEARCHINPUT: {
365             QueryContainer c = (QueryContainer) findParentTag(QueryContainer.class, (String JavaDoc) container.getValue(this), false);
366             if (c == null) { // produce a String to use in a constraint attribute of a list (legacy)
367
log.debug("creating string constraint");
368                 show = whereHtmlInput(field);
369             } else {
370                 Query query = c.getQuery();
371                 if (log.isDebugEnabled()) {
372                     log.debug("Using " + query);
373                 }
374                 whereHtmlInput(field, query);
375                 show = "";
376             }
377
378             break;
379         }
380         case TYPE_REUSESEARCHINPUT: {
381             paramHtmlInput((ParamHandler) findParentTag(ParamHandler.class, null), field);
382             show = "";
383             break;
384         }
385         case TYPE_TYPE:
386             show = "" + field.getType();
387             break;
388         case TYPE_TYPEDESCRIPTION:
389             show = org.mmbase.core.util.Fields.getTypeDescription(field.getType());
390             break;
391         case TYPE_GUITYPE:
392             show = field.getGUIType();
393             break;
394         case TYPE_DESCRIPTION:
395             show = field.getDescription(locale);
396             break;
397         case TYPE_DATATYPE:
398             show = field.getDataType().getName();
399             break;
400         case TYPE_DATATYPEDESCRIPTION:
401             show = field.getDataType().getLocalizedDescription().get(locale);
402             break;
403         default:
404             log.debug("Unknown info type " + infoType);
405             break;
406         }
407
408
409         helper.useEscaper(false); // fieldinfo typicaly produces xhtml
410
helper.setValue(show);
411         if (getId() != null) {
412             getContextProvider().getContextContainer().register(getId(), helper.getValue());
413         }
414         return EVAL_BODY_BUFFERED;
415     }
416
417
418
419     /**
420      * Creates a form entry.
421      * @param node for this node.
422      * @param field and this field.
423      */

424
425     private String JavaDoc htmlInput(Node node, Field field, boolean search) throws JspTagException JavaDoc {
426         if (log.isDebugEnabled()) {
427             String JavaDoc value = "<search>";
428             if (! search) {
429                 if (node == null) {
430                     value = "<create>";
431                 } else {
432                     value = node.getStringValue(field.getName());
433                 }
434             }
435             log.debug("field " + field.getName() + " data type: " + field.getDataType() + " value: " + value);
436         }
437         return getTypeHandler(field).htmlInput(node, field, search);
438     }
439
440
441     /**
442      * Applies a form entry.
443      */

444
445     private boolean useHtmlInput(Node node, Field field) throws JspTagException JavaDoc {
446         return getTypeHandler(field).useHtmlInput(node, field);
447     }
448
449
450
451     private String JavaDoc checkHtmlInput(Node node, Field field, boolean errors) throws JspTagException JavaDoc {
452         return getTypeHandler(field).checkHtmlInput(node, field, errors);
453     }
454
455
456     /**
457      * If you use a form entry to search, then you can use this functions to create the where part.
458      * @param field and this field.
459      */

460     private String JavaDoc whereHtmlInput(Field field) throws JspTagException JavaDoc {
461         return getTypeHandler(field).whereHtmlInput(field);
462     }
463
464     private void paramHtmlInput(ParamHandler handler, Field field) throws JspTagException JavaDoc {
465          getTypeHandler(field).paramHtmlInput(handler, field);
466     }
467
468
469     private void whereHtmlInput(Field field, Query query) throws JspTagException JavaDoc {
470         getTypeHandler(field).whereHtmlInput(field, query);
471     }
472
473
474     /**
475      * Write the value of the fieldinfo.
476      */

477     public int doEndTag() throws JspTagException JavaDoc {
478         helper.doEndTag();
479         return super.doEndTag();
480     }
481
482     public int doAfterBody() throws JspException JavaDoc {
483         return helper.doAfterBody();
484     }
485
486
487     /**
488      * @since MMBase-1.8
489      */

490     public String JavaDoc getPrefix() throws JspTagException JavaDoc {
491         FormTag ft = (FormTag) findParentTag(FormTag.class, null, false);
492         String JavaDoc id = (ft != null ? ft.getId() : null);
493         if (id == null) {
494             id = findFieldProvider().getId();
495         }
496         if (id == null) {
497             id = "";
498         }
499         return id;
500     }
501
502     /**
503      * decode and encode can be overriden.
504      */

505
506     public String JavaDoc decode(String JavaDoc value, org.mmbase.bridge.Node n) throws JspTagException JavaDoc {
507         return value;
508     }
509
510     public String JavaDoc encode(String JavaDoc value, Field f) throws JspTagException JavaDoc {
511         return value;
512     }
513
514
515 }
516
Popular Tags