/**
* Copyright (c) 2009--2015 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.
*/
package com.redhat.rhn.frontend.action.common;
import com.redhat.rhn.domain.Identifiable;
import com.redhat.rhn.domain.rhnset.RhnSet;
import com.redhat.rhn.domain.rhnset.RhnSetElement;
import com.redhat.rhn.domain.user.User;
import com.redhat.rhn.frontend.struts.RequestContext;
import com.redhat.rhn.frontend.struts.RhnHelper;
import com.redhat.rhn.manager.rhnset.RhnSetDecl;
import com.redhat.rhn.manager.rhnset.RhnSetManager;
import org.apache.log4j.Logger;
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 java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* BaseSetOperateOnDiffAction - extension of RhnSetAction
* that provides a framework for performing specified business
* operations on the currently selected items in the list.
*
* @version $Rev$
*/
public abstract class BaseSetOperateOnDiffAction extends RhnSetAction {
private static Logger log = Logger.getLogger(BaseSetOperateOnDiffAction.class);
/**
* Execute some operation on the items that have removed or added
* from the set. Forwards to the "default"
*
* NOTE: Inheriting classes must either define two
* StringResources, or override the generateUserMessage method.
* The StringResources must be of the form:
*
* getSetName() + ".removed"
* getSetName() + ".added"
*
* To provide messages to the UI that would say:
* "2 Activation Key(s) added."
* "1 Activation Key(s) removed."
*
* If a different message format is required, just override generateUserMessage
*
* @param mapping ActionMapping
* @param formIn ActionForm
* @param request ServletRequest
* @param response ServletResponse
* @return The ActionForward to go to next.
*/
public ActionForward operateOnDiff(ActionMapping mapping,
ActionForm formIn,
HttpServletRequest request,
HttpServletResponse response) {
log.debug("operateOnDiff called");
User user = new RequestContext(request).getCurrentUser();
// RhnSet originalSet = getSetDecl().get(user);
RhnSet currentset = updateSet(request);
RhnSetManager.store(currentset);
Map<String, Object> params = makeParamMap(formIn, request);
Map<RhnSetElement, String> diffmap = new HashMap<RhnSetElement, String>();
Iterator<Identifiable> originalItems = getCurrentItemsIterator(new RequestContext(
request));
if (log.isDebugEnabled()) {
log.debug("current set : " + currentset.getElements());
}
while (originalItems.hasNext()) {
Identifiable ido = originalItems.next();
if (log.isDebugEnabled()) {
log.debug("original item : " + ido.getId());
}
diffmap.put(new RhnSetElement(user.getId(),
getSetDecl().getLabel(), ido.getId(), null),
"original");
}
Iterator<RhnSetElement> currentIter = currentset.getElements().iterator();
ArrayList<RhnSetElement> added = new ArrayList<RhnSetElement>();
ArrayList<RhnSetElement> removed = new ArrayList<RhnSetElement>();
while (currentIter.hasNext()) {
RhnSetElement elem = currentIter.next();
if (!diffmap.containsKey(elem)) {
added.add(elem);
}
else {
diffmap.put(elem, "both");
}
}
Iterator<RhnSetElement> mapIter = diffmap.keySet().iterator();
while (mapIter.hasNext()) {
RhnSetElement elem = mapIter.next();
if (diffmap.get(elem) == "original") {
removed.add(elem);
}
}
if (log.isDebugEnabled()) {
log.debug("removed : " + removed);
log.debug("added : " + added);
}
operateOnRemovedElements(removed, request);
operateOnAddedElements(added, request);
generateUserMessage(added, removed, request);
return getStrutsDelegate().forwardParams(mapping.findForward(
RhnHelper.DEFAULT_FORWARD), params);
}
protected void generateUserMessage(List<RhnSetElement> added,
List<RhnSetElement> removed, HttpServletRequest request) {
ActionMessages msg = new ActionMessages();
if (!removed.isEmpty()) {
String msgKey = getSetDecl().getLabel() + ".removed";
Object[] args = new Object[1];
args[0] = new Integer(removed.size()).toString();
msg.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(msgKey, args));
}
if (!added.isEmpty()) {
String msgKey = getSetDecl().getLabel() + ".added";
Object[] args = new Object[1];
args[0] = new Integer(added.size()).toString();
msg.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(msgKey, args));
}
if (msg.size(ActionMessages.GLOBAL_MESSAGE) > 0) {
getStrutsDelegate().saveMessages(request, msg);
}
}
/**
* Operate on the removed elements, whatever that entails for a
* given subclass. This method is called immediately before
* operateOnAddedElements.
* @param elements The elements which were removed
* @param request The request
*/
protected abstract void operateOnRemovedElements(List<RhnSetElement> elements,
HttpServletRequest request);
/**
* Operate on the added elements, whatever that entails for a
* given subclass. This method is called immediately after
* operateOnRemovedElements.
* @param elements The elements which were added
* @param request The request
*/
protected abstract void operateOnAddedElements(List<RhnSetElement> elements,
HttpServletRequest request);
/**
* Get the RhnSet 'Decl' for the action
* @return The set decleration
*/
public abstract RhnSetDecl getSetDecl();
/**
* Get the Iterator for a Collection of Objects
* that implement the Identifiable interface. This is required
* so this base class can calculate the original set of items
* that are associated with the main object we are operating on.
*
* This iterator is then 'diffed' against the items in the RhnSet
* to determine what should be added vs removed.
*
* @param ctx to fetch info from
* @return Iterator containing Identifiable objects.
*/
protected abstract <T extends Identifiable> Iterator<T> getCurrentItemsIterator(
RequestContext ctx);
protected List<Long> getPrimaryElementIds(List<RhnSetElement> elements) {
List<Long> ret = new ArrayList<Long>();
for (RhnSetElement e : elements) {
ret.add(e.getElement());
}
return ret;
}
}