org.esupportail.papercut.webportlet.EsupPapercutPortletController.java Source code

Java tutorial

Introduction

Here is the source code for org.esupportail.papercut.webportlet.EsupPapercutPortletController.java

Source

/**
 * Licensed to EsupPortail under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for
 * additional information regarding copyright ownership.
 *
 * EsupPortail licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.esupportail.papercut.webportlet;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.annotation.Resource;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.esupportail.papercut.domain.EsupPapercutSessionObject;
import org.esupportail.papercut.domain.PayBoxForm;
import org.esupportail.papercut.domain.PayboxPapercutTransactionLog;
import org.esupportail.papercut.domain.UserPapercutInfos;
import org.esupportail.papercut.services.EsupPaperCutService;
import org.esupportail.papercut.services.UserAgentInspector;
import org.hibernate.ejb.criteria.ValueHandlerFactory.DoubleValueHandler;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.portlet.ModelAndView;
import org.springframework.web.portlet.util.PortletUtils;

@Controller
@Scope("request")
@RequestMapping("VIEW")
public class EsupPapercutPortletController {

    static Logger log = Logger.getLogger(EsupPapercutPortletController.class);

    private final static String PREF_PAPERCUT_CONTEXT = "paperCutContext";

    private final static String PREF_PAPERCUT_USER_UID_ATTR = "papercutUserUidAttr";

    private final static String PREF_PAPERCUT_USER_MAIL_ATTR = "userEmail";

    private final static String PREF_VALIDATE_AFTER_REDIRECT = "validatePayboxJustWithRedirection";

    @Resource
    Map<String, EsupPaperCutService> esupPaperCutServices;

    @Resource
    protected UserAgentInspector userAgentInspector;

    @RequestMapping
    public ModelAndView renderView(RenderRequest request, RenderResponse response) {

        ModelMap model = new ModelMap();

        model.put("htmlHeader", request.getPreferences().getValue("htmlHeader", ""));
        model.put("htmlFooter", request.getPreferences().getValue("htmlFooter", ""));
        model.put("payboxMontantMin", request.getPreferences().getValue("payboxMontantMin", "0.5"));
        model.put("payboxMontantMax", request.getPreferences().getValue("payboxMontantMax", "5.0"));
        model.put("payboxMontantStep", request.getPreferences().getValue("payboxMontantStep", "0.5"));
        model.put("payboxMontantDefaut", request.getPreferences().getValue("payboxMontantDefaut", "2.0"));

        double papercutSheetCost = Double.parseDouble(request.getPreferences().getValue("papercutSheetCost", "-1"));
        double papercutColorSheetCost = Double
                .parseDouble(request.getPreferences().getValue("papercutColorSheetCost", "-1"));

        String paperCutContext = request.getPreferences().getValue(PREF_PAPERCUT_CONTEXT, null);
        EsupPaperCutService esupPaperCutService = esupPaperCutServices.get(paperCutContext);

        String uid = getUid(request);
        String userMail = getUserMail(request);

        // check if the user can make a transaction
        int transactionNbMax = Integer.parseInt(request.getPreferences().getValue("transactionNbMax", "-1"));
        BigDecimal transactionMontantMax = new BigDecimal(
                request.getPreferences().getValue("transactionMontantMax", "-1"));
        boolean canMakeTransaction = true;

        // constraints via transactionNbMax
        if (transactionNbMax > -1) {
            long nbTransactionsNotArchived = PayboxPapercutTransactionLog
                    .countFindPayboxPapercutTransactionLogsByUidEqualsAndPaperCutContextEqualsAndArchived(uid,
                            paperCutContext, false);
            if (transactionNbMax <= nbTransactionsNotArchived) {
                canMakeTransaction = false;
            }
        }

        BigDecimal payboxMontantMin = new BigDecimal(request.getPreferences().getValue("payboxMontantMin", "0.5"));
        BigDecimal payboxMontantMax = new BigDecimal(request.getPreferences().getValue("payboxMontantMax", "5.0"));
        BigDecimal payboxMontantStep = new BigDecimal(
                request.getPreferences().getValue("payboxMontantStep", "0.5"));
        BigDecimal payboxMontantDefaut = new BigDecimal(
                request.getPreferences().getValue("payboxMontantDefaut", "2.0"));
        // constraints on the slider via transactionMontantMax
        if (canMakeTransaction && transactionMontantMax.intValue() > -1) {
            List<PayboxPapercutTransactionLog> transactionsNotArchived = PayboxPapercutTransactionLog
                    .findPayboxPapercutTransactionLogsByUidEqualsAndPaperCutContextEqualsAndArchived(uid,
                            paperCutContext, false)
                    .getResultList();
            BigDecimal montantTotalTransactionsNotArchived = new BigDecimal("0");
            for (PayboxPapercutTransactionLog txLog : transactionsNotArchived) {
                montantTotalTransactionsNotArchived = montantTotalTransactionsNotArchived
                        .add(new BigDecimal(txLog.getMontant()));
            }
            transactionMontantMax = transactionMontantMax.multiply(new BigDecimal("100"))
                    .subtract(montantTotalTransactionsNotArchived);
            if (transactionMontantMax.doubleValue() < payboxMontantMax.doubleValue() * 100) {
                payboxMontantMax = transactionMontantMax.divide(payboxMontantStep).multiply(payboxMontantStep);
                payboxMontantMax = payboxMontantMax.divide(new BigDecimal("100"));
                if (payboxMontantDefaut.compareTo(payboxMontantMax) == 1) {
                    payboxMontantDefaut = payboxMontantMax;
                }
                if (payboxMontantMax.compareTo(payboxMontantMin) == -1) {
                    canMakeTransaction = false;
                }
                model.put("payboxMontantMax", payboxMontantMax.doubleValue());
                model.put("payboxMontantDefaut", payboxMontantDefaut.doubleValue());
            }
        }

        // generation de l'ensemble des payboxForm :  payboxMontantMin -> payboxMontantMax par pas de payboxMontantStep
        String portletContextPath = ((RenderResponse) response).createRenderURL().toString();
        Map<Integer, PayBoxForm> payboxForms = new HashMap<Integer, PayBoxForm>();
        for (BigDecimal montant = payboxMontantMin; montant.compareTo(payboxMontantMax) <= 0; montant = montant
                .add(payboxMontantStep)) {
            PayBoxForm payBoxForm = esupPaperCutService.getPayBoxForm(uid, userMail, montant.doubleValue(),
                    paperCutContext, portletContextPath);
            if (papercutSheetCost > 0) {
                int nbSheets = (int) (montant.doubleValue() / papercutSheetCost);
                payBoxForm.setNbSheets(nbSheets);
            }
            if (papercutColorSheetCost > 0) {
                int nbColorSheets = (int) (montant.doubleValue() / papercutColorSheetCost);
                payBoxForm.setNbColorSheets(nbColorSheets);
            }

            payboxForms.put(montant.multiply(new BigDecimal(100)).intValue(), payBoxForm);
        }
        Map<Integer, PayBoxForm> sortedMap = new TreeMap<Integer, PayBoxForm>(payboxForms);

        model.put("payboxForms", sortedMap);
        model.put("payboxMontantDefautCents", payboxMontantDefaut.multiply(new BigDecimal(100)).intValue());

        model.put("canMakeTransaction", canMakeTransaction);

        UserPapercutInfos userPapercutInfos = esupPaperCutService.getUserPapercutInfos(uid);
        model.put("userPapercutInfos", userPapercutInfos);

        boolean isAdmin = isAdmin(request);
        boolean isManager = isManager(request);
        model.put("isAdmin", isAdmin);
        model.put("isManager", isManager);
        model.put("active", "home");
        return new ModelAndView(getViewName(request, "index"), model);
    }

    @RequestMapping(params = "action=admin")
    public ModelAndView adminList(@RequestParam(value = "page", required = false) Integer page,
            @RequestParam(value = "size", required = false) Integer size,
            @RequestParam(value = "sortFieldName", required = false) String sortFieldName,
            @RequestParam(value = "sortOrder", required = false) String sortOrder, RenderRequest request,
            RenderResponse response) {

        boolean isAdmin = isAdmin(request);
        boolean isManager = isManager(request);

        ModelMap model = new ModelMap();
        model.put("isAdmin", isAdmin);
        model.put("adminView", true);
        model.put("isManager", isManager);

        if (isAdmin || isManager) {

            String paperCutContext = request.getPreferences().getValue(PREF_PAPERCUT_CONTEXT, null);

            if (sortFieldName == null) {
                sortFieldName = "transactionDate";
                sortOrder = "desc";
            }

            if (size == null) {
                size = 10;
            }

            if (page != null || size != null) {
                int sizeNo = size == null ? 10 : size.intValue();
                final int firstResult = page == null ? 0 : (page.intValue() - 1) * sizeNo;
                model.put("payboxpapercuttransactionlogs",
                        PayboxPapercutTransactionLog
                                .findPayboxPapercutTransactionLogsByPaperCutContextEquals(paperCutContext,
                                        sortFieldName, sortOrder)
                                .setFirstResult(firstResult).setMaxResults(sizeNo).getResultList());
                float nrOfPages = (float) PayboxPapercutTransactionLog
                        .countFindPayboxPapercutTransactionLogsByPaperCutContextEquals(paperCutContext) / sizeNo;
                model.put("maxPages",
                        (int) ((nrOfPages > (int) nrOfPages || nrOfPages == 0.0) ? nrOfPages + 1 : nrOfPages));
            } else {
                model.put("payboxpapercuttransactionlogs",
                        PayboxPapercutTransactionLog.findPayboxPapercutTransactionLogsByPaperCutContextEquals(
                                paperCutContext, sortFieldName, sortOrder).getResultList());
            }
            addDateTimeFormatPatterns(model);

            String sharedSessionId = response.getNamespace();
            EsupPapercutSessionObject objectShared = new EsupPapercutSessionObject();
            objectShared.setIsAdmin(true);
            objectShared.setPaperCutContext(paperCutContext);
            PortletUtils.setSessionAttribute(request, sharedSessionId, objectShared,
                    PortletSession.APPLICATION_SCOPE);
            model.put("sharedSessionId", sharedSessionId);
            model.put("active", "admin");
        }

        model.put("sortFieldName", sortFieldName);
        model.put("sortOrder", sortOrder);

        return new ModelAndView(getViewName(request, "history"), model);
    }

    @RequestMapping(params = "action=myhistory")
    public ModelAndView myhistoryList(@RequestParam(value = "page", required = false) Integer page,
            @RequestParam(value = "size", required = false) Integer size,
            @RequestParam(value = "sortFieldName", required = false) String sortFieldName,
            @RequestParam(value = "sortOrder", required = false) String sortOrder, RenderRequest request) {

        String uid = getUid(request);
        String paperCutContext = request.getPreferences().getValue(PREF_PAPERCUT_CONTEXT, null);

        if (sortFieldName == null) {
            sortFieldName = "transactionDate";
            sortOrder = "desc";
        }

        if (size == null) {
            size = 10;
        }

        ModelMap model = new ModelMap();
        if (page != null || size != null) {
            int sizeNo = size == null ? 10 : size.intValue();
            final int firstResult = page == null ? 0 : (page.intValue() - 1) * sizeNo;
            model.put("payboxpapercuttransactionlogs",
                    PayboxPapercutTransactionLog
                            .findPayboxPapercutTransactionLogsByUidEqualsAndPaperCutContextEquals(uid,
                                    paperCutContext, sortFieldName, sortOrder)
                            .setFirstResult(firstResult).setMaxResults(sizeNo).getResultList());
            float nrOfPages = (float) PayboxPapercutTransactionLog
                    .countFindPayboxPapercutTransactionLogsByUidEqualsAndPaperCutContextEquals(uid, paperCutContext)
                    / sizeNo;
            model.put("maxPages",
                    (int) ((nrOfPages > (int) nrOfPages || nrOfPages == 0.0) ? nrOfPages + 1 : nrOfPages));
        } else {
            model.put("payboxpapercuttransactionlogs",
                    PayboxPapercutTransactionLog
                            .findPayboxPapercutTransactionLogsByUidEqualsAndPaperCutContextEquals(uid,
                                    paperCutContext, sortFieldName, sortOrder)
                            .getResultList());
        }
        addDateTimeFormatPatterns(model);

        model.put("isAdmin", isAdmin(request));
        model.put("isManager", isManager(request));
        model.put("active", "history");

        model.put("sortFieldName", sortFieldName);
        model.put("sortOrder", sortOrder);

        return new ModelAndView(getViewName(request, "history"), model);
    }

    @RequestMapping(params = "action=show")
    public ModelAndView viewTransactionLog(@RequestParam(value = "id", required = true) Long id,
            RenderRequest request) {
        ModelMap model = new ModelMap();
        addDateTimeFormatPatterns(model);
        model.put("payboxpapercuttransactionlog",
                PayboxPapercutTransactionLog.findPayboxPapercutTransactionLog(id));
        model.put("itemId", id);
        model.put("isAdmin", isAdmin(request));
        model.put("isManager", isManager(request));
        model.put("active", "admin");
        return new ModelAndView("show-transactionlog", model);
    }

    void addDateTimeFormatPatterns(ModelMap model) {
        model.put("payboxPapercutTransactionLog_transactiondate_date_format", "dd/MM/yyyy-HH:mm:ss");
    }

    private String getUid(PortletRequest request) {
        String uidAttr = request.getPreferences().getValue(PREF_PAPERCUT_USER_UID_ATTR, null);
        Map<String, String> userinfo = (Map<String, String>) request.getAttribute(PortletRequest.USER_INFO);
        String uid = userinfo.get(uidAttr);
        return uid;
    }

    private String getUserMail(PortletRequest request) {
        String mailAttr = request.getPreferences().getValue(PREF_PAPERCUT_USER_MAIL_ATTR, null);
        Map<String, String> userinfo = (Map<String, String>) request.getAttribute(PortletRequest.USER_INFO);
        String mail = userinfo.get(mailAttr);
        return mail;
    }

    private boolean isAdmin(PortletRequest request) {
        return request.isUserInRole("esupPapercutAdmin");
    }

    private boolean isManager(PortletRequest request) {
        return request.isUserInRole("esupPapercutManager");
    }

    /**
     * When user is redirected on the portlet after the paybox process, 
     * and if validatePayboxJustWithRedirection in pref portlet is true,
     * we validate the transaction regarding informations on queryString 
     * (there is a paybox signature that secures this, 
     * so we can do that even if we can consider it "less" secure than the direct call of paybox) 
     */
    @RequestMapping(params = "signature")
    public ModelAndView renderViewAfterPaybox(@RequestParam(required = false) String montant,
            @RequestParam String reference, @RequestParam(required = false) String auto,
            @RequestParam String erreur, @RequestParam String idtrans, @RequestParam String signature,
            RenderRequest request, RenderResponse response) {

        if ("true".equals(request.getPreferences().getValue(PREF_VALIDATE_AFTER_REDIRECT, "false"))) {
            String uid = getUid(request);
            String paperCutContext = request.getPreferences().getValue(PREF_PAPERCUT_CONTEXT, null);
            String queryString = getQueryString(montant, reference, auto, erreur, idtrans, signature);

            log.debug(queryString);

            esupPaperCutServices.get(paperCutContext).payboxCallback(montant, reference, auto, erreur, idtrans,
                    signature, queryString, null, uid);
        }

        return renderView(request, response);
    }

    private static String getQueryString(String montant, String reference, String auto, String erreur,
            String idtrans, String signature) {
        StringBuilder sb = new StringBuilder();

        if (montant != null) {
            sb.append(String.format("%s=%s", "montant", montant));
            sb.append("&");
        }

        sb.append(String.format("%s=%s", "reference", reference));
        sb.append("&");

        if (auto != null) {
            sb.append(String.format("%s=%s", "auto", auto));
            sb.append("&");
        }

        sb.append(String.format("%s=%s", "erreur", erreur));
        sb.append("&");

        sb.append(String.format("%s=%s", "idtrans", idtrans));
        sb.append("&");

        sb.append(String.format("%s=%s", "signature", signature));

        return sb.toString();
    }

    @Transactional
    @RequestMapping(params = "action=archiveAll") // action phase
    public void archiveAll(ActionRequest request, ActionResponse response) {

        if (isAdmin(request)) {
            List<PayboxPapercutTransactionLog> txLogs = PayboxPapercutTransactionLog
                    .findPayboxPapercutTransactionLogsByArchived(false).getResultList();
            for (PayboxPapercutTransactionLog txLog : txLogs) {
                txLog.setArchived(true);
            }
        }

        response.setRenderParameter("action", "admin");
    }

    @Transactional
    @RequestMapping(params = "action=archive") // action phase
    public void archive(@RequestParam(value = "txLogId", required = true) Long txLogId, ActionRequest request,
            ActionResponse response) {

        if (isAdmin(request)) {
            PayboxPapercutTransactionLog txLog = PayboxPapercutTransactionLog
                    .findPayboxPapercutTransactionLog(txLogId);
            txLog.setArchived(true);
        }

        Map<String, String[]> parameters = new HashMap<String, String[]>();
        parameters.put("action", new String[] { "show" });
        parameters.put("id", new String[] { String.valueOf(txLogId) });

        response.setRenderParameters(parameters);
    }

    public String getViewName(PortletRequest request, String viewName) {
        if (userAgentInspector.isMobile(request)) {
            viewName = "m_".concat(viewName);
        }
        return viewName;
    }

}