In Automation 360, you can create an iterator with the SDK package. An iterator is used to loop through multiple objects of similar type and is used with the Loop package. It consists of two methods, next and hasNext, which return the actual object and a boolean value.

Required annotations

When iterator is used, the next method returns the next available value. If no more values are available, an exception is shown. The hasNext method checks for other values and returns false if no more values are available. In Automation 360, when the loop is executed, hasNext() is called first, and next() is called only if hasNext() returned a true value.

For creating an iterator, the following annotations are required.

Use case example

The example use case loops through number of times, for example, for (int i=0; I<n; i++) Java construct. It accepts the value of n from the Bot Creator when the bot is created.

  1. Make sure you have imported the following packages to ensure all the functionalities works as described in the sample.
    import com.automationanywhere.botcommand.data.Value;
    import com.automationanywhere.botcommand.data.impl.NumberValue;
    import com.automationanywhere.commandsdk.annotations.BotCommand;
    import com.automationanywhere.commandsdk.annotations.CommandPkg;
    import com.automationanywhere.commandsdk.annotations.HasNext;
    import com.automationanywhere.commandsdk.annotations.Idx;
    import com.automationanywhere.commandsdk.annotations.Inject;
    import com.automationanywhere.commandsdk.annotations.Next;
    import com.automationanywhere.commandsdk.annotations.Pkg;
    import com.automationanywhere.commandsdk.annotations.BotCommand.CommandType;
    import com.automationanywhere.commandsdk.annotations.rules.GreaterThanEqualTo;
    import com.automationanywhere.commandsdk.annotations.rules.NotEmpty;
    import com.automationanywhere.commandsdk.annotations.rules.NumberInteger;
    import com.automationanywhere.commandsdk.model.AttributeType;
    import com.automationanywhere.commandsdk.model.DataType;
  2. Create the POJO class with the business logic.

    Ensure that the POJO has a method and returns a boolean value. This will act as the comparison method.

    @BotCommand(commandType=CommandType.Iterator)
    @CommandPkg(return_label = "Return the value in variable", node_label = ": {{times}} times", 
    label = "Iterator demo", description = "Iterate number of times", name = "iteratorTypeDemo", return_type = DataType.NUMBER)
    public class IteratorTypeDemo {
        @Idx(index = "1", type = AttributeType.NUMBER)
        @Pkg(label = "times", default_value = "10", default_value_type = DataType.NUMBER)
        @GreaterThanEqualTo("0")
        @NumberInteger
        @NotEmpty
        @Inject
    	private Double times = 10d;
    
    	private Double counter = 0d;
    
        @HasNext
        public boolean hasNext() {
    		return counter < times;
        }
    
        @Next
        public Value<Double> next() throws Exception{
    		if (counter >= times)
    			throw new Exception("Counter '"+ counter +"' is exceed the times limit '"+times+"'");
    
    		counter++;
            NumberValue result = new NumberValue();
            result.set(counter);
            return result;
        }
    
        public void setTimes(Double times) {
            this.times = times;
        }
    }
  3. Annotate the POJO class to enable it for the Automation 360 iterator and to create a package.
    @BotCommand(commandType = CommandType.Iterator)
    @CommandPkg(return_label = "Return the value in variable", node_label = ": {{times}} times",
    	label = "Iterator demo", description = "Iterate number of times", name = "iteratorTypeDemo", return_type = DataType.NUMBER)
    public class IteratorTypeDemo {
    
    	private Double times = 10 d;
    	private Double counter = 0 d;
    
    	public boolean hasNext() {
    		return counter < times;
    	}
  4. Annotate the hasNext() and next() method appropriately.
    @HasNext
    public boolean hasNext() {
    	return counter < times;
    }
    
    @Next
    public Value < Double > next() throws Exception {
    	if (counter >= times)
    		throw new Exception("Counter '" + counter + "' is exceed the times limit '" + times + "'");
    
    	counter++;
    	NumberValue result = new NumberValue();
    	result.set(counter);
    	return result;
    }

    The methods are named in easy-to-use way and are in parallel with the Java iterator interface. There is no restriction from the SDK side when naming methods.

    In an iterator, do not use parameter methods, but use setter injection.

  5. Annotate the variables with Idx and Pkg.

    Add @NotEmpty to ensure the value is not null, and add @GreaterThanEqualTo to ensure the value is always greater than 0.

    @Idx(index = "1", type = AttributeType.NUMBER)
    @Pkg(label = "times", default_value = "10", default_value_type = DataType.NUMBER)
    @GreaterThanEqualTo("0")
    @NotEmpty
    @Inject
    private Double times = 10 d;

    The attribute type number returns a Double.