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; 028 029import javax.inject.Provider; 030 031import dk.netarkivet.common.exceptions.ArgumentNotValid; 032import dk.netarkivet.common.utils.Named; 033import dk.netarkivet.harvester.datamodel.dao.DAOProviderFactory; 034import dk.netarkivet.harvester.datamodel.extendedfield.ExtendableEntity; 035import dk.netarkivet.harvester.datamodel.extendedfield.ExtendedFieldDAO; 036import dk.netarkivet.harvester.datamodel.extendedfield.ExtendedFieldTypes; 037import dk.netarkivet.harvester.datamodel.extendedfield.ExtendedFieldValue; 038 039/** 040 * This abstract class models the general properties of a harvest definition, i.e. object id , name, comments, and 041 * submission date 042 * <p> 043 * The specializing classes FullHarvest and PartielHarvest contains the specific properties and operations of snapshot 044 * harvestdefinitions and all other kinds of harvestdefinitions, respectively. 045 * <p> 046 * Methods exist to generate jobs from this harvest definition. 047 */ 048public abstract class HarvestDefinition extends ExtendableEntity implements Named { 049 050 protected Long oid; 051 protected String harvestDefName; 052 /** The intended audience for the harvest. */ 053 protected String audience; 054 055 /** The time this harvest definition was first written. */ 056 protected Date submissionDate; 057 protected String comments; 058 059 /** Edition is used by the DAO to keep track of changes. */ 060 protected long edition = -1; 061 062 /** 063 * Determines if the harvest definition is active and ready for scheduling. When true the jobs should be scheduled 064 * otherwise the scheduler should ignore the definition. Initially a definition is assumed active - the original 065 * behaviour before the isActive flag was introduced. 066 */ 067 protected boolean isActive = true; 068 069 /** The number of times this event has already run. */ 070 protected int numEvents; 071 072 /** The id of the associated harvest channel, or null if the default one is to be used. */ 073 protected Long channelId; 074 075 protected HarvestDefinition(Provider<ExtendedFieldDAO> extendedFieldDAO) { 076 super(extendedFieldDAO); 077 } 078 079 /** 080 * Create new instance of a PartialHavest configured according to the properties of the supplied 081 * DomainConfiguration. 082 * 083 * @param domainConfigurations a list of domain configurations 084 * @param schedule the harvest definition schedule 085 * @param harvestDefName the name of the harvest definition 086 * @param comments comments 087 * @return the newly created PartialHarvest 088 */ 089 public static PartialHarvest createPartialHarvest(List<DomainConfiguration> domainConfigurations, 090 Schedule schedule, String harvestDefName, String comments, String audience) { 091 092 return new PartialHarvest(domainConfigurations, schedule, harvestDefName, comments, audience); 093 } 094 095 /** 096 * Create snapshot harvestdefinition. A snapshot harvestdefinition creates jobs for all domains, using the default 097 * configuration for each domain. The HarvestDefinition is scheduled to run once as soon as possible. 098 * <p> 099 * When a previous harvest definition is supplied, only domains not completely harvested by the previous 100 * harvestdefinition are included in this harvestdefinition. indexready set to false. 101 * 102 * @param harvestDefName the name of the harvest definition 103 * @param comments description of the harvestdefinition 104 * @param prevHarvestOid an id of a previous harvest to use as basis for this definition, ignored when null. 105 * @param maxCountObjects the maximum number of objects harvested from any domain 106 * @param maxBytes the maximum number of bytes harvested from any domain 107 * @param maxJobRunningTime The maximum running time for each job 108 * @return a snapshot harvestdefinition 109 */ 110 public static FullHarvest createFullHarvest(String harvestDefName, String comments, Long prevHarvestOid, 111 long maxCountObjects, long maxBytes, long maxJobRunningTime) { 112 113 return new FullHarvest(harvestDefName, comments, prevHarvestOid, maxCountObjects, maxBytes, maxJobRunningTime, 114 false, DAOProviderFactory.getHarvestDefinitionDAOProvider(), DAOProviderFactory.getJobDAOProvider(), 115 DAOProviderFactory.getExtendedFieldDAOProvider(), DAOProviderFactory.getDomainDAOProvider()); 116 } 117 118 /** 119 * Set the object ID of this harvest definition. 120 * 121 * @param oid The oid 122 * @throws ArgumentNotValid if the oid is null 123 */ 124 public void setOid(Long oid) { 125 ArgumentNotValid.checkNotNull(oid, "oid"); 126 this.oid = oid; 127 } 128 129 /** 130 * Return the object ID of this harvest definition. 131 * 132 * @return The object id, or null if none. 133 */ 134 public Long getOid() { 135 return oid; 136 } 137 138 /** 139 * Check if this harvestdefinition has an ID set yet (doesn't happen until the DBDAO persists it). 140 * 141 * @return true, if this harvestdefinition has an ID set 142 */ 143 boolean hasID() { 144 return oid != null; 145 } 146 147 /** 148 * Set the submission date. 149 * 150 * @param submissionDate the time when the harvestdefinition was created 151 */ 152 public void setSubmissionDate(Date submissionDate) { 153 this.submissionDate = submissionDate; 154 } 155 156 /** 157 * Returns the submission date. 158 * 159 * @return the submission date 160 */ 161 public Date getSubmissionDate() { 162 return submissionDate; 163 } 164 165 /** 166 * Returns the name of the harvest definition. 167 * 168 * @return the harvest definition name 169 */ 170 public String getName() { 171 return harvestDefName; 172 } 173 174 /** 175 * Returns the comments for this harvest definition. 176 * 177 * @return the comments for this harvest definition. 178 */ 179 public String getComments() { 180 return comments; 181 } 182 183 /** 184 * Set the comments for this harvest definition. 185 * 186 * @param comments A user-entered string. 187 */ 188 public void setComments(String comments) { 189 ArgumentNotValid.checkNotNull(comments, "comments"); 190 this.comments = comments; 191 } 192 193 /** 194 * Get the edition number. 195 * 196 * @return The edition number 197 */ 198 public long getEdition() { 199 return edition; 200 } 201 202 /** 203 * Set the edition number. 204 * 205 * @param theEdition the new edition of the harvestdefinition 206 */ 207 public void setEdition(long theEdition) { 208 edition = theEdition; 209 } 210 211 /** 212 * Get the number of times this harvest definition has been run so far. 213 * 214 * @return That number 215 */ 216 public int getNumEvents() { 217 return numEvents; 218 } 219 220 /** 221 * Set the number of times this harvest definition has been run so far. 222 * 223 * @param numEvents The number. 224 * @throws ArgumentNotValid if numEvents is negative 225 */ 226 public void setNumEvents(int numEvents) { 227 ArgumentNotValid.checkNotNegative(numEvents, "numEvents"); 228 this.numEvents = numEvents; 229 } 230 231 /** 232 * Set's activation status. Only active harvestdefinitions should be scheduled. 233 * 234 * @param active new activation status 235 */ 236 public void setActive(boolean active) { 237 isActive = active; 238 } 239 240 /** 241 * Returns the activation status. 242 * 243 * @return activation status 244 */ 245 public boolean getActive() { 246 return isActive; 247 } 248 249 /** 250 * Returns a iterator of domain configurations for this harvest definition. 251 * 252 * @return Iterator containing information about the domain configurations 253 */ 254 public abstract Iterator<DomainConfiguration> getDomainConfigurations(); 255 256 /** 257 * Return a human-readable string representation of this object. 258 * 259 * @return A human-readable string representation of this object 260 */ 261 public String toString() { 262 return "HD #" + oid + ": '" + getName() + "'"; 263 } 264 265 /** 266 * Tests whether some other object is "equal to" this HarvestDefinition. Cfr. documentation of 267 * java.lang.Object.equals() 268 * 269 * @param o 270 * @return True or false, indicating equality. 271 */ 272 public boolean equals(Object o) { 273 if (this == o) { 274 return true; 275 } 276 if (!(o instanceof HarvestDefinition)) { 277 return false; 278 } 279 280 final HarvestDefinition harvestDefinition = (HarvestDefinition) o; 281 282 if (!comments.equals(harvestDefinition.comments)) { 283 return false; 284 } 285 if (!harvestDefName.equals(harvestDefinition.harvestDefName)) { 286 return false; 287 } 288 if (oid != null ? !oid.equals(harvestDefinition.oid) : harvestDefinition.oid != null) { 289 return false; 290 } 291 292 if ((extendedFieldValues == null && harvestDefinition.getExtendedFieldValues() != null) 293 || (extendedFieldValues != null && harvestDefinition.getExtendedFieldValues() == null)) { 294 return false; 295 } 296 297 if (extendedFieldValues != null && harvestDefinition.getExtendedFieldValues() != null) { 298 if (extendedFieldValues.size() != harvestDefinition.getExtendedFieldValues().size()) { 299 return false; 300 } 301 302 for (int i = 0; i < extendedFieldValues.size(); i++) { 303 ExtendedFieldValue e1 = extendedFieldValues.get(i); 304 ExtendedFieldValue e2 = harvestDefinition.getExtendedFieldValues().get(i); 305 306 if ((e1 == null && e2 != null) || (e1 != null && e2 == null)) { 307 return false; 308 } 309 310 if (e1 != null && e2 != null) { 311 if (!e1.equals(e2)) { 312 return false; 313 } 314 } 315 } 316 } 317 318 return true; 319 } 320 321 /** 322 * Returns a hashcode of this object generated on fields oid, harvestDefName, and comments. 323 * 324 * @return the hashCode 325 */ 326 public int hashCode() { 327 int result; 328 result = (oid != null ? oid.hashCode() : 0); 329 result = 29 * result + harvestDefName.hashCode(); 330 result = 29 * result + comments.hashCode(); 331 return result; 332 } 333 334 /** 335 * Check if this harvest definition should be run, given the time now. 336 * 337 * @param now The current time 338 * @return true if harvest definition should be run 339 */ 340 public abstract boolean runNow(Date now); 341 342 /** 343 * Used to check if a harvestdefinition is a snapshot harvestdefinition. 344 * 345 * @return true if this harvestdefinition defines a snapshot harvest 346 */ 347 public abstract boolean isSnapShot(); 348 349 /** 350 * Returns how many objects to harvest per domain, or 0 for no limit. 351 * 352 * @return how many objects to harvest per domain 353 */ 354 public abstract long getMaxCountObjects(); 355 356 /** 357 * Returns how many bytes to harvest per domain, or -1 for no limit. 358 * 359 * @return how many bytes to harvest per domain 360 */ 361 public abstract long getMaxBytes(); 362 363 /** 364 * @return the intended audience for this harvest. 365 */ 366 public String getAudience() { 367 return this.audience; 368 } 369 370 /** 371 * Set the audience. 372 * 373 * @param audience the audience. 374 */ 375 public void setAudience(String audience) { 376 this.audience = audience; 377 } 378 379 public Long getChannelId() { 380 return channelId; 381 } 382 383 protected void setChannelId(Long channelId) { 384 this.channelId = channelId; 385 } 386 387 /** 388 * All derived classes allow ExtendedFields from Type ExtendedFieldTypes.HARVESTDEFINITION 389 * 390 * @return ExtendedFieldTypes.HARVESTDEFINITION 391 */ 392 protected int getExtendedFieldType() { 393 return ExtendedFieldTypes.HARVESTDEFINITION; 394 } 395 396}