2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2018 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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * ============LICENSE_END=========================================================
26 package org.onap.appc.util;
28 import java.util.ArrayList;
29 import java.util.List;
30 import java.util.Properties;
31 import java.util.regex.Matcher;
32 import java.util.regex.Pattern;
35 * This class is used to assemble properties that are defined using a structured name into groups, and allow them to be
36 * processed as sets of definitions.
38 * For example, a structured name uses a dotted-notation, like "provider.name". Further, the nodes of the structured
39 * name may be serialized using a suffix ordinal number (e.g., "provider1.name"). These structured properties form a
40 * hierarchical name space where the names are grouped together and can be retrieved as a set.
45 public class StructuredPropertyHelper {
48 * This method scans the properties object for all properties that match the root name and constructs a list of
49 * structured property node graphs that represents the namespaces of the properties.
51 * For example, assume that there are structured properties of the form "provider1.name", "provider2.name",
52 * "provider3.name", and so forth. There may also be other subordinate properties as well (e.g., "provider1.type").
53 * This method would construct a list of graphs of nodes, where each node represents one value of the structured
54 * name. The roots would be the values "provider1", "provider2", "provider3", and so forth. The values of the
55 * subordinate nodes would be the second, third, and so forth name nodes of the compound name. The value of the
56 * property is associated with nodes that are representative of the leaf of the name space.
60 * The properties to be processed
62 * The prefix of the root structured property name
63 * @return The node graph of the properties
65 public static List<Node> getStructuredProperties(Properties properties, String prefix) {
66 List<Node> roots = new ArrayList<>();
68 for (String name : properties.stringPropertyNames()) {
69 if (name.startsWith(prefix)) {
70 String value = properties.getProperty(name);
71 processNamespace(roots, name, value);
79 * This method recursively walks the name space of the structured property and constructs the node graph to
80 * represent the property
83 * The collection of nodes for the current level of the name space
85 * The name of the node
88 * @return The node for this level in the namespace
90 @SuppressWarnings("nls")
91 private static Node processNamespace(List<Node> nodes, String propertyName, String value) {
92 String[] tokens = propertyName.split("\\.", 2);
93 String nodeName = normalizeNodeName(tokens[0]);
95 Node namespaceNode = null;
96 for (Node node : nodes) {
97 if (node.getName().equals(nodeName)) {
102 if (namespaceNode == null) {
103 namespaceNode = new Node();
104 namespaceNode.setName(nodeName);
105 nodes.add(namespaceNode);
108 if (tokens.length == 1 || tokens[1] == null || tokens[1].length() == 0) {
109 namespaceNode.setValue(value);
111 processNamespace(namespaceNode.getChildren(), tokens[1], value);
114 return namespaceNode;
118 * This method normalizes a node name of the structured property name by removing leading and trailing whitespace,
119 * and by converting any ordinal position to a simple expression without leading zeroes.
122 * The token to be normalized
123 * @return The normalized name, or null if the token was null;
125 @SuppressWarnings("nls")
126 private static String normalizeNodeName(String token) {
131 StringBuffer buffer = new StringBuffer(token.trim());
132 Pattern pattern = Pattern.compile("([^0-9]+)([0-9]*)");
133 Matcher matcher = pattern.matcher(buffer);
134 if (matcher.matches()) {
135 String nameRoot = matcher.group(1);
136 String ordinal = matcher.group(2);
137 if (ordinal != null && ordinal.length() > 0) {
138 int i = Integer.parseInt(ordinal);
140 buffer.append(nameRoot);
141 buffer.append(Integer.toString(i));
144 return buffer.toString();
148 * This class represents a node in the structured property name space
151 public static class Node implements Comparable<Node> {
154 * The name of the structured property node
159 * If the node is a leaf, then the value of the property
161 private String value;
164 * If the node is not a leaf, then the sub-nodes of the property
166 private List<Node> children;
169 * @return the value of name
171 public String getName() {
179 public void setName(String name) {
184 * @return the value of value
186 public String getValue() {
192 * the value for value
194 public void setValue(String value) {
199 * @return the value of children
201 public List<Node> getChildren() {
202 if (children == null) {
203 children = new ArrayList<>();
209 * @see java.lang.Object#hashCode()
212 public int hashCode() {
213 return name.hashCode() + (value != null ? value.hashCode() : children.hashCode());
217 * @see java.lang.Object#equals(java.lang.Object)
220 public boolean equals(Object obj) {
223 if (this.getClass() != obj.getClass())
226 Node other = (Node) obj;
227 boolean result = name.equals(other.name);
230 result &= other.value == null;
232 result &= value.equals(other.value);
234 if (children == null) {
235 result &= other.children == null;
237 result &= children.equals(other.children);
243 * @see java.lang.Object#toString()
245 @SuppressWarnings("nls")
247 public String toString() {
249 return String.format("%s = %s", name, value);
251 return String.format("%s.%s", name, children.toString());
255 public int compareTo(StructuredPropertyHelper.Node o) {
256 return name.compareTo(o.name);