e6d35ac7f5bb5ba2d42258cfc7cfe0b2f90b9d81
[appc.git] / appc-dispatcher / appc-dispatcher-common / ranking-framework-lib / src / main / java / org / openecomp / appc / rankingframework / impl / BacktraceStrategy.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Copyright (C) 2017 Amdocs
8  * =============================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * 
21  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22  * ============LICENSE_END=========================================================
23  */
24
25 package org.openecomp.appc.rankingframework.impl;
26
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Set;
30
31 import org.openecomp.appc.rankingframework.RankedAttributesContext;
32 import com.att.eelf.configuration.EELFLogger;
33 import com.att.eelf.configuration.EELFManager;
34
35 class BacktraceStrategy implements Strategy {
36
37     private static final EELFLogger logger = EELFManager.getInstance().getLogger(BacktraceStrategy.class);
38
39     @Override
40     public <R> R resolve(CompositeNode<R> rootNode, List<String> rankedNames, RankedAttributesContext context) {
41
42         if (logger.isDebugEnabled()) {
43             StringBuilder buff = new StringBuilder(128);
44             for (String name : rankedNames) {
45                 buff.append("/{").append(name).append(" = ").append(Utils.value(context.getAttributeValue(name))).append('}');
46             }
47             logger.debug(String.format("Trying to resolve path: %s", buff));
48         }
49
50         Set<String> visited = new HashSet<>();
51
52         CompositeNode<R> parentNode = rootNode;
53         int depth = 0;
54         boolean stop = false;
55         R result = null;
56
57         String attribute = null;
58         Object value = null;
59
60         do {
61             if (value == null) {
62                 attribute = rankedNames.get(depth);
63                 value = Utils.value(context.getAttributeValue(attribute));
64             }
65
66             Node<R> childNode = parentNode.children().get(value);
67
68             if (childNode != null) {
69                 if (logger.isDebugEnabled()) {
70                     logger.debug(String.format("Found matching node '%s' - checking it out", childNode));
71                 }
72
73                 if (!visited.add(childNode.id())) {
74                     if (logger.isDebugEnabled()) {
75                         logger.debug(String.format("The matching node '%s' was checked before - ignoring it", childNode));
76                     }
77                     childNode = null;
78                 }
79             } else {
80                 if (logger.isDebugEnabled()) {
81                     logger.debug(String.format("Node '%s/{%s = %s}' not found  - falling back", parentNode, attribute, value != null ? value : "NULL"));
82                 }
83             }
84
85             if (childNode != null) {
86                 switch (childNode.type()) {
87                     case COMPOSITE:
88                         depth++;
89                         value = null;
90                         parentNode = (CompositeNode<R>) childNode;
91                         break;
92                     case LEAF:
93                         if (logger.isDebugEnabled()) {
94                             logger.debug( String.format("Result node has been resolved succesfully - '%s'", childNode));
95                         }
96                         result = ((LeafNode<R>) childNode).result();
97                         stop = true;
98                         break;
99                     default:
100                         throw new IllegalStateException(childNode.type().name());
101                 }
102             } else {
103                 if (!value.equals(Constants.DEFAULT_MATCH)) {
104                     logger.debug("Exact match didn't work, trying the default option, if any");
105                     value = Constants.DEFAULT_MATCH;
106                 } else if (depth > 0) {
107                     if (logger.isDebugEnabled()) {
108                         logger.debug(String.format("Exact match didn't work and no default option available beneath '%s' - moving out", parentNode));
109                     }
110                     depth--;
111                     value = null;
112                     parentNode = parentNode.parent();
113                 } else {
114                     logger.debug("Didn't success to resolve the path - stopping without result");
115                     stop = true;
116                 }
117             }
118         } while (!stop);
119
120         return result;
121     }
122 }