1 16 package org.apache.cocoon.forms.binding; 17 18 import java.util.Collection ; 19 import java.util.Iterator ; 20 import java.util.Map ; 21 22 import org.apache.avalon.framework.logger.LogEnabled; 23 import org.apache.avalon.framework.logger.Logger; 24 import org.apache.cocoon.forms.binding.library.Library; 25 import org.apache.cocoon.forms.formmodel.Widget; 26 import org.apache.cocoon.util.jxpath.DOMFactory; 27 import org.apache.commons.jxpath.JXPathContext; 28 import org.apache.commons.jxpath.Pointer; 29 import org.apache.commons.jxpath.ri.model.beans.BeanPropertyPointer; 30 import org.apache.commons.jxpath.util.TypeUtils; 31 import org.apache.commons.lang.exception.NestableRuntimeException; 32 33 40 public abstract class JXPathBindingBase implements Binding, LogEnabled { 41 42 45 private Logger logger; 46 47 50 private Library localLibrary = null; 51 52 55 private final JXPathBindingBuilderBase.CommonAttributes commonAtts; 56 57 60 protected Binding parent; 61 62 65 protected Map classes; 66 67 private JXPathBindingBase() { 68 this(JXPathBindingBuilderBase.CommonAttributes.DEFAULT); 69 } 70 71 protected JXPathBindingBase( 72 JXPathBindingBuilderBase.CommonAttributes commonAtts) { 73 this.commonAtts = commonAtts; 74 } 75 76 public Library getLocalLibrary() { 77 if(parent != null) { 78 return parent.getLocalLibrary(); 79 } else { 80 return localLibrary; 81 } 82 } 83 public void setLocalLibary(Library lib) { 84 this.localLibrary = lib; 85 } 86 87 public boolean isValid() { 88 if(this.localLibrary!=null) { 89 if(parent!=null) 90 return parent.isValid(); 91 return true; } else { 93 try { 94 return !this.localLibrary.dependenciesHaveChanged(); 95 } catch(Exception e) { 96 logger.error("Error checking dependencies!",e); 97 throw new NestableRuntimeException("Error checking dependencies!",e); 98 } 99 } 100 } 101 102 public JXPathBindingBuilderBase.CommonAttributes getCommonAtts() { 103 return this.commonAtts; 104 } 105 106 109 public String getLocation() { 110 return this.commonAtts.location; 111 } 112 113 116 public void setParent(Binding binding) { 117 this.parent = binding; 118 } 119 120 123 public String getId() { 124 return null; 125 } 126 127 public Binding getClass(String id) { 128 129 Binding classBinding = null; 130 131 try { 132 if(this.localLibrary!=null && (classBinding = this.localLibrary.getBinding(id))!=null) 133 return classBinding; 134 } catch(Exception ignore) {} 135 136 if (classes != null) { 137 classBinding = (Binding)classes.get(id); 139 } 140 if (classBinding == null) { 141 if (parent != null) { 143 classBinding = parent.getClass(id); 144 151 } else { 153 throw new RuntimeException ("Class \"" + id + "\" not found (" + getLocation() + ")"); 154 } 155 } 156 return classBinding; 157 } 158 159 169 protected Widget selectWidget(Widget parent, String id) { 170 if (id == null) return parent; 171 172 Widget childWidget = null; 173 174 childWidget = parent.lookupWidget(id); 175 176 if (childWidget == null) { 177 String containerId = parent.getRequestParameterName(); 178 if(containerId == null || "".equals(containerId)) { 179 containerId = "top-level form-widget"; 180 } else { 181 containerId = "container \"" + containerId + "\""; 182 } 183 throw new RuntimeException (getClass().getName() + " (" + getLocation() + "): Widget \"" + 184 id + "\" does not exist in the " + containerId + 185 " (" + parent.getLocation() + ")."); 186 } 187 188 return childWidget; 189 } 190 191 195 public abstract void doLoad(Widget frmModel, JXPathContext jxpc) 196 throws BindingException; 197 198 204 public final void loadFormFromModel(Widget frmModel, JXPathContext jxpc) 205 throws BindingException { 206 boolean inheritedLeniency = jxpc.isLenient(); 207 applyLeniency(jxpc); 208 applyNSDeclarations(jxpc); 209 if (this.commonAtts.loadEnabled) { 210 doLoad(frmModel, jxpc); 211 } 212 jxpc.setLenient(inheritedLeniency); 213 } 214 215 220 public final void loadFormFromModel(Widget frmModel, Object objModel) 221 throws BindingException { 222 if (objModel != null) { 223 JXPathContext jxpc = makeJXPathContext(objModel); 224 loadFormFromModel(frmModel, jxpc); 225 } else { 226 throw new NullPointerException ( 227 "null object passed to loadFormFromModel() method"); 228 } 229 } 230 231 235 public abstract void doSave(Widget frmModel, JXPathContext jxpc) 236 throws BindingException; 237 238 244 public final void saveFormToModel(Widget frmModel, JXPathContext jxpc) 245 throws BindingException{ 246 boolean inheritedLeniency = jxpc.isLenient(); 247 applyLeniency(jxpc); 248 applyNSDeclarations(jxpc); 249 if (this.commonAtts.saveEnabled) { 250 doSave(frmModel, jxpc); 251 } 252 jxpc.setLenient(inheritedLeniency); 253 } 254 255 260 public void saveFormToModel(Widget frmModel, Object objModel) 261 throws BindingException { 262 if (objModel != null) { 263 JXPathContext jxpc = makeJXPathContext(objModel); 264 saveFormToModel(frmModel, jxpc); 265 } else { 266 throw new NullPointerException ( 267 "null object passed to saveFormToModel() method"); 268 } 269 } 270 271 private void applyLeniency(JXPathContext jxpc) { 272 if (this.commonAtts.leniency != null) { 273 jxpc.setLenient(this.commonAtts.leniency.booleanValue()); 274 } 275 } 276 277 private void applyNSDeclarations(JXPathContext jxpc) 278 { 279 if (this.commonAtts.nsDeclarations != null) 280 { 281 Iterator keysIter = this.commonAtts.nsDeclarations.keySet().iterator(); 282 while (keysIter.hasNext()) 283 { 284 String nsuri = (String ) keysIter.next(); 285 String pfx = (String ) this.commonAtts.nsDeclarations.get(nsuri); 286 jxpc.registerNamespace(pfx, nsuri); 287 } 288 } 289 } 290 291 private JXPathContext makeJXPathContext(Object objModel) { 292 JXPathContext jxpc; 293 if (!(objModel instanceof JXPathContext)) { 294 jxpc = JXPathContext.newContext(objModel); 295 jxpc.setLenient(true); 296 jxpc.setFactory(new BindingJXPathFactory()); 297 } else { 298 jxpc = (JXPathContext) objModel; 299 } 300 return jxpc; 301 } 302 303 308 public void enableLogging(Logger logger) { 309 this.logger = logger; 310 } 311 312 protected Logger getLogger() { 313 return logger; 314 } 315 316 319 private static class BindingJXPathFactory extends DOMFactory { 320 321 public boolean createObject(JXPathContext context, Pointer pointer, Object parent, String name, int index) { 322 if (createCollectionItem(context, pointer, parent, name, index)) { 323 return true; 324 } else if (pointer instanceof BeanPropertyPointer) { 326 return createBeanField(context, pointer, parent, name, index); 327 } else { 328 return super.createObject(context, pointer, parent, name, index); 329 } 330 } 331 332 private boolean createCollectionItem(JXPathContext context, Pointer pointer, Object parent, String name, int index) { 333 final Object o = context.getValue(name); 336 if (o == null) { 337 return false; 338 } 339 if (o instanceof Collection ) { 340 ((Collection )o).add(null); 341 } else if(o.getClass().isArray()) { 342 return false; 344 } else { 345 return false; 346 } 347 return true; 348 } 349 350 private boolean createBeanField(JXPathContext context, Pointer pointer, Object parent, String name, int index) { 357 try { 358 Class clazz = parent.getClass().getDeclaredField(name).getType(); 359 Object o = context.getValue(name); 360 if (o == null) { 361 final Class [] parametersTypes = {String .class}; 362 final Object [] initArgs = {"0"}; 363 try { 364 o = clazz.getConstructor(parametersTypes).newInstance(initArgs); 368 } catch (Exception e) { 369 o = clazz.newInstance(); 373 } 374 } else if (TypeUtils.canConvert(o, clazz)) { 375 o = TypeUtils.convert(o, clazz); 376 } 377 if (o != null) { 378 pointer.setValue(o); 379 return true; } 381 } catch (Exception e) { 382 } 384 return false; 385 } 386 } 387 } 388 | Popular Tags |