/* * This could be made a whole lot faster using a recursive query or some other techniques, but due to the caching and, * generally speaking, the relatively flat nature of the state machine this shouldn't be expensive. */ public State[] getConcreteDescendentStates(int[] stateIds) throws ApplicationException { if (stateIds == null) { return null; } if (stateIds.length == 0) { return new State[0]; } ArrayList results = new ArrayList(); for (int i = 0; i < stateIds.length; i++) { ArrayList childrenOfState = (ArrayList) cache.get("descendents/" + stateIds[i]); if (childrenOfState == null) { childrenOfState = new ArrayList(); State state = this.getStateById(stateIds[i]); if (!state.isAbstract()) { childrenOfState.add(state); } ArrayList children = StateManager.getStatesByParentId(state.getId()); int[] childrenIds = new int[children.size()]; for (int j = 0; j < children.size(); j++) { childrenIds[j] = ((State) children.get(j)).getId(); } childrenOfState.addAll(Arrays.asList(getConcreteDescendentStates(childrenIds))); if (!childrenOfState.isEmpty()) { cache.put("descendents/" + stateIds[i], childrenOfState); } } results.addAll(childrenOfState); } return (State[]) ArrayUtils.toTypedArray(results, State.class); }