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