Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / cacheinvalidation / src / java / com / google / ipc / invalidation / common / ObjectIdDigestUtils.java
1 /*
2  * Copyright 2011 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.google.ipc.invalidation.common;
18
19 import com.google.ipc.invalidation.util.Bytes;
20 import com.google.ipc.invalidation.util.Preconditions;
21
22 import java.nio.ByteBuffer;
23 import java.nio.ByteOrder;
24 import java.security.MessageDigest;
25 import java.security.NoSuchAlgorithmException;
26
27 /**
28  * Digest-related utilities for object ids.
29  *
30  */
31 public class ObjectIdDigestUtils {
32   /**
33    * Implementation of {@link DigestFunction} using SHA-1.
34    */
35   public static class Sha1DigestFunction
36       implements DigestFunction {
37     /** Digest implementation. */
38     private MessageDigest sha1;
39
40     /**
41      * Whether the {@link #reset()} method needs to be called. This is set to true
42      * when {@link #getDigest()} is called and aims to prevent subtle bugs caused by
43      * failing to reset the object before computing a new digest.
44      */
45     private boolean resetNeeded = false;
46
47     public Sha1DigestFunction() {
48       try {
49       this.sha1 = MessageDigest.getInstance("SHA-1");
50       } catch (NoSuchAlgorithmException exception) {
51         throw new RuntimeException(exception);
52       }
53     }
54
55     @Override
56     public void reset() {
57       resetNeeded = false;
58       sha1.reset();
59     }
60
61     @Override
62     public void update(byte[] data) {
63       Preconditions.checkState(!resetNeeded);
64       sha1.update(data);
65     }
66
67     @Override
68     public byte[] getDigest() {
69       Preconditions.checkState(!resetNeeded);
70       resetNeeded = true;
71       return sha1.digest();
72     }
73   }
74
75   /**
76    * Returns the digest of {@code objectIdDigests} using {@code digestFn}.
77    * <p>
78    * REQUIRES: {@code objectIdDigests} iterate in sorted order.
79    */
80   public static Bytes getDigest(Iterable<Bytes> objectIdDigests, DigestFunction digestFn) {
81     digestFn.reset();
82     for (Bytes objectIdDigest : objectIdDigests) {
83       digestFn.update(objectIdDigest.getByteArray());
84     }
85     return new Bytes(digestFn.getDigest());
86   }
87
88   /**
89    * Returns the digest for the object id with source {@code objectSource} and name
90    * {@code objectName} using {@code digestFn}.
91    */
92   public static Bytes getDigest(int objectSource, byte[] objectName, DigestFunction digestFn) {
93     digestFn.reset();
94     ByteBuffer buffer = ByteBuffer.allocate(Integer.SIZE / 8).order(ByteOrder.LITTLE_ENDIAN);
95     buffer.putInt(objectSource);
96
97     // Little endian number for type followed by bytes.
98     digestFn.update(buffer.array());
99     digestFn.update(objectName);
100     return new Bytes(digestFn.getDigest());
101   }
102 }