/**
* Copyright (c) 2009--2012 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;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DownloadAction;
import com.redhat.rhn.common.db.datasource.CachedStatement;
import com.redhat.rhn.common.db.datasource.Elaborator;
import com.redhat.rhn.common.util.CSVWriter;
import com.redhat.rhn.common.util.download.ByteArrayStreamInfo;
import com.redhat.rhn.domain.user.User;
import com.redhat.rhn.frontend.dto.SystemSearchPartialResult;
import com.redhat.rhn.frontend.dto.SystemSearchResult;
import com.redhat.rhn.frontend.struts.RequestContext;
import com.redhat.rhn.frontend.taglibs.list.TagHelper;
/**
* Expects that the following parameters are available from the request object:
* EXPORT_COLUMNS set to the value of the session attribute containing the
* exportColumns
* PAGE_LIST_DATA set to the value of the session attribute containg the List
* of items to export
* UNIQUE_NAME set to the value of the uniqueName associated with this list
* from the CSVTag
*
* @author jmatthews
* @version $Rev: $
*/
public class CSVDownloadAction extends DownloadAction {
public static final String EXPORT_COLUMNS = "__CSV__exportColumnsParam";
public static final String PAGE_LIST_DATA = "___CSV_pageListData";
public static final String QUERY_DATA = "__CSV_queryMode";
public static final String UNIQUE_NAME = "__CSV_uniqueName";
public static final String HEADER_NAME = "__CSV_headerName";
/**
* {@inheritDoc}
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
try {
super.execute(mapping, form, request, response);
}
catch (Exception e) {
/**
* Overridden to redirect for case of errors while processing CSV Export,
* example: Session timeout.
*/
e.printStackTrace();
return mapping.findForward("error");
}
return null;
}
/**
* Returns String containing a comma separated list of names to represent the
* header values of the List or throws Exception if request attribute
* EXPORT_COLUMNN is missing or session attribute is null.
*
* @param request HTTP request
* @param session HTTP session
* @return exported columns
* @throws Exception thrown if request attribute EXPORT_COLUMN is missing.
*/
protected String getExportColumns(HttpServletRequest request,
HttpSession session)
throws Exception {
String paramExportColumns = request.getParameter(EXPORT_COLUMNS);
if (null == paramExportColumns) {
throw new Exception("Missing request parameter, " + EXPORT_COLUMNS);
}
String exportColumns = (String) session.getAttribute(paramExportColumns);
if (null == exportColumns) {
throw new Exception("Missing value for session attribute, " +
paramExportColumns);
}
return exportColumns;
}
/**
* Returns List of data referred to by session attribute with the name
* PAGE_LIST_DATA. Throws Exception if request attribute PAGE_LIST_DATA is
* missing or session attribute is null.
*
* @param request HTTP Request
* @param session HTTP session
* @return page data
* @throws Exception thrown if column missing.
*/
protected List getPageData(HttpServletRequest request, HttpSession session)
throws Exception {
String paramQuery = request.getParameter(QUERY_DATA);
if (paramQuery != null) {
CachedStatement query = (CachedStatement) session.getAttribute(paramQuery);
if (query == null) {
throw new Exception("Missing request parameter, " + QUERY_DATA);
}
/*if (session.getAttribute("ssr_" + paramQuery) != null) {
return (DataResult) session.getAttribute("ssr_" + paramQuery);
}*/
return query.restartQuery();
}
String paramPageData = request.getParameter(PAGE_LIST_DATA);
if (null == paramPageData) {
throw new Exception("Missing request parameter, " + EXPORT_COLUMNS);
}
List pageData = (List) session.getAttribute(paramPageData);
if (null == pageData) {
throw new Exception("Missing value for session attribute, " +
paramPageData);
}
return pageData;
}
/**
* Returns the value of the UNIQUE_NAME attribute or exception if value
* is null.
* @param request HTTP request containing UNIQUE_NAME parameter
* @return unique name
* @throws Exception thrown if UNIQUE_NAME value is null.
*/
protected String getUniqueName(HttpServletRequest request) throws Exception {
String uniqueName = request.getParameter(UNIQUE_NAME);
if (uniqueName == null) {
throw new Exception("Missing request parameter, " + UNIQUE_NAME);
}
return uniqueName;
}
/**
* Returns the header name
* @param request
* @return the header name
* @throws Exception
*/
protected String getHeaderText(HttpServletRequest request, HttpSession session)
throws Exception {
String paramHeader = request.getParameter(HEADER_NAME);
if (null == paramHeader) {
// this is an optional parameter, return null if it's not there.
return null;
}
String header = (String) session.getAttribute(paramHeader);
if (null == header) {
throw new Exception("Missing value for session attribute, " +
paramHeader);
}
return header;
}
/**
* {@inheritDoc}
*/
protected StreamInfo getStreamInfo(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
HttpSession session = request.getSession(false);
if (null == session) {
throw new Exception("Missing session");
}
String exportColumns = getExportColumns(request, session);
List pageData = getPageData(request, session);
// Read the CSV separator from user preferences
User user = new RequestContext(request).getCurrentUser();
CSVWriter expW = new CSVWriter(new StringWriter(), user.getCsvSeparator());
String[] columns = exportColumns.split("\\s*,\\s*");
expW.setColumns(Arrays.asList(columns));
String header = getHeaderText(request, session);
if (header != null) {
expW.setHeaderText(header);
}
Elaborator elab = TagHelper.lookupElaboratorFor(
getUniqueName(request), request);
if (elab != null) {
elab.elaborate(pageData);
if (!pageData.isEmpty() && pageData.get(0) instanceof SystemSearchResult) {
pageData = mergeWithPartialResult(pageData,
(Map)session.getAttribute("ssr_" + request
.getParameter(QUERY_DATA)));
}
}
String contentType = expW.getMimeType() + ";charset=" +
response.getCharacterEncoding();
response.setHeader("Content-Disposition",
"attachment; filename=download." + expW.getFileExtension());
expW.write(pageData);
return new ByteArrayStreamInfo(contentType, expW.getContents().getBytes());
}
private List mergeWithPartialResult(List full, Map partial) {
for (Iterator iter = full.iterator(); iter.hasNext();) {
SystemSearchResult r = (SystemSearchResult) iter.next();
SystemSearchPartialResult p =
(SystemSearchPartialResult) partial.get(r.getId());
r.setMatchingField(p.getMatchingField());
r.setMatchingFieldValue(p.getMatchingFieldValue());
}
return full;
}
}