Merge "BUG-2955: Fix error reporting for wrong YangInstanceIdentifier"
[yangtools.git] / yang / yang-model-util / src / main / java / org / opendaylight / yangtools / yang / model / util / DerivedType.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.util;
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
30 /**
31  *
32  * Implementations of derived type.
33  *
34  * This is set of utility classes which implements derived YANG type,
35  * preserving original implemented interface instead of {@link ExtendedType}
36  * which does not preserve final type of data.
37  *
38  */
39 public abstract class DerivedType<T extends TypeDefinition<T>> implements TypeDefinition<T> {
40
41     private final ExtendedType definition;
42     private final Class<T> publicType;
43
44     DerivedType(final Class<T> publicType, final ExtendedType delegate) {
45         this.definition = Preconditions.checkNotNull(delegate);
46         this.publicType = Preconditions.checkNotNull(publicType);
47     }
48
49     public static TypeDefinition<?> from(TypeDefinition<?> type) {
50         if(type instanceof ExtendedType) {
51             return from((ExtendedType) type);
52         }
53         return type;
54     }
55
56     public static TypeDefinition<?> from(final ExtendedType type) {
57         TypeDefinition<? extends TypeDefinition<?>> baseType = type;
58         while (baseType.getBaseType() != null) {
59             baseType = baseType.getBaseType();
60         }
61         if (baseType instanceof BinaryTypeDefinition) {
62             return new DerivedBinaryType(type);
63         }
64         if (baseType instanceof BooleanTypeDefinition) {
65             return new DerivedBooleanType(type);
66         }
67         if (baseType instanceof DecimalTypeDefinition) {
68             return new DerivedDecimalType(type);
69         }
70         if (baseType instanceof IdentityrefTypeDefinition) {
71             return new DerivedIdentityrefType(type);
72         }
73         if (baseType instanceof InstanceIdentifierTypeDefinition) {
74             return new DerivedInstanceIdentifierType(type);
75         }
76         if (baseType instanceof IntegerTypeDefinition) {
77             return new DerivedIntegerType(type);
78         }
79         if (baseType instanceof LeafrefTypeDefinition) {
80             return new DerivedLeafrefType(type);
81         }
82         if (baseType instanceof UnsignedIntegerTypeDefinition) {
83             return new DerivedUnsignedIntegerType(type);
84         }
85         if (baseType instanceof StringTypeDefinition) {
86             return new DerivedStringType(type);
87         }
88         if(baseType instanceof UnionTypeDefinition) {
89             return new DerivedUnionType(type);
90         }
91         if(baseType instanceof EnumTypeDefinition) {
92             return new DerivedEnumType(type);
93         }
94         if(baseType instanceof BitsTypeDefinition) {
95             return new DerivedBitsType(type);
96         }
97         throw new IllegalArgumentException("Not supported base type of " + baseType.getClass());
98     }
99
100     @Override
101     public final QName getQName() {
102         return definition.getQName();
103     }
104
105     @Override
106     public final SchemaPath getPath() {
107         return definition.getPath();
108     }
109
110     @Override
111     public final List<UnknownSchemaNode> getUnknownSchemaNodes() {
112         return definition.getUnknownSchemaNodes();
113     }
114
115     @Override
116     public final String getDescription() {
117         return definition.getDescription();
118     }
119
120     @Override
121     public final String getReference() {
122         return definition.getReference();
123     }
124
125     @Override
126     public final String getUnits() {
127         return definition.getUnits();
128     }
129
130     @Override
131     public final Object getDefaultValue() {
132         return definition.getDefaultValue();
133     }
134
135     @Override
136     public final Status getStatus() {
137         return definition.getStatus();
138     }
139
140     @Override
141     public final T getBaseType() {
142         final TypeDefinition<?> base = definition.getBaseType();
143         if (publicType.isInstance(base)) {
144             return publicType.cast(base);
145         } else if (base instanceof ExtendedType) {
146             return createDerived((ExtendedType) base);
147         }
148         throw new IllegalStateException("Unsupported base type.");
149     }
150
151     protected ExtendedType delegate() {
152         return definition;
153     }
154
155     /**
156      *
157      * Creates derived type from supplied ExtendedType, which will implement
158      * proper {@link TypeDefinition} interface.
159      *
160      * @param base Base definition, which does not implement concrete API
161      * @return wrapper which implements proper subinterface of {@link TypeDefinition}.
162      */
163     abstract T createDerived(ExtendedType base);
164
165
166 }