/** * 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; }
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; }
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; }
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; }
/** * 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); }
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); } }