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