Change action input/output naming strategy
[mdsal.git] / binding / mdsal-binding-generator / src / main / java / org / opendaylight / mdsal / binding / generator / impl / reactor / SerialVersionHelper.java
1 /*
2  * Copyright (c) 2014 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.mdsal.binding.generator.impl.reactor;
9
10 import com.google.common.collect.Collections2;
11 import java.io.ByteArrayOutputStream;
12 import java.io.DataOutputStream;
13 import java.io.IOException;
14 import java.security.MessageDigest;
15 import java.security.NoSuchAlgorithmException;
16 import java.util.ArrayList;
17 import java.util.Collection;
18 import java.util.Comparator;
19 import java.util.Set;
20 import org.opendaylight.mdsal.binding.model.api.AccessModifier;
21 import org.opendaylight.mdsal.binding.model.api.ConcreteType;
22 import org.opendaylight.mdsal.binding.model.api.Type;
23 import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedPropertyBuilder;
24 import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilderBase;
25 import org.opendaylight.mdsal.binding.model.api.type.builder.MethodSignatureBuilder;
26 import org.opendaylight.mdsal.binding.model.api.type.builder.TypeMemberBuilder;
27 import org.opendaylight.mdsal.binding.model.ri.BindingTypes;
28
29 public final class SerialVersionHelper {
30     private static final Set<ConcreteType> IGNORED_INTERFACES =
31         Set.of(BindingTypes.BITS_TYPE_OBJECT, BindingTypes.SCALAR_TYPE_OBJECT, BindingTypes.UNION_TYPE_OBJECT);
32     private static final Comparator<TypeMemberBuilder<?>> SUID_MEMBER_COMPARATOR =
33         Comparator.comparing(TypeMemberBuilder::getName);
34     private static final Comparator<Type> SUID_NAME_COMPARATOR = Comparator.comparing(Type::getFullyQualifiedName);
35     private static final ThreadLocal<MessageDigest> SHA1_MD = ThreadLocal.withInitial(() -> {
36         try {
37             return MessageDigest.getInstance("SHA");
38         } catch (final NoSuchAlgorithmException e) {
39             throw new IllegalStateException("Failed to get a SHA digest provider", e);
40         }
41     });
42
43     private SerialVersionHelper() {
44         // Hidden on purpose
45     }
46
47     public static long computeDefaultSUID(final GeneratedTypeBuilderBase<?> to) {
48         final ByteArrayOutputStream bout = new ByteArrayOutputStream();
49         try (DataOutputStream dout = new DataOutputStream(bout)) {
50             dout.writeUTF(to.getName());
51             dout.writeInt(to.isAbstract() ? 3 : 7);
52
53             for (final Type ifc : sortedCollection(SUID_NAME_COMPARATOR, filteredImplementsTypes(to))) {
54                 dout.writeUTF(ifc.getFullyQualifiedName());
55             }
56
57             for (final GeneratedPropertyBuilder gp : sortedCollection(SUID_MEMBER_COMPARATOR, to.getProperties())) {
58                 dout.writeUTF(gp.getName());
59             }
60
61             for (final MethodSignatureBuilder m : sortedCollection(SUID_MEMBER_COMPARATOR, to.getMethodDefinitions())) {
62                 if (!m.getAccessModifier().equals(AccessModifier.PRIVATE)) {
63                     dout.writeUTF(m.getName());
64                     dout.write(m.getAccessModifier().ordinal());
65                 }
66             }
67
68             dout.flush();
69         } catch (final IOException e) {
70             throw new IllegalStateException("Failed to hash object " + to, e);
71         }
72
73         final byte[] hashBytes = SHA1_MD.get().digest(bout.toByteArray());
74         long hash = 0;
75         for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) {
76             hash = hash << 8 | hashBytes[i] & 0xFF;
77         }
78         return hash;
79     }
80
81     private static Collection<Type> filteredImplementsTypes(final GeneratedTypeBuilderBase<?> to) {
82         return Collections2.filter(to.getImplementsTypes(), item -> !IGNORED_INTERFACES.contains(item));
83     }
84
85     private static <T> Iterable<T> sortedCollection(final Comparator<? super T> comparator, final Collection<T> input) {
86         if (input.size() <= 1) {
87             return input;
88         }
89
90         final var ret = new ArrayList<>(input);
91         ret.sort(comparator);
92         return ret;
93     }
94 }