/**
   * Actively performs the binding from the ObjectModel wrapped in a jxpath context to the
   * CForms-form-widget specified in this object.
   */
  public void doLoad(Widget frmModel, JXPathContext jxpc) throws BindingException {
    Widget widget = selectWidget(frmModel, this.fieldId);
    if (widget == null) {
      throw new BindingException(
          "The widget with the ID ["
              + this.fieldId
              + "] referenced in the binding does not exist in the form definition.");
    }

    Object value = jxpc.getValue(this.xpath);
    if (value != null && convertor != null) {
      if (value instanceof String) {
        ConversionResult conversionResult =
            convertor.convertFromString((String) value, convertorLocale, null);
        if (conversionResult.isSuccessful()) value = conversionResult.getResult();
        else value = null;
      } else {
        getLogger().warn("Convertor ignored on backend-value which isn't of type String.");
      }
    }

    widget.setValue(value);
    if (getLogger().isDebugEnabled()) {
      getLogger().debug("Done loading " + this + " -- value= " + value);
    }
  }
Example #2
0
  public Widget getWidgetForPath(TreePath path) {
    Widget result = (Widget) this.pathWidgets.get(path);
    if (result == null && !this.pathWidgets.containsKey(path)) {
      result = createWidgetForPath(path);
      if (result != null) {
        result.setAttribute("TreePath", path);
      }
      this.pathWidgets.put(path, result);
    }

    return result;
  }
  /**
   * Actively performs the binding from the CForms-form to the ObjectModel wrapped in a jxpath
   * context
   */
  public void doSave(Widget frmModel, JXPathContext jxpc) throws BindingException {
    Widget widget = selectWidget(frmModel, this.fieldId);
    Object value = widget.getValue();
    if (value != null && convertor != null) {
      value = convertor.convertToString(value, convertorLocale, null);
    }

    Object oldValue = jxpc.getValue(this.xpath);
    if (getLogger().isDebugEnabled()) {
      getLogger().debug("value= " + value + " -- oldvalue=" + oldValue);
    }

    boolean update = false;

    if ((value == null && oldValue != null) || value != null && !value.equals(oldValue)) {
      // first update the value itself
      jxpc.createPathAndSetValue(this.xpath, value);

      // now perform any other bindings that need to be performed when the value is updated
      JXPathContext subContext = null;
      try {
        subContext = jxpc.getRelativeContext(jxpc.getPointer(this.xpath));
      } catch (JXPathException e) {
        // if the value has been set to null and the underlying model is a bean, then
        // JXPath will not be able to create a relative context
        if (getLogger().isDebugEnabled()) {
          getLogger()
              .debug("(Ignorable) problem binding field " + widget.getRequestParameterName(), e);
        }
      }
      if (subContext != null) {
        this.updateBinding.saveFormToModel(frmModel, subContext);
      }

      update = true;
    }

    if (getLogger().isDebugEnabled()) {
      getLogger()
          .debug("done saving " + this + " -- value= " + value + " -- on-update == " + update);
    }
  }
  public void doLoad(Widget frmModel, JXPathContext jctx) throws BindingException {
    // (There should be a general widget type checker for all the bindings to use,
    // coupled with a general informative exception class to throw if the widget is
    // of the wrong type or null.)
    Repeater repeater = (Repeater) selectWidget(frmModel, this.repeaterId);
    if (repeater == null) {
      String fullId = frmModel.getRequestParameterName();
      if (fullId == null || fullId.length() == 0) {
        fullId = "";
      } else {
        fullId = fullId + ".";
      }
      throw new RuntimeException(
          "TempRepeaterJXPathBinding: Repeater \""
              + fullId
              + this.repeaterId
              + "\" does not exist ("
              + frmModel.getLocation()
              + ")");
    }

    // Start by clearing the repeater, if necessary.
    if (this.clearOnLoad) {
      repeater.clear();
    }

    // Find the location of the repeater data.
    Pointer repeaterPointer = jctx.getPointer(this.repeaterPath);

    // Check if there is data present.
    //
    // (Otherwise, should we check the leniency config option
    // to decide whether to be silent or throw an exception?)
    if (repeaterPointer != null) {

      // Narrow to repeater context.
      JXPathContext repeaterContext = jctx.getRelativeContext(repeaterPointer);

      // Build a jxpath iterator for the repeater row pointers.
      Iterator rowPointers = repeaterContext.iteratePointers(this.rowPath);

      // Iterate through the rows of data.
      int rowNum = 0;
      while (rowPointers.hasNext()) {

        // Get or create a row widget.
        Repeater.RepeaterRow thisRow;
        if (repeater.getSize() > rowNum) {
          thisRow = repeater.getRow(rowNum);
        } else {
          thisRow = repeater.addRow();
        }
        rowNum++;

        // Narrow to the row context.
        Pointer rowPointer = (Pointer) rowPointers.next();
        JXPathContext rowContext = repeaterContext.getRelativeContext(rowPointer);

        // If virtual rows are requested, place a deep clone of the row data
        // into a temporary node, and narrow the context to this virtual row.
        //
        // (A clone of the data is used to prevent modifying the source document.
        // Otherwise, the appendChild method would remove the data from the source
        // document.  Is this protection worth the penalty of a deep clone?)
        //
        // (This implementation of virtual rows currently only supports DOM
        // bindings, but could easily be extended to support other bindings.)

        if (virtualRows) {
          Node repeaterNode = (Node) repeaterPointer.getNode();
          Node virtualNode = repeaterNode.getOwnerDocument().createElementNS(null, "virtual");
          Node node = (Node) rowPointer.getNode();
          Node clone = node.cloneNode(true);
          Node fakeDocElement = node.getOwnerDocument().getDocumentElement().cloneNode(false);
          virtualNode.appendChild(clone);
          fakeDocElement.appendChild(virtualNode);
          rowContext = JXPathContext.newContext(repeaterContext, fakeDocElement);
          rowContext = rowContext.getRelativeContext(rowContext.getPointer("virtual"));
        }

        // Finally, perform the load row binding.
        this.rowBinding.loadFormFromModel(thisRow, rowContext);
      }
    }

    if (getLogger().isDebugEnabled()) getLogger().debug("done loading rows " + this);
  }