Checkstyle changes for apex model
[policy/apex-pdp.git] / model / policy-model / src / main / java / org / onap / policy / apex / model / policymodel / concepts / AxStateTree.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  * 
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  * 
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  * 
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.apex.model.policymodel.concepts;
22
23 import java.util.ArrayList;
24 import java.util.LinkedHashSet;
25 import java.util.List;
26 import java.util.Set;
27 import java.util.TreeSet;
28
29 import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
30 import org.onap.policy.apex.model.utilities.Assertions;
31
32 /**
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.
37  * 
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.
40  */
41 public class AxStateTree implements Comparable<AxStateTree> {
42     private final AxState thisState;
43     private final Set<AxStateTree> nextStates;
44
45     /**
46      * This constructor recursively creates a state tree for the given policy starting at the given
47      * state.
48      *
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
53      */
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");
57
58         this.thisState = thisState;
59         nextStates = new TreeSet<>();
60
61         for (final AxStateOutput stateOutput : thisState.getStateOutputs().values()) {
62             final AxState nextState = policy.getStateMap().get(stateOutput.getNextState().getLocalName());
63
64             // Check for end of state branch
65             if (stateOutput.getNextState().equals(AxReferenceKey.getNullKey())) {
66                 continue;
67             }
68
69             if (referencedStateNameSet == null) {
70                 referencedStateNameSet = new LinkedHashSet<>();
71                 referencedStateNameSet.add(thisState.getKey());
72             }
73
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");
79             }
80             referencedStateNameSet.add(stateOutput.getNextState());
81             nextStates.add(new AxStateTree(policy, nextState, referencedStateNameSet));
82         }
83     }
84
85     /**
86      * Gets the state for this state tree node.
87      *
88      * @return the state
89      */
90     public AxState getState() {
91         return thisState;
92     }
93
94     /**
95      * Gets the next states for this state tree node.
96      *
97      * @return the next states
98      */
99     public Set<AxStateTree> getNextStates() {
100         return nextStates;
101     }
102
103     /**
104      * Gets the list of states referenced by this state tree as a list.
105      *
106      * @return the list of states referenced
107      */
108     public List<AxState> getReferencedStateList() {
109         final List<AxState> referencedStateList = new ArrayList<>();
110
111         referencedStateList.add(thisState);
112         for (final AxStateTree nextStateTree : nextStates) {
113             referencedStateList.addAll(nextStateTree.getReferencedStateList());
114         }
115
116         return referencedStateList;
117     }
118
119     /**
120      * Gets the list of states referenced by this state tree as a set.
121      *
122      * @return the set of states referenced
123      */
124     public Set<AxState> getReferencedStateSet() {
125         final Set<AxState> referencedStateSet = new TreeSet<>();
126
127         referencedStateSet.add(thisState);
128         for (final AxStateTree nextStateTree : nextStates) {
129             referencedStateSet.addAll(nextStateTree.getReferencedStateSet());
130         }
131
132         return referencedStateSet;
133     }
134
135     /*
136      * (non-Javadoc)
137      *
138      * @see java.lang.Comparable#compareTo(java.lang.Object)
139      */
140     @Override
141     public int compareTo(final AxStateTree otherObj) {
142         Assertions.argumentNotNull(otherObj, "comparison object may not be null");
143
144         if (this == otherObj) {
145             return 0;
146         }
147
148         final AxStateTree other = otherObj;
149         if (!thisState.equals(other.thisState)) {
150             return thisState.compareTo(other.thisState);
151         }
152         if (!nextStates.equals(other.nextStates)) {
153             return (nextStates.hashCode() - other.nextStates.hashCode());
154         }
155         return 0;
156     }
157 }