com.redhat.rhn.frontend.action.errata.EditAction.java Source code

Java tutorial

Introduction

Here is the source code for com.redhat.rhn.frontend.action.errata.EditAction.java

Source

/**
 * Copyright (c) 2009--2014 Red Hat, Inc.
 *
 * This software is licensed to you under the GNU General Public License,
 * version 2 (GPLv2). There is NO WARRANTY for this software, express or
 * implied, including the implied warranties of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
 * along with this software; if not, see
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
 *
 * Red Hat trademarks are not licensed under GPLv2. No permission is
 * granted to use or replicate Red Hat trademarks that are incorporated
 * in this software or its documentation.
 */
/*
 * Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany.
 */
package com.redhat.rhn.frontend.action.errata;

import com.redhat.rhn.common.hibernate.HibernateFactory;
import com.redhat.rhn.common.hibernate.HibernateRuntimeException;
import com.redhat.rhn.common.localization.LocalizationService;
import com.redhat.rhn.common.util.StringUtil;
import com.redhat.rhn.domain.errata.Errata;
import com.redhat.rhn.domain.errata.ErrataFactory;
import com.redhat.rhn.domain.errata.Keyword;
import com.redhat.rhn.frontend.action.common.BadParameterException;
import com.redhat.rhn.frontend.struts.RequestContext;
import com.redhat.rhn.frontend.struts.RhnHelper;
import com.redhat.rhn.frontend.struts.RhnValidationHelper;
import com.redhat.rhn.frontend.struts.StrutsDelegate;
import com.redhat.rhn.manager.errata.ErrataManager;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.IteratorUtils;
import org.apache.commons.collections.Transformer;
import org.apache.commons.lang.StringUtils;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.action.DynaActionForm;
import org.apache.struts.actions.LookupDispatchAction;
import org.hibernate.HibernateException;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * EditAction
 * @version $Rev$
 */
public class EditAction extends LookupDispatchAction {

    private StrutsDelegate getStrutsDelegate() {
        return StrutsDelegate.getInstance();
    }

    /**
     * This method acts as the default if the dispatch parameter is not in the map
     * It also represents the SetupAction
     * @param mapping ActionMapping
     * @param formIn ActionForm
     * @param request HttpServletRequest
     * @param response HttpServletResponse
     * @return ActionForward, the forward for the jsp
     */
    public ActionForward unspecified(ActionMapping mapping, ActionForm formIn, HttpServletRequest request,
            HttpServletResponse response) {

        RequestContext requestContext = new RequestContext(request);
        Errata errata = requestContext.lookupErratum();

        DynaActionForm form = (DynaActionForm) formIn;

        String keywordDisplay = StringUtil.join(LocalizationService.getInstance().getMessage("list delimiter"),
                IteratorUtils.getIterator(CollectionUtils.collect(errata.getKeywords(), new Transformer() {
                    public Object transform(Object o) {
                        return o.toString();
                    }
                })));

        //pre-populate form with current values
        form.set("synopsis", errata.getSynopsis());
        form.set("advisoryName", errata.getAdvisoryName());
        form.set("advisoryRelease", errata.getAdvisoryRel().toString());
        form.set("advisoryType", errata.getAdvisoryType());
        form.set("advisoryTypeLabels", ErrataManager.advisoryTypeLabels());
        form.set("product", errata.getProduct());
        form.set("errataFrom", errata.getErrataFrom());
        form.set("topic", errata.getTopic());
        form.set("description", errata.getDescription());
        form.set("solution", errata.getSolution());
        form.set("refersTo", errata.getRefersTo());
        form.set("notes", errata.getNotes());
        form.set("keywords", keywordDisplay);

        return setupPage(request, mapping, errata);
    }

    /**
     * This method sets up the page for view
     * @param request HttpServletRequest
     * @param mapping ActionMapping
     * @param errata The errata being edited
     * @return ActionForward the default forward
     */
    public ActionForward setupPage(HttpServletRequest request, ActionMapping mapping, Errata errata) {

        //What type of errata is this? we need to set isPublished
        if (errata.isPublished()) {
            request.setAttribute("isPublished", "true");
        } else {
            request.setAttribute("isPublished", "false");
        }
        //set the list of bugs
        request.setAttribute("bugs", errata.getBugs());
        //set advisory for toolbar
        request.setAttribute("advisory", errata.getAdvisory());
        //set advisoryTypes list for select drop down
        request.setAttribute("advisoryTypes", ErrataManager.advisoryTypes());

        return mapping.findForward(RhnHelper.DEFAULT_FORWARD);
    }

    /**
     * This method handles changing an UnpublishedErrata to a PublishedErrata
     * @param mapping Action mapping
     * @param formIn Form
     * @param request The request
     * @param response The response
     * @return Returns an ActionForward for either published or failure
     */
    public ActionForward publish(ActionMapping mapping, ActionForm formIn, HttpServletRequest request,
            HttpServletResponse response) {
        //forward to the channels page so user can associate channels
        //with this errata.
        return getStrutsDelegate().forwardParam(mapping.findForward("published"), "eid",
                request.getParameter("eid"));
    }

    /**
     * Sends a notification
     * @param mapping Action mapping
     * @param formIn Form
     * @param request The request
     * @param response The response
     * @return Returns an ActionForward for either notified or failure
     */
    public ActionForward notify(ActionMapping mapping, ActionForm formIn, HttpServletRequest request,
            HttpServletResponse response) {
        //forward to notify page with eid
        return getStrutsDelegate().forwardParam(mapping.findForward("notified"), "eid",
                request.getParameter("eid"));
    }

    /**
     * Updates the errata according to info on the page.
     * @param mapping Action mapping
     * @param formIn Form
     * @param request The request
     * @param response The response
     * @return Returns an ActionForward for either updated or failure
     */
    public ActionForward update(ActionMapping mapping, ActionForm formIn, HttpServletRequest request,
            HttpServletResponse response) {
        //Get the errata
        Errata e = new RequestContext(request).lookupErratum();

        DynaActionForm form = (DynaActionForm) formIn;
        //Validate the form to make sure everything was filled out correctly
        List bugs = new ArrayList();
        ActionErrors errors = validateForm(form, request, e, bugs);

        //set l10n-ed advisoryTypeLabels list for select drop down
        form.set("advisoryTypeLabels", ErrataManager.advisoryTypeLabels());

        if (!errors.isEmpty()) { //Something is wrong. Forward to failure mapping.
            addErrors(request, errors);
            //return to the same page with the errors
            return setupPage(request, mapping, e);
        }

        //Fill out errata
        e.setSynopsis(form.getString("synopsis"));
        e.setAdvisoryName(form.getString("advisoryName"));
        e.setAdvisoryRel(new Long(form.getString("advisoryRelease")));
        e.setAdvisoryType(form.getString("advisoryType"));
        e.setProduct(form.getString("product"));
        e.setErrataFrom(form.getString("errataFrom"));
        //Advisory = advisoryName-advisoryRelease
        e.setAdvisory(form.getString("advisoryName") + "-" + form.getString("advisoryRelease"));
        e.setTopic(form.getString("topic"));
        e.setDescription(form.getString("description"));
        e.setSolution(form.getString("solution"));
        e.setRefersTo(form.getString("refersTo"));
        e.setNotes(form.getString("notes"));

        //Clear all the keywords and bugs we have, and then add the ones on page
        if (e.getKeywords() != null) {
            for (Keyword key : e.getKeywords()) {
                ErrataFactory.remove(key);
            }
            e.getKeywords().clear();
        }
        if (e.getBugs() != null) {
            e.getBugs().clear();
        }
        try {
            //We have to flush the session so that orphaned keywords and bugs
            //get deleted from the database.  This is BS, Hibernate should in all
            //reasonable application be able to manage sets correctly so that we
            //don't have to do this.  Consulting www.hibernate.org brings this 'fix'
            //of flushing the session and states, "This kind of problem occurs
            //rarely in practice."  #yell, curse, complain#
            HibernateFactory.getSession().flush();
        } catch (HibernateException ex) {
            throw new HibernateRuntimeException("Error flushing session", ex);
        }

        //add bugs from the form
        Iterator i = bugs.iterator();
        while (i.hasNext()) {
            String[] bug = (String[]) i.next();
            Long bugid = new Long(bug[0]);
            String summary = bug[1];
            String url = bug[2];
            //should this be a published or unpublished bug?
            if (e.isPublished()) {
                e.addBug(ErrataManager.createNewPublishedBug(bugid, summary, url));
            } else { //add a new UnpublishedBug
                e.addBug(ErrataManager.createNewUnpublishedBug(bugid, summary, url));
            }
        }

        //add keywords... split on commas and add separately to list
        String keywordsField = form.getString("keywords");
        if (keywordsField != null && keywordsField.length() > 0) {
            List keywordsOnPage = Arrays.asList(keywordsField.split(","));
            Iterator keywordItr = keywordsOnPage.iterator();
            while (keywordItr.hasNext()) {
                String keyword = (String) keywordItr.next();
                keyword = keyword.trim();
                if (keyword != null && keyword.length() > 0) {
                    e.addKeyword(keyword);
                }
            }
        }

        //Save errata back to db
        ErrataManager.storeErrata(e);

        ActionMessages messages = new ActionMessages();
        messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("errata.edit.updated"));
        getStrutsDelegate().saveMessages(request, messages);
        //return to the same page with the message
        return setupPage(request, mapping, e);
    }

    /**
     * Validate the form and add bugs to the list
     * @param form The form we are validating
     * @param request HttpServletRequest
     * @param errata The errata we are editing
     * @param bugs list of the bugs for the errata
     * @return ActionErrors, empty if no errors
     */
    public ActionErrors validateForm(DynaActionForm form, HttpServletRequest request, Errata errata, List bugs) {

        ActionErrors errors = RhnValidationHelper.validateDynaActionForm(this, form);

        /*
         * Errata error check
         * Make sure advisory name is unique and does not begin with 'RH'
         */
        String advisoryNameFromForm = form.getString("advisoryName");

        //Get all the parameters (so we can detect changes to existing bugs)
        Iterator params = request.getParameterMap().keySet().iterator();

        /*
         * Now we add each bug id to a list
         * The reason we have to do this is so that users can edit existing bugs
         * The implementation here is a little annoying, but since there can be
         * any number of bugs here, this seems to be the only real way.
         */
        List bugIds = new ArrayList();
        while (params.hasNext()) {
            String next = (String) params.next();
            if (next.startsWith("buglistId")) {
                bugIds.add(next);
            }
        }

        // Make sure advisoryName is unique
        if (!ErrataManager.advisoryNameIsUnique(errata.getId(), advisoryNameFromForm)) {
            errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("errata.edit.error.uniqueAdvisoryName"));
        }
        // Make sure advisoryName does not begin with RH
        if (advisoryNameFromForm.toUpperCase().startsWith("RH")) {
            errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("errata.edit.error.rhAdvisoryName"));
        }

        Iterator i = bugIds.iterator();
        Set ids = new HashSet(); //This is for verifying that each id is unique
        while (i.hasNext()) {
            String next = (String) i.next();
            String id;
            String summary;
            String url;
            //The suffix is the bug id or 'New'.  It is needed to match the id and summary
            //fields and to deal with the special differences between old bugs and new bugs
            String suffix = next.substring("buglistId".length());
            //the one possible new bug has the 'New' suffix
            boolean newbug = suffix.equals("New");

            try {
                id = request.getParameter(next).trim();
                summary = request.getParameter("buglistSummary" + suffix);
                url = request.getParameter("buglistUrl" + suffix);
            } catch (IllegalArgumentException iae) {
                //This means that the buglistId key is not in the parameter map
                //or that it doesn't have a corresponding summary key
                //The former should never happen because we got the key from the
                //map to begin with.  The latter should never happen unless somebody
                //is screwing with the request.  @see WEB-INF/pages/errata/edit.jsp
                throw new BadParameterException("Invalid bugListId", iae);
            }

            //Test that all existing bugs have the id field filled in
            if (!newbug && id.length() == 0) {
                errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("errata.edit.error.id"));
            }
            //Test that all existing bugs have the summary field filled in
            if (!newbug && summary.length() == 0) {
                errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("errata.edit.error.summary"));
            }
            //Test that new bugs have either both or neither id and summary
            if (newbug && id.length() > 0 && summary.length() == 0) {
                errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("errata.edit.error.summary"));
            }
            if (newbug && summary.length() > 0 && id.length() == 0) {
                errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("errata.edit.error.id"));
            }
            //Test that bug id is a number
            if (!StringUtils.isNumeric(id)) {
                errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("errata.edit.error.idNonNumeric"));
            }
            //Make sure that bug summary isn't too big
            if (summary.length() > 4000) {
                errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("errata.edit.error.summaryLength"));
            }
            //Make sure that bug id isn't too big
            if (id.length() > 18) {
                errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("errata.edit.error.idLength"));
            }
            //Test that bug id is unique
            if (ids.contains(id)) {
                errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("errata.edit.error.idUnique"));
            }

            //Add this bug to the collection so that we can update the errata easily
            ids.add(id);
            if (!newbug || id.length() > 0) {
                String[] bug = new String[3];
                bug[0] = id;
                bug[1] = summary;
                bug[2] = url;
                bugs.add(bug);
            }
        }

        return errors;
    }

    /**
     * {@inheritDoc}
     */
    protected Map getKeyMethodMap() {
        Map map = new HashMap();
        map.put("errata.edit.publisherrata", "publish");
        map.put("errata.edit.sendnotification", "notify");
        map.put("errata.edit.submit", "addBug");
        map.put("errata.edit.delete", "deleteBug");
        map.put("errata.edit.updateerrata", "update");
        return map;
    }

}