2 * ============LICENSE_START=======================================================
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
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 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 * ============LICENSE_END=========================================================
27 package org.onap.appc.util;
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.Properties;
32 import java.util.regex.Matcher;
33 import java.util.regex.Pattern;
36 * This class is used to assemble properties that are defined using a structured name into groups, and allow them to be
37 * processed as sets of definitions.
39 * For example, a structured name uses a dotted-notation, like "provider.name". Further, the nodes of the structured
40 * name may be serialized using a suffix ordinal number (e.g., "provider1.name"). These structured properties form a
41 * hierarchical name space where the names are grouped together and can be retrieved as a set.
46 public class StructuredPropertyHelper {
49 * This method scans the properties object for all properties that match the root name and constructs a list of
50 * structured property node graphs that represents the namespaces of the properties.
52 * For example, assume that there are structured properties of the form "provider1.name", "provider2.name",
53 * "provider3.name", and so forth. There may also be other subordinate properties as well (e.g., "provider1.type").
54 * This method would construct a list of graphs of nodes, where each node represents one value of the structured
55 * name. The roots would be the values "provider1", "provider2", "provider3", and so forth. The values of the
56 * subordinate nodes would be the second, third, and so forth name nodes of the compound name. The value of the
57 * property is associated with nodes that are representative of the leaf of the name space.
61 * The properties to be processed
63 * The prefix of the root structured property name
64 * @return The node graph of the properties
66 public static List<Node> getStructuredProperties(Properties properties, String prefix) {
67 List<Node> roots = new ArrayList<>();
69 for (String name : properties.stringPropertyNames()) {
70 if (name.startsWith(prefix)) {
71 String value = properties.getProperty(name);
72 processNamespace(roots, name, value);
80 * This method recursively walks the name space of the structured property and constructs the node graph to
81 * represent the property
84 * The collection of nodes for the current level of the name space
86 * The name of the node
89 * @return The node for this level in the namespace
91 @SuppressWarnings("nls")
92 private static Node processNamespace(List<Node> nodes, String propertyName, String value) {
93 String[] tokens = propertyName.split("\\.", 2);
94 String nodeName = normalizeNodeName(tokens[0]);
96 Node namespaceNode = null;
97 for (Node node : nodes) {
98 if (node.getName().equals(nodeName)) {
103 if (namespaceNode == null) {
104 namespaceNode = new Node();
105 namespaceNode.setName(nodeName);
106 nodes.add(namespaceNode);
109 if (tokens.length == 1 || tokens[1] == null || tokens[1].length() == 0) {
110 namespaceNode.setValue(value);
112 processNamespace(namespaceNode.getChildren(), tokens[1], value);
115 return namespaceNode;
119 * This method normalizes a node name of the structured property name by removing leading and trailing whitespace,
120 * and by converting any ordinal position to a simple expression without leading zeroes.
123 * The token to be normalized
124 * @return The normalized name, or null if the token was null;
126 @SuppressWarnings("nls")
127 private static String normalizeNodeName(String token) {
132 StringBuffer buffer = new StringBuffer(token.trim());
133 Pattern pattern = Pattern.compile("([^0-9]+)([0-9]*)");
134 Matcher matcher = pattern.matcher(buffer);
135 if (matcher.matches()) {
136 String nameRoot = matcher.group(1);
137 String ordinal = matcher.group(2);
138 if (ordinal != null && ordinal.length() > 0) {
139 int i = Integer.parseInt(ordinal);
141 buffer.append(nameRoot);
142 buffer.append(Integer.toString(i));
145 return buffer.toString();
149 * This class represents a node in the structured property name space
152 public static class Node implements Comparable<Node> {
155 * The name of the structured property node
160 * If the node is a leaf, then the value of the property
162 private String value;
165 * If the node is not a leaf, then the sub-nodes of the property
167 private List<Node> children;
170 * @return the value of name
172 public String getName() {
180 public void setName(String name) {
185 * @return the value of value
187 public String getValue() {
193 * the value for value
195 public void setValue(String value) {
200 * @return the value of children
202 public List<Node> getChildren() {
203 if (children == null) {
204 children = new ArrayList<>();
210 * @see java.lang.Object#hashCode()
213 public int hashCode() {
214 return name.hashCode() + (value != null ? value.hashCode() : children.hashCode());
218 * @see java.lang.Object#equals(java.lang.Object)
221 public boolean equals(Object obj) {
224 if (this.getClass() != obj.getClass())
227 Node other = (Node) obj;
228 boolean result = name.equals(other.name);
231 result &= other.value == null;
233 result &= value.equals(other.value);
235 if (children == null) {
236 result &= other.children == null;
238 result &= children.equals(other.children);
244 * @see java.lang.Object#toString()
246 @SuppressWarnings("nls")
248 public String toString() {
250 return String.format("%s = %s", name, value);
252 return String.format("%s.%s", name, children.toString());
256 public int compareTo(StructuredPropertyHelper.Node o) {
257 return name.compareTo(o.name);