Merge changes I0f752636,Idd154499,Ic35fa3e8
[controller.git] / opendaylight / netconf / config-netconf-connector / src / main / java / org / opendaylight / controller / netconf / confignetconfconnector / operations / runtimerpc / RuntimeRpcElementResolved.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.netconf.confignetconfconnector.operations.runtimerpc;
10
11 import com.google.common.base.Preconditions;
12 import com.google.common.base.Strings;
13 import com.google.common.collect.Maps;
14 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
15 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.rpc.ModuleRpcs;
16 import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
17
18 import javax.management.ObjectName;
19 import java.util.HashMap;
20 import java.util.Map;
21 import java.util.regex.Matcher;
22 import java.util.regex.Pattern;
23
24 /**
25  * Represents parsed xpath to runtime bean instance
26  */
27 public final class RuntimeRpcElementResolved {
28     private final String moduleName;
29     private final String instanceName;
30     private final String namespace;
31     private final String runtimeBeanName;
32     private final Map<String, String> additionalAttributes;
33
34     private RuntimeRpcElementResolved(String namespace, String moduleName, String instanceName, String runtimeBeanName,
35             Map<String, String> additionalAttributes) {
36         this.moduleName = Preconditions.checkNotNull(moduleName, "Module name");
37         this.instanceName =  Preconditions.checkNotNull(instanceName, "Instance name");
38         this.additionalAttributes = additionalAttributes;
39         this.namespace = Preconditions.checkNotNull(namespace, "Namespace");
40         this.runtimeBeanName = Preconditions.checkNotNull(runtimeBeanName, "Runtime bean name");
41     }
42
43     public String getModuleName() {
44         return moduleName;
45     }
46
47     public String getInstanceName() {
48         return instanceName;
49     }
50
51     public String getNamespace() {
52         return namespace;
53     }
54
55     public String getRuntimeBeanName() {
56         return runtimeBeanName;
57     }
58
59     public ObjectName getObjectName(ModuleRpcs rpcMapping) {
60         Map<String, String> additionalAttributesJavaNames = Maps
61                 .newHashMapWithExpectedSize(additionalAttributes.size());
62         for (String attributeYangName : additionalAttributes.keySet()) {
63             String attributeJavaName = rpcMapping.getRbeJavaName(attributeYangName);
64             Preconditions.checkState(attributeJavaName != null,
65                     "Cannot find java name for runtime bean wtih yang name %s", attributeYangName);
66             additionalAttributesJavaNames.put(attributeJavaName, additionalAttributes.get(attributeYangName));
67         }
68         return ObjectNameUtil.createRuntimeBeanName(moduleName, instanceName, additionalAttributesJavaNames);
69     }
70
71     private static final String xpathPatternBlueprint =
72             "/" + XmlNetconfConstants.MODULES_KEY
73             + "/" + XmlNetconfConstants.MODULE_KEY
74             + "\\["
75
76             + "(?<key1>type|name)"
77             + "='(?<value1>[^']+)'"
78             + "( and |\\]\\[)"
79             + "(?<key2>type|name)"
80             + "='(?<value2>[^']+)'"
81
82             + "\\]"
83             + "(?<additional>.*)";
84
85     private static final Pattern xpathPattern = Pattern.compile(xpathPatternBlueprint);
86     private static final String additionalPatternBlueprint = "(?<additionalKey>.+)\\[(.+)='(?<additionalValue>.+)'\\]";
87     private static final Pattern additionalPattern = Pattern.compile(additionalPatternBlueprint);
88
89     public static RuntimeRpcElementResolved fromXpath(String xpath, String elementName, String namespace) {
90         Matcher matcher = xpathPattern.matcher(xpath);
91         Preconditions.checkState(matcher.matches(),
92                 "Node %s with value '%s' not in required form on rpc element %s, required format is %s",
93                 RuntimeRpc.CONTEXT_INSTANCE, xpath, elementName, xpathPatternBlueprint);
94
95         PatternGroupResolver groups = new PatternGroupResolver(matcher.group("key1"), matcher.group("value1"),
96                 matcher.group("key2"), matcher.group("value2"), matcher.group("additional"));
97
98         String moduleName = groups.getModuleName();
99         String instanceName = groups.getInstanceName();
100
101         HashMap<String, String> additionalAttributes = groups.getAdditionalKeys(elementName, moduleName);
102
103         return new RuntimeRpcElementResolved(namespace, moduleName, instanceName, groups.getRuntimeBeanYangName(),
104                 additionalAttributes);
105     }
106
107     private static final class PatternGroupResolver {
108
109         private final String key1, key2, value1, value2;
110         private final String additional;
111         private String runtimeBeanYangName;
112
113         PatternGroupResolver(String key1, String value1, String key2, String value2, String additional) {
114             this.key1 = Preconditions.checkNotNull(key1);
115             this.value1 = Preconditions.checkNotNull(value1);
116
117             this.key2 = Preconditions.checkNotNull(key2);
118             this.value2 = Preconditions.checkNotNull(value2);
119
120             this.additional = Preconditions.checkNotNull(additional);
121         }
122
123         String getModuleName() {
124             return key1.equals(XmlNetconfConstants.TYPE_KEY) ? value1 : value2;
125         }
126
127         String getInstanceName() {
128             return key1.equals(XmlNetconfConstants.NAME_KEY) ? value1 : value2;
129         }
130
131         HashMap<String, String> getAdditionalKeys(String elementName, String moduleName) {
132             HashMap<String, String> additionalAttributes = Maps.newHashMap();
133
134             runtimeBeanYangName = moduleName;
135             for (String additionalKeyValue : additional.split("/")) {
136                 if (Strings.isNullOrEmpty(additionalKeyValue))
137                     continue;
138                 Matcher matcher = additionalPattern.matcher(additionalKeyValue);
139                 Preconditions
140                         .checkState(
141                                 matcher.matches(),
142                                 "Attribute %s not in required form on rpc element %s, required format for additional attributes is  %s",
143                                 additionalKeyValue, elementName, additionalPatternBlueprint);
144                 String name = matcher.group("additionalKey");
145                 runtimeBeanYangName = name;
146                 additionalAttributes.put(name, matcher.group("additionalValue"));
147             }
148             return additionalAttributes;
149         }
150
151         private String getRuntimeBeanYangName() {
152             Preconditions.checkState(runtimeBeanYangName!=null);
153             return runtimeBeanYangName;
154         }
155     }
156 }