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.Date;
026import java.util.Iterator;
027import java.util.List;
028import java.util.Set;
029
030import dk.netarkivet.common.exceptions.ArgumentNotValid;
031import dk.netarkivet.common.exceptions.IOFailure;
032import dk.netarkivet.common.exceptions.UnknownID;
033
034/**
035 * A Data Access Object for harvest definitions. This object is a singleton to ensure thread-safety. It handles the
036 * transformation from harvest definitions to persistent storage.
037 */
038public abstract class HarvestDefinitionDAO implements DAO, Iterable<HarvestDefinition> {
039
040    /** The one and only instance of the HarvestDefinitionDAO class to ensure thread-safety. */
041    private static HarvestDefinitionDAO instance;
042
043    /**
044     * Default constructor. Does not do anything, however.
045     */
046    protected HarvestDefinitionDAO() {
047    }
048
049    /**
050     * Creates the singleton.
051     *
052     * @return the HarvestDefinitionDAO singleton.
053     * @throws IOFailure if unable to create the singleton.
054     */
055    public static synchronized HarvestDefinitionDAO getInstance() {
056        if (instance == null) {
057            instance = new HarvestDefinitionDBDAO();
058        }
059        return instance;
060    }
061
062    /**
063     * Create a harvest definition in persistent storage.
064     *
065     * @param harvestDefinition A new harvest definition to write out.
066     * @return The harvestId for the just created harvest definition.
067     */
068    public abstract Long create(HarvestDefinition harvestDefinition);
069
070    /**
071     * Read the stored harvest definition for the given ID.
072     *
073     * @param harvestDefinitionID An ID number for a harvest definition
074     * @return A harvest definition that has been read from persistent storage.
075     * @throws UnknownID if no file with that ID exists
076     * @throws IOFailure if the File does not exist, does not have the correct ID, or otherwise fails to load correctly.
077     */
078    public abstract HarvestDefinition read(Long harvestDefinitionID) throws UnknownID, IOFailure;
079
080    /**
081     * Update an existing harvest definition with new info in persistent storage.
082     *
083     * @param harvestDefinition An updated harvest definition object to be persisted.
084     */
085    public abstract void update(HarvestDefinition harvestDefinition);
086
087    /**
088     * Activates or deactivates a partial harvest definition, depending on its activation status.
089     *
090     * @param harvestDefinition the harvest definition object
091     */
092    public abstract void flipActive(SparsePartialHarvest harvestDefinition);
093
094    /**
095     * Check, if there exists a HarvestDefinition identified by a given OID.
096     *
097     * @param oid a given OID
098     * @return true, if such a harvestdefinition exists.
099     */
100    public abstract boolean exists(Long oid);
101
102    /**
103     * Check, if there exists a HarvestDefinition identified by a given name.
104     *
105     * @param name a given name
106     * @return true, if such a harvestdefinition exists.
107     */
108    public abstract boolean exists(String name);
109
110    /**
111     * Get a list of all existing harvest definitions.
112     *
113     * @return An iterator that give the existing harvest definitions in turn
114     */
115    public abstract Iterator<HarvestDefinition> getAllHarvestDefinitions();
116
117    /**
118     * Get an iterator of all harvest definitions. Implements the Iterable interface.
119     *
120     * @return Iterator of all harvest definitions, Selective and Full both.
121     */
122    public Iterator<HarvestDefinition> iterator() {
123        return getAllHarvestDefinitions();
124    }
125
126    /**
127     * Gets default configurations for all domains.
128     *
129     * @return Iterator containing the default DomainConfiguration for all domains
130     */
131    public abstract Iterator<DomainConfiguration> getSnapShotConfigurations();
132
133    /**
134     * Get the IDs of the harvest definitions that are ready to run.
135     *
136     * @param now
137     * @return IDs of the harvest definitions that are currently ready to be scheduled. Some of these might already be
138     * in the process of being scheduled.
139     */
140    public abstract Iterable<Long> getReadyHarvestDefinitions(Date now);
141
142    /**
143     * Get the harvest definition that has the given name, or null, if no harvestdefinition exist with this name.
144     *
145     * @param name The name of a harvest definition.
146     * @return The HarvestDefinition object with that name, or null if none has that name.
147     */
148    public abstract HarvestDefinition getHarvestDefinition(String name);
149
150    /**
151     * Returns a list with information on the runs of a particular harvest. The list is ordered by descending run
152     * number.
153     *
154     * @param harvestID ID of an existing harvest
155     * @return List of objects with selected information.
156     */
157    public abstract List<HarvestRunInfo> getHarvestRunInfo(long harvestID);
158
159    /**
160     * Reset the DAO instance. Only for use in tests.
161     */
162    static void reset() {
163        instance = null;
164    }
165
166    /**
167     * Get all domain,configuration pairs for a harvest definition in sparse version for GUI purposes.
168     *
169     * @param harvestDefinitionID The ID of the harvest definition.
170     * @return Domain, configuration pairs for that HD. Returns an empty list for unknown harvest definitions.
171     * @throws ArgumentNotValid on null argument.
172     */
173    public abstract List<SparseDomainConfiguration> getSparseDomainConfigurations(Long harvestDefinitionID);
174
175    /**
176     * Get a sparse version of a partial harvest for GUI purposes.
177     *
178     * @param harvestName Name of harvest definition.
179     * @return Sparse version of partial harvest or null for none.
180     * @throws ArgumentNotValid on null or empty name.
181     */
182    public abstract SparsePartialHarvest getSparsePartialHarvest(String harvestName);
183
184    /**
185     * Get all sparse versions of partial harvests for GUI purposes.
186     *
187     * @param excludeInactive If true only active harvest definitions are returned.
188     * @return An iterable (possibly empty) of SparsePartialHarvests
189     */
190    public abstract Iterable<SparsePartialHarvest> getSparsePartialHarvestDefinitions(boolean excludeInactive);
191
192    /**
193     * Get a sparse version of a full harvest for GUI purposes.
194     *
195     * @param harvestName Name of harvest definition.
196     * @return Sparse version of full harvest or null for none.
197     * @throws ArgumentNotValid on null or empty name.
198     */
199    public abstract SparseFullHarvest getSparseFullHarvest(String harvestName);
200
201    /**
202     * Get all sparse versions of full harvests for GUI purposes.
203     *
204     * @return An iterable (possibly empty) of SparseFullHarvests
205     */
206    public abstract Iterable<SparseFullHarvest> getAllSparseFullHarvestDefinitions();
207
208    /**
209     * Get the name of a harvest given its ID.
210     *
211     * @param harvestDefinitionID The ID of a harvest
212     * @return The name of the given harvest.
213     * @throws ArgumentNotValid on null argument
214     * @throws UnknownID if no harvest has the given ID.
215     * @throws IOFailure on any other error talking to the database
216     */
217    public abstract String getHarvestName(Long harvestDefinitionID);
218
219    /**
220     * Get whether a given harvest is a snapshot or selective harvest.
221     *
222     * @param harvestDefinitionID ID of a harvest
223     * @return True if the given harvest is a snapshot harvest, false otherwise.
224     * @throws ArgumentNotValid on null argument
225     * @throws UnknownID if no harvest has the given ID.
226     * @throws IOFailure on any other error talking to the database
227     */
228    public abstract boolean isSnapshot(Long harvestDefinitionID);
229
230    /**
231     * Get a sorted list of all domainnames of a HarvestDefintion
232     *
233     * @param harvestName of HarvestDefintion
234     * @return List of all domains of the HarvestDefinition.
235     * @throws ArgumentNotValid on null argument
236     * @throws IOFailure on any other error talking to the database
237     */
238    public abstract List<String> getListOfDomainsOfHarvestDefinition(String harvestName);
239
240    /**
241     * Get a sorted list of all seeds of a Domain in a HarvestDefinition.
242     *
243     * @param harvestName of HarvestDefintion
244     * @param domainName of Domain
245     * @return List of all seeds of the Domain in the HarvestDefinition.
246     * @throws ArgumentNotValid on null argument
247     * @throws IOFailure on any other error talking to the database
248     */
249    public abstract List<String> getListOfSeedsOfDomainOfHarvestDefinition(String harvestName, String domainName);
250
251    /**
252     * Get a collection of jobIds for snapshot deduplication index.
253     *
254     * @param harvestId the id of the harvest
255     * @return a collection of jobIds to create a deduplication index.
256     */
257    public abstract Set<Long> getJobIdsForSnapshotDeduplicationIndex(Long harvestId);
258
259    /**
260     * Set the isindexready field available for snapshot harvests.
261     *
262     * @param harvestId the ID of the harvest.
263     * @param newValue the new isindexready value
264     */
265    public abstract void setIndexIsReady(Long harvestId, boolean newValue);
266
267    /**
268     * Remove Domain configuration from a specific PartialHarvest.
269     *
270     * @param harvestId Id for a specific PartialHarvest
271     * @param key a SparseDomainConfiguration uniquely identifying the domainconfig.
272     */
273    public abstract void removeDomainConfiguration(Long harvestId, SparseDomainConfiguration key);
274
275    /**
276     * Update the given PartialHarvest (i.e. Selective Harvest) with a new time for the next harvestrun. If no selective
277     * harvest matching the given id is found in the storage, the method should silently return.
278     *
279     * @param harvestId A given PartialHarvest id (i.e. Selective Harvest).
280     * @param nextdate A new date for the next harvest run.
281     */
282    public abstract void updateNextdate(long harvestId, Date nextdate);
283
284    /**
285     * Add a domainconfiguration to a PartialHarvest.
286     *
287     * @param hdd a given PartialHarvest
288     * @param sparseDomainConfiguration a reduced domainconfiguration object
289     */
290    public abstract void addDomainConfiguration(PartialHarvest hdd, SparseDomainConfiguration sparseDomainConfiguration);
291
292    /**
293     * Reset the list of domainconfiguration for a PartialHarvest.
294     *
295     * @param hdd a given PartialHarvest
296     * @param dcList the new list of domainconfigurations
297     */
298    public abstract void resetDomainConfigurations(PartialHarvest hdd, List<DomainConfiguration> dcList);
299
300    /**
301     * Maps a harvest definition to a harvest channel.
302     *
303     * @param harvestDefinitionId the harvest definition id
304     * @param channel the harvest channel
305     */
306    public abstract void mapToHarvestChannel(long harvestDefinitionId, HarvestChannel channel);
307
308}