001/*
002 * (C) Copyright 2006-2007 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.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.webapp.context;
020
021import static org.jboss.seam.annotations.Install.FRAMEWORK;
022
023import java.io.Serializable;
024
025import org.apache.commons.logging.Log;
026import org.apache.commons.logging.LogFactory;
027import org.jboss.seam.Component;
028import org.jboss.seam.ScopeType;
029import org.jboss.seam.annotations.In;
030import org.jboss.seam.annotations.Install;
031import org.jboss.seam.annotations.Name;
032import org.jboss.seam.annotations.Observer;
033import org.jboss.seam.annotations.Scope;
034import org.nuxeo.ecm.core.api.CoreSession;
035import org.nuxeo.ecm.core.api.DocumentModel;
036import org.nuxeo.ecm.core.api.DocumentNotFoundException;
037import org.nuxeo.ecm.platform.ui.web.api.NavigationContext;
038import org.nuxeo.ecm.platform.ui.web.api.WebActions;
039
040/**
041 * Seam Bean that is responsible from refetching the CurrentDocument in case it is Dirty (Transient modifications not
042 * pushed inside the DB).
043 * <p>
044 * This can happen if a low level Listener decides to RollBack the transaction.
045 * <p>
046 * In this case the DocumentModel won't be saved to the DB, but since the ApplyModelValue JSF phase has run, the
047 * DocumentModel will have been modified resulting in a Dirty state inside the Context.
048 * <p>
049 * We want to keep this dirty state as long as we stay on the same Tab, but as soon as we navigate somewhere else, we
050 * must reset the state.
051 *
052 * @author <a href="mailto:tdelprat@nuxeo.com">Tiry</a>
053 * @since 5.6
054 */
055@Name("transientStateCleaner")
056@Scope(ScopeType.EVENT)
057@Install(precedence = FRAMEWORK)
058public class TransientStateCleaner implements Serializable {
059
060    private static final long serialVersionUID = 1L;
061
062    @In(create = true, required = false)
063    protected transient NavigationContext navigationContext;
064
065    protected static final Log log = LogFactory.getLog(TransientStateCleaner.class);
066
067    @Observer(value = { WebActions.CURRENT_TAB_CHANGED_EVENT }, create = true)
068    public void flushTransientStateIfNeeded() {
069        DocumentModel currentDocument = navigationContext.getCurrentDocument();
070        if (currentDocument != null && currentDocument.isDirty()) {
071            CoreSession documentManager = (CoreSession) Component.getInstance("documentManager", false);
072            if (documentManager != null) {
073                try {
074                    // refetch
075                    currentDocument = documentManager.getDocument(currentDocument.getRef());
076                    // force refresh
077                    navigationContext.setCurrentDocument(null);
078                    navigationContext.setCurrentDocument(currentDocument);
079                } catch (DocumentNotFoundException e) {
080                    log.error("Error during reset of transient state", e);
081                }
082            }
083        }
084    }
085}