First things first, an ArrayList is not a traditional array like you are used to in other programming languages. As far as I can tell you can’t do just plain old arrays in the Xbase based domain specific language of openHAB’s rules. I could be wrong on this point but when I’ve tried in the past doing things the Xtend documentation says I should be able to do I’ve failed to get it to work.
An ArrayList is, as you might notice from the imports, a Java container class and if you ever have questions about it see the ArrayList JavaDocs.
So, from an array list perspective there are several problems with the code above, almost all of which are problems with casting.
The declaration:
val List<Integer> theArray = newArrayList(1, 2, 3, 4, 5, 6, 7, 8)
This helps give the rules engine some hints as to what is going into the array list. Otherwise the members are treated as just Objects or Numbers if you are lucky. It may be redundant but when having problems like this I find it helps to be as specific as possible.
temp = theArray.get(2)
This works because the get() method on ArrayList takes a primitive int as its argument.
temp = theArray.get(index_val.state)
This doesn’t work because index_val.state returns an object of type State, or if the rules engine is being particularly smart here you are getting a Number. But no matter how smart the rules engine is about figuring out how to cast things, it can’t cast from an Object to a primitive. So you need to take this last little step yourself.
temp = theArray.get((index_val.state as Number).intValue)
The “as Number” part is making double sure that the state is cast to a Number object instead of just being a State object.
// theArray[3] = 20
theArray.put("3", 20)
ArrayList doesn’t have a put() method and you can’t use a String as an index. It looks like you are getting the syntax for a HashMap mixed up with the syntax for ArrayList. What you really want is add():
theArray.add(3, 20)
The first argument must be a primitive integer and the second must be the same type as what your ArrayList is storing (in this case a Number). One thing that may be confusing is that the rules engine is smart enough here to realize that it needs to create an Integer object to represent and store the 20 inside the ArrayList.
So, based on the above the last line should be:
theArray.add((index_val.state as Number).intValue, SomeValue.state as Integer)
For writing this sort of rule and figuring out these sorts of errors I can not recommend highly enough the use of Designer and the <ctrl><space>
key combo. Designer will tell you that your code is not syntactically correct as you type it and the key combo will auto-complete what you are typing by giving you a list of possible valid completions. For example if you typed theArray.<ctrl><space>
a menu will pop up showing you all of the methods that you can call on theArray with the types each takes as its arguments and what the method returns. You can learn A LOT this way and save a lot of internet searching.