예제 #1
0
  /**
   * fetches a resources with the help of a Connector. For HTML the response will be a string
   * containing markup that needs to be parsed. <br>
   * <br>
   * If a fragment is given on the URI only the resulting part of the response is returned.
   *
   * @param absoluteURI
   * @return a Node
   * @throws XFormsException
   */
  private Node getEmbeddedDocument(String absoluteURI) throws XFormsException {
    // load resource from absoluteURI
    ConnectorFactory factory = ConnectorFactory.getFactory();
    factory.setContext(this.container.getProcessor().getContext());
    URIResolver uriResolver = factory.createURIResolver(absoluteURI, this.element);

    Object answer = uriResolver.resolve();
    Node embed = null;
    if (answer instanceof Node) {
      embed = (Node) answer;
    } else if (answer instanceof String) {
      // we got some plain HTML and this is returned as a string
      try {
        embed = DOMUtil.parseString((String) answer, true, false);
      } catch (ParserConfigurationException e) {
        throw new XFormsException(e);
      } catch (IOException e) {
        throw new XFormsException(e);
      } catch (SAXException e) {
        throw new XFormsException(e);
      }
    }
    //        embed = extractFragment(absoluteURI, embed);
    return embed;
  }
예제 #2
0
  private String getInlineJavaScript(Node embed) throws XFormsException {
    // fetch style element(s) from Node to embed
    String javaScriptCode = "";
    if (embed instanceof Document) {
      embed = ((Document) embed).getDocumentElement();
    }

    // Get all inline script ignoring script that folllows a xforms:node
    List result =
        XPathUtil.evaluate(
            (Element) embed,
            "//*[not( namespace-uri()='http://www.w3.org/2002/xforms' )]/*[(@type='text/javascript') and (not(boolean(@src)))]");
    if (result.size() == 0) {
      return null;
    }
    for (int i = 0; i < result.size(); i++) {
      Object item = result.get(i);
      if (result.get(i) instanceof NodeWrapper) {
        NodeWrapper wrapper = (NodeWrapper) item;
        if (!"action".equals(((NodeWrapper) item).getParent().getLocalPart())) {
          Node n = (Node) wrapper.getUnderlyingNode();
          javaScriptCode += DOMUtil.getTextNodeAsString(n);
        }
      }
    }

    return javaScriptCode;
  }
예제 #3
0
  private Node extractFragment(String absoluteURI, Node embed) throws XFormsException {
    if (embed instanceof Document && absoluteURI.indexOf("#") != -1) {
      String s = absoluteURI.substring(absoluteURI.indexOf("#") + 1);
      embed = DOMUtil.getById((Document) embed, s);
    }

    if (embed == null) {
      throw new XFormsException("content returned from URI could not be recognized");
    }
    if (embed instanceof Document) {
      embed = ((Document) embed).getDocumentElement();
    }
    return embed;
  }
  /**
   * Serializes and submits the given instance data over the <code>mailto</code> protocol.
   *
   * @param submission the submission issuing the request.
   * @param instance the instance data to be serialized and submitted.
   * @return <code>null</code>.
   * @throws XFormsException if any error occurred during submission.
   */
  public Map submit(Submission submission, Node instance) throws XFormsException {

    if (!submission.getReplace().equals("none")) {
      throw new XFormsException(
          "submission mode '"
              + submission.getReplace()
              + "' at: "
              + DOMUtil.getCanonicalPath(submission.getElement())
              + " not supported");
    }

    try {
      String mediatype = "application/xml";
      if (submission.getMediatype() != null) {
        mediatype = submission.getMediatype();
      }

      String encoding = getDefaultEncoding();
      if (submission.getEncoding() != null) {
        encoding = submission.getEncoding();
      }

      SerializerRequestWrapper wrapper = new SerializerRequestWrapper(new ByteArrayOutputStream());
      serialize(submission, instance, wrapper);
      ByteArrayOutputStream stream = (ByteArrayOutputStream) wrapper.getBodyStream();

      /*
       * Some extension mechanism here could be handy
       */
      String method = submission.getMethod();
      if (method.equals("post")) {
        send(getURI(), stream.toByteArray(), encoding, mediatype);
      } else if (method.equals("multipart-post")) {
        send(getURI(), stream.toByteArray(), encoding, "multipart/related");
      } else if (method.equals("form-data-post")) {
        send(getURI(), stream.toByteArray(), encoding, "multipart/form-data");
      } else if (method.equals("urlencoded-post")) {
        send(getURI(), stream.toByteArray(), encoding, "application/x-www-form-urlencoded");
      } else {
        // Note: user has to provide mediatype in submission element otherwise this will
        // be probably wrong type (application/xml) ...
        send(getURI(), stream.toByteArray(), encoding, mediatype);
      }
    } catch (Exception e) {
      throw new XFormsException(e);
    }

    return null;
  }
예제 #5
0
 private String getInlineCSS(Node embed) throws XFormsException {
   // fetch style element(s) from Node to embed
   String cssRules = "";
   if (embed instanceof Document) {
     embed = ((Document) embed).getDocumentElement();
   }
   List result =
       XPathUtil.evaluate((Element) embed, "//*[@type='text/css' and (not(boolean(@href)))]");
   if (result.size() == 0) {
     return null;
   }
   for (int i = 0; i < result.size(); i++) {
     Object item = result.get(i);
     if (result.get(i) instanceof NodeWrapper) {
       NodeWrapper wrapper = (NodeWrapper) item;
       Node n = (Node) wrapper.getUnderlyingNode();
       cssRules += DOMUtil.getTextNodeAsString(n);
     }
   }
   return cssRules;
 }
예제 #6
0
  /**
   * Performs the <code>load</code> action.
   *
   * @throws XFormsException if an error occurred during <code>load</code> processing.
   */
  public void perform() throws XFormsException {
    String bindAttribute = getXFormsAttribute(BIND_ATTRIBUTE);
    String refAttribute = getXFormsAttribute(REF_ATTRIBUTE);
    boolean includeCSS = true;
    boolean includeScript = true;

    Element extension =
        DOMUtil.findFirstChildNS(this.element, NamespaceConstants.XFORMS_NS, EXTENSION);
    if (extension != null) {
      includeCSS =
          ("true".equalsIgnoreCase(getXFormsAttribute(extension, "includeCSS"))) ? true : false;
      includeScript =
          ("true".equalsIgnoreCase(getXFormsAttribute(extension, "includeScript"))) ? true : false;
    }

    if (this.resource.isAvailable() && (bindAttribute != null || refAttribute != null)) {
      // issue warning
      getLogger()
          .warn(
              this
                  + " perform: since both binding and linking attributes are present this action has no effect");
      return;
    }

    // obtain relative URI
    String relativeURI;
    String absoluteURI = null;
    try {
      // todo: needs refactoring
      updateXPathContext();
      if ("none".equals(this.showAttribute)) {
        // todo: dirty dirty dirty
        String evaluatedTarget = evalAttributeValueTemplates(this.targetAttribute, this.element);
        //                Element targetElem = this.container.getElementById(evaluatedTarget);
        Element targetElem = getTargetElement(evaluatedTarget);
        destroyembeddedModels(targetElem);
        DOMUtil.removeAllChildren(targetElem);
        HashMap map = new HashMap();

        map.put("show", this.showAttribute);
        if (isRepeated()) {
          map.put("nameTarget", evaluatedTarget);
          String idForNamedElement = getXFormsAttribute(getTargetElement(evaluatedTarget), "id");
          map.put("xlinkTarget", idForNamedElement);

        } else {
          map.put("xlinkTarget", evaluatedTarget);
        }

        this.container.dispatch(this.target, BetterFormEventNames.LOAD_URI, map);
        return;
      }

      if (this.resource.isAvailable()) {
        relativeURI = this.resource.getValue();
      } else {

        if (this.nodeset == null || this.nodeset.size() == 0) {
          getLogger().warn(this + " perform: nodeset '" + getLocationPath() + "' is empty");
          return;
        }

        final Instance instance = this.model.getInstance(getInstanceId());
        relativeURI = instance.getNodeValue(XPathUtil.getAsNode(this.nodeset, 1));
      }

      // resolve uri
      absoluteURI =
          this.container.getConnectorFactory().getAbsoluteURI(relativeURI, this.element).toString();

      HashMap map = new HashMap();
      handleEmbedding(absoluteURI, map, includeCSS, includeScript);

    } catch (XFormsException e) {
      LOGGER.error(
          "Error performing xf:load action at: " + DOMUtil.getCanonicalPath(this.getElement()));
      throw new XFormsException(
          "Error performing xf:load action at: " + DOMUtil.getCanonicalPath(this.getElement()), e);
    }

    // backwards compat
    //        storeInContext(absoluteURI, this.showAttribute);
  }
예제 #7
0
  private void handleEmbedding(
      String absoluteURI, HashMap map, boolean includeCSS, boolean includeScript)
      throws XFormsException {

    //        if(this.targetAttribute == null) return;
    // todo: handle multiple params
    if (absoluteURI.indexOf("?") > 0) {
      String name = absoluteURI.substring(absoluteURI.indexOf("?") + 1);
      String value = name.substring(name.indexOf("=") + 1, name.length());
      name = name.substring(0, name.indexOf("="));
      this.container.getProcessor().setContextParam(name, value);
    }
    if (this.targetAttribute == null) {
      map.put("uri", absoluteURI);
      map.put("show", this.showAttribute);

      // dispatch internal betterform event
      this.container.dispatch(this.target, BetterFormEventNames.LOAD_URI, map);
      return;
    }

    if (!("embed".equals(this.showAttribute))) {
      throw new XFormsException(
          "@show must be 'embed' if @target is given but was: '"
              + this.showAttribute
              + "' on Element "
              + DOMUtil.getCanonicalPath(this.element));
    }
    // todo: dirty dirty dirty
    String evaluatedTarget = evalAttributeValueTemplates(this.targetAttribute, this.element);
    if (LOGGER.isDebugEnabled()) {
      LOGGER.debug("targetid evaluated to: " + evaluatedTarget);
    }
    Node embed = getEmbeddedDocument(absoluteURI);

    // Check for 'ClientSide' events (DOMFocusIN / DOMFocusOUT / xforms-select)
    String utilizedEvents = this.getEventsInSubform(embed);

    // fetch CSS / JavaScript
    String inlineCssRules = "";
    String externalCssRules = "";
    String inlineJavaScript = "";
    String externalJavaScript = "";

    if (includeCSS) {
      inlineCssRules = getInlineCSS(embed);
      externalCssRules = getExternalCSS(embed);
    }
    if (includeScript) {
      inlineJavaScript = getInlineJavaScript(embed);
      externalJavaScript = getExternalJavaScript(embed);
    }
    embed = extractFragment(absoluteURI, embed);
    if (LOGGER.isDebugEnabled()) {
      DOMUtil.prettyPrintDOM(embed);
    }

    if (embed == null) {
      // todo: review: context info params containing a '-' fail during access in javascript!
      // todo: the following property should have been 'resource-uri' according to spec
      map.put("resourceUri", absoluteURI);
      this.container.dispatch(this.target, XFormsEventNames.LINK_EXCEPTION, map);
      return;
    }

    Element embeddedNode;
    Element targetElem = getTargetElement(evaluatedTarget);

    // Test if targetElem exist.
    if (targetElem != null) {
      // destroy existing embedded form within targetNode
      if (targetElem.hasChildNodes()) {
        destroyembeddedModels(targetElem);
        Initializer.disposeUIElements(targetElem);
      }

      // import referenced embedded form into host document
      embeddedNode = (Element) this.container.getDocument().importNode(embed, true);

      // import namespaces
      NamespaceResolver.applyNamespaces(
          targetElem.getOwnerDocument().getDocumentElement(), (Element) embeddedNode);

      // keep original targetElem id within hostdoc
      embeddedNode.setAttributeNS(null, "id", targetElem.getAttributeNS(null, "id"));
      // copy all Attributes that might have been on original mountPoint to embedded node
      DOMUtil.copyAttributes(targetElem, embeddedNode, null);
      targetElem.getParentNode().replaceChild(embeddedNode, targetElem);

      map.put("uri", absoluteURI);
      map.put("show", this.showAttribute);
      map.put("targetElement", embeddedNode);
      map.put("nameTarget", evaluatedTarget);
      map.put("xlinkTarget", getXFormsAttribute(targetElem, "id"));
      map.put("inlineCSS", inlineCssRules);
      map.put("externalCSS", externalCssRules);
      map.put("inlineJavascript", inlineJavaScript);
      map.put("externalJavascript", externalJavaScript);
      map.put("utilizedEvents", utilizedEvents);

      this.container.dispatch((EventTarget) embeddedNode, BetterFormEventNames.EMBED, map);
      // create model for it
      this.container.createEmbeddedForm((Element) embeddedNode);

      // dispatch internal betterform event
      this.container.dispatch((EventTarget) embeddedNode, BetterFormEventNames.EMBED_DONE, map);

      this.container.dispatch(this.target, BetterFormEventNames.LOAD_URI, map);
      //        storeInContext(absoluteURI, this.showAttribute);
    } else {
      String message =
          "Element reference for targetid: "
              + this.targetAttribute
              + " not found. "
              + DOMUtil.getCanonicalPath(this.element);
      /*
      Element div = this.element.getOwnerDocument().createElementNS("", "div");
      div.setAttribute("class", "bfException");
      div.setTextContent("Element reference for targetid: " + this.targetAttribute + "not found. " + DOMUtil.getCanonicalPath(this.element));

      Element body = (Element) this.container.getDocument().getElementsByTagName("body").item(0);
      body.insertBefore(div, DOMUtil.getFirstChildElement(body));
      */
      map.put("message", message);
      map.put("exceptionPath", DOMUtil.getCanonicalPath(this.element));
      this.container.dispatch(this.target, BetterFormEventNames.EXCEPTION, map);
      // throw new XFormsException(message);
    }
  }