2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.controller.config.yangjmxgenerator.attribute;
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 java.util.ArrayList;
15 import java.util.HashMap;
16 import java.util.List;
18 import java.util.Map.Entry;
20 import javax.management.openmbean.CompositeType;
21 import javax.management.openmbean.OpenDataException;
22 import javax.management.openmbean.OpenType;
23 import org.opendaylight.controller.config.yangjmxgenerator.TypeProviderWrapper;
24 import org.opendaylight.mdsal.binding.model.api.JavaTypeName;
25 import org.opendaylight.mdsal.binding.model.api.Type;
26 import org.opendaylight.mdsal.binding.model.util.ReferencedTypeImpl;
27 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
28 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
29 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
30 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
31 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
32 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
33 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
35 public class TOAttribute extends AbstractAttribute implements TypedAttribute {
37 private final String nullableDescription, nullableDefault;
38 private final Map<String, AttributeIfc> yangNameToAttributeMap;
39 private final Map<String, String> attributeNameMap;
40 private final String packageName;
42 private static final Set<Class<? extends DataSchemaNode>> ALLOWED_CHILDREN = Sets
45 ALLOWED_CHILDREN.add(LeafListSchemaNode.class);
46 ALLOWED_CHILDREN.add(ListSchemaNode.class);
47 ALLOWED_CHILDREN.add(LeafSchemaNode.class);
48 ALLOWED_CHILDREN.add(ContainerSchemaNode.class);
51 public static <T extends DataNodeContainer & AugmentationTarget & DataSchemaNode> TOAttribute create(
52 final T containerSchemaNode, final TypeProviderWrapper typeProviderWrapper, final String packageName) {
53 // Transfer Object: get the leaves
54 final Map<String, AttributeIfc> map = new HashMap<>();
55 final Map<String, String> attributeNameMap = new HashMap<>();
56 for (final DataSchemaNode dataSchemaNode : containerSchemaNode.getChildNodes()) {
58 final String yangName = dataSchemaNode.getQName().getLocalName();
59 map.put(yangName, createInnerAttribute(dataSchemaNode, typeProviderWrapper, packageName));
60 } catch (final IllegalArgumentException e) {
61 throw new IllegalStateException("Unable to create TO", e);
64 return new TOAttribute(containerSchemaNode, map, attributeNameMap,
65 containerSchemaNode.getDescription().orElse(null), packageName);
68 private static AttributeIfc createInnerAttribute(
69 final DataSchemaNode dataSchemaNode,
70 final TypeProviderWrapper typeProviderWrapper, final String packageName) {
71 final Class<? extends DataSchemaNode> type = isAllowedType(dataSchemaNode);
73 if (type.equals(LeafSchemaNode.class)) {
74 return new JavaAttribute((LeafSchemaNode) dataSchemaNode, typeProviderWrapper);
75 } else if (type.equals(ListSchemaNode.class)) {
76 return ListAttribute.create((ListSchemaNode) dataSchemaNode, typeProviderWrapper, packageName);
77 } else if (type.equals(LeafListSchemaNode.class)) {
78 return ListAttribute.create((LeafListSchemaNode) dataSchemaNode, typeProviderWrapper);
79 } else if (type.equals(ContainerSchemaNode.class)) {
80 return TOAttribute.create((ContainerSchemaNode) dataSchemaNode, typeProviderWrapper, packageName);
83 throw new IllegalStateException("This should never happen");
86 private static Class<? extends DataSchemaNode> isAllowedType(
87 final DataSchemaNode dataSchemaNode) {
88 for (final Class<? extends DataSchemaNode> allowedType : ALLOWED_CHILDREN) {
89 if (allowedType.isAssignableFrom(dataSchemaNode.getClass())) {
93 throw new IllegalArgumentException("Illegal child node for TO: "
94 + dataSchemaNode.getClass() + " allowed node types: "
98 private TOAttribute(final DataSchemaNode attrNode,
99 final Map<String, AttributeIfc> transferObject,
100 final Map<String, String> attributeNameMap, final String nullableDescription, final String packageName) {
102 this.yangNameToAttributeMap = transferObject;
103 this.attributeNameMap = attributeNameMap;
104 this.nullableDescription = nullableDescription;
105 this.nullableDefault = null;
106 this.packageName = packageName;
109 public Map<String, String> getAttributeNameMap() {
110 return this.attributeNameMap;
113 public Map<String, AttributeIfc> getCapitalizedPropertiesToTypesMap() {
114 final Map<String, AttributeIfc> capitalizedPropertiesToTypesMap = Maps
116 for (final Entry<String, AttributeIfc> entry : this.yangNameToAttributeMap
119 capitalizedPropertiesToTypesMap.put(
120 TypeProviderWrapper.convertToJavaName(entry.getKey(), true),
123 return capitalizedPropertiesToTypesMap;
126 public Map<String, AttributeIfc> getJmxPropertiesToTypesMap() {
127 final Map<String, AttributeIfc> jmxPropertiesToTypesMap = Maps.newHashMap();
128 for (final Entry<String, AttributeIfc> entry : this.yangNameToAttributeMap
131 jmxPropertiesToTypesMap.put(
132 TypeProviderWrapper.convertToJavaName(entry.getKey(), false),
135 return jmxPropertiesToTypesMap;
138 public Map<String, AttributeIfc> getYangPropertiesToTypesMap() {
139 return this.yangNameToAttributeMap;
143 public String getNullableDescription() {
144 return this.nullableDescription;
148 public String getNullableDefault() {
149 return this.nullableDefault;
153 public boolean equals(final Object o) {
157 if (o == null || getClass() != o.getClass()) {
160 if (!super.equals(o)) {
164 final TOAttribute that = (TOAttribute) o;
166 if (this.nullableDefault != null ? !this.nullableDefault
167 .equals(that.nullableDefault) : that.nullableDefault != null) {
170 if (this.nullableDescription != null ? !this.nullableDescription
171 .equals(that.nullableDescription)
172 : that.nullableDescription != null) {
175 if (this.yangNameToAttributeMap != null ? !this.yangNameToAttributeMap
176 .equals(that.yangNameToAttributeMap)
177 : that.yangNameToAttributeMap != null) {
185 public int hashCode() {
186 int result = super.hashCode();
189 + (this.nullableDescription != null ? this.nullableDescription.hashCode()
192 + (this.nullableDefault != null ? this.nullableDefault.hashCode() : 0);
195 + (this.yangNameToAttributeMap != null ? this.yangNameToAttributeMap
201 public String toString() {
202 return "TOAttribute{" + getAttributeYangName() + "," + "to="
203 + this.yangNameToAttributeMap + '}';
207 public Type getType() {
208 // TODO: ReferencedTypeImpl from Types
209 return new ReferencedTypeImpl(JavaTypeName.create(this.packageName, getUpperCaseCammelCase()));
213 public CompositeType getOpenType() {
214 final String description = getNullableDescription() == null ? getAttributeYangName() : getNullableDescription();
216 final FunctionImpl functionImpl = new FunctionImpl();
217 final Map<String, AttributeIfc> jmxPropertiesToTypesMap = getJmxPropertiesToTypesMap();
218 final OpenType<?>[] itemTypes = Collections2.transform(
219 jmxPropertiesToTypesMap.entrySet(), functionImpl).toArray(
220 new OpenType<?>[] {});
221 final String[] itemNames = functionImpl.getItemNames();
223 // TODO add package name to create fully qualified name for this
225 final CompositeType compositeType = new CompositeType(
226 getUpperCaseCammelCase(), description, itemNames,
227 itemNames, itemTypes);
228 return compositeType;
229 } catch (final OpenDataException e) {
230 throw new RuntimeException("Unable to create CompositeType for "
235 public String getPackageName() {
236 return this.packageName;
241 class FunctionImpl implements
242 Function<Entry<String, AttributeIfc>, OpenType<?>> {
243 private final List<String> itemNames = new ArrayList<>();
246 public OpenType<?> apply(final Entry<String, AttributeIfc> input) {
247 final AttributeIfc innerType = input.getValue();
248 this.itemNames.add(input.getKey());
249 return innerType.getOpenType();
252 public String[] getItemNames(){
253 return this.itemNames.toArray(new String[this.itemNames.size()]);