2 * Copyright (c) 2020 PANTHEON.tech, s.r.o. 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.mdsal.binding.java.api.generator;
10 import com.google.common.annotations.Beta;
11 import java.io.Serializable;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.Comparator;
15 import java.util.List;
17 import org.eclipse.jdt.annotation.NonNull;
18 import org.opendaylight.mdsal.binding.model.api.ConcreteType;
19 import org.opendaylight.mdsal.binding.model.api.GeneratedProperty;
20 import org.opendaylight.mdsal.binding.model.api.GeneratedTransferObject;
21 import org.opendaylight.mdsal.binding.model.api.ParameterizedType;
22 import org.opendaylight.mdsal.binding.model.api.Type;
23 import org.opendaylight.mdsal.binding.model.api.TypeMember;
24 import org.opendaylight.mdsal.binding.model.ri.BaseYangTypes;
25 import org.opendaylight.mdsal.binding.model.ri.BindingTypes;
26 import org.opendaylight.mdsal.binding.model.ri.TypeConstants;
27 import org.opendaylight.mdsal.binding.model.ri.Types;
28 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
29 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
32 * By type member {@link Comparator} which provides sorting by type for members (variables)
33 * in a generated class.
35 * @param <T> TypeMember type
38 final class ByTypeMemberComparator<T extends TypeMember> implements Comparator<T>, Serializable {
39 private static final long serialVersionUID = 1L;
42 * Fixed-size comparison. These are all numeric types, boolean, empty, identityref.
44 private static final int RANK_FIXED_SIZE = 0;
46 * Variable-sized comparison across simple components. These are string, binary and bits type.
48 private static final int RANK_VARIABLE_ARRAY = 1;
50 * Variable-size comparison across complex components.
52 private static final int RANK_INSTANCE_IDENTIFIER = 2;
54 * Composite structure. DataObject, OpaqueObject and similar.
56 private static final int RANK_COMPOSITE = 3;
58 private static final Set<Type> FIXED_TYPES = Set.of(
59 BaseYangTypes.INT8_TYPE,
60 BaseYangTypes.INT16_TYPE,
61 BaseYangTypes.INT32_TYPE,
62 BaseYangTypes.INT64_TYPE,
63 BaseYangTypes.DECIMAL64_TYPE,
64 BaseYangTypes.UINT8_TYPE,
65 BaseYangTypes.UINT16_TYPE,
66 BaseYangTypes.UINT32_TYPE,
67 BaseYangTypes.UINT64_TYPE,
68 BaseYangTypes.BOOLEAN_TYPE,
69 BaseYangTypes.EMPTY_TYPE);
74 private static final @NonNull ByTypeMemberComparator<?> INSTANCE = new ByTypeMemberComparator<>();
76 private ByTypeMemberComparator() {
81 * Returns the one and only instance of this class.
83 * @return this comparator
85 @SuppressWarnings("unchecked")
86 public static <T extends TypeMember> ByTypeMemberComparator<T> getInstance() {
87 return (ByTypeMemberComparator<T>) INSTANCE;
90 public static <T extends TypeMember> Collection<T> sort(final Collection<T> input) {
91 if (input.size() < 2) {
95 final List<T> ret = new ArrayList<>(input);
96 ret.sort(getInstance());
101 public int compare(final T member1, final T member2) {
102 final Type type1 = getConcreteType(member1.getReturnType());
103 final Type type2 = getConcreteType(member2.getReturnType());
104 if (!type1.getIdentifier().equals(type2.getIdentifier())) {
105 final int cmp = rankOf(type1) - rankOf(type2);
110 return member1.getName().compareTo(member2.getName());
113 @SuppressWarnings("static-method")
114 private Object readResolve() {
118 private static Type getConcreteType(final Type type) {
119 if (type instanceof ConcreteType) {
121 } else if (type instanceof ParameterizedType) {
122 return ((ParameterizedType) type).getRawType();
123 } else if (type instanceof GeneratedTransferObject) {
124 GeneratedTransferObject rootGto = (GeneratedTransferObject) type;
125 while (rootGto.getSuperType() != null) {
126 rootGto = rootGto.getSuperType();
128 for (GeneratedProperty s : rootGto.getProperties()) {
129 if (TypeConstants.VALUE_PROP.equals(s.getName())) {
130 return s.getReturnType();
137 private static int rankOf(final Type type) {
138 if (FIXED_TYPES.contains(type) || BindingTypes.isIdentityType(type)) {
139 return RANK_FIXED_SIZE;
141 if (type.equals(BaseYangTypes.STRING_TYPE) || type.equals(Types.BYTE_ARRAY)) {
142 return RANK_VARIABLE_ARRAY;
144 if (type.equals(BindingTypes.INSTANCE_IDENTIFIER) || type.equals(BindingTypes.KEYED_INSTANCE_IDENTIFIER)) {
145 return RANK_INSTANCE_IDENTIFIER;
147 if (type instanceof GeneratedTransferObject) {
148 final TypeDefinition<?> typedef = topParentTransportObject((GeneratedTransferObject) type).getBaseType();
149 if (typedef instanceof BitsTypeDefinition) {
150 return RANK_VARIABLE_ARRAY;
153 return RANK_COMPOSITE;
156 private static GeneratedTransferObject topParentTransportObject(final GeneratedTransferObject type) {
157 GeneratedTransferObject ret = type;
158 GeneratedTransferObject parent = ret.getSuperType();
159 while (parent != null) {
161 parent = ret.getSuperType();