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;
30 import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
31 import org.onap.policy.common.utils.validation.Assertions;
34 * The Class is used to return the tree that represents the state branches or chains in a policy. It
35 * creates a tree that holds the state fan out branches in a policy that starts from the given top
36 * state of the tree. Each branch from a state is held in a set of next states for the top state and
37 * each branch in the state tree is itself a {@link AxStateTree} instance.
39 * <p>Validation checks for recursive state use, in other words validation forbids the use of a given
40 * state more than once in a state tree.
42 public class AxStateTree implements Comparable<AxStateTree> {
43 private final AxState thisState;
44 private final Set<AxStateTree> nextStates;
47 * This constructor recursively creates a state tree for the given policy starting at the given
50 * @param policy the policy from which to read states
51 * @param thisState the state to start state tree construction at
52 * @param referencedStateNameSet a set of state names already referenced in the tree, null for
53 * the first recursive call
55 public AxStateTree(final AxPolicy policy, final AxState thisState, Set<AxReferenceKey> referencedStateNameSet) {
56 Assertions.argumentNotNull(policy, "policy may not be null");
57 Assertions.argumentNotNull(thisState, "thisState may not be null");
59 this.thisState = thisState;
60 nextStates = new TreeSet<>();
62 for (final AxStateOutput stateOutput : thisState.getStateOutputs().values()) {
63 final AxState nextState = policy.getStateMap().get(stateOutput.getNextState().getLocalName());
65 // Check for end of state branch
66 if (stateOutput.getNextState().equals(AxReferenceKey.getNullKey())) {
70 if (referencedStateNameSet == null) {
71 referencedStateNameSet = new LinkedHashSet<>();
72 referencedStateNameSet.add(thisState.getKey());
75 // Check for state tree loops
76 if (referencedStateNameSet.contains(nextState.getKey())) {
77 throw new PolicyRuntimeException("loop detected in state tree for policy " + policy.getId() + " state "
78 + thisState.getKey().getLocalName() + ", next state " + nextState.getKey().getLocalName()
79 + " referenced more than once");
81 referencedStateNameSet.add(stateOutput.getNextState());
82 nextStates.add(new AxStateTree(policy, nextState, referencedStateNameSet));
87 * Gets the state for this state tree node.
91 public AxState getState() {
96 * Gets the next states for this state tree node.
98 * @return the next states
100 public Set<AxStateTree> getNextStates() {
105 * Gets the list of states referenced by this state tree as a list.
107 * @return the list of states referenced
109 public List<AxState> getReferencedStateList() {
110 final List<AxState> referencedStateList = new ArrayList<>();
112 referencedStateList.add(thisState);
113 for (final AxStateTree nextStateTree : nextStates) {
114 referencedStateList.addAll(nextStateTree.getReferencedStateList());
117 return referencedStateList;
121 * Gets the list of states referenced by this state tree as a set.
123 * @return the set of states referenced
125 public Set<AxState> getReferencedStateSet() {
126 final Set<AxState> referencedStateSet = new TreeSet<>();
128 referencedStateSet.add(thisState);
129 for (final AxStateTree nextStateTree : nextStates) {
130 referencedStateSet.addAll(nextStateTree.getReferencedStateSet());
133 return referencedStateSet;
140 public int compareTo(final AxStateTree otherObj) {
141 Assertions.argumentNotNull(otherObj, "comparison object may not be null");
143 if (this == otherObj) {
147 final AxStateTree other = otherObj;
148 if (!thisState.equals(other.thisState)) {
149 return thisState.compareTo(other.thisState);
151 if (!nextStates.equals(other.nextStates)) {
152 return (nextStates.hashCode() - other.nextStates.hashCode());