2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2016-2018 Ericsson. All rights reserved.
4 * Modifications Copyright (C) 2019 Nordix Foundation.
5 * ================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.apex.model.policymodel.concepts;
24 import java.util.ArrayList;
25 import java.util.LinkedHashSet;
26 import java.util.List;
28 import java.util.TreeSet;
29 import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
30 import org.onap.policy.common.utils.validation.Assertions;
33 * The Class is used to return the tree that represents the state branches or chains in a policy. It
34 * creates a tree that holds the state fan out branches in a policy that starts from the given top
35 * state of the tree. Each branch from a state is held in a set of next states for the top state and
36 * each branch in the state tree is itself a {@link AxStateTree} instance.
38 * <p>Validation checks for recursive state use, in other words validation forbids the use of a given
39 * state more than once in a state tree.
41 public class AxStateTree implements Comparable<AxStateTree> {
42 private final AxState thisState;
43 private final Set<AxStateTree> nextStates;
46 * This constructor recursively creates a state tree for the given policy starting at the given
49 * @param policy the policy from which to read states
50 * @param thisState the state to start state tree construction at
51 * @param referencedStateNameSet a set of state names already referenced in the tree, null for
52 * the first recursive call
54 public AxStateTree(final AxPolicy policy, final AxState thisState, Set<AxReferenceKey> referencedStateNameSet) {
55 Assertions.argumentNotNull(policy, "policy may not be null");
56 Assertions.argumentNotNull(thisState, "thisState may not be null");
58 this.thisState = thisState;
59 nextStates = new TreeSet<>();
61 for (final AxStateOutput stateOutput : thisState.getStateOutputs().values()) {
62 final AxState nextState = policy.getStateMap().get(stateOutput.getNextState().getLocalName());
64 // Check for end of state branch
65 if (stateOutput.getNextState().equals(AxReferenceKey.getNullKey())) {
69 if (referencedStateNameSet == null) {
70 referencedStateNameSet = new LinkedHashSet<>();
71 referencedStateNameSet.add(thisState.getKey());
74 // Check for state tree loops
75 if (referencedStateNameSet.contains(nextState.getKey())) {
76 throw new PolicyRuntimeException("loop detected in state tree for policy " + policy.getId() + " state "
77 + thisState.getKey().getLocalName() + ", next state " + nextState.getKey().getLocalName()
78 + " referenced more than once");
80 referencedStateNameSet.add(stateOutput.getNextState());
81 nextStates.add(new AxStateTree(policy, nextState, referencedStateNameSet));
86 * Gets the state for this state tree node.
90 public AxState getState() {
95 * Gets the next states for this state tree node.
97 * @return the next states
99 public Set<AxStateTree> getNextStates() {
104 * Gets the list of states referenced by this state tree as a list.
106 * @return the list of states referenced
108 public List<AxState> getReferencedStateList() {
109 final List<AxState> referencedStateList = new ArrayList<>();
111 referencedStateList.add(thisState);
112 for (final AxStateTree nextStateTree : nextStates) {
113 referencedStateList.addAll(nextStateTree.getReferencedStateList());
116 return referencedStateList;
120 * Gets the list of states referenced by this state tree as a set.
122 * @return the set of states referenced
124 public Set<AxState> getReferencedStateSet() {
125 final Set<AxState> referencedStateSet = new TreeSet<>();
127 referencedStateSet.add(thisState);
128 for (final AxStateTree nextStateTree : nextStates) {
129 referencedStateSet.addAll(nextStateTree.getReferencedStateSet());
132 return referencedStateSet;
139 public int compareTo(final AxStateTree otherObj) {
140 Assertions.argumentNotNull(otherObj, "comparison object may not be null");
142 if (this == otherObj) {
146 final AxStateTree other = otherObj;
147 if (!thisState.equals(other.thisState)) {
148 return thisState.compareTo(other.thisState);
150 if (!nextStates.equals(other.nextStates)) {
151 return (nextStates.hashCode() - other.nextStates.hashCode());