Initial code drop of yang model driven configuration system
[controller.git] / opendaylight / config / yang-jmx-generator / src / main / java / org / opendaylight / controller / config / yangjmxgenerator / attribute / TOAttribute.java
diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/TOAttribute.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/TOAttribute.java
new file mode 100644 (file)
index 0000000..20029d0
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.yangjmxgenerator.attribute;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenType;
+
+import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
+import org.opendaylight.controller.config.yangjmxgenerator.TypeProviderWrapper;
+import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
+public class TOAttribute extends AbstractAttribute {
+
+    private final String nullableDescription, nullableDefault;
+    private final Map<String, AttributeIfc> yangNameToAttributeMap;
+    private final Map<String, String> attributeNameMap;
+
+    private static final Set<Class<? extends DataSchemaNode>> ALLOWED_CHILDREN = Sets
+            .newHashSet();
+    static {
+        ALLOWED_CHILDREN.add(LeafListSchemaNode.class);
+        ALLOWED_CHILDREN.add(ListSchemaNode.class);
+        ALLOWED_CHILDREN.add(LeafSchemaNode.class);
+        ALLOWED_CHILDREN.add(ContainerSchemaNode.class);
+    }
+
+    public static <T extends DataNodeContainer & AugmentationTarget & DataSchemaNode> TOAttribute create(
+            T containerSchemaNode, TypeProviderWrapper typeProviderWrapper) {
+        // Transfer Object: get the leaves
+        Map<String, AttributeIfc> map = new HashMap<>();
+        Map<String, String> attributeNameMap = new HashMap<>();
+        for (DataSchemaNode dataSchemaNode : containerSchemaNode
+                .getChildNodes()) {
+            try {
+                String yangName = dataSchemaNode.getQName().getLocalName();
+                map.put(yangName,
+                        createInnerAttribute(dataSchemaNode,
+                                typeProviderWrapper));
+            } catch (IllegalArgumentException e) {
+                throw new IllegalStateException("Unable to create TO");
+            }
+        }
+        return new TOAttribute(containerSchemaNode, map, attributeNameMap,
+                containerSchemaNode.getDescription());
+    }
+
+    private static AttributeIfc createInnerAttribute(
+            DataSchemaNode dataSchemaNode,
+            TypeProviderWrapper typeProviderWrapper) {
+        Class<? extends DataSchemaNode> type = isAllowedType(dataSchemaNode);
+
+        if (type.equals(LeafSchemaNode.class))
+            return new JavaAttribute((LeafSchemaNode) dataSchemaNode,
+                    typeProviderWrapper);
+        else if (type.equals(ListSchemaNode.class))
+            return ListAttribute.create((ListSchemaNode) dataSchemaNode,
+                    typeProviderWrapper);
+        else if (type.equals(LeafListSchemaNode.class))
+            return ListAttribute.create((LeafListSchemaNode) dataSchemaNode,
+                    typeProviderWrapper);
+        else if (type.equals(ContainerSchemaNode.class))
+            return TOAttribute.create((ContainerSchemaNode) dataSchemaNode,
+                    typeProviderWrapper);
+
+        throw new IllegalStateException("This should never happen");
+    }
+
+    private static Class<? extends DataSchemaNode> isAllowedType(
+            DataSchemaNode dataSchemaNode) {
+        for (Class<? extends DataSchemaNode> allowedType : ALLOWED_CHILDREN) {
+            if (allowedType.isAssignableFrom(dataSchemaNode.getClass()) == true)
+                return allowedType;
+        }
+        throw new IllegalArgumentException("Illegal child node for TO: "
+                + dataSchemaNode.getClass() + " allowed node types: "
+                + ALLOWED_CHILDREN);
+    }
+
+    private TOAttribute(DataSchemaNode attrNode,
+            Map<String, AttributeIfc> transferObject,
+            Map<String, String> attributeNameMap, String nullableDescription) {
+        super(attrNode);
+        yangNameToAttributeMap = transferObject;
+        this.attributeNameMap = attributeNameMap;
+        this.nullableDescription = nullableDescription;
+        nullableDefault = null;
+    }
+
+    public Map<String, String> getAttributeNameMap() {
+        return attributeNameMap;
+    }
+
+    public Map<String, AttributeIfc> getCapitalizedPropertiesToTypesMap() {
+        Map<String, AttributeIfc> capitalizedPropertiesToTypesMap = Maps
+                .newHashMap();
+        for (Entry<String, AttributeIfc> entry : yangNameToAttributeMap
+                .entrySet()) {
+
+            capitalizedPropertiesToTypesMap.put(
+                    ModuleMXBeanEntry.convertToJavaName(entry.getKey(), true),
+                    entry.getValue());
+        }
+        return capitalizedPropertiesToTypesMap;
+    }
+
+    public Map<String, AttributeIfc> getJmxPropertiesToTypesMap() {
+        Map<String, AttributeIfc> jmxPropertiesToTypesMap = Maps.newHashMap();
+        for (Entry<String, AttributeIfc> entry : yangNameToAttributeMap
+                .entrySet()) {
+
+            jmxPropertiesToTypesMap.put(
+                    ModuleMXBeanEntry.convertToJavaName(entry.getKey(), false),
+                    entry.getValue());
+        }
+        return jmxPropertiesToTypesMap;
+    }
+
+    public Map<String, AttributeIfc> getYangPropertiesToTypesMap() {
+        return yangNameToAttributeMap;
+    }
+
+    @Override
+    public String getNullableDescription() {
+        return nullableDescription;
+    }
+
+    @Override
+    public String getNullableDefault() {
+        return nullableDefault;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        if (o == null || getClass() != o.getClass())
+            return false;
+        if (!super.equals(o))
+            return false;
+
+        TOAttribute that = (TOAttribute) o;
+
+        if (nullableDefault != null ? !nullableDefault
+                .equals(that.nullableDefault) : that.nullableDefault != null)
+            return false;
+        if (nullableDescription != null ? !nullableDescription
+                .equals(that.nullableDescription)
+                : that.nullableDescription != null)
+            return false;
+        if (yangNameToAttributeMap != null ? !yangNameToAttributeMap
+                .equals(that.yangNameToAttributeMap)
+                : that.yangNameToAttributeMap != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        result = 31
+                * result
+                + (nullableDescription != null ? nullableDescription.hashCode()
+                        : 0);
+        result = 31 * result
+                + (nullableDefault != null ? nullableDefault.hashCode() : 0);
+        result = 31
+                * result
+                + (yangNameToAttributeMap != null ? yangNameToAttributeMap
+                        .hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "TOAttribute{" + getAttributeYangName() + "," + "to="
+                + yangNameToAttributeMap + '}';
+    }
+
+    @Override
+    public OpenType<?> getOpenType() {
+        String description = getNullableDescription() == null ? getAttributeYangName()
+                : getNullableDescription();
+        final String[] itemNames = new String[yangNameToAttributeMap.keySet()
+                .size()];
+        String[] itemDescriptions = itemNames;
+        FunctionImpl functionImpl = new FunctionImpl(itemNames);
+        Map<String, AttributeIfc> jmxPropertiesToTypesMap = getJmxPropertiesToTypesMap();
+        OpenType<?>[] itemTypes = Collections2.transform(
+                jmxPropertiesToTypesMap.entrySet(), functionImpl).toArray(
+                new OpenType<?>[] {});
+        try {
+            // TODO add package name to create fully qualified name for this
+            // type
+            CompositeType compositeType = new CompositeType(
+                    getUpperCaseCammelCase(), description, itemNames,
+                    itemDescriptions, itemTypes);
+            return compositeType;
+        } catch (OpenDataException e) {
+            throw new RuntimeException("Unable to create CompositeType for "
+                    + this, e);
+        }
+    }
+
+    private static final class FunctionImpl implements
+            Function<Entry<String, AttributeIfc>, OpenType<?>> {
+        private final String[] itemNames;
+        int i = 0;
+
+        private FunctionImpl(String[] itemNames) {
+            this.itemNames = itemNames;
+        }
+
+        @Override
+        public OpenType<?> apply(Entry<String, AttributeIfc> input) {
+            AttributeIfc innerType = input.getValue();
+            itemNames[i++] = input.getKey();
+            return innerType.getOpenType();
+        }
+    }
+}