1 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 ; 17 import javax.servlet.jsp.JspException ; 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 ; 35 import org.w3c.dom.Element ; 36 37 38 47 public class FieldInfoTag extends FieldReferrerTag implements Writer { 48 private static Logger log; 49 50 private static Class defaultHandler = DefaultTypeHandler.class; 51 private static Map handlers = new HashMap(); 53 static { 54 try { 55 log = Logging.getLoggerInstance(FieldInfoTag.class); 56 initializeTypeHandlers(); 57 } catch (Exception 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 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 sessionName = "cloud_mmbase"; 88 89 public String getSessionName() { 90 return sessionName; 91 } 92 93 protected Attribute type = Attribute.NULL; 94 95 public void setType(String t) throws JspTagException { 96 type = getAttribute(t); 97 } 98 99 protected Attribute container = Attribute.NULL; 101 102 protected int getType() throws JspTagException { 105 String 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 ("Unknown value for attribute type (" + t + ")"); 144 } 145 } 146 private Attribute options = Attribute.NULL; 147 public void setOptions(String o) throws JspTagException { 148 options = getAttribute(o); 149 } 150 151 public String getOptions() throws JspTagException { 152 return (String ) options.getValue(this); 153 } 154 155 private Attribute dataType = Attribute.NULL; 156 159 public void setDatatype(String d) throws JspTagException { 160 dataType = getAttribute(d); 161 } 162 165 public DataType getDataType() throws JspTagException { 166 String dataTypeName = dataType.getString(this); 167 if (dataTypeName.equals("")) { 168 return null; 169 } 170 return DataTypes.getDataType(dataTypeName); 171 } 172 173 177 protected TypeHandler getTypeHandler(Field field) { 178 DataType dataType = field.getDataType(); 179 Class dataTypeClass = dataType.getClass(); 180 Class handler = (Class ) 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 ) 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 ) 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 []{FieldInfoTag.class}).newInstance(new Object []{this}); 202 } catch (Exception 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 211 private static void initializeTypeHandlers() { 212 log.service("Reading taglib field-handlers"); 213 handlers = new HashMap(); 214 215 Class thisClass = FieldInfoTag.class; 216 InputSource fieldtypes = new InputSource (thisClass.getResourceAsStream("resources/fieldtypes.xml")); 217 DocumentReader reader = new DocumentReader(fieldtypes, thisClass); 218 Element fieldtypesElement = reader.getElementByPath("fieldtypes"); 219 220 for (Iterator iter = reader.getChildElements(fieldtypesElement, "fieldtype"); iter.hasNext();) { 221 Element element = (Element ) iter.next(); 222 String type = element.getAttribute("id"); 223 DataType dataType = DataTypes.getDataType(type); 224 Class dataTypeClass = dataType.getClass(); 225 if (dataType == null) { 226 log.warn("'" + type + "' is not a known datatype"); 227 } 228 String 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 ex) { 233 log.error("Class " + claz + " could not be found for type " + type + "(" + dataTypeClass + ")"); 234 handlers.put(dataTypeClass, defaultHandler); 235 } 236 } 237 } 238 239 242 private static Class getDefaultTypeHandler() { 243 return defaultHandler; 244 } 245 246 247 248 public int doStartTag() throws JspTagException { 249 findWriter(false); 251 Node node = null; 252 FieldProvider fieldProvider = findFieldProvider(); 253 Field field = fieldProvider.getFieldVar(); 254 String fieldName = field.getName(); 255 256 { 257 260 CloudTag ct = null; 261 ct = (CloudTag) findParentTag(CloudTag.class, null, false); 262 if (ct != null) { 263 sessionName = ct.getSessionName(); 264 } 265 266 } 267 String show = null; 269 270 int infoType = getType(); 271 272 if (log.isDebugEnabled()) { 273 log.debug("infotype:" + type.getValue(this) + " -> " + infoType); 274 } 275 switch(infoType) { 277 case TYPE_CHECK: 278 case TYPE_ERRORS: 279 if (node == null) { node = fieldProvider.getNodeVar(); 281 } break; 283 case TYPE_INPUT: 284 if (node == null) { node = fieldProvider.getNodeVar(); 286 } if (field.isReadOnly()) { 288 if (node != null) { 290 infoType = TYPE_GUIVALUE; 291 } else { 292 infoType = TYPE_UNSET; 293 } 294 } 295 break; 296 case TYPE_USEINPUT: 299 if (field.isReadOnly()) { 300 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 ("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 ) container.getValue(this), false); 366 if (c == null) { 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); 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 424 425 private String htmlInput(Node node, Field field, boolean search) throws JspTagException { 426 if (log.isDebugEnabled()) { 427 String 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 444 445 private boolean useHtmlInput(Node node, Field field) throws JspTagException { 446 return getTypeHandler(field).useHtmlInput(node, field); 447 } 448 449 450 451 private String checkHtmlInput(Node node, Field field, boolean errors) throws JspTagException { 452 return getTypeHandler(field).checkHtmlInput(node, field, errors); 453 } 454 455 456 460 private String whereHtmlInput(Field field) throws JspTagException { 461 return getTypeHandler(field).whereHtmlInput(field); 462 } 463 464 private void paramHtmlInput(ParamHandler handler, Field field) throws JspTagException { 465 getTypeHandler(field).paramHtmlInput(handler, field); 466 } 467 468 469 private void whereHtmlInput(Field field, Query query) throws JspTagException { 470 getTypeHandler(field).whereHtmlInput(field, query); 471 } 472 473 474 477 public int doEndTag() throws JspTagException { 478 helper.doEndTag(); 479 return super.doEndTag(); 480 } 481 482 public int doAfterBody() throws JspException { 483 return helper.doAfterBody(); 484 } 485 486 487 490 public String getPrefix() throws JspTagException { 491 FormTag ft = (FormTag) findParentTag(FormTag.class, null, false); 492 String 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 505 506 public String decode(String value, org.mmbase.bridge.Node n) throws JspTagException { 507 return value; 508 } 509 510 public String encode(String value, Field f) throws JspTagException { 511 return value; 512 } 513 514 515 } 516 | Popular Tags |