2 * Copyright (c) 2014 Cisco Systems, Inc. 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.generator.impl.reactor;
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;
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;
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(() -> {
37 return MessageDigest.getInstance("SHA");
38 } catch (final NoSuchAlgorithmException e) {
39 throw new IllegalStateException("Failed to get a SHA digest provider", e);
43 private SerialVersionHelper() {
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);
53 for (final Type ifc : sortedCollection(SUID_NAME_COMPARATOR, filteredImplementsTypes(to))) {
54 dout.writeUTF(ifc.getFullyQualifiedName());
57 for (final GeneratedPropertyBuilder gp : sortedCollection(SUID_MEMBER_COMPARATOR, to.getProperties())) {
58 dout.writeUTF(gp.getName());
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());
69 } catch (final IOException e) {
70 throw new IllegalStateException("Failed to hash object " + to, e);
73 final byte[] hashBytes = SHA1_MD.get().digest(bout.toByteArray());
75 for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) {
76 hash = hash << 8 | hashBytes[i] & 0xFF;
81 private static Collection<Type> filteredImplementsTypes(final GeneratedTypeBuilderBase<?> to) {
82 return Collections2.filter(to.getImplementsTypes(), item -> !IGNORED_INTERFACES.contains(item));
85 private static <T> Iterable<T> sortedCollection(final Comparator<? super T> comparator, final Collection<T> input) {
86 if (input.size() <= 1) {
90 final var ret = new ArrayList<>(input);