KickJava   Java API By Example, From Geeks To Geeks.

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


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.util.Notfound;
14 import org.mmbase.bridge.jsp.taglib.editor.EditTag;
15 import javax.servlet.jsp.*;
16 import javax.servlet.jsp.tagext.*;
17
18 import org.mmbase.bridge.*;
19 import org.mmbase.storage.search.*;
20
21 import org.mmbase.util.logging.Logger;
22 import org.mmbase.util.logging.Logging;
23
24 /**
25  * The FieldTag can be used as a child of a 'NodeProvider' tag.
26  *
27  * @author Michiel Meeuwissen
28  * @version $Id: FieldTag.java,v 1.67.2.1 2006/11/29 09:20:59 johannes Exp $
29  */

30 public class FieldTag extends FieldReferrerTag implements FieldProvider, Writer {
31
32     private static final Logger log = Logging.getLoggerInstance(FieldTag.class);
33
34     protected Field field;
35     protected String JavaDoc fieldName;
36     protected Attribute name = Attribute.NULL;
37     protected Attribute notfound = Attribute.NULL;
38
39
40     public void setName(String JavaDoc n) throws JspTagException {
41         name = getAttribute(n);
42     }
43
44     public void setNotfound(String JavaDoc i) throws JspTagException {
45         notfound = getAttribute(i);
46     }
47
48
49     // NodeProvider Implementation
50
/**
51      * A fieldprovider also provides a node.
52      */

53
54     public Node getNodeVar() throws JspTagException {
55         return getNode();
56     }
57
58
59     public Field getFieldVar() {
60         return field;
61     }
62
63     protected void setFieldVar(String JavaDoc n) throws JspTagException {
64         if (n != null) {
65             try {
66                 Node nd = getNode();
67                 if (nd == null) throw new JspTagException("No node found (" + findNodeProvider() + ")");
68                 NodeManager nm = nd.getNodeManager();
69                 if (nm == null) throw new RuntimeException JavaDoc("NodeManager for " + n + " is null!");
70                     field = nm.getField(n);
71         /*
72                 if (!nm.getName().equals("virtual_manager")) {
73         } else {
74             field = null;
75         }
76         */

77             } catch (NotFoundException e) {
78                 field = null;
79             }
80             fieldName = n;
81             if (getReferid() != null) {
82                 throw new JspTagException ("Could not indicate both 'referid' and 'name' attribute");
83             }
84         } else {
85             if (getReferid() == null) {
86                 field = getField(); // get from parent.
87
getNode(); // be sure to set the nodevar too, though.
88
fieldName = field.getName();
89             }
90         }
91     }
92     protected void setFieldVar() throws JspTagException {
93         setFieldVar((String JavaDoc) name.getValue(this));
94     }
95
96     /**
97      * Does something with the generated output. This default
98      * implementation does nothing, but extending classes could
99      * override this function.
100      *
101      **/

102     protected String JavaDoc convert (String JavaDoc s) throws JspTagException { // virtual
103
return s;
104     }
105
106
107     /**
108      * Method to handle the EditTag if it is present around fields and their nodes.
109      * <br /><br />
110      * When the FieldTag finds itself inside an EditTag then it will register its
111      * contents with the EditTag. The EditTag can provide access to an editor.
112      * Not only the field and its nodes will be registered but also the query it
113      * originated from. It passes these to the method
114      * EditTag#registerField(Query query, int nodenr, String fieldName).
115      * @see org.mmbase.bridge.jsp.taglib.editor.EditTag
116      *
117      * @since MMBase-1.8
118      * @todo EXPERIMENTAL
119      */

120     protected void handleEditTag() {
121         // See if this FieldTag has a parent EditTag
122
Tag t = findAncestorWithClass(this, EditTag.class);
123         if (t == null) {
124             if (log.isDebugEnabled()) log.debug("No EditTag as parent. We don't want to edit, i presume.");
125         } else {
126             EditTag et = (EditTag)t;
127             Query query = null;
128             try {
129                 query = findNodeProvider().getGeneratingQuery();
130             } catch (JspTagException jte) {
131                 log.error("JspTagException, no GeneratingQuery found : " + jte);
132             }
133
134             Node node = null;
135             try {
136                 node = getNodeVar();
137             } catch (JspTagException jte) {
138                 if (log.isDebugEnabled()) log.debug("Node not found in getNodeVar() " + jte);
139             }
140
141             if (fieldName == null) {
142                 if (log.isDebugEnabled()) log.debug("fieldName still null. Image tag? URL tag? Attachment?");
143                 if (this instanceof ImageTag) {
144                     if (log.isDebugEnabled()) log.debug("Image! fieldName = handle");
145                     fieldName = "handle";
146                 }
147             }
148             if (fieldName.indexOf(".") < 0) { // No nodemanager? add one
149
fieldName = node.getNodeManager().getName() + "." + fieldName;
150             }
151
152
153             int nodenr = node.getIntValue("number"); // nodenr of this field to pass to EditTag
154
if (nodenr < 0) {
155                 java.util.List JavaDoc steps = query.getSteps();
156                 Step nodeStep = null;
157                 if (query instanceof NodeQuery) {
158                     nodeStep = ((NodeQuery) query).getNodeStep();
159                 }
160                 for (int j = 0; j < steps.size(); j++) {
161                     Step step = (Step)steps.get(j);
162                     if (step.equals(nodeStep)) {
163                         nodenr = node.getIntValue("number");
164                     } else {
165                         String JavaDoc pref = step.getAlias();
166                         if (pref == null) pref = step.getTableName();
167
168                         // check with correct nodemanager
169
String JavaDoc nm = fieldName.substring(0, fieldName.indexOf("."));
170                         if (pref.equals(nm)) {
171                             nodenr = node.getIntValue(pref + ".number");
172                         }
173
174
175                     }
176                 }
177             }
178
179             // register stuff with EditTag
180
if (log.isDebugEnabled()) log.debug("Registering fieldName '" + fieldName + "' with nodenr '" + nodenr + "' and query: " + query);
181             et.registerField(query, nodenr, fieldName);
182         }
183     }
184
185     public int doStartTag() throws JspTagException {
186         Node node = getNode();
187         fieldName = (String JavaDoc) name.getValue(this);
188         if ("number".equals(fieldName)) {
189             if (findNodeProvider() instanceof org.mmbase.bridge.jsp.taglib.edit.CreateNodeTag) {
190                 // WHY can't it simply return the number it _will_ get?
191
throw new JspTagException("It does not make sense to ask 'number' field on uncommited node");
192             }
193         }
194         boolean findValue = true;
195         boolean hasField = node != null && fieldName != null && node.getNodeManager().hasField(fieldName);
196         if (! hasField) {
197             switch(Notfound.get(notfound, this)) {
198             case Notfound.SKIP:
199                 return SKIP_BODY;
200             case Notfound.PROVIDENULL:
201                 findValue = false;
202                 break;
203             case Notfound.MESSAGE:
204                 findValue = false;
205                 try {
206                     getPageContext().getOut().write("Field '" + fieldName + "' does not exist in " + getNode().getNodeManager().getName());
207                 } catch (java.io.IOException JavaDoc ioe) {
208                     log.warn(ioe);
209                 }
210                 break;
211             case Notfound.THROW:
212             default:
213                 if ("log".equals(pageContext.getServletContext().getInitParameter("mmbase.taglib.field.nonExistance"))) {
214                     log.error("Tried to use non-existing field '" + fieldName + "' of node '"
215                                 + node.getNumber() + "' from "
216                                 + getNode().getNodeManager().getName() + "\n"
217                                 + Logging.stackTrace(5));
218                     findValue = false;
219                 }
220
221                 // will cause exception
222
}
223         }
224         Object JavaDoc value = null;
225         if (findValue) {
226             if (hasField || fieldName == null) setFieldVar(fieldName); // set field and node
227
if (log.isDebugEnabled()) {
228                 log.debug("Field.doStartTag(); '" + fieldName + "'");
229             }
230
231             // found the node now. Now we can decide what must be shown:
232
// now also 'node' is availabe;
233
if (field == null) { // some function, or 'referid' was used.
234
if (getReferid() != null) { // referid
235
value = getObject(getReferid());
236                 } else { // function
237
value = node.getValue(fieldName);
238                 }
239             } else { // a field was found!
240
// if direct parent is a Formatter Tag, then communicate
241
FormatterTag f = (FormatterTag) findParentTag(FormatterTag.class, null, false);
242                 if (f != null && f.wantXML()) {
243                     if (log.isDebugEnabled()) log.debug("field " + field.getName() + " is in a formatter tag, creating objects Element. ");
244                     f.getGenerator().add(node, field); // add the field
245
f.setCloud(node.getCloud());
246                     value = "";
247                 } else { // do the rest as well.
248

249                     // if a value is really null, should it be past as null or cast?
250
// I am leaning to the latter but it would break backward compatibility.
251
// currently implemented this behavior for DateTime values (new fieldtype)
252
// Maybe better is an attribute on fieldtag that determines this?
253
// I.e. ifempty = "skip|asis|default"
254
// where:
255
// skip: skips the field tag
256
// asis: returns null as a value
257
// default: returns a default value
258

259                     switch(helper.getVartype()) {
260                     case WriterHelper.TYPE_NODE:
261                         value = node.getNodeValue(fieldName);
262                         break;
263                     case WriterHelper.TYPE_FIELDVALUE:
264                         value = node.getFieldValue(fieldName);
265                         break;
266                     case WriterHelper.TYPE_FIELD:
267                         value = node.getFieldValue(fieldName).getField();
268                         break;
269                     default:
270                         switch(field.getType()) {
271                         case Field.TYPE_BINARY:
272                             value = node.getByteValue(fieldName);
273                             break;
274                         case Field.TYPE_INTEGER:
275                         case Field.TYPE_NODE:
276                             value = new Integer JavaDoc(node.getIntValue(fieldName));
277                             break;
278                         case Field.TYPE_DOUBLE:
279                             value = new Double JavaDoc(node.getDoubleValue(fieldName));
280                             break;
281                         case Field.TYPE_LONG:
282                             value = new Long JavaDoc(node.getLongValue(fieldName));
283                             break;
284                         case Field.TYPE_FLOAT:
285                             value = new Float JavaDoc(node.getFloatValue(fieldName));
286                             break;
287                         case Field.TYPE_DATETIME:
288                             value = node.getValue(fieldName);
289                             if (value != null) {
290                                 value = node.getDateValue(fieldName);
291                             }
292                             break;
293                         case Field.TYPE_BOOLEAN:
294                             value = Boolean.valueOf(node.getBooleanValue(fieldName));
295                             break;
296                         case Field.TYPE_LIST:
297                             value = node.getListValue(fieldName);
298                             break;
299                         default:
300                             value = convert(node.getStringValue(fieldName));
301                         }
302                     }
303                 }
304             }
305             if (log.isDebugEnabled()) log.debug("value of " + fieldName + ": " + value);
306         }
307         handleEditTag();
308
309         helper.setValue(value);
310         if (getId() != null) {
311             getContextProvider().getContextContainer().register(getId(), helper.getValue());
312         }
313         log.debug("end of doStartTag");
314         return EVAL_BODY_BUFFERED;
315     }
316
317
318     public int doAfterBody() throws JspException {
319         return helper.doAfterBody();
320     }
321
322     /**
323      * write the value of the field.
324      **/

325     public int doEndTag() throws JspTagException {
326         log.debug("doEndTag of FieldTag");
327         if ((! "".equals(helper.getString()) && getReferid() != null)) {
328             throw new JspTagException("Cannot use body in reused field (only the value of the field was stored, because a real 'field' object does not exist in MMBase)");
329         }
330         helper.doEndTag();
331         return super.doEndTag();
332     }
333
334     public void doFinally() {
335         field = null;
336         fieldName = null;
337         helper.doFinally();
338         super.doFinally();
339     }
340 }
341
Popular Tags