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;
19 import java.util.List;
21 import org.opendaylight.mdsal.binding.model.api.AccessModifier;
22 import org.opendaylight.mdsal.binding.model.api.ConcreteType;
23 import org.opendaylight.mdsal.binding.model.api.Type;
24 import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedPropertyBuilder;
25 import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilderBase;
26 import org.opendaylight.mdsal.binding.model.api.type.builder.MethodSignatureBuilder;
27 import org.opendaylight.mdsal.binding.model.api.type.builder.TypeMemberBuilder;
28 import org.opendaylight.mdsal.binding.model.ri.BindingTypes;
30 public final class SerialVersionHelper {
31 private static final Set<ConcreteType> IGNORED_INTERFACES =
32 Set.of(BindingTypes.TYPE_OBJECT, BindingTypes.SCALAR_TYPE_OBJECT);
33 private static final Comparator<TypeMemberBuilder<?>> SUID_MEMBER_COMPARATOR =
34 Comparator.comparing(TypeMemberBuilder::getName);
35 private static final Comparator<Type> SUID_NAME_COMPARATOR = Comparator.comparing(Type::getFullyQualifiedName);
36 private static final ThreadLocal<MessageDigest> SHA1_MD = ThreadLocal.withInitial(() -> {
38 return MessageDigest.getInstance("SHA");
39 } catch (final NoSuchAlgorithmException e) {
40 throw new IllegalStateException("Failed to get a SHA digest provider", e);
44 private SerialVersionHelper() {
48 public static long computeDefaultSUID(final GeneratedTypeBuilderBase<?> to) {
49 final ByteArrayOutputStream bout = new ByteArrayOutputStream();
50 try (DataOutputStream dout = new DataOutputStream(bout)) {
51 dout.writeUTF(to.getName());
52 dout.writeInt(to.isAbstract() ? 3 : 7);
54 for (final Type ifc : sortedCollection(SUID_NAME_COMPARATOR, filteredImplementsTypes(to))) {
55 dout.writeUTF(ifc.getFullyQualifiedName());
58 for (final GeneratedPropertyBuilder gp : sortedCollection(SUID_MEMBER_COMPARATOR, to.getProperties())) {
59 dout.writeUTF(gp.getName());
62 for (final MethodSignatureBuilder m : sortedCollection(SUID_MEMBER_COMPARATOR, to.getMethodDefinitions())) {
63 if (!m.getAccessModifier().equals(AccessModifier.PRIVATE)) {
64 dout.writeUTF(m.getName());
65 dout.write(m.getAccessModifier().ordinal());
70 } catch (final IOException e) {
71 throw new IllegalStateException("Failed to hash object " + to, e);
74 final byte[] hashBytes = SHA1_MD.get().digest(bout.toByteArray());
76 for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) {
77 hash = hash << 8 | hashBytes[i] & 0xFF;
82 private static Collection<Type> filteredImplementsTypes(final GeneratedTypeBuilderBase<?> to) {
83 return Collections2.filter(to.getImplementsTypes(), item -> !IGNORED_INTERFACES.contains(item));
86 private static <T> Iterable<T> sortedCollection(final Comparator<? super T> comparator, final Collection<T> input) {
87 if (input.size() <= 1) {
91 final List<T> ret = new ArrayList<>(input);