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