Beispiel #1
0
  private void processPropertyBindings(Component comp, String propName) {
    final ComponentCtrl compCtrl = (ComponentCtrl) comp;

    // validator and converter information
    ValidatorInfo validatorInfo = parseValidator(compCtrl, propName);
    ConverterInfo converterInfo = parseConverter(compCtrl, propName);

    // scan init
    Collection<Annotation> initannos = compCtrl.getAnnotations(propName, INIT_ANNO);
    if (initannos.size() > 1) {
      throw new IllegalSyntaxException("Allow only one @init for " + propName + " of " + comp);
    } else if (initannos.size() == 1) {
      processPropertyInit(comp, propName, initannos.iterator().next(), converterInfo);
    }

    Collection<Annotation> annos =
        compCtrl.getAnnotations(propName); // init in the annotation with the sequence

    for (Annotation anno : annos) {
      if (anno.getName().equals(BIND_ANNO)) {
        processPropertyPromptBindings(comp, propName, anno, converterInfo, validatorInfo);
      } else if (anno.getName().equals(LOAD_ANNO)) {
        processPropertyLoadBindings(comp, propName, anno, converterInfo);
      } else if (anno.getName().equals(SAVE_ANNO)) {
        processPropertySaveBindings(comp, propName, anno, converterInfo, validatorInfo);
      }
    }
  }
Beispiel #2
0
  private void processCommandBinding(Component comp, String propName) {
    final ComponentCtrl compCtrl = (ComponentCtrl) comp;
    final Collection<Annotation> anncol = compCtrl.getAnnotations(propName, COMMAND_ANNO);
    if (anncol.size() == 0) return;
    if (anncol.size() > 1) {
      throw new IllegalSyntaxException(
          "Allow only one command binding for event " + propName + " of " + compCtrl);
    }
    final Annotation ann = anncol.iterator().next();

    final Map<String, String[]> attrs = ann.getAttributes(); // (tag, tagExpr)
    Map<String, String[]> args = null;
    final List<String> cmdExprs = new ArrayList<String>();
    for (final Iterator<Entry<String, String[]>> it = attrs.entrySet().iterator(); it.hasNext(); ) {
      final Entry<String, String[]> entry = it.next();
      final String tag = entry.getKey();
      final String[] tagExpr = entry.getValue();
      if ("value".equals(tag)) {
        cmdExprs.add(testString(comp, propName, tag, tagExpr));
      } else { // other unknown tag, keep as arguments
        if (args == null) {
          args = new HashMap<String, String[]>();
        }
        args.put(tag, tagExpr);
      }
    }

    final Map<String, Object> parsedArgs = args == null ? null : parsedArgs(args);
    for (String cmd : cmdExprs) {
      _binder.addCommandBinding(comp, propName, cmd, parsedArgs);
    }
  }
Beispiel #3
0
  private void processFormBindings(Component comp) {
    final ComponentCtrl compCtrl = (ComponentCtrl) comp;
    final BindEvaluatorX eval = _binder.getEvaluatorX();
    // validator information
    ValidatorInfo validatorInfo = parseValidator(compCtrl, FORM_ATTR);

    String formId = null;

    Collection<Annotation> idannos = compCtrl.getAnnotations(FORM_ATTR, ID_ANNO);
    if (idannos.size() == 0) {
      throw new IllegalSyntaxException("@id is not found for a form binding of " + compCtrl);
    } else if (idannos.size() > 1) {
      throw new IllegalSyntaxException("Allow only one @id for a form binding of " + compCtrl);
    }

    final Annotation idanno = idannos.iterator().next();
    final String idExpr = idanno.getAttribute("value");

    if (idExpr != null) {
      formId = BindEvaluatorXUtil.eval(eval, comp, idExpr, String.class);
    }
    if (formId == null) {
      throw new UiException(
          "value of @id is not found for a form binding of "
              + compCtrl
              + ", exprssion is "
              + idExpr);
    }

    // scan init first
    Collection<Annotation> initannos = compCtrl.getAnnotations(FORM_ATTR, INIT_ANNO);
    if (initannos.size() > 1) {
      throw new IllegalSyntaxException("Allow only one @init for " + FORM_ATTR + " of " + comp);
    } else if (initannos.size() == 1) {
      processFormInit(comp, formId, initannos.iterator().next());
    }

    Collection<Annotation> annos =
        compCtrl.getAnnotations(FORM_ATTR); // get all annotation in the form with the order.

    for (Annotation anno : annos) {
      if (anno.getName().equals(LOAD_ANNO)) {
        processFormLoadBindings(comp, formId, anno);
      } else if (anno.getName().equals(SAVE_ANNO)) {
        processFormSaveBindings(comp, formId, anno, validatorInfo);
      }
    }
  }
Beispiel #4
0
  /**
   * Process the event. Note: it doesn't invoke EventThreadInit and EventThreadCleanup.
   *
   * <p>This method is to implement {@link org.zkoss.zk.ui.sys.EventProcessingThread}. See also
   * {@link org.zkoss.zk.ui.util.Configuration#isEventThreadEnabled}.
   */
  public void process() throws Exception {
    final ExecutionMonitor execmon = _desktop.getWebApp().getConfiguration().getExecutionMonitor();
    // Bug 1506712: event listeners might be zscript, so we have to
    // keep built-in variables as long as possible
    final Scope scope = Scopes.beforeInterpret(_comp);
    // we have to push since process0 might invoke methods from zscript class
    try {
      Scopes.setImplicit("event", _event);

      _event = ((DesktopCtrl) _desktop).beforeProcessEvent(_event);
      if (_event != null) {
        if (execmon != null) execmon.eventStart(_event);

        Scopes.setImplicit("event", _event); // _event might change
        ((ComponentCtrl) _comp).service(_event, scope);
        ((DesktopCtrl) _desktop).afterProcessEvent(_event);
      }
    } finally {
      final Execution exec = _desktop.getExecution();
      if (exec != null) // just in case
      ((ExecutionCtrl) exec).setExecutionInfo(null);
      if (execmon != null && _event != null) execmon.eventComplete(_event);
      Scopes.afterInterpret();
    }
  }
Beispiel #5
0
 private ValidatorInfo parseValidator(ComponentCtrl compCtrl, String propName) {
   final Collection<Annotation> annos = compCtrl.getAnnotations(propName, VALIDATOR_ANNO);
   if (annos.size() == 0) return null;
   if (annos.size() > 1) {
     throw new IllegalSyntaxException(
         "Allow only one validator for " + propName + " of " + compCtrl);
   }
   final Annotation anno = annos.iterator().next();
   ValidatorInfo info = new ValidatorInfo();
   Map<String, String[]> args = null;
   for (final Iterator<Entry<String, String[]>> it = anno.getAttributes().entrySet().iterator();
       it.hasNext(); ) {
     final Entry<String, String[]> entry = it.next();
     final String tag = entry.getKey();
     final String[] tagExpr = entry.getValue();
     if ("value".equals(tag)) {
       info.expr = testString(compCtrl, propName, tag, tagExpr);
     } else { // other unknown tag, keep as arguments
       if (args == null) {
         args = new HashMap<String, String[]>();
       }
       args.put(tag, tagExpr);
     }
   }
   if (Strings.isBlank(info.expr)) {
     throw new IllegalSyntaxException(
         "Must specify a validator for " + propName + " of " + compCtrl);
   }
   info.args = args == null ? null : parsedArgs(args);
   return info;
 }
Beispiel #6
0
  private void processComponentBindings0(Component comp) {
    final ComponentCtrl compCtrl = (ComponentCtrl) comp;

    final List<String> props =
        compCtrl.getAnnotatedProperties(); // look every property has annotation
    for (final Iterator<?> it = props.iterator(); it.hasNext(); ) {
      final String propName = (String) it.next();
      if (isEventProperty(propName)) {
        processCommandBinding(comp, propName);
      } else if (FORM_ATTR.equals(propName)) {
        processFormBindings(comp);
      } else if (VIEW_MODEL_ATTR.equals(propName)) {
        // ignore
      } else if (BINDER_ATTR.equals(propName)) {
        // ignore
      } else {
        processPropertyBindings(comp, propName);
      }
    }
  }
  public void redraw(Writer out) throws java.io.IOException {
    // Note: _tag == null can NOT be handled specially
    final Execution exec = Executions.getCurrent();
    final boolean root =
        getParent() == null
            && (getPage().isComplete()
                || (exec != null && "complete".equals(ExecutionsCtrl.getPageRedrawControl(exec))));
    if (exec == null
        || exec.isAsyncUpdate(null)
        || (!root && !HtmlPageRenders.isDirectContent(exec))) {
      super.redraw(out); // renderProperties (assume in zscript)
      return;
    }

    Writer oldout = null;
    if (exec != null
        && !HtmlPageRenders.isZkTagsGenerated(exec)
        && exec.getAttribute(ATTR_TOP_NATIVE) == null) { // need to check topmost native only
      String tn;
      if (root
          || "html".equals(tn = _tag != null ? _tag.toLowerCase() : "")
          || "body".equals(tn)
          || "head".equals(tn)) {
        exec.setAttribute(ATTR_TOP_NATIVE, Boolean.TRUE);
        oldout = out;
        out = new StringWriter();
      }
    }

    out.write(getPrologHalf());

    // children
    Component child = getFirstChild();
    if (child == null) {
      // need to invoke outStandalone to generate response if any (Bug 3009925)
      // however, it is not required if not root (since others will invoke)
      if (root) HtmlPageRenders.outStandalone(exec, null, out);
    } else {
      if (root) HtmlPageRenders.setDirectContent(exec, true);
      do {
        Component next = child.getNextSibling();
        if (child instanceof Native
            || ((ComponentCtrl) child).getExtraCtrl() instanceof DirectContent) {
          ((ComponentCtrl) child).redraw(out);
        } else {
          HtmlPageRenders.setDirectContent(exec, false);
          HtmlPageRenders.outStandalone(exec, child, out);
          HtmlPageRenders.setDirectContent(exec, true);
        }
        child = next;
      } while (child != null);
    }

    out.write(getEpilogHalf());

    if (oldout != null) {
      exec.removeAttribute(ATTR_TOP_NATIVE);

      // order: <html><head><zkhead><body>
      // 1. replace <zkhead/> if found
      // 2. insert before </head> if found
      // 3. insert after <body> if found
      // 4. insert after <html> if found
      // 5. insert at the end if none of above found
      final StringBuffer sb = ((StringWriter) out).getBuffer();
      if (!HtmlPageRenders.isZkTagsGenerated(exec)) {
        int jhead = -1, // anchor of header
            junav = -1, // anchor of unavailable
            head = -1, // index of <head>
            heade = -1, // index of </head>
            html = -1; // index of <html>
        for (int j = 0, len = sb.length(); (j = sb.indexOf("<", j)) >= 0; ) {
          ++j;
          if (jhead < 0 && startsWith(sb, "zkhead", j)) {
            int l = Strings.indexOf(sb, '>', j) + 1;
            sb.delete(jhead = --j, l); // jhead found
            len = sb.length();
          } else if (head < 0 && startsWith(sb, "head", j)) {
            head = Strings.indexOf(sb, '>', j) + 1;
          } else if (html < 0 && startsWith(sb, "html", j)) {
            html = Strings.indexOf(sb, '>', j) + 1;
          } else if (junav < 0 && startsWith(sb, "body", j)) {
            junav = Strings.indexOf(sb, '>', j) + 1; // junav found
            break; // done
          } else if (sb.charAt(j) == '/' && startsWith(sb, "head", ++j)) {
            heade = j - 2;
          }
        }

        boolean disableUnavailable = false;
        if (jhead < 0
            && ((jhead = heade) < 0) // use </head> if no <zkhead>
            && ((jhead = head) < 0) // use <head> if no </head> (though unlikely)
            && ((jhead = junav) < 0) // use <body> if no <head>
            && ((jhead = html) < 0)) { // use <html> if no <body>
          if (_tag != null) {
            final String tn = _tag.toLowerCase();
            if ("div".equals(tn) || "span".equals(tn)) {
              l_loop:
              for (int j = 0, len = sb.length(); j < len; ++j)
                switch (sb.charAt(j)) {
                  case '>':
                    disableUnavailable = true; // make output cleaner
                    jhead = j + 1; // found
                  case '=': // it might have something depends on JS
                  case '"':
                    break l_loop;
                }
            }
          }
          if (jhead < 0) jhead = 0; // insert at head if not found
        }

        final String msg = HtmlPageRenders.outUnavailable(exec);
        // called if disableUnavailable (so it won't be generated later)
        if (msg != null && !disableUnavailable) {
          if (junav < 0) {
            if (html >= 0) junav = sb.lastIndexOf("</html");
          }
          if (junav >= 0) sb.insert(junav < jhead ? jhead : junav, msg);
          else sb.append(msg);
        }

        final String zktags = HtmlPageRenders.outHeaderZkTags(exec, getPage());
        if (zktags != null) sb.insert(jhead, zktags);
      }

      oldout.write(sb.toString());
    }
  }