Package org.jasig.portal

Source Code of org.jasig.portal.UserPreferencesManager

/**
* Licensed to Jasig under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Jasig 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.jasig.portal;

import java.io.IOException;
import java.io.InputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jasig.portal.i18n.LocaleManager;
import org.jasig.portal.jndi.IJndiManager;
import org.jasig.portal.layout.IUserLayoutManager;
import org.jasig.portal.layout.IUserLayoutStore;
import org.jasig.portal.layout.UserLayoutManagerFactory;
import org.jasig.portal.layout.UserLayoutStoreFactory;
import org.jasig.portal.layout.node.IUserLayoutChannelDescription;
import org.jasig.portal.properties.PropertiesManager;
import org.jasig.portal.security.IPerson;
import org.jasig.portal.spring.locator.JndiManagerLocator;
import org.jasig.portal.utils.PropsMatcher;
import org.w3c.dom.Document;


/**
* UserPreferencesManager is responsible for keeping: user id, user layout, user preferences
* and stylesheet descriptions.
* For method descriptions please see {@link IUserPreferencesManager}.
* @author Peter Kharchenko {@link <a href="mailto:pkharchenko@interactivebusiness.com">pkharchenko@interactivebusiness.com</a>}
* @version $Revision: 19776 $
*/
public class UserPreferencesManager implements IUserPreferencesManager {
    private static final String BROWSER_MAPPINGS_PROPERTIES = "/properties/browser.mappings";

    private static final String USER_PREFERENCES_KEY = UserPreferencesManager.class.getName();
   
    /**
     * Default value for saveUserPreferencesAtLogout.
     * This value will be used when the corresponding property cannot be loaded.
     */
    private static final boolean DEFAULT_SAVE_USER_PREFERENCES_AT_LOGOUT = false;

    private static final boolean saveUserPreferencesAtLogout = PropertiesManager.getPropertyAsBoolean(UserPreferencesManager.class.getName() + ".save_UserPreferences_at_logout", DEFAULT_SAVE_USER_PREFERENCES_AT_LOGOUT);

    // user agent mapper for guessing the profile
    private static PropsMatcher userAgentMatcher;

    protected final static Log logger = LogFactory.getLog(UserPreferencesManager.class);
   
   
    private IUserLayoutManager userLayoutManager;

    private UserPreferences completeUserPreferences;
    // caching of stylesheet descriptions is recommended
    // if they'll take up too much space, we can take them
    // out, but cache stylesheet URIs, mime type and serializer name.
    // Those are used in every rendering cycle.
    private ThemeStylesheetDescription themeStylesheetDescription;
    private StructureStylesheetDescription structureStylesheetDescription;
    private boolean unmappedUserAgent = false;
    private final IPerson person;
    IUserLayoutStore userLayoutStore = null;
   
   
    /**
     * @return lazily initialized access to the UserAgentMatcher
     * TODO this should be re-written & tested in a static initializer or injected
     */
    public static synchronized PropsMatcher getUserAgentMatcher() {
        if (userAgentMatcher == null) {
            InputStream userAgentMatcherStream = null;
            try {
                userAgentMatcherStream = UserPreferencesManager.class.getResourceAsStream(BROWSER_MAPPINGS_PROPERTIES);
                userAgentMatcher = new PropsMatcher(userAgentMatcherStream);
            }
            catch (IOException ioe) {
                logger.error("Failed to load browser mapping file: '" + BROWSER_MAPPINGS_PROPERTIES + "'", ioe);
            }
            finally {
                IOUtils.closeQuietly(userAgentMatcherStream);
            }
        }

        return userAgentMatcher;
    }



    /**
     * Constructor does the following
     *  1. Read layout.properties
     *  2. read userLayout from the database
     *  @param req the servlet request object
     *  @param person the person object
     */
    public UserPreferencesManager (HttpServletRequest req, IPerson person) throws PortalException {
        this(req, person, null);
    }

    /**
     * Constructor does the following
     *  1. Read layout.properties
     *  2. read userLayout from the database
     *  @param req the servlet request object
     *  @param person the person object
     *  @param localeManager the locale manager
     */
    public UserPreferencesManager (HttpServletRequest req, IPerson person, LocaleManager localeManager) throws PortalException {
        this.userLayoutManager=null;
        try {
            this.person = person;
           
           
            // load user preferences
            // Should obtain implementation in a different way!!
            this.userLayoutStore = UserLayoutStoreFactory.getUserLayoutStoreImpl();
           
           
            // determine user profile
            String userAgent = req.getHeader("User-Agent");
            if(StringUtils.isEmpty(userAgent)) {
                userAgent=MediaManager.NULL_USER_AGENT;
            }
           
           
            UserProfile userProfile = this.userLayoutStore.getUserProfile(this.person, userAgent);
            if (userProfile == null) {
                userProfile = this.userLayoutStore.getSystemProfile(userAgent);
            }
           
            // try guessing the profile through pattern matching
            if(userProfile==null) {
                final PropsMatcher userAgentMatcher = getUserAgentMatcher();
                if (userAgentMatcher != null) {
                    // try matching
                    final String profileFname = userAgentMatcher.match(userAgent);
                   
                    // user agent has been matched
                    if (profileFname != null) {
                     
                      userProfile = userLayoutStore.getUserProfileByFname(person, profileFname);
                     
                      if (userProfile == null) {
                            userProfile = userLayoutStore.getSystemProfileByFname(profileFname);
                      }
                     
                    }
                }

            }

            if (userProfile != null) {
                if (localeManager != null && LocaleManager.isLocaleAware()) {
                    userProfile.setLocaleManager(localeManager);
                }
                userLayoutManager=UserLayoutManagerFactory.getUserLayoutManager(this.person,userProfile);

                final HttpSession session = req.getSession(true);
                try {
                    if (session != null) {
                        completeUserPreferences = (UserPreferences)session.getAttribute(USER_PREFERENCES_KEY);
                    }

                    if (completeUserPreferences == null) {
                        completeUserPreferences=userLayoutStore.getUserPreferences(this.person, userProfile);
                    }
                    else {
                        logger.debug("Found UserPreferences in session, using it instead of creating new UserPreferences");
                    }
                }
                catch (Exception e) {
                    logger.error( "UserPreferencesManager(): caught an exception trying to retreive user preferences for user=\"" + this.person.getID() + "\", profile=\"" + userProfile.getProfileName() + "\".", e);
                    completeUserPreferences=new UserPreferences(userProfile);
                }

                if (completeUserPreferences != null) {
                    session.setAttribute(USER_PREFERENCES_KEY, completeUserPreferences);
                }

                try {
                    final IJndiManager jndiManager = JndiManagerLocator.getJndiManager();
                   
                    // Initialize the JNDI context for this user
                    final String userId = Integer.toString(this.person.getID());
                    final String layoutId = Integer.toString(userProfile.getLayoutId());
                    final Document userLayoutDom = userLayoutManager.getUserLayoutDOM();
                    jndiManager.initializeSessionContext(session, userId, layoutId, userLayoutDom);
                }
                catch(PortalException ipe) {
                  logger.error( "UserPreferencesManager(): Could not properly initialize user context", ipe);
                }
            }
            else {
                // there is no user-defined mapping for this particular browser.
                // user should be redirected to a browser-registration page.
                unmappedUserAgent = true;
                if (logger.isDebugEnabled())
                    logger.debug("UserPreferencesManager::UserPreferencesManager() : unable to find a profile for user \"" + this.person.getID()+"\" and userAgent=\""+ userAgent + "\".");
            }
        }
        catch (PortalException pe) {
            throw pe;
        }
        catch (Exception e) {
            final String msg = "Exception constructing UserPreferencesManager on request " + req + " for user " + this.person;
            logger.error(msg, e);
            throw new PortalException(msg, e);
        }
    }

    /**
     * A simpler constructor, that only initialises the person object.
     * Needed for ancestors.
     * @param person an <code>IPerson</code> object.
     */
    UserPreferencesManager(IPerson person) {
        this.person = person;
    }

    /**
     * Returns current person object
     * @return current <code>IPerson</code>
     */
    public IPerson getPerson () {
        return  (person);
    }

    /**
     * Returns a global channel Id given a channel instance Id
     * @param channelSubscribeId subscribe id of a channel
     * @return channel global id
     */
    protected String getChannelPublishId(String channelSubscribeId) throws PortalException {
        // Get the channel node from the user's layout
        IUserLayoutChannelDescription channel=(IUserLayoutChannelDescription) getUserLayoutManager().getNode(channelSubscribeId);
        if(channel!=null) {
            return channel.getChannelPublishId();
        }
       
        return null;
    }

    public boolean isUserAgentUnmapped() {
        return  unmappedUserAgent;
    }

    /*
     * Resets both user layout and user preferences.
     * Note that if any of the two are "null", old values will be used.
     */
    public void setNewUserLayoutAndUserPreferences(IUserLayoutManager newUlm, UserPreferences newPreferences) throws PortalException {
      try {
        if (newPreferences != null) {
            // see if the profile has changed
            if(!completeUserPreferences.getProfile().getProfileFname().equals(newPreferences.getProfile().getProfileFname()) || completeUserPreferences.getProfile().isSystemProfile()!=newPreferences.getProfile().isSystemProfile()) {
                // see if a layout was passed
                if(newUlm !=null && newUlm.getLayoutId()==newPreferences.getProfile().getLayoutId()) {
                    // just use a new layout
                    this.userLayoutManager=newUlm;
                } else {
                    // construct a new user layout manager, for a new profile
                    userLayoutManager=UserLayoutManagerFactory.getUserLayoutManager(person,newPreferences.getProfile());
                }
            }
            userLayoutStore.putUserPreferences(person, newPreferences);
            completeUserPreferences=newPreferences;

        }
      } catch (Exception e) {
        logger.error("Exception setting new user layout manager " + newUlm +
                " and/or new prefererences " + newPreferences, e);
        throw  new GeneralRenderingException(e);
      }
    }

    public IUserLayoutManager getUserLayoutManager() {
        return userLayoutManager;
    }
   
    /* (non-Javadoc)
     * @see org.jasig.portal.IUserPreferencesManager#finishedSession(javax.servlet.http.HttpSession)
     */
    public void finishedSession(HttpSession session) {
        // persist the layout and user preferences
        try {
            if(saveUserPreferencesAtLogout) {
                userLayoutStore.putUserPreferences(person, completeUserPreferences);
                userLayoutManager.saveUserLayout();
            }
        } catch (Exception e) {
            logger.error("UserPreferencesManager::finishedSession() : unable to persist layout upon session termination !", e);
        }
    }

    public UserPreferences getUserPreferencesCopy() {
        return  new UserPreferences(this.getUserPreferences());
    }


    public UserProfile getCurrentProfile() {
        return  this.getUserPreferences().getProfile();
    }

    public ThemeStylesheetDescription getThemeStylesheetDescription() throws Exception {
        if (this.themeStylesheetDescription == null) {
           themeStylesheetDescription = userLayoutStore.getThemeStylesheetDescription(this.getCurrentProfile().getThemeStylesheetId());
        }
        return  themeStylesheetDescription;
    }

    public StructureStylesheetDescription getStructureStylesheetDescription() throws Exception {
        if (this.structureStylesheetDescription == null) {
            structureStylesheetDescription = userLayoutStore.getStructureStylesheetDescription(this.getCurrentProfile().getStructureStylesheetId());
        }
        return  structureStylesheetDescription;
    }

    public UserPreferences getUserPreferences() {
        return completeUserPreferences;
    }
}


TOP

Related Classes of org.jasig.portal.UserPreferencesManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.