1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.security;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.Serializable;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.CertPath;
227365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilsonimport java.util.Date;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code Timestamp} represents a signed time stamp. {@code Timestamp} is
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * immutable.
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic final class Timestamp implements Serializable {
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final long serialVersionUID = -5502683707821851294L;
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Date timestamp;
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private CertPath signerCertPath;
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Cached hash
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient int hash;
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new instance of {@code Timestamp} with the specified {@code
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * timestamp} and the given certificate path.
422f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param timestamp
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            date and time.
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param signerCertPath
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the certificate path.
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code timestamp} is {@code null} or if {@code
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             signerCertPath} is {@code null}.
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Timestamp(Date timestamp, CertPath signerCertPath) {
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (timestamp == null) {
53897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new NullPointerException("timestamp == null");
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (signerCertPath == null) {
56897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new NullPointerException("signerCertPath == null");
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Clone timestamp to prevent modifications
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.timestamp = new Date(timestamp.getTime());
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.signerCertPath = signerCertPath;
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Compares the specified object with this {@code Timestamp} for equality
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * and returns {@code true} if the specified object is equal, {@code false}
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * otherwise. The given object is equal to this {@code Timestamp}, if it is
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * an instance of {@code Timestamp}, the two timestamps have an equal date
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * and time and their certificate paths are equal.
692f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            object to be compared for equality with this {@code
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            Timestamp}.
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the specified object is equal to this {@code
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         Timestamp}, otherwise {@code false}.
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #hashCode
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
772f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes    @Override
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean equals(Object obj) {
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (obj == this) {
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return true;
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (obj instanceof Timestamp) {
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Timestamp that = (Timestamp) obj;
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return timestamp.equals(that.timestamp)
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    && signerCertPath.equals(that.signerCertPath);
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the certificate path of this {@code Timestamp}.
922f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the certificate path of this {@code Timestamp}.
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public CertPath getSignerCertPath() {
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return signerCertPath;
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the date and time of this {@code Timestamp}.
1012f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the date and time of this {@code Timestamp}.
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Date getTimestamp() {
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return (Date) timestamp.clone();
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the hash code value for this {@code Timestamp}. Returns the same
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * hash code for {@code Timestamp}s that are equal to each other as
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * required by the general contract of {@link Object#hashCode}.
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the hash code value for this {@code Timestamp}.
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see Object#equals(Object)
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see Timestamp#equals(Object)
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1172f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes    @Override
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int hashCode() {
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (hash == 0) {
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            hash = timestamp.hashCode() ^ signerCertPath.hashCode();
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return hash;
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a string containing a concise, human-readable description of this
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code Timestamp}.
1282f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a printable representation for this {@code Timestamp}.
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1312f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes    @Override
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
1332f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        StringBuilder buf = new StringBuilder(256);
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Dump only the first certificate
135f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        buf.append("Timestamp [").append(timestamp).append(" certPath=");
136f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        buf.append(signerCertPath.getCertificates().get(0)).append("]");
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return buf.toString();
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1392f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes}
140