96656338df130f30ef569fbb54537727ff9a0b3a
[controller.git] / opendaylight / config / yang-jmx-generator / src / main / java / org / opendaylight / controller / config / yangjmxgenerator / attribute / TOAttribute.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 package org.opendaylight.controller.config.yangjmxgenerator.attribute;
9
10 import com.google.common.base.Function;
11 import com.google.common.collect.Collections2;
12 import com.google.common.collect.Maps;
13 import com.google.common.collect.Sets;
14 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
15 import org.opendaylight.controller.config.yangjmxgenerator.TypeProviderWrapper;
16 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
17 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
18 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
19 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
20 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
21 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
22 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
23
24 import javax.management.openmbean.CompositeType;
25 import javax.management.openmbean.OpenDataException;
26 import javax.management.openmbean.OpenType;
27 import java.util.HashMap;
28 import java.util.Map;
29 import java.util.Map.Entry;
30 import java.util.Set;
31
32 public class TOAttribute extends AbstractAttribute {
33
34     private final String nullableDescription, nullableDefault;
35     private final Map<String, AttributeIfc> yangNameToAttributeMap;
36     private final Map<String, String> attributeNameMap;
37
38     private static final Set<Class<? extends DataSchemaNode>> ALLOWED_CHILDREN = Sets
39             .newHashSet();
40     static {
41         ALLOWED_CHILDREN.add(LeafListSchemaNode.class);
42         ALLOWED_CHILDREN.add(ListSchemaNode.class);
43         ALLOWED_CHILDREN.add(LeafSchemaNode.class);
44         ALLOWED_CHILDREN.add(ContainerSchemaNode.class);
45     }
46
47     public static <T extends DataNodeContainer & AugmentationTarget & DataSchemaNode> TOAttribute create(
48             T containerSchemaNode, TypeProviderWrapper typeProviderWrapper) {
49         // Transfer Object: get the leaves
50         Map<String, AttributeIfc> map = new HashMap<>();
51         Map<String, String> attributeNameMap = new HashMap<>();
52         for (DataSchemaNode dataSchemaNode : containerSchemaNode
53                 .getChildNodes()) {
54             try {
55                 String yangName = dataSchemaNode.getQName().getLocalName();
56                 map.put(yangName,
57                         createInnerAttribute(dataSchemaNode,
58                                 typeProviderWrapper));
59             } catch (IllegalArgumentException e) {
60                 throw new IllegalStateException("Unable to create TO", e);
61             }
62         }
63         return new TOAttribute(containerSchemaNode, map, attributeNameMap,
64                 containerSchemaNode.getDescription());
65     }
66
67     private static AttributeIfc createInnerAttribute(
68             DataSchemaNode dataSchemaNode,
69             TypeProviderWrapper typeProviderWrapper) {
70         Class<? extends DataSchemaNode> type = isAllowedType(dataSchemaNode);
71
72         if (type.equals(LeafSchemaNode.class))
73             return new JavaAttribute((LeafSchemaNode) dataSchemaNode,
74                     typeProviderWrapper);
75         else if (type.equals(ListSchemaNode.class))
76             return ListAttribute.create((ListSchemaNode) dataSchemaNode,
77                     typeProviderWrapper);
78         else if (type.equals(LeafListSchemaNode.class))
79             return ListAttribute.create((LeafListSchemaNode) dataSchemaNode,
80                     typeProviderWrapper);
81         else if (type.equals(ContainerSchemaNode.class))
82             return TOAttribute.create((ContainerSchemaNode) dataSchemaNode,
83                     typeProviderWrapper);
84
85         throw new IllegalStateException("This should never happen");
86     }
87
88     private static Class<? extends DataSchemaNode> isAllowedType(
89             DataSchemaNode dataSchemaNode) {
90         for (Class<? extends DataSchemaNode> allowedType : ALLOWED_CHILDREN) {
91             if (allowedType.isAssignableFrom(dataSchemaNode.getClass()) == true)
92                 return allowedType;
93         }
94         throw new IllegalArgumentException("Illegal child node for TO: "
95                 + dataSchemaNode.getClass() + " allowed node types: "
96                 + ALLOWED_CHILDREN);
97     }
98
99     private TOAttribute(DataSchemaNode attrNode,
100             Map<String, AttributeIfc> transferObject,
101             Map<String, String> attributeNameMap, String nullableDescription) {
102         super(attrNode);
103         yangNameToAttributeMap = transferObject;
104         this.attributeNameMap = attributeNameMap;
105         this.nullableDescription = nullableDescription;
106         nullableDefault = null;
107     }
108
109     public Map<String, String> getAttributeNameMap() {
110         return attributeNameMap;
111     }
112
113     public Map<String, AttributeIfc> getCapitalizedPropertiesToTypesMap() {
114         Map<String, AttributeIfc> capitalizedPropertiesToTypesMap = Maps
115                 .newHashMap();
116         for (Entry<String, AttributeIfc> entry : yangNameToAttributeMap
117                 .entrySet()) {
118
119             capitalizedPropertiesToTypesMap.put(
120                     ModuleMXBeanEntry.convertToJavaName(entry.getKey(), true),
121                     entry.getValue());
122         }
123         return capitalizedPropertiesToTypesMap;
124     }
125
126     public Map<String, AttributeIfc> getJmxPropertiesToTypesMap() {
127         Map<String, AttributeIfc> jmxPropertiesToTypesMap = Maps.newHashMap();
128         for (Entry<String, AttributeIfc> entry : yangNameToAttributeMap
129                 .entrySet()) {
130
131             jmxPropertiesToTypesMap.put(
132                     ModuleMXBeanEntry.convertToJavaName(entry.getKey(), false),
133                     entry.getValue());
134         }
135         return jmxPropertiesToTypesMap;
136     }
137
138     public Map<String, AttributeIfc> getYangPropertiesToTypesMap() {
139         return yangNameToAttributeMap;
140     }
141
142     @Override
143     public String getNullableDescription() {
144         return nullableDescription;
145     }
146
147     @Override
148     public String getNullableDefault() {
149         return nullableDefault;
150     }
151
152     @Override
153     public boolean equals(Object o) {
154         if (this == o)
155             return true;
156         if (o == null || getClass() != o.getClass())
157             return false;
158         if (!super.equals(o))
159             return false;
160
161         TOAttribute that = (TOAttribute) o;
162
163         if (nullableDefault != null ? !nullableDefault
164                 .equals(that.nullableDefault) : that.nullableDefault != null)
165             return false;
166         if (nullableDescription != null ? !nullableDescription
167                 .equals(that.nullableDescription)
168                 : that.nullableDescription != null)
169             return false;
170         if (yangNameToAttributeMap != null ? !yangNameToAttributeMap
171                 .equals(that.yangNameToAttributeMap)
172                 : that.yangNameToAttributeMap != null)
173             return false;
174
175         return true;
176     }
177
178     @Override
179     public int hashCode() {
180         int result = super.hashCode();
181         result = 31
182                 * result
183                 + (nullableDescription != null ? nullableDescription.hashCode()
184                         : 0);
185         result = 31 * result
186                 + (nullableDefault != null ? nullableDefault.hashCode() : 0);
187         result = 31
188                 * result
189                 + (yangNameToAttributeMap != null ? yangNameToAttributeMap
190                         .hashCode() : 0);
191         return result;
192     }
193
194     @Override
195     public String toString() {
196         return "TOAttribute{" + getAttributeYangName() + "," + "to="
197                 + yangNameToAttributeMap + '}';
198     }
199
200     @Override
201     public CompositeType getOpenType() {
202         String description = getNullableDescription() == null ? getAttributeYangName()
203                 : getNullableDescription();
204         final String[] itemNames = new String[yangNameToAttributeMap.keySet()
205                 .size()];
206         String[] itemDescriptions = itemNames;
207         FunctionImpl functionImpl = new FunctionImpl(itemNames);
208         Map<String, AttributeIfc> jmxPropertiesToTypesMap = getJmxPropertiesToTypesMap();
209         OpenType<?>[] itemTypes = Collections2.transform(
210                 jmxPropertiesToTypesMap.entrySet(), functionImpl).toArray(
211                 new OpenType<?>[] {});
212         try {
213             // TODO add package name to create fully qualified name for this
214             // type
215             CompositeType compositeType = new CompositeType(
216                     getUpperCaseCammelCase(), description, itemNames,
217                     itemDescriptions, itemTypes);
218             return compositeType;
219         } catch (OpenDataException e) {
220             throw new RuntimeException("Unable to create CompositeType for "
221                     + this, e);
222         }
223     }
224
225     private static final class FunctionImpl implements
226             Function<Entry<String, AttributeIfc>, OpenType<?>> {
227         private final String[] itemNames;
228         int i = 0;
229
230         private FunctionImpl(String[] itemNames) {
231             this.itemNames = itemNames;
232         }
233
234         @Override
235         public OpenType<?> apply(Entry<String, AttributeIfc> input) {
236             AttributeIfc innerType = input.getValue();
237             itemNames[i++] = input.getKey();
238             return innerType.getOpenType();
239         }
240     }
241 }