Bug 2497: Added YIN Export for Effective Schema Context.
[yangtools.git] / yang / yang-model-export / src / main / java / org / opendaylight / yangtools / yang / model / export / NormalizatedDerivedType.java
1 /*
2  * Copyright (c) 2015 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.yangtools.yang.model.export;
9
10 import com.google.common.base.Preconditions;
11 import java.util.List;
12 import org.opendaylight.yangtools.yang.common.QName;
13 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
14 import org.opendaylight.yangtools.yang.model.api.Status;
15 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
16 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
17 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
18 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
19 import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
20 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
21 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
22 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
23 import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
24 import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
25 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
26 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
27 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
28 import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
29 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
30
31 /**
32  *
33  * Implementations of derived type.
34  *
35  * This is set of utility classes which implements derived YANG type,
36  * preserving original implemented interface instead of {@link ExtendedType}
37  * which does not preserve final type of data.
38  *
39  *  FIXME: Lithium: Should be move to yang-model-util package or deprecated
40  * if linking parser is reworked to adhere to base type contract
41  */
42 abstract class NormalizatedDerivedType<T extends TypeDefinition<T>> implements TypeDefinition<T> {
43
44     private final ExtendedType definition;
45     private final Class<T> publicType;
46
47     NormalizatedDerivedType(final Class<T> publicType, final ExtendedType delegate) {
48         this.definition = Preconditions.checkNotNull(delegate);
49         this.publicType = Preconditions.checkNotNull(publicType);
50     }
51
52     static TypeDefinition<?> from(final ExtendedType type) {
53         TypeDefinition<? extends TypeDefinition<?>> baseType = type;
54         while (baseType.getBaseType() != null) {
55             baseType = baseType.getBaseType();
56         }
57         if (baseType instanceof BinaryTypeDefinition) {
58             return new DerivedBinary(type);
59         }
60         if (baseType instanceof BooleanTypeDefinition) {
61             return new DerivedBoolean(type);
62         }
63         if (baseType instanceof DecimalTypeDefinition) {
64             return new DerivedDecimal(type);
65         }
66         if (baseType instanceof IdentityrefTypeDefinition) {
67             return new DerivedIdentityref(type);
68         }
69         if (baseType instanceof InstanceIdentifierTypeDefinition) {
70             return new DerivedInstanceIdentifier(type);
71         }
72         if (baseType instanceof IntegerTypeDefinition) {
73             return new DerivedInteger(type);
74         }
75         if (baseType instanceof LeafrefTypeDefinition) {
76             return new DerivedLeafref(type);
77         }
78         if (baseType instanceof UnsignedIntegerTypeDefinition) {
79             return new DerivedUnsignedInteger(type);
80         }
81         if (baseType instanceof StringTypeDefinition) {
82             return new DerivedString(type);
83         }
84         if(baseType instanceof UnionTypeDefinition) {
85             return new DerivedUnion(type);
86         }
87         if(baseType instanceof EnumTypeDefinition) {
88             return new DerivedEnum(type);
89         }
90         if(baseType instanceof BitsTypeDefinition) {
91             return new DerivedBits(type);
92         }
93         throw new IllegalArgumentException("Not supported base type of " + baseType.getClass());
94     }
95
96     @Override
97     public final QName getQName() {
98         return definition.getQName();
99     }
100
101     @Override
102     public final SchemaPath getPath() {
103         return definition.getPath();
104     }
105
106     @Override
107     public final List<UnknownSchemaNode> getUnknownSchemaNodes() {
108         return definition.getUnknownSchemaNodes();
109     }
110
111     @Override
112     public final String getDescription() {
113         return definition.getDescription();
114     }
115
116     @Override
117     public final String getReference() {
118         return definition.getReference();
119     }
120
121     @Override
122     public final String getUnits() {
123         return definition.getUnits();
124     }
125
126     @Override
127     public final Object getDefaultValue() {
128         return definition.getDefaultValue();
129     }
130
131     @Override
132     public final Status getStatus() {
133         return definition.getStatus();
134     }
135
136     @Override
137     public final T getBaseType() {
138         final TypeDefinition<?> base = definition.getBaseType();
139         if (publicType.isInstance(base)) {
140             return publicType.cast(base);
141         } else if (base instanceof ExtendedType) {
142             return createDerived((ExtendedType) base);
143         }
144         throw new IllegalStateException("Unsupported base type.");
145     }
146
147     protected ExtendedType delegate() {
148         return definition;
149     }
150
151     /**
152      *
153      * Creates derived type from supplied ExtendedType, which will implement
154      * proper {@link TypeDefinition} interface.
155      *
156      * @param base Base definition, which does not implement concrete API
157      * @return wrapper which implements proper subinterface of {@link TypeDefinition}.
158      */
159     abstract T createDerived(ExtendedType base);
160 }