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.util.ArrayList;
027import java.util.List;
028
029import javax.servlet.ServletRequest;
030import javax.servlet.jsp.PageContext;
031
032import dk.netarkivet.common.exceptions.ArgumentNotValid;
033import dk.netarkivet.common.exceptions.ForwardedToErrorPage;
034import dk.netarkivet.common.utils.I18n;
035import dk.netarkivet.common.webinterface.HTMLUtils;
036import dk.netarkivet.harvester.datamodel.Domain;
037import dk.netarkivet.harvester.datamodel.DomainConfiguration;
038import dk.netarkivet.harvester.datamodel.DomainDAO;
039import dk.netarkivet.harvester.datamodel.Password;
040import dk.netarkivet.harvester.datamodel.SeedList;
041import dk.netarkivet.harvester.datamodel.TemplateDAO;
042
043/**
044 * Utility class containing methods for processing a GUI-request to update the details of a domain-configuration.
045 */
046
047public class DomainConfigurationDefinition {
048
049    /**
050     * Extracts all required parameters from the request, checks for any inconsistencies, and passes the requisite data
051     * to the updateDomain method for processing. The specified domain configuration is then updated and the result
052     * stored in the database.
053     * <p>
054     * update: This method does nothing if update is not set
055     * <p>
056     * name: must be the name of a known domain
057     * <p>
058     * default: the defaultconfig is set to this value. Must be non-null and a known configuration of this domain.
059     * <p>
060     * edition: The edition number the config was originally read as, if any.
061     * <p>
062     * (configName, order_xml, maxRate, maxObjects, maxBytes, urlListList[], passwordList): group specifying a
063     * configuration to update or add. If configName is non null then order_xml must be a known order-xml and
064     * urlListList must contain only known seedlists, (and at least one such). load, maxObjects, maxBytes, edition must
065     * be parsable as integers if present. passwordList is currently ignored.
066     *
067     * @param context The context of this request
068     * @param i18n I18n information
069     * @throws ForwardedToErrorPage if a user error has caused forwarding to the error page, in which case processing
070     * should abort.
071     */
072    public static void processRequest(PageContext context, I18n i18n) {
073        ArgumentNotValid.checkNotNull(context, "PageContext context");
074        ArgumentNotValid.checkNotNull(i18n, "I18n i18n");
075
076        ServletRequest request = context.getRequest();
077        String update = request.getParameter(Constants.UPDATE_PARAM);
078        if (update == null) {
079            return; // no need to continue
080        }
081
082        HTMLUtils.forwardOnEmptyParameter(context, Constants.DOMAIN_PARAM, Constants.CONFIG_NAME_PARAM,
083                Constants.ORDER_XML_NAME_PARAM, Constants.URLLIST_LIST_PARAM);
084        String name = request.getParameter(Constants.DOMAIN_PARAM).trim();
085        String configName = request.getParameter(Constants.CONFIG_NAME_PARAM).trim();
086        String order_xml = request.getParameter(Constants.ORDER_XML_NAME_PARAM).trim();
087        String[] urlListList = request.getParameterValues(Constants.URLLIST_LIST_PARAM);
088
089        if (!DomainDAO.getInstance().exists(name)) {
090            HTMLUtils.forwardWithErrorMessage(context, i18n, "errormsg;unknown.domain.0", name);
091            throw new ForwardedToErrorPage("Domain " + name + " does not exist");
092        }
093
094        Domain domain = DomainDAO.getInstance().read(name);
095
096        long edition = HTMLUtils.parseOptionalLong(context, Constants.EDITION_PARAM, -1L);
097
098        // check the edition number before updating
099        if (domain.getEdition() != edition) {
100            HTMLUtils.forwardWithRawErrorMessage(
101                    context,
102                    i18n,
103                    "errormsg;domain.definition.changed.0.retry.1",
104                    "<br/><a href=\"Definitions-edit-domain.jsp?" + Constants.DOMAIN_PARAM + "="
105                            + HTMLUtils.escapeHtmlValues(HTMLUtils.encode(name)) + "\">", "</a>");
106            throw new ForwardedToErrorPage("Domain '" + name + "' has changed");
107        }
108
109        if (!TemplateDAO.getInstance().exists(order_xml)) {
110            HTMLUtils.forwardWithErrorMessage(context, i18n, "errormsg;harvest.template.0.does.not.exist", order_xml);
111            throw new ForwardedToErrorPage("Unknown template " + order_xml);
112        }
113
114        for (String s : urlListList) {
115            s = s.trim();
116            if (s.length() == 0 || !domain.hasSeedList(s)) {
117                HTMLUtils.forwardWithErrorMessage(context, i18n, "errormsg;unknown.seed.list.0", s);
118                throw new ForwardedToErrorPage("Unknown seed list " + s);
119            }
120        }
121
122        int load = HTMLUtils.parseOptionalLong(context, Constants.MAX_RATE_PARAM,
123                (long) dk.netarkivet.harvester.datamodel.Constants.DEFAULT_MAX_REQUEST_RATE).intValue();
124        long maxObjects = HTMLUtils.parseOptionalLong(context, Constants.MAX_OBJECTS_PARAM,
125                dk.netarkivet.harvester.datamodel.Constants.DEFAULT_MAX_OBJECTS);
126        long maxBytes = HTMLUtils.parseOptionalLong(context, Constants.MAX_BYTES_PARAM,
127                dk.netarkivet.harvester.datamodel.Constants.DEFAULT_MAX_BYTES);
128
129        String comments = request.getParameter(Constants.COMMENTS_PARAM);
130
131        updateDomain(domain, configName, order_xml, load, maxObjects, maxBytes, urlListList, comments);
132    }
133
134    /**
135     * Given the parsed values, update or create a configuration in the domain.
136     *
137     * @param domain The domain
138     * @param configName Name of config - if this exists we update, otherwise we create a new.
139     * @param orderXml Order-template name
140     * @param load Request rate
141     * @param maxObjects Max objects
142     * @param maxBytes Max bytes
143     * @param urlListList List of url list names
144     * @param comments Comments, or null for none.
145     */
146    private static void updateDomain(Domain domain, String configName, String orderXml, int load, long maxObjects,
147            long maxBytes, String[] urlListList, String comments) {
148
149        // Update/create new configuration
150
151        List<SeedList> seedlistList = new ArrayList<SeedList>();
152        for (String seedlistName : urlListList) {
153            seedlistList.add(domain.getSeedList(seedlistName));
154        }
155        DomainConfiguration domainConf;
156        if (domain.hasConfiguration(configName)) {
157            domainConf = domain.getConfiguration(configName);
158        } else { // new DomainConfiguration
159            domainConf = new DomainConfiguration(configName, domain, seedlistList, new ArrayList<Password>());
160            domain.addConfiguration(domainConf);
161        }
162        domainConf.setOrderXmlName(orderXml);
163        domainConf.setMaxObjects(maxObjects);
164        domainConf.setMaxBytes(maxBytes);
165        domainConf.setMaxRequestRate(load);
166        domainConf.setSeedLists(domain, seedlistList);
167        if (comments != null) {
168            domainConf.setComments(comments);
169        }
170        DomainDAO.getInstance().update(domain);
171    }
172}