001/*
002 * (C) Copyright 2013 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Nuxeo - initial API and implementation
016 *
017 */
018
019package org.nuxeo.ecm.platform.ui.web.seam;
020
021import static org.jboss.seam.annotations.Install.FRAMEWORK;
022
023import javax.faces.context.FacesContext;
024import javax.servlet.http.HttpServletRequest;
025import javax.servlet.http.HttpServletResponse;
026
027import org.jboss.seam.ScopeType;
028import org.jboss.seam.annotations.Install;
029import org.jboss.seam.annotations.Name;
030import org.jboss.seam.annotations.Scope;
031import org.jboss.seam.annotations.intercept.BypassInterceptors;
032import org.jboss.seam.core.ConversationEntry;
033import org.jboss.seam.international.StatusMessage.Severity;
034import org.jboss.seam.jsf.concurrency.AbstractResolver;
035import org.jboss.seam.jsf.concurrency.ConcurrentRequestResolver;
036import org.nuxeo.ecm.platform.ui.web.rest.api.URLPolicyService;
037import org.nuxeo.ecm.platform.web.common.vh.VirtualHostHelper;
038
039/**
040 * Default implementation to handle concurrent requests against the same Seam Conversation. This component can be
041 * overridden using the standard Seam override system.
042 *
043 * @since 5.7.3
044 * @author <a href="mailto:tdelprat@nuxeo.com">Tiry</a>
045 */
046@Scope(ScopeType.STATELESS)
047@Name(ConcurrentRequestResolver.NAME)
048@Install(precedence = FRAMEWORK)
049@BypassInterceptors
050public class NuxeoConcurrentRequestResolver extends AbstractResolver implements ConcurrentRequestResolver {
051
052    @Override
053    public boolean handleConcurrentRequest(ConversationEntry ce, HttpServletRequest request,
054            HttpServletResponse response) {
055
056        if (request.getMethod().equalsIgnoreCase("get")) {
057            // flag request to skip apply method bindings
058            request.setAttribute(URLPolicyService.DISABLE_ACTION_BINDING_KEY, Boolean.TRUE);
059            // let's try to continue
060            addTransientMessage(Severity.WARN, "org.nuxeo.seam.concurrent.unsaferun",
061                    "This page may be not up to date, an other concurrent requests is still running");
062            return true;
063        } else if (request.getMethod().equalsIgnoreCase("post")) {
064
065            if (FacesContext.getCurrentInstance() == null) {
066                // we are not inside JSF
067                // may be an Automation call inside the Seam context
068                // continuing is not safe !
069                return false;
070            }
071
072            String url = request.getHeader("referer");
073            if (url == null || url.length() == 0) {
074                url = VirtualHostHelper.getServerURL(request) + request.getRequestURI();
075            }
076            addTransientMessage(Severity.WARN, "org.nuxeo.seam.concurrent.skip",
077                    "Your request was not processed because you already have a requests in processing.");
078            // XXX should Mark Request for No Tx Commit !
079            return handleRedirect(ce, response, url);
080        } else {
081            return handleNoResponse(response);
082        }
083    }
084
085}