/** * This method converts an XML element into a specific kind of widget. Special cases are the XML * widget, Header, @Require widget. Otherwise a standard widget is created. */ @SuppressWarnings({"JavaDoc"}) @NotNull private <N extends Node> Renderable widgetize( PageCompilingContext pc, N node, WidgetChain childsChildren) { if (node instanceof XmlDeclaration) { try { XmlDeclaration decl = (XmlDeclaration) node; return registry.xmlDirectiveWidget(decl.getWholeDeclaration(), pc.lexicalScopes.peek()); } catch (ExpressionCompileException e) { pc.errors.add(CompileError.in(node.outerHtml()).near(line(node)).causedBy(e)); } } // Header widget is a special case, where we match by the name of the tag =( if ("head".equals(node.nodeName())) { try { return registry.headWidget( childsChildren, parseAttribs(node.attributes()), pc.lexicalScopes.peek()); } catch (ExpressionCompileException e) { pc.errors.add(CompileError.in(node.outerHtml()).near(line(node)).causedBy(e)); } } String annotation = node.attr(ANNOTATION); // if there is no annotation, treat as a raw xml-widget (i.e. tag) if ((null == annotation) || 0 == annotation.trim().length()) try { checkUriConsistency(pc, node); checkFormFields(pc, node); return registry.xmlWidget( childsChildren, node.nodeName(), parseAttribs(node.attributes()), pc.lexicalScopes.peek()); } catch (ExpressionCompileException e) { pc.errors.add(CompileError.in(node.outerHtml()).near(line(node)).causedBy(e)); return Chains.terminal(); } // Special case: is this annotated with @Require // if so, tags in head need to be promoted to head of enclosing page. if (REQUIRE_WIDGET.equalsIgnoreCase(annotation.trim())) try { return registry.requireWidget( registry.xmlWidget( childsChildren, node.nodeName(), parseAttribs(node.attributes()), pc.lexicalScopes.peek())); } catch (ExpressionCompileException e) { pc.errors.add(CompileError.in(node.outerHtml()).near(line(node)).causedBy(e)); return Chains.terminal(); } // If this is NOT a self-rendering widget, give it a child. // final String widgetName = node.attr(ANNOTATION_KEY).trim().toLowerCase()); final String widgetName = node.attr(ANNOTATION_KEY).toLowerCase(); if (!registry.isSelfRendering(widgetName)) try { childsChildren = Chains.singleton( registry.xmlWidget( childsChildren, node.nodeName(), parseAttribs(node.attributes()), pc.lexicalScopes.peek())); } catch (ExpressionCompileException e) { pc.errors.add(CompileError.in(node.outerHtml()).near(line(node)).causedBy(e)); } // Recursively build widget from [Key, expression, child widgets]. try { return registry.newWidget( widgetName, node.attr(ANNOTATION_CONTENT), childsChildren, pc.lexicalScopes.peek()); } catch (ExpressionCompileException e) { pc.errors.add(CompileError.in(node.outerHtml()).near(line(node)).causedBy(e)); // This should never be used. return Chains.terminal(); } }