001package votorola.a.diff.harvest;// Copyright 2011-2012. Christian Weilbach.  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Votorola Software"), to deal in the Votorola Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Votorola Software, and to permit persons to whom the Votorola Software is furnished to do so, subject to the following conditions: The preceding copyright notice and this permission notice shall be included in all copies or substantial portions of the Votorola Software. THE VOTOROLA SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE VOTOROLA SOFTWARE OR THE USE OR OTHER DEALINGS IN THE VOTOROLA SOFTWARE.
002
003/**
004 * This interface is for possible message objects.
005 */
006
007import java.util.Collections;
008import java.util.Date;
009import java.util.List;
010
011import votorola.a.diff.harvest.cache.HarvestCache;
012import votorola.g.lang.ThreadSafe;
013
014/**
015 * Data structure for message-contexts as long as the Url is unknown and the
016 * message is therefore only known (including diff-urls) to determine harvesting
017 * {@linkplain votorola.a.diff.harvest.kick.UpdateKick}s. If you already know
018 * the url of the posting on the web-archive and all the other data, then you
019 * can pass a {@linkplain Message} object to {@linkplain HarvestCache} to store
020 * it directly without web harvesting. Look at the documentation of
021 * {@linkplain HarvestCache} to get an overview over the caching process.
022 * 
023 * @see Message
024 * @see HarvestCache
025 */
026@ThreadSafe
027final public class MessageContext {
028
029    /**
030     * All fields may not be null or empty. 
031     * @param sender
032     * @param archiveUrl
033     * @param diffUrls
034     * @param sentDate may not have 'getTime()==0'
035     */
036    private MessageContext(final String sender, final String archiveUrl,
037            final List<String> diffUrls, final Date sentDate) {
038        if (archiveUrl == null) {
039            throw new IllegalArgumentException("archiveUrl is null.");
040        }
041        if (sender == null) {
042            throw new IllegalArgumentException(archiveUrl + ": sender is null.");
043        }
044        if (diffUrls == null) {
045            throw new IllegalArgumentException(archiveUrl
046                    + ": diffUrls is null.");
047        }
048        if (sentDate == null) {
049            throw new IllegalArgumentException(archiveUrl
050                    + ": sentDate is null.");
051        }
052        
053        if (archiveUrl.isEmpty()) {
054            throw new IllegalArgumentException("archiveUrl is empty.");
055        }
056        if (sender.isEmpty()) {
057            throw new IllegalArgumentException(archiveUrl + ": sender is empty.");
058        }
059        if (diffUrls.isEmpty()) {
060            throw new IllegalArgumentException(archiveUrl
061                    + ": diffUrls is empty.");
062        }
063        if (sentDate.getTime()==0) {
064            throw new IllegalArgumentException(archiveUrl
065                    + ": sentDate is zero seconds unix time.");
066        }
067
068        this.sender = sender;
069        this.archiveUrl = archiveUrl;
070        this.diffUrls = Collections.unmodifiableList(diffUrls);
071        this.sentDate = sentDate;
072    }
073
074    /**
075     * Create a context.
076     * 
077     * @param sender
078     *            , may not be null
079     * @param archiveUrl
080     *            , may not be null
081     * @param diffUrls
082     *            , may not be null, set through
083     *            {@link HarvestCache#findDiffUrls(String)}
084     * @param sentDate
085     *            , may not be null
086     */
087    public static MessageContext create(final String sender,
088            final String archiveUrl, final List<String> diffUrls,
089            final Date sentDate) {
090        return new MessageContext(sender, archiveUrl, diffUrls, sentDate);
091    }
092
093    final private String sender;
094
095    /**
096     * Sender of the message as known to the medium. This is later resolved
097     * through {@linkplain HarvestCache#store(Message, Authenticator)} by a
098     * {@linkplain votorola.a.diff.harvest.auth.Authenticator} to
099     * mailish-usernames of Votorola.
100     * 
101     * @return sender
102     */
103    public String sender() {
104        return sender;
105    }
106
107    final private String archiveUrl;
108
109    /**
110     * The base-url which acts as a system wide identifier for archives.
111     * 
112     * @return base-url
113     */
114    public String archiveUrl() {
115        return archiveUrl;
116    }
117
118    final private List<String> diffUrls;
119
120    /**
121     * Diff-urls detected in this message. This can be done through
122     * {@linkplain HarvestCache#findDiffUrls(String)}
123     * 
124     * @return diff-urls
125     */
126    public List<String> diffUrls() {
127        return diffUrls;
128    }
129
130    final private Date sentDate;
131
132    /**
133     * Date the message has been sent due to the archive information. This
134     * information is crucial for proper archive access, both through harvesting
135     * and later for browsing.
136     * 
137     * @return sent-date
138     */
139    public Date sentDate() {
140        return sentDate;
141    }
142
143    /**
144     * Compares all constructor variables.
145     * 
146     * @return whether the contexts equal each other
147     */
148    @Override
149    public boolean equals(final Object o) {
150        return (o instanceof MessageContext)
151                && sender.equals(((MessageContext) o).sender)
152                && archiveUrl.equals(((MessageContext) o).archiveUrl)
153                && diffUrls.equals(((MessageContext) o).diffUrls)
154                && sentDate.equals(((MessageContext) o).sentDate);
155    }
156
157    /**
158     * Obey equals contract.
159     */
160    @Override
161    public int hashCode() {
162        int hash = sender.hashCode();
163        hash = hash * 37 + archiveUrl.hashCode();
164        hash = hash * 37 + diffUrls.hashCode();
165        hash = hash * 37 + sentDate.hashCode();
166        return hash;
167    }
168
169    /**
170     * Prints all constructor variables separated by ":". This format is not
171     * guaranteed.
172     */
173    @Override
174    public String toString() {
175        return archiveUrl + "|" + sender + "|" + sentDate.toString() + "|"
176                + diffUrls.toString();
177    }
178
179}