001/*
002 * #%L
003 * Netarchivesuite - harvester
004 * %%
005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library,
006 *             the National Library of France and the Austrian National Library.
007 * %%
008 * This program is free software: you can redistribute it and/or modify
009 * it under the terms of the GNU Lesser General Public License as
010 * published by the Free Software Foundation, either version 2.1 of the
011 * License, or (at your option) any later version.
012 * 
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Lesser Public License for more details.
017 * 
018 * You should have received a copy of the GNU General Lesser Public
019 * License along with this program.  If not, see
020 * <http://www.gnu.org/licenses/lgpl-2.1.html>.
021 * #L%
022 */
023package dk.netarkivet.harvester.datamodel;
024
025import java.util.Comparator;
026import java.util.Iterator;
027import java.util.SortedSet;
028import java.util.TreeSet;
029
030import dk.netarkivet.common.exceptions.ArgumentNotValid;
031
032/**
033 * Container for the historical information available for a domain.
034 */
035public class DomainHistory {
036
037    /**
038     * Harvest information sorted with newest harvests first.
039     */
040    private SortedSet<HarvestInfo> harvestInfo;
041    /**
042     * Sorts HarvestInfo with newest first. Sorting on HarvestID and DomainConfiguration is only to make comparator
043     * consistent with equals.
044     */
045    private static final Comparator<HarvestInfo> DATE_COMPARATOR = new Comparator<HarvestInfo>() {
046        public int compare(HarvestInfo hi1, HarvestInfo hi2) {
047            int i = hi2.getDate().compareTo(hi1.getDate());
048            if (i != 0) {
049                return i;
050            }
051            int i2 = hi2.getHarvestID().compareTo(hi1.getHarvestID());
052            if (i2 != 0) {
053                return i2;
054            }
055            return hi2.getDomainConfigurationName().compareTo(hi1.getDomainConfigurationName());
056        }
057    };
058
059    /**
060     * Create new DomainHistory instance.
061     */
062    public DomainHistory() {
063        this.harvestInfo = new TreeSet<HarvestInfo>(DATE_COMPARATOR);
064    }
065
066    /**
067     * Get all harvest information domain history.
068     *
069     * @return Iterator of harvest information registered for this domain. The information is sorted by date with the
070     * most recent information as the first entry.
071     */
072    public Iterator<HarvestInfo> getHarvestInfo() {
073        return harvestInfo.iterator();
074    }
075
076    /**
077     * Gets the most recent harvestinfo for a specific DomainConfiguration.
078     *
079     * @param cfgName name of the configuration
080     * @return the most recent harvest info or null if no matching harvestinfo found
081     */
082    public HarvestInfo getMostRecentHarvestInfo(String cfgName) {
083        ArgumentNotValid.checkNotNull(cfgName, "cfgName");
084
085        if (harvestInfo.size() == 0) {
086            return null;
087        }
088        for (HarvestInfo hi : harvestInfo) {
089            if (hi.getDomainConfigurationName().equals(cfgName)) {
090                return hi;
091            }
092        }
093        return null;
094    }
095
096    /**
097     * Gets the newest harvestinfo for a specific HarvestDefinition and DomainConfiguration.
098     *
099     * @param oid id of the harvest definition
100     * @param cfgName the name of the domain configuration
101     * @return the harvest info or null if no matching harvestinfo found
102     */
103    public HarvestInfo getSpecifiedHarvestInfo(Long oid, String cfgName) {
104        ArgumentNotValid.checkNotNull(oid, "oid");
105        ArgumentNotValid.checkNotNull(cfgName, "cfgName");
106
107        Iterator<HarvestInfo> iter = harvestInfo.iterator();
108        HarvestInfo hi;
109        while (iter.hasNext()) {
110            hi = iter.next();
111            if (hi.getHarvestID().equals(oid) && hi.getDomainConfigurationName().equals(cfgName)) {
112                return hi;
113            }
114        }
115        return null;
116    }
117
118    /**
119     * Add new harvestinformation to the domainHistory.
120     *
121     * @param hi the harvest information to add
122     */
123    public void addHarvestInfo(HarvestInfo hi) {
124        ArgumentNotValid.checkNotNull(hi, "hi");
125        harvestInfo.add(hi);
126    }
127
128    /**
129     * Return the most recent harvestresult for the configuration identified by name that was a complete harvest of the
130     * domain.
131     *
132     * @param configName The name of the configuration
133     * @param history The domainHistory for a domain
134     * @return the most recent harvestresult for the configuration identified by name that was a complete harvest of the
135     * domain.
136     */
137    public static HarvestInfo getBestHarvestInfoExpectation(String configName, DomainHistory history) {
138        ArgumentNotValid.checkNotNullOrEmpty(configName, "String configName");
139        ArgumentNotValid.checkNotNull(history, "DomainHistory history");
140        // Remember best expectation
141        HarvestInfo best = null;
142
143        // loop through all harvest infos for this configuration. The iterator is
144        // sorted by date with most recent first
145        Iterator<HarvestInfo> i = history.getHarvestInfo();
146        while (i.hasNext()) {
147            HarvestInfo hi = i.next();
148            if (hi.getDomainConfigurationName().equals(configName)) {
149                // Remember this expectation, if it harvested at least
150                // as many objects as the previously remembered
151                if ((best == null) || (best.getCountObjectRetrieved() <= hi.getCountObjectRetrieved())) {
152                    best = hi;
153                }
154                // if this harvest completed, stop search and return best
155                // expectation,
156                if (hi.getStopReason() == StopReason.DOWNLOAD_COMPLETE) {
157                    return best;
158                }
159            }
160        }
161
162        // Return maximum uncompleted harvest, or null if never harvested
163        return best;
164    }
165
166}