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