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