public PluginInvoke invoke()

in src/main/java/org/apache/sling/scripting/sightly/impl/plugin/RepeatPlugin.java [49:179]


    public PluginInvoke invoke(final Expression expression, final PluginCallInfo callInfo, final CompilerContext compilerContext) {
        return new DefaultPluginInvoke() {

            private String listVariable = compilerContext.generateVariable("collectionVar");
            private String collectionSizeVar = compilerContext.generateVariable("size");
            private String collectionNotEmpty = compilerContext.generateVariable("notEmpty");
            private String beginVariable = compilerContext.generateVariable(BEGIN);
            private String stepVariable = compilerContext.generateVariable(STEP);
            private String endVariable = compilerContext.generateVariable(END);
            private String validStartStepEnd = compilerContext.generateVariable("validStartStepEnd");

            private boolean beginAtIndexZero = false;
            private boolean stepOne = false;

            @Override
            public void beforeElement(PushStream stream, String tagName) {
                stream.write(new VariableBinding.Start(listVariable, expression.getRoot()));
                stream.write(new VariableBinding.Start(collectionSizeVar,
                        new UnaryOperation(UnaryOperator.LENGTH, new Identifier(listVariable))));
                stream.write(new VariableBinding.Start(collectionNotEmpty, new BinaryOperation(BinaryOperator.GT, new Identifier
                        (collectionSizeVar), NumericConstant.ZERO)));
                stream.write(new Conditional.Start(collectionNotEmpty, true));
                Map<String, ExpressionNode> options = expression.getOptions();
                if (options.containsKey(BEGIN)) {
                    stream.write(new VariableBinding.Start(beginVariable, expression.getOptions().get(BEGIN)));
                } else {
                    beginAtIndexZero = true;
                    stream.write(new VariableBinding.Start(beginVariable, NumericConstant.ZERO));
                }
                if (options.containsKey(STEP)) {
                    stream.write(new VariableBinding.Start(stepVariable, expression.getOptions().get(STEP)));
                } else {
                    stepOne = true;
                    stream.write(new VariableBinding.Start(stepVariable, NumericConstant.ONE));
                }
                if (options.containsKey(END)) {
                    stream.write(new VariableBinding.Start(endVariable, expression.getOptions().get(END)));
                } else {
                    stream.write(new VariableBinding.Start(endVariable, new Identifier(collectionSizeVar)));
                }
                stream.write(new VariableBinding.Start(validStartStepEnd,
                                new BinaryOperation(BinaryOperator.AND,
                                        new BinaryOperation(BinaryOperator.AND,
                                                new BinaryOperation(BinaryOperator.LT, new Identifier(beginVariable), new Identifier(collectionSizeVar)),
                                                new BinaryOperation(
                                                        BinaryOperator.AND,
                                                        new BinaryOperation(BinaryOperator.GEQ, new Identifier(beginVariable), NumericConstant.ZERO),
                                                        new BinaryOperation(BinaryOperator.GT, new Identifier(stepVariable), NumericConstant.ZERO)
                                                )
                                        ),
                                        new BinaryOperation(BinaryOperator.GT, new Identifier(endVariable), NumericConstant.ZERO)
                                )
                        )
                );
                stream.write(new Conditional.Start(validStartStepEnd, true));
                String itemVariable = decodeItemVariable();
                String loopStatusVar = Syntax.itemLoopStatusVariable(itemVariable);
                String indexVariable = compilerContext.generateVariable("index");
                stream.write(new Loop.Start(listVariable, itemVariable, indexVariable));
                stream.write(new VariableBinding.Start(loopStatusVar, buildStatusObj(indexVariable, collectionSizeVar)));
                String stepConditionVariable = compilerContext.generateVariable("stepCondition");
                stream.write(new VariableBinding.Start(stepConditionVariable,
                                beginAtIndexZero && stepOne ? new NumericConstant(0) :
                                new BinaryOperation(
                                        BinaryOperator.REM,
                                        new BinaryOperation(
                                                BinaryOperator.SUB,
                                                new Identifier(indexVariable),
                                                new Identifier(beginVariable)
                                        ),
                                        new Identifier(stepVariable))
                        )
                );
                String loopTraversalVariable = compilerContext.generateVariable("traversal");
                stream.write(new VariableBinding.Start(loopTraversalVariable,
                                new BinaryOperation(
                                        BinaryOperator.AND,
                                        new BinaryOperation(
                                                BinaryOperator.AND,
                                                new BinaryOperation(BinaryOperator.GEQ, new Identifier(indexVariable), new Identifier(
                                                        beginVariable)),
                                                new BinaryOperation(BinaryOperator.LEQ, new Identifier(indexVariable), new Identifier(endVariable))
                                        ),
                                        new BinaryOperation(BinaryOperator.EQ, new Identifier(stepConditionVariable), NumericConstant.ZERO)
                                )
                        )
                );
                stream.write(new Conditional.Start(loopTraversalVariable, true));

            }

            @Override
            public void afterTagClose(PushStream stream, boolean isSelfClosing) {
                stream.write(NEW_LINE);
            }

            @Override
            public void afterElement(PushStream stream) {
                stream.write(Conditional.END);
                stream.write(VariableBinding.END);
                stream.write(VariableBinding.END);
                stream.write(VariableBinding.END);
                stream.write(Loop.END);
                stream.write(Conditional.END);
                stream.write(VariableBinding.END);
                stream.write(VariableBinding.END);
                stream.write(VariableBinding.END);
                stream.write(VariableBinding.END);
                stream.write(Conditional.END);
                stream.write(VariableBinding.END);
                stream.write(VariableBinding.END);
                stream.write(VariableBinding.END);
            }


            private String decodeItemVariable() {
                String[] args = callInfo.getArguments();
                if (args.length > 0) {
                    return args[0];
                }
                return Syntax.DEFAULT_LIST_ITEM_VAR_NAME;
            }

            private ExpressionNode parityCheck(ExpressionNode numericExpression, NumericConstant expected) {
                return new BinaryOperation(
                        BinaryOperator.EQ,
                        new BinaryOperation(BinaryOperator.REM, numericExpression, NumericConstant.TWO),
                        expected);
            }
        };
    }