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 * $Id: JOOoConvertPluginImpl.java 18651 2007-05-13 20:28:53Z sfermigier $
018 */
019
020package org.nuxeo.ecm.webapp.helpers;
021
022import static org.jboss.seam.ScopeType.SESSION;
023
024import java.io.Serializable;
025import java.security.Principal;
026
027import javax.faces.context.FacesContext;
028import javax.servlet.http.HttpServletRequest;
029
030import org.apache.commons.logging.Log;
031import org.apache.commons.logging.LogFactory;
032import org.jboss.seam.annotations.Begin;
033import org.jboss.seam.annotations.In;
034import org.jboss.seam.annotations.Install;
035import org.jboss.seam.annotations.Name;
036import org.jboss.seam.annotations.Scope;
037import org.jboss.seam.contexts.Context;
038import org.jboss.seam.core.Events;
039import org.jboss.seam.international.LocaleSelector;
040import org.nuxeo.ecm.core.api.CoreSession;
041import org.nuxeo.ecm.core.api.DocumentModel;
042import org.nuxeo.ecm.core.api.DocumentModelList;
043import org.nuxeo.ecm.core.api.LifeCycleConstants;
044import org.nuxeo.ecm.core.api.NuxeoException;
045import org.nuxeo.ecm.core.api.repository.RepositoryManager;
046import org.nuxeo.ecm.core.api.security.SecurityConstants;
047import org.nuxeo.ecm.core.query.sql.NXQL;
048import org.nuxeo.ecm.core.schema.FacetNames;
049import org.nuxeo.ecm.platform.ui.web.api.NavigationContext;
050import org.nuxeo.ecm.platform.ui.web.api.WebActions;
051import org.nuxeo.ecm.platform.ui.web.rest.RestHelper;
052import org.nuxeo.ecm.platform.util.RepositoryLocation;
053import org.nuxeo.ecm.webapp.dashboard.DashboardNavigationHelper;
054
055@Name("startupHelper")
056@Scope(SESSION)
057@Install(precedence = Install.FRAMEWORK)
058public class StartupHelper implements Serializable {
059
060    protected static final String SERVERS_VIEW = "view_servers";
061
062    protected static final String DOMAINS_VIEW = "view_domains";
063
064    protected static final String DOMAIN_TYPE = "Domain";
065
066    protected static final String DOCUMENT_MANAGEMENT_TAB = WebActions.MAIN_TABS_CATEGORY + ":"
067            + WebActions.DOCUMENTS_MAIN_TAB_ID;
068
069    private static final long serialVersionUID = 3248972387619873245L;
070
071    private static final Log log = LogFactory.getLog(StartupHelper.class);
072
073    @In(create = true)
074    protected transient RepositoryManager repositoryManager;
075
076    @In(create = true)
077    protected transient NavigationContext navigationContext;
078
079    @In(create = true)
080    protected transient WebActions webActions;
081
082    @In
083    protected transient Context sessionContext;
084
085    @In(create = true)
086    protected DashboardNavigationHelper dashboardNavigationHelper;
087
088    @In(create = true)
089    ConversationIdGenerator conversationIdGenerator;
090
091    @In(create = true, required = false)
092    protected transient CoreSession documentManager;
093
094    /**
095     * @deprecated since 5.6: use {@link RestHelper#setLocaleString(String)} instead of
096     *             {@link LocaleSelector#setLocaleString(String)}
097     */
098    @In(create = true)
099    @Deprecated
100    protected transient LocaleSelector localeSelector;
101
102    @In(create = true)
103    protected transient RestHelper restHelper;
104
105    /**
106     * Initializes the context with the principal id, and try to connect to the default server if any. If several
107     * servers are available, let the user choose.
108     *
109     * @return the view_id of the contextually computed startup page
110     */
111    public String initServerAndFindStartupPage() {
112
113        setupCurrentUser();
114
115        // we try to select the server to go to the next screen
116        if (navigationContext.getCurrentServerLocation() == null) {
117            // update location
118            RepositoryLocation repLoc = new RepositoryLocation(repositoryManager.getDefaultRepositoryName());
119            navigationContext.setCurrentServerLocation(repLoc);
120        }
121
122        if (documentManager == null) {
123            documentManager = navigationContext.getOrCreateDocumentManager();
124        }
125
126        if (Events.exists()) {
127            Events.instance().raiseEvent(EventNames.USER_SESSION_STARTED, documentManager);
128        }
129
130        // select home page
131
132        DocumentModel rootDocument = documentManager.getRootDocument();
133        if (!documentManager.hasPermission(rootDocument.getRef(), SecurityConstants.READ_CHILDREN)) {
134            // user cannot see the root but maybe she can see contained
135            // documents thus forwarding her to her dashboard
136            return dashboardNavigationHelper.navigateToDashboard();
137        }
138
139        webActions.setCurrentTabIds(DOCUMENT_MANAGEMENT_TAB);
140        // if more than one repo : display the server selection screen
141        if (repositoryManager.getRepositoryNames().size() > 1) {
142            return SERVERS_VIEW;
143        }
144
145        // the Repository Location is initialized, skip the first screen
146        return DOMAINS_VIEW;
147    }
148
149    /**
150     * Initializes the context with the principal id, and tries to connect to the default server if any then: - if the
151     * server has several domains, redirect to the list of domains - if the server has only one domain, select it and
152     * redirect to viewId - if the server is empty, create a new domain with title 'domainTitle' and redirect to it on
153     * viewId.
154     * <p>
155     * If several servers are available, let the user choose.
156     *
157     * @return the view id of the contextually computed startup page
158     */
159    @Begin(id = "#{conversationIdGenerator.nextMainConversationId}", join = true)
160    public String initDomainAndFindStartupPage(String domainTitle, String viewId) {
161
162        try {
163            // delegate server initialized to the default helper
164            String result = initServerAndFindStartupPage();
165
166            HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
167
168            // more than one repo
169            if (SERVERS_VIEW.equals(result)) {
170                return result;
171            }
172
173            String query = "SELECT * FROM Domain WHERE " + NXQL.ECM_MIXINTYPE + " <> '"
174                    + FacetNames.HIDDEN_IN_NAVIGATION + "' AND " + NXQL.ECM_LIFECYCLESTATE + " <> '"
175                    + LifeCycleConstants.DELETED_STATE + "'" + " AND ecm:isCheckedInVersion = 0 "
176                    + " AND ecm:isProxy = 0 ";
177            DocumentModelList domains = documentManager.query(query);
178            if (domains.size() == 1) {
179                // select and go to the unique domain
180                webActions.setCurrentTabIds(DOCUMENT_MANAGEMENT_TAB);
181                return navigationContext.navigateToDocument(domains.get(0), viewId);
182            }
183
184            // zero or several domains: let the user decide what to do if he has
185            // right on the Root document
186            DocumentModel rootDocument = documentManager.getRootDocument();
187            if (documentManager.hasPermission(rootDocument.getRef(), SecurityConstants.READ_CHILDREN)) {
188                webActions.setCurrentTabIds(DOCUMENT_MANAGEMENT_TAB);
189                navigationContext.navigateToDocument(rootDocument);
190                return DOMAINS_VIEW;
191            }
192
193            return result;
194        } catch (NuxeoException e) {
195            // avoid pages.xml contribution to catch exceptions silently
196            // hiding the cause of the problem to developers
197            // TODO: remove this catch clause if we find a way not to make it
198            // fail silently
199            log.error("error while initializing the Seam context with a CoreSession instance: " + e.getMessage(), e);
200            return null;
201        }
202    }
203
204    public void setupCurrentUser() {
205        Principal currentUser = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
206        sessionContext.set("currentUser", currentUser);
207    }
208
209}