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 */
023
024package dk.netarkivet.harvester.webinterface;
025
026import java.io.File;
027import java.util.HashMap;
028import java.util.HashSet;
029import java.util.Locale;
030import java.util.Map;
031import java.util.Set;
032
033import javax.servlet.ServletRequest;
034import javax.servlet.jsp.PageContext;
035
036import org.slf4j.Logger;
037import org.slf4j.LoggerFactory;
038
039import dk.netarkivet.common.exceptions.ArgumentNotValid;
040import dk.netarkivet.common.exceptions.ForwardedToErrorPage;
041import dk.netarkivet.common.utils.I18n;
042import dk.netarkivet.common.webinterface.HTMLUtils;
043import dk.netarkivet.harvester.datamodel.HarvestDefinitionDAO;
044import dk.netarkivet.harvester.datamodel.PartialHarvest;
045import dk.netarkivet.harvester.datamodel.TemplateDAO;
046import dk.netarkivet.harvester.datamodel.eav.EAV;
047
048/**
049 * Contains utility methods for supporting event harvest GUI.
050 */
051public final class EventHarvestUtil {
052
053    static final Logger log = LoggerFactory.getLogger(EventHarvestUtil.class);
054
055    /**
056     * Private Constructor. Instances are not meaningful.
057     */
058    private EventHarvestUtil() {
059    }
060
061    /**
062     * Adds a bunch of configurations to a given PartialHarvest. For full definitions of the parameters, see
063     * Definitions-add-event-seeds.jsp. For each seed in the list, the following steps are taken: 1) The domain is
064     * parsed out of the seed. If no such domain is known, it is created with the usual defaults. 2) For each domain, a
065     * configuration with the name &lt;harvestDefinition&gt;_&lt;orderTemplate&gt;_&lt;maxBytes&gt;Bytes is created
066     * unless it already exists. The configuration uses orderTemplate, and the specified maxBytes. If maxBytes is
067     * unspecified, its default value is used. The configuration is added to the harvest specified by the
068     * harvestDefinition argument. 3) For each domain, a seedlist with the name
069     * &lt;harvestDefinition&gt;_&lt;orderTemplate&gt;_&lt;maxBytes&gt;Bytes is created if it does not already exist and
070     * the given url is added to it. This seedlist is the only seedlist associated with the configuration of the same
071     * name.
072     *
073     * @param context the current JSP context
074     * @param i18n the translation information to use in this context
075     * @param eventHarvestName The name of the partial harvest to which these seeds are to be added
076     * @throws ForwardedToErrorPage If maxBytes is not a number, or if any of the seeds is badly formatted such that no
077     * domain name can be parsed from it, or if orderTemplate is not given or unknown.
078     */
079    public static void addConfigurations(PageContext context, I18n i18n, String eventHarvestName) {
080        ArgumentNotValid.checkNotNull(context, "PageContext context");
081        ArgumentNotValid.checkNotNull(i18n, "I18n i18n");
082        ArgumentNotValid.checkNotNull(eventHarvestName, "String eventHarvestName");
083
084        HTMLUtils.forwardOnMissingParameter(context, Constants.SEEDS_PARAM);
085        ServletRequest request = context.getRequest();
086
087        // If no seeds are specified, just return
088        String seeds = request.getParameter(Constants.SEEDS_PARAM);
089        if (seeds == null || seeds.trim().length() == 0) {
090            return;
091        }
092        // split the seeds up into individual seeds
093        // Note: Matches any sort of newline (unix/mac/dos), but won't get empty
094        // lines, which is fine for this purpose
095
096        Set<String> seedSet = new HashSet<String>();
097        for (String seed : seeds.split("[\n\r]+")) {
098            seedSet.add(seed);
099        }
100
101        HTMLUtils.forwardOnEmptyParameter(context, Constants.ORDER_TEMPLATE_PARAM);
102        String orderTemplate = request.getParameter(Constants.ORDER_TEMPLATE_PARAM);
103        // Check that order template exists
104        if (!TemplateDAO.getInstance().exists(orderTemplate)) {
105            HTMLUtils.forwardWithErrorMessage(context, i18n, "errormsg;harvest.template.0.does.not.exist",
106                    orderTemplate);
107            throw new ForwardedToErrorPage("The orderTemplate with name '" + orderTemplate + "' does not exist!");
108        }
109
110        // Check that numerical parameters are meaningful and replace null or
111        // empty with default values
112        long maxBytes = HTMLUtils.parseOptionalLong(context, Constants.MAX_BYTES_PARAM,
113                dk.netarkivet.harvester.datamodel.Constants.DEFAULT_MAX_BYTES);
114        long maxObjectsL = HTMLUtils.parseOptionalLong(context, Constants.MAX_OBJECTS_PARAM,
115                dk.netarkivet.harvester.datamodel.Constants.DEFAULT_MAX_OBJECTS);
116        int maxObjects = (int) maxObjectsL;
117        
118        Map<String,String> attributeValues = new HashMap<String,String>();
119        // Fetch all attributes from context to be used later
120        for (String attrParam: EAV.getAttributeNames(EAV.DOMAIN_TREE_ID)){
121            String paramValue = context.getRequest().getParameter(attrParam);
122            log.debug("Read attribute {}. The value in form: {}", attrParam, paramValue);
123            attributeValues.put(attrParam, paramValue);
124        }
125        
126        // All parameters are valid, so call method
127        try {
128            PartialHarvest eventHarvest = (PartialHarvest) HarvestDefinitionDAO.getInstance().getHarvestDefinition(
129                    eventHarvestName);
130            eventHarvest.addSeeds(seedSet, orderTemplate, maxBytes, maxObjects, attributeValues);
131        } catch (Exception e) {
132            log.error("Unexpected exception thrown", e);
133            HTMLUtils.forwardWithErrorMessage(context, i18n, "errormsg;error.adding.seeds.to.0", eventHarvestName, e);
134            throw new ForwardedToErrorPage("Error while adding seeds", e);
135        }
136    }
137
138    /**
139     * Add configurations to an existing selective harvest.
140     *
141     * @param context The current JSP context
142     * @param i18n The translation information to use in this context
143     * @param eventHarvestName The name of the partial harvest to which these seeds are to be added
144     * @param seeds The seeds as a file (each seed on a separate line)
145     * @param maxbytesString The given maxbytes as a string
146     * @param maxobjectsString The given maxobjects as a string
147     * @param maxrateString The given maxrate as a string (currently not used)
148     * @param ordertemplate The name of the ordertemplate to use
149     * @param attributes A list of attributes and form values
150     */
151    public static void addConfigurationsFromSeedsFile(PageContext context, I18n i18n, String eventHarvestName,
152            File seeds, String maxbytesString, String maxobjectsString, String maxrateString, String ordertemplate, Map<String,String> attributes) {
153        ArgumentNotValid.checkNotNull(context, "PageContext context");
154        ArgumentNotValid.checkNotNull(i18n, "I18n i18n");
155        ArgumentNotValid.checkNotNullOrEmpty(eventHarvestName, "String eventHarvestName");
156        ArgumentNotValid.checkNotNull(seeds, "String seeds");
157        ArgumentNotValid.checkNotNull(ordertemplate, "String ordertemplate");
158
159        long maxBytes = 0L;
160        int maxObjects = 0;
161
162        try {
163            if (maxbytesString == null) {
164                maxBytes = dk.netarkivet.harvester.datamodel.Constants.DEFAULT_MAX_BYTES;
165            } else {
166                Locale loc = HTMLUtils.getLocaleObject(context);
167                maxBytes = HTMLUtils.parseLong(loc, maxbytesString, Constants.MAX_BYTES_PARAM,
168                        dk.netarkivet.harvester.datamodel.Constants.DEFAULT_MAX_BYTES);
169            }
170
171            if (maxobjectsString == null) {
172                maxObjects = (int) dk.netarkivet.harvester.datamodel.Constants.DEFAULT_MAX_OBJECTS;
173            } else {
174                Locale loc = HTMLUtils.getLocaleObject(context);
175                long maxObjectsL = HTMLUtils.parseLong(loc, maxobjectsString, Constants.MAX_OBJECTS_PARAM,
176                        dk.netarkivet.harvester.datamodel.Constants.DEFAULT_MAX_OBJECTS);
177                maxObjects = (int) maxObjectsL;
178            }
179
180        } catch (Exception e) {
181            HTMLUtils.forwardWithErrorMessage(context, i18n, "Exception.thrown.when.adding.seeds", e);
182            return;
183        }
184        // Check that order template exists
185        if (!TemplateDAO.getInstance().exists(ordertemplate)) {
186            HTMLUtils.forwardWithErrorMessage(context, i18n, "errormsg;harvest.template.0.does.not.exist",
187                    ordertemplate);
188            throw new ForwardedToErrorPage("The orderTemplate with name '" + ordertemplate + "' does not exist!");
189        }
190
191        // All parameters are valid, so call method
192        try {
193            PartialHarvest eventHarvest = (PartialHarvest) HarvestDefinitionDAO.getInstance().getHarvestDefinition(
194                    eventHarvestName);
195            
196            eventHarvest.addSeedsFromFile(seeds, ordertemplate, maxBytes, maxObjects, attributes);
197        } catch (Exception e) {
198            log.error("Unexpected exception thrown", e);
199            HTMLUtils
200                    .forwardWithErrorMessage(context, i18n, "errormsg;error.adding.seeds.to.0", e, eventHarvestName, e);
201            throw new ForwardedToErrorPage("Error while adding seeds", e);
202        }
203    }
204}