package de.neuland.jade4j.parser.node; import java.util.*; import de.neuland.jade4j.compiler.IndentWriter; import de.neuland.jade4j.exceptions.ExpressionException; import de.neuland.jade4j.exceptions.JadeCompilerException; import de.neuland.jade4j.model.JadeModel; import de.neuland.jade4j.template.JadeTemplate; import de.neuland.jade4j.util.ArgumentSplitter; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; public class CallNode extends AttrsNode { protected List<String> arguments = new ArrayList<String>(); boolean call = false; private boolean dynamicMixins = false; @Override public void execute(IndentWriter writer, JadeModel model, JadeTemplate template) throws JadeCompilerException { boolean dynamic = getName().charAt(0)=='#'; if (dynamic) this.dynamicMixins = true; String newname = (dynamic ? getName().substring(2,getName().length()-1):'"'+getName()+'"'); try { newname = (String) template.getExpressionHandler().evaluateExpression(newname,model); } catch (ExpressionException e) { e.printStackTrace(); } MixinNode mixin; if(dynamic) mixin = model.getMixin(newname); else mixin = model.getMixin(getName()); if (mixin == null) { throw new JadeCompilerException(this, template.getTemplateLoader(), "mixin " + getName() + " is not defined"); } // Clone mixin try { mixin = (MixinNode) mixin.clone(); } catch (CloneNotSupportedException e) { // Can't happen throw new IllegalStateException(e); } if (hasBlock()) { List<MixinBlockNode> injectionPoints = getInjectionPoints(mixin.getBlock()); for (MixinBlockNode point : injectionPoints) { point.getNodes().add(block); } } if (this.isCall()) { model.pushScope(); model.put("block", block); writeVariables(model, mixin, template); writeAttributes(model, mixin, template); mixin.getBlock().execute(writer, model, template); model.put("block",null); model.popScope(); }else{ } } private List<MixinBlockNode> getInjectionPoints(Node block) { List<MixinBlockNode> result = new ArrayList<MixinBlockNode>(); for (Node node : block.getNodes()) { if (node instanceof MixinBlockNode && !node.hasNodes()) { result.add((MixinBlockNode) node); } else if(node instanceof ConditionalNode){ for (IfConditionNode condition : ((ConditionalNode) node).getConditions()) { result.addAll(getInjectionPoints(condition.getBlock())); } // } else if(node instanceof CaseNode.When){ // for (CaseConditionNode condition : ((CaseNode) node).getCaseConditionNodes()) { // result.addAll(getInjectionPoints(condition.getBlock())); // } } else if (node.hasBlock()) { result.addAll(getInjectionPoints(node.getBlock())); } } return result; } private void writeVariables(JadeModel model, MixinNode mixin, JadeTemplate template) { List<String> names = mixin.getArguments(); List<String> values = arguments; if (names == null) { return; } for (int i = 0; i < names.size(); i++) { String key = names.get(i); Object value = null; if (i < values.size()) { value = values.get(i); } if (value != null) { try { value = template.getExpressionHandler().evaluateExpression(values.get(i), model); } catch (Throwable e) { throw new JadeCompilerException(this, template.getTemplateLoader(), e); } } if (key != null) { model.put(key, value); } } if(mixin.getRest()!=null) { ArrayList<Object> restArguments = new ArrayList<Object>(); for (int i = names.size(); i < arguments.size(); i++) { Object value = null; if (i < values.size()) { value = values.get(i); } if (value != null) { try { value = template.getExpressionHandler().evaluateExpression(values.get(i), model); } catch (Throwable e) { throw new JadeCompilerException(this, template.getTemplateLoader(), e); } } restArguments.add(value); } model.put(mixin.getRest(), restArguments); } } private void writeAttributes(JadeModel model, MixinNode mixin, JadeTemplate template) { // model.put("attributes", mergeInheritedAttributes(model)); // model.put("attributes", getArguments()); LinkedList<Attr> newAttributes = new LinkedList<Attr>(attributes); if (attributeBlocks.size()>0) { //Todo: AttributesBlock needs to be evaluated for (String attributeBlock : attributeBlocks) { Object o = null; try { o = template.getExpressionHandler().evaluateExpression(attributeBlock, model); } catch (ExpressionException e) { e.printStackTrace(); } if(o!=null) { if(o instanceof Map) { for (Map.Entry<String, String> entry : ((Map<String,String>) o).entrySet()) { Attr attr = new Attr(entry.getKey(),entry.getValue(),false); newAttributes.add(attr); } }else if(o instanceof String){ System.out.print(o); } } } } if (newAttributes.size()>0) { LinkedHashMap<String,String> attrs = attrs(model, template, newAttributes); model.put("attributes", attrs); }else{ model.put("attributes", null); } } public List<String> getArguments() { return arguments; } public void setArguments(List<String> arguments) { this.arguments = arguments; } public void setArguments(String arguments) { this.arguments.clear(); this.arguments = ArgumentSplitter.split(arguments); } public boolean isCall() { return call; } public void setCall(boolean call) { this.call = call; } }