Package org.jasig.portal.layout

Source Code of org.jasig.portal.layout.StylesheetUserPreferencesServiceImpl$StylesheetPreferencesKey

/**
* 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.layout;

import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

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

import org.jasig.portal.IUserPreferencesManager;
import org.jasig.portal.IUserProfile;
import org.jasig.portal.layout.dao.IStylesheetDescriptorDao;
import org.jasig.portal.layout.dao.IStylesheetUserPreferencesDao;
import org.jasig.portal.layout.om.ILayoutAttributeDescriptor;
import org.jasig.portal.layout.om.IOutputPropertyDescriptor;
import org.jasig.portal.layout.om.IStylesheetData;
import org.jasig.portal.layout.om.IStylesheetData.Scope;
import org.jasig.portal.layout.om.IStylesheetDescriptor;
import org.jasig.portal.layout.om.IStylesheetParameterDescriptor;
import org.jasig.portal.layout.om.IStylesheetUserPreferences;
import org.jasig.portal.security.IPerson;
import org.jasig.portal.user.IUserInstance;
import org.jasig.portal.user.IUserInstanceManager;
import org.jasig.portal.utils.Populator;
import org.jasig.portal.utils.web.PortalWebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.util.WebUtils;

import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;

/**
* Handles retrieving and storing the various scopes of stylesheet user preference data.
*
* @author Eric Dalquist
* @version $Revision$
*/
@Service
public class StylesheetUserPreferencesServiceImpl implements IStylesheetUserPreferencesService {
    private static final String OUTPUT_PROPERTIES_KEY = StylesheetUserPreferencesServiceImpl.class.getName() + ".OUTPUT_PROPERTIES";
    private static final String STYLESHEET_PARAMETERS_KEY = StylesheetUserPreferencesServiceImpl.class.getName() + ".STYLESHEET_PARAMETERS";
    private static final String LAYOUT_ATTRIBUTES_KEY = StylesheetUserPreferencesServiceImpl.class.getName() + ".LAYOUT_ATTRIBUTES";
   
    protected final Logger logger = LoggerFactory.getLogger(getClass());
   
    private IUserInstanceManager userInstanceManager;
    private IStylesheetDescriptorDao stylesheetDescriptorDao;
    private IStylesheetUserPreferencesDao stylesheetUserPreferencesDao;

    @Autowired
    public void setUserInstanceManager(IUserInstanceManager userInstanceManager) {
        this.userInstanceManager = userInstanceManager;
    }
   
    @Autowired
    public void setStylesheetDescriptorDao(IStylesheetDescriptorDao stylesheetDescriptorDao) {
        this.stylesheetDescriptorDao = stylesheetDescriptorDao;
    }
   
    @Autowired
    public void setStylesheetUserPreferencesDao(IStylesheetUserPreferencesDao stylesheetUserPreferencesDao) {
        this.stylesheetUserPreferencesDao = stylesheetUserPreferencesDao;
    }
   
   
    protected static final class StylesheetPreferencesKey {
        private final IPerson person;
        private final IUserProfile userProfile;
        private final IStylesheetDescriptor stylesheetDescriptor;
        private final String str;
       
        private StylesheetPreferencesKey(IPerson person, IUserProfile userProfile,
                IStylesheetDescriptor stylesheetDescriptor) {
            this.person = person;
            this.userProfile = userProfile;
            this.stylesheetDescriptor = stylesheetDescriptor;
           
            this.str = "[" + stylesheetDescriptor.getId() + "," + person.getUserName() + "," + userProfile.getProfileId() + "]";
        }

        public String toString() {
            return this.str;
        }
    }

    protected final StylesheetPreferencesKey getStylesheetPreferencesKey(HttpServletRequest request, PreferencesScope prefScope) {
        final IUserInstance userInstance = this.userInstanceManager.getUserInstance(request);
       
        final IPerson person = userInstance.getPerson();

        final IUserPreferencesManager preferencesManager = userInstance.getPreferencesManager();
        final IUserProfile userProfile = preferencesManager.getUserProfile();
       
        final int stylesheetId = prefScope.getStylesheetId(userProfile);
        final IStylesheetDescriptor stylesheetDescriptor = this.stylesheetDescriptorDao.getStylesheetDescriptor(stylesheetId);
       
        return new StylesheetPreferencesKey(person, userProfile, stylesheetDescriptor);
    }
   
    protected final IStylesheetUserPreferences getDistributedStylesheetUserPreferences(HttpServletRequest request, PreferencesScope prefScope) {
        final IUserInstance userInstance = this.userInstanceManager.getUserInstance(request);
        final IUserPreferencesManager preferencesManager = userInstance.getPreferencesManager();
        final IUserLayoutManager userLayoutManager = preferencesManager.getUserLayoutManager();
        final IUserLayout userLayout = userLayoutManager.getUserLayout();
       
        return prefScope.getDistributedIStylesheetUserPreferences(userLayout);
    }
   
    protected final Scope getWriteScope(HttpServletRequest request, PreferencesScope prefScope, StylesheetPreferencesKey stylesheetPreferencesKey, IStylesheetData descriptor) {
        final Scope scope = descriptor.getScope();
        final boolean persistentScopeReadOnly = this.isPersistentScopeReadOnly(request, prefScope, stylesheetPreferencesKey);
        if (persistentScopeReadOnly && Scope.PERSISTENT == scope) {
            return Scope.SESSION;
        }
        return scope;
    }
   
    protected boolean isPersistentScopeReadOnly(HttpServletRequest request, PreferencesScope prefScope, StylesheetPreferencesKey stylesheetPreferencesKey) {
        return stylesheetPreferencesKey.person.isGuest();
    }
   
    protected final boolean compareValues(String value, String defaultValue) {
        return value == defaultValue || (value != null && value.equals(defaultValue));
    }
   
    protected final <T> T getDataValue(HttpServletRequest request, StylesheetPreferencesKey stylesheetPreferencesKey, Scope scope, String mapKey, String name) {
        switch (scope) {
            case SESSION: {
                final HttpSession session = request.getSession(false);
                if (session == null) {
                    return null;
                }
               
                final Map<String, T> outputProperties = PortalWebUtils.getMapSessionAttribute(session, mapKey + stylesheetPreferencesKey.toString(), false);
                if (outputProperties == null) {
                    return null;
                }

                return outputProperties.get(name);
            }
            case REQUEST: {
                final Map<String, T> outputProperties = PortalWebUtils.getMapRequestAttribute(request, mapKey + stylesheetPreferencesKey.toString(), false);
                if (outputProperties == null) {
                    return null;
                }
               
                return outputProperties.get(name);
            }
            default: {
                return null;
            }
        }
    }
   
    protected final <T> T putDataValue(HttpServletRequest request, StylesheetPreferencesKey stylesheetPreferencesKey, Scope scope, String mapKey, String name, T value) {
        switch (scope) {
            case SESSION: {
                final HttpSession session = request.getSession();
                final Map<String, T> outputProperties = PortalWebUtils.getMapSessionAttribute(session, mapKey + stylesheetPreferencesKey.toString());

                return outputProperties.put(name, value);
            }
            case REQUEST: {
                final Map<String, T> outputProperties = PortalWebUtils.getMapRequestAttribute(request, mapKey + stylesheetPreferencesKey.toString());
               
                return outputProperties.put(name, value);
            }
            default: {
                return null;
            }
        }
    }
   
    protected final <T> T removeDataValue(HttpServletRequest request, StylesheetPreferencesKey stylesheetPreferencesKey, Scope scope, String mapKey, String name) {
        switch (scope) {
            case SESSION: {
                final HttpSession session = request.getSession(false);
                if (session == null) {
                    return null;
                }
               
                final Map<String, T> outputProperties = PortalWebUtils.getMapSessionAttribute(session, mapKey + stylesheetPreferencesKey.toString(), false);
                if (outputProperties == null) {
                    return null;
                }

                return outputProperties.remove(name);
            }
            case REQUEST: {
                final Map<String, T> outputProperties = PortalWebUtils.getMapRequestAttribute(request, mapKey + stylesheetPreferencesKey.toString(), false);
                if (outputProperties == null) {
                    return null;
                }
               
                return outputProperties.remove(name);
            }
            default: {
                return null;
            }
        }
    }
   
    @Override
    public IStylesheetDescriptor getStylesheetDescriptor(HttpServletRequest request, PreferencesScope prefScope) {
        final IUserInstance userInstance = this.userInstanceManager.getUserInstance(request);
       
        final IUserPreferencesManager preferencesManager = userInstance.getPreferencesManager();
        final IUserProfile userProfile = preferencesManager.getUserProfile();
       
        final int stylesheetId = prefScope.getStylesheetId(userProfile);
        return this.stylesheetDescriptorDao.getStylesheetDescriptor(stylesheetId);
    }

    @Override
    public String getOutputProperty(HttpServletRequest request, PreferencesScope prefScope, String name) {
        final StylesheetPreferencesKey stylesheetPreferencesKey = this.getStylesheetPreferencesKey(request, prefScope);
        final IStylesheetDescriptor stylesheetDescriptor = stylesheetPreferencesKey.stylesheetDescriptor;
        final IOutputPropertyDescriptor outputPropertyDescriptor = stylesheetDescriptor.getOutputPropertyDescriptor(name);
        if (outputPropertyDescriptor == null) {
            logger.warn("Attempted to get output property {} but no such output property is defined in stylesheet descriptor {}. null will be returned", new Object[] {name, stylesheetDescriptor.getName()});
            return null;
        }


        final String value;
        final Scope scope = outputPropertyDescriptor.getScope();
        switch (scope) {
            case PERSISTENT: {
                final IStylesheetUserPreferences stylesheetUserPreferences = this.getStylesheetUserPreferences(request, stylesheetPreferencesKey);
                if (stylesheetUserPreferences == null) {
                    return null;
                }
               
                value = stylesheetUserPreferences.getOutputProperty(name);
                break;
            }
            default: {
                value = this.getDataValue(request, stylesheetPreferencesKey, scope, OUTPUT_PROPERTIES_KEY, name);
                break;
            }
        }
       
        if (value == null) {
            return null;
        }
       
        //If the value is equal to the default value remove the property and return null
        if (this.compareValues(value, outputPropertyDescriptor.getDefaultValue())) {
            this.removeOutputProperty(request, prefScope, name);
            return null;
        }
       
        return value;
    }

    @Transactional
    @Override
    public String setOutputProperty(HttpServletRequest request, PreferencesScope prefScope, String name, String value) {
        final StylesheetPreferencesKey stylesheetPreferencesKey = this.getStylesheetPreferencesKey(request, prefScope);
        final IStylesheetDescriptor stylesheetDescriptor = stylesheetPreferencesKey.stylesheetDescriptor;
        final IOutputPropertyDescriptor outputPropertyDescriptor = stylesheetDescriptor.getOutputPropertyDescriptor(name);
        if (outputPropertyDescriptor == null) {
            logger.warn("Attempted to set output property {}={} but no such output property is defined in stylesheet descriptor {}. It will be ignored", new Object[] {name, value, stylesheetDescriptor.getName()});
            return null;
        }
       
        if (this.compareValues(value, outputPropertyDescriptor.getDefaultValue())) {
            return this.removeOutputProperty(request, prefScope, name);
        }
       
        final Scope scope = this.getWriteScope(request, prefScope, stylesheetPreferencesKey, outputPropertyDescriptor);
        switch (scope) {
            case PERSISTENT: {
                IStylesheetUserPreferences stylesheetUserPreferences = this.getStylesheetUserPreferences(request, stylesheetPreferencesKey);
                if (stylesheetUserPreferences == null) {
                    stylesheetUserPreferences = this.stylesheetUserPreferencesDao.createStylesheetUserPreferences(stylesheetDescriptor, stylesheetPreferencesKey.person, stylesheetPreferencesKey.userProfile);
                    this.clearStylesheetUserPreferencesCache(request, stylesheetPreferencesKey);
                }
               
                final String oldValue = stylesheetUserPreferences.setOutputProperty(name, value);
                this.stylesheetUserPreferencesDao.storeStylesheetUserPreferences(stylesheetUserPreferences);
                return oldValue;
            }
            default: {
                return this.putDataValue(request, stylesheetPreferencesKey, scope, OUTPUT_PROPERTIES_KEY, name, value);
            }
        }
    }

    @Transactional
    @Override
    public String removeOutputProperty(HttpServletRequest request, PreferencesScope prefScope, String name) {
        final StylesheetPreferencesKey stylesheetPreferencesKey = this.getStylesheetPreferencesKey(request, prefScope);
        final IStylesheetDescriptor stylesheetDescriptor = stylesheetPreferencesKey.stylesheetDescriptor;
        final IOutputPropertyDescriptor outputPropertyDescriptor = stylesheetDescriptor.getOutputPropertyDescriptor(name);
        if (outputPropertyDescriptor == null) {
            logger.warn("Attempted to remove output property {} but no such output property is defined in stylesheet descriptor {}. It will be ignored", new Object[] {name, stylesheetDescriptor.getName()});
            return null;
        }
       
        final Scope scope = this.getWriteScope(request, prefScope, stylesheetPreferencesKey, outputPropertyDescriptor);
        switch (scope) {
            case PERSISTENT: {
                final IStylesheetUserPreferences stylesheetUserPreferences = this.getStylesheetUserPreferences(request, stylesheetPreferencesKey);
                if (stylesheetUserPreferences == null) {
                    return null;
                }
               
                final String oldValue = stylesheetUserPreferences.removeOutputProperty(name);
                this.stylesheetUserPreferencesDao.storeStylesheetUserPreferences(stylesheetUserPreferences);
                this.clearStylesheetUserPreferencesCache(request, stylesheetPreferencesKey);
                return oldValue;
            }
            default: {
                return removeDataValue(request, stylesheetPreferencesKey, scope, OUTPUT_PROPERTIES_KEY, name);
            }
        }
    }
   
    @Override
    public <P extends Populator<String, String>> P populateOutputProperties(HttpServletRequest request,
            PreferencesScope prefScope, P properties) {
        final StylesheetPreferencesKey stylesheetPreferencesKey = this.getStylesheetPreferencesKey(request, prefScope);
        final IStylesheetDescriptor stylesheetDescriptor = stylesheetPreferencesKey.stylesheetDescriptor;
       
        //Get the scoped sources once
        final IStylesheetUserPreferences stylesheetUserPreferences = this.getStylesheetUserPreferences(request, stylesheetPreferencesKey);
       
        final Map<String, String> sessionOutputProperties;
        final HttpSession session = request.getSession(false);
        if (session == null) {
            sessionOutputProperties = null;
        }
        else {
            sessionOutputProperties = PortalWebUtils.getMapSessionAttribute(session, OUTPUT_PROPERTIES_KEY + stylesheetPreferencesKey.toString(), false);
        }
       
        final Map<String, String> requestOutputProperties = PortalWebUtils.getMapRequestAttribute(request, OUTPUT_PROPERTIES_KEY + stylesheetPreferencesKey.toString(), false);
       
        //Try getting each output property to populate the Properties
        for (final IOutputPropertyDescriptor outputPropertyDescriptor : stylesheetDescriptor.getOutputPropertyDescriptors()) {
            final String name = outputPropertyDescriptor.getName();

            final String value;
            final Scope scope = outputPropertyDescriptor.getScope();
            switch (scope) {
                case PERSISTENT: {
                    if (stylesheetUserPreferences == null) {
                        value = null;
                        break;
                    }
                   
                    value = stylesheetUserPreferences.getOutputProperty(name);
                    break;
                }
                case SESSION: {
                    if (sessionOutputProperties == null) {
                        value = null;
                        break;
                    }

                    value = sessionOutputProperties.get(name);
                    break;
                }
                case REQUEST: {
                    if (requestOutputProperties == null) {
                        value = null;
                        break;
                    }
                   
                    value = requestOutputProperties.get(name);
                    break;
                }
                default: {
                    value = null;
                    break;
                }
            }
           
            //Don't add unset properties
            if (value == null) {
                continue;
            }
           
            //If the value is equal to the default value remove the property and return null
            if (this.compareValues(value, outputPropertyDescriptor.getDefaultValue())) {
                this.removeOutputProperty(request, prefScope, name);
                continue;
            }
           
            properties.put(name, value);
        }
       
        return properties;
    }

    @Transactional
    @Override
    public void clearOutputProperties(HttpServletRequest request, PreferencesScope prefScope) {
        final StylesheetPreferencesKey stylesheetPreferencesKey = this.getStylesheetPreferencesKey(request, prefScope);
       
        final IStylesheetUserPreferences stylesheetUserPreferences = this.getStylesheetUserPreferences(request, stylesheetPreferencesKey);
        if (stylesheetUserPreferences != null) {
            stylesheetUserPreferences.clearOutputProperties();
            this.stylesheetUserPreferencesDao.storeStylesheetUserPreferences(stylesheetUserPreferences);
        }
       
        final HttpSession session = request.getSession(false);
        if (session != null) {
            session.removeAttribute(OUTPUT_PROPERTIES_KEY + stylesheetPreferencesKey.toString());
        }
       
        request.removeAttribute(OUTPUT_PROPERTIES_KEY + stylesheetPreferencesKey.toString());
    }
   

   

    @Override
    public String getStylesheetParameter(HttpServletRequest request, PreferencesScope prefScope, String name) {
        final StylesheetPreferencesKey stylesheetPreferencesKey = this.getStylesheetPreferencesKey(request, prefScope);
        final IStylesheetDescriptor stylesheetDescriptor = stylesheetPreferencesKey.stylesheetDescriptor;
        final IStylesheetParameterDescriptor stylesheetParameterDescriptor = stylesheetDescriptor.getStylesheetParameterDescriptor(name);
        if (stylesheetParameterDescriptor == null) {
            logger.warn("Attempted to get stylesheet parameter {} but no such stylesheet parameter is defined in stylesheet descriptor {}. null will be returned", new Object[] {name, stylesheetDescriptor.getName()});
            return null;
        }


        final String value;
        final Scope scope = stylesheetParameterDescriptor.getScope();
        switch (scope) {
            case PERSISTENT: {
                final IStylesheetUserPreferences stylesheetUserPreferences = this.getStylesheetUserPreferences(request, stylesheetPreferencesKey);
                if (stylesheetUserPreferences == null) {
                    return null;
                }
               
                value = stylesheetUserPreferences.getStylesheetParameter(name);
                break;
            }
            default: {
                value = this.getDataValue(request, stylesheetPreferencesKey, scope, STYLESHEET_PARAMETERS_KEY, name);
                break;
            }
        }
       
        if (value == null) {
            return null;
        }
       
        //If the value is equal to the default value remove the property and return null
        if (this.compareValues(value, stylesheetParameterDescriptor.getDefaultValue())) {
            this.removeStylesheetParameter(request, prefScope, name);
            return null;
        }
       
        return value;
    }

    @Transactional
    @Override
    public String setStylesheetParameter(HttpServletRequest request, PreferencesScope prefScope, String name, String value) {

        logger.trace("Setting stylesheet parameter {} with scope {} to {}.", name, prefScope, value);

        final StylesheetPreferencesKey stylesheetPreferencesKey = this.getStylesheetPreferencesKey(request, prefScope);
        final IStylesheetDescriptor stylesheetDescriptor = stylesheetPreferencesKey.stylesheetDescriptor;
        final IStylesheetParameterDescriptor stylesheetParameterDescriptor = stylesheetDescriptor.getStylesheetParameterDescriptor(name);
        if (stylesheetParameterDescriptor == null) {
            logger.warn("Attempted to set stylesheet parameter {}={} but no such stylesheet parameter is defined in stylesheet descriptor {}. It will be ignored", new Object[] {name, value, stylesheetDescriptor.getName()});
            return null;
        }
       
        if (this.compareValues(value, stylesheetParameterDescriptor.getDefaultValue())) {
            return this.removeStylesheetParameter(request, prefScope, name);
        }
       
        final Scope scope = this.getWriteScope(request, prefScope, stylesheetPreferencesKey, stylesheetParameterDescriptor);
        switch (scope) {
            case PERSISTENT: {
                IStylesheetUserPreferences stylesheetUserPreferences = this.getStylesheetUserPreferences(request, stylesheetPreferencesKey);
                if (stylesheetUserPreferences == null) {
                    stylesheetUserPreferences = this.stylesheetUserPreferencesDao.createStylesheetUserPreferences(stylesheetDescriptor, stylesheetPreferencesKey.person, stylesheetPreferencesKey.userProfile);
                    this.clearStylesheetUserPreferencesCache(request, stylesheetPreferencesKey);
                }
               
                final String oldValue = stylesheetUserPreferences.setStylesheetParameter(name, value);
                this.stylesheetUserPreferencesDao.storeStylesheetUserPreferences(stylesheetUserPreferences);
                return oldValue;
            }
            default: {
                return this.putDataValue(request, stylesheetPreferencesKey, scope, STYLESHEET_PARAMETERS_KEY, name, value);
            }
        }
    }

    @Transactional
    @Override
    public String removeStylesheetParameter(HttpServletRequest request, PreferencesScope prefScope, String name) {
        final StylesheetPreferencesKey stylesheetPreferencesKey = this.getStylesheetPreferencesKey(request, prefScope);
        final IStylesheetDescriptor stylesheetDescriptor = stylesheetPreferencesKey.stylesheetDescriptor;
        final IStylesheetParameterDescriptor stylesheetParameterDescriptor = stylesheetDescriptor.getStylesheetParameterDescriptor(name);
        if (stylesheetParameterDescriptor == null) {
            logger.warn("Attempted to remove stylesheet parameter {} but no such stylesheet parameter is defined in stylesheet descriptor {}. It will be ignored", new Object[] {name, stylesheetDescriptor.getName()});
            return null;
        }
       
        final Scope scope = this.getWriteScope(request, prefScope, stylesheetPreferencesKey, stylesheetParameterDescriptor);
        switch (scope) {
            case PERSISTENT: {
                final IStylesheetUserPreferences stylesheetUserPreferences = this.getStylesheetUserPreferences(request, stylesheetPreferencesKey);
                if (stylesheetUserPreferences == null) {
                    return null;
                }
               
                final String oldValue = stylesheetUserPreferences.removeStylesheetParameter(name);
                this.stylesheetUserPreferencesDao.storeStylesheetUserPreferences(stylesheetUserPreferences);
                return oldValue;
            }
            default: {
                return removeDataValue(request, stylesheetPreferencesKey, scope, STYLESHEET_PARAMETERS_KEY, name);
            }
        }
    }

    @Override
    public Iterable<String> getStylesheetParameterNames(HttpServletRequest request, PreferencesScope prefScope) {
        final StylesheetPreferencesKey stylesheetPreferencesKey = this.getStylesheetPreferencesKey(request, prefScope);
        final IStylesheetDescriptor stylesheetDescriptor = stylesheetPreferencesKey.stylesheetDescriptor;
        final Collection<IStylesheetParameterDescriptor> stylesheetParameterDescriptors = stylesheetDescriptor.getStylesheetParameterDescriptors();
       
        return Collections2.transform(stylesheetParameterDescriptors, new Function<IStylesheetParameterDescriptor, String>() {
            @Override
            public String apply(IStylesheetParameterDescriptor input) {
                return input.getName();
            }
        });
    }

    @Override
    public <P extends Populator<String, String>> P populateStylesheetParameters(HttpServletRequest request,
            PreferencesScope prefScope, P stylesheetParameters) {
        final StylesheetPreferencesKey stylesheetPreferencesKey = this.getStylesheetPreferencesKey(request, prefScope);
        final IStylesheetDescriptor stylesheetDescriptor = stylesheetPreferencesKey.stylesheetDescriptor;
       
        //Get the scoped sources once
        final IStylesheetUserPreferences stylesheetUserPreferences = this.getStylesheetUserPreferences(request, stylesheetPreferencesKey);
        final Map<String, String> sessionStylesheetParameters;
        final HttpSession session = request.getSession(false);
        if (session == null) {
            sessionStylesheetParameters = null;
        }
        else {
            sessionStylesheetParameters = PortalWebUtils.getMapSessionAttribute(session, STYLESHEET_PARAMETERS_KEY + stylesheetPreferencesKey.toString(), false);
        }
        final Map<String, String> requestStylesheetParameters = PortalWebUtils.getMapRequestAttribute(request, STYLESHEET_PARAMETERS_KEY + stylesheetPreferencesKey.toString(), false);
       
        //Try getting each stylesheet parameter to populate the Map
        for (final IStylesheetParameterDescriptor stylesheetParameterDescriptor : stylesheetDescriptor.getStylesheetParameterDescriptors()) {
            final String name = stylesheetParameterDescriptor.getName();

            final String value;
            final Scope scope = stylesheetParameterDescriptor.getScope();
            switch (scope) {
                case PERSISTENT: {
                    if (stylesheetUserPreferences == null) {
                        value = null;
                        break;
                    }
                   
                    value = stylesheetUserPreferences.getStylesheetParameter(name);
                    break;
                }
                case SESSION: {
                    if (sessionStylesheetParameters == null) {
                        value = null;
                        break;
                    }

                    value = sessionStylesheetParameters.get(name);
                    break;
                }
                case REQUEST: {
                    if (requestStylesheetParameters == null) {
                        value = null;
                        break;
                    }
                   
                    value = requestStylesheetParameters.get(name);
                    break;
                }
                default: {
                    value = null;
                    break;
                }
            }
           
            //Don't add unset properties
            if (value == null) {
                continue;
            }
           
            //If the value is equal to the default value remove the property and return null
            if (this.compareValues(value, stylesheetParameterDescriptor.getDefaultValue())) {
                this.removeStylesheetParameter(request, prefScope, name);
                continue;
            }
           
            stylesheetParameters.put(name, value);
        }
       
        return stylesheetParameters;
    }

    @Transactional
    @Override
    public void clearStylesheetParameters(HttpServletRequest request, PreferencesScope prefScope) {
        final StylesheetPreferencesKey stylesheetPreferencesKey = this.getStylesheetPreferencesKey(request, prefScope);
       
        final IStylesheetUserPreferences stylesheetUserPreferences = this.getStylesheetUserPreferences(request, stylesheetPreferencesKey);
        if (stylesheetUserPreferences != null) {
            stylesheetUserPreferences.clearStylesheetParameters();
            this.stylesheetUserPreferencesDao.storeStylesheetUserPreferences(stylesheetUserPreferences);
        }
       
        final HttpSession session = request.getSession(false);
        if (session != null) {
            session.removeAttribute(STYLESHEET_PARAMETERS_KEY + stylesheetPreferencesKey.toString());
        }
       
        request.removeAttribute(STYLESHEET_PARAMETERS_KEY + stylesheetPreferencesKey.toString());
    }

    @Override
    public String getLayoutAttribute(HttpServletRequest request, PreferencesScope prefScope, String nodeId, String name) {
        final StylesheetPreferencesKey stylesheetPreferencesKey = this.getStylesheetPreferencesKey(request, prefScope);
        final IStylesheetDescriptor stylesheetDescriptor = stylesheetPreferencesKey.stylesheetDescriptor;
        final ILayoutAttributeDescriptor layoutAttributeDescriptor = stylesheetDescriptor.getLayoutAttributeDescriptor(name);
        if (layoutAttributeDescriptor == null) {
            logger.warn("Attempted to get layout attribute {} for ID=\"{}\" but no such stylesheet parameter is defined in stylesheet descriptor {}. Null will be returned", new Object[] {name, nodeId, stylesheetDescriptor.getName()});
            return null;
        }


       
        //Load the default value
        String defaultValue = null;
        final IStylesheetUserPreferences distributedStylesheetUserPreferences = this.getDistributedStylesheetUserPreferences(request, prefScope);
        if (distributedStylesheetUserPreferences != null) {
            defaultValue = distributedStylesheetUserPreferences.getLayoutAttribute(nodeId, name);
           
            if (this.compareValues(defaultValue, layoutAttributeDescriptor.getDefaultValue())) {
                //DLM attribute value matches the stylesheet descriptor default, remove the DLM value
                distributedStylesheetUserPreferences.removeLayoutAttribute(nodeId, name);
                defaultValue = null;
            }
        }
       
        final String value;
        final Scope scope = layoutAttributeDescriptor.getScope();
        switch (scope) {
            case PERSISTENT: {
                final IStylesheetUserPreferences stylesheetUserPreferences = this.getStylesheetUserPreferences(request, stylesheetPreferencesKey);
                if (stylesheetUserPreferences == null) {
                    value = null;
                    break;
                }
               
                value = stylesheetUserPreferences.getLayoutAttribute(nodeId, name);
                break;
            }
            default: {
                final Map<String, String> nodeAttributes = this.getDataValue(request, stylesheetPreferencesKey, scope, LAYOUT_ATTRIBUTES_KEY, nodeId);
                if (nodeAttributes == null) {
                    value = null;
                    break;
                }
               
                value = nodeAttributes.get(name);
                break;
            }
        }
       
        if (value == null) {
            return defaultValue;
        }
       
        if (this.compareValues(value, layoutAttributeDescriptor.getDefaultValue()) || //Value is equal to stylesheet descriptor default
            (defaultValue != null && this.compareValues(value, defaultValue))) { //Value is equal to DLM stylesheet preferences default
           
            //Remove the user's customized value
            this.removeLayoutAttribute(request, prefScope, nodeId, name);
            return null;
        }
       
        return value;
    }
   
    private static final String NO_PERSISTENT_IStylesheetUserPreferences = StylesheetUserPreferencesServiceImpl.class.getName() + ".NO_PERSISTENT_IStylesheetUserPreferences";

    private String getCacheKey(StylesheetPreferencesKey stylesheetPreferencesKey) {
        return NO_PERSISTENT_IStylesheetUserPreferences + "." + stylesheetPreferencesKey.toString();
    }
   
    private IStylesheetUserPreferences getStylesheetUserPreferences(HttpServletRequest request, StylesheetPreferencesKey stylesheetPreferencesKey) {
        final String key = getCacheKey(stylesheetPreferencesKey);
       
        if (request.getAttribute(key) != null) {
            return null;
        }
       
        final HttpSession session = request.getSession();
        if (session.getAttribute(key) != null) {
            request.setAttribute(key, Boolean.TRUE);
            return null;
        }
       
        final IStylesheetUserPreferences stylesheetUserPreferences = this.stylesheetUserPreferencesDao.getStylesheetUserPreferences(stylesheetPreferencesKey.stylesheetDescriptor, stylesheetPreferencesKey.person, stylesheetPreferencesKey.userProfile);
       
        if (stylesheetUserPreferences == null) {
            session.setAttribute(key, Boolean.TRUE);
            request.setAttribute(key, Boolean.TRUE);
        }

        return stylesheetUserPreferences;
    }
   
    private void clearStylesheetUserPreferencesCache(HttpServletRequest request, StylesheetPreferencesKey stylesheetPreferencesKey) {
        final String key = getCacheKey(stylesheetPreferencesKey);
       
        request.removeAttribute(key);

        final HttpSession session = request.getSession();
        session.removeAttribute(key);
    }

    /**
     * @return Map<nodeId, Map<name, value>>
     */
    protected ConcurrentMap<String, Map<String, String>> getRequestLayoutAttributes(HttpServletRequest request,
            StylesheetPreferencesKey stylesheetPreferencesKey) {
        return PortalWebUtils.getMapRequestAttribute(request, LAYOUT_ATTRIBUTES_KEY + stylesheetPreferencesKey.toString(), false);
    }

    /**
     * @return Map<nodeId, Map<name, value>>
     */
    protected ConcurrentMap<String, Map<String, String>> getSessionLayoutAttributes(HttpSession session,
            StylesheetPreferencesKey stylesheetPreferencesKey) {
        return PortalWebUtils.getMapSessionAttribute(session, LAYOUT_ATTRIBUTES_KEY + stylesheetPreferencesKey.toString(), false);
    }
   
    @Transactional
    @Override
    public String setLayoutAttribute(HttpServletRequest request, PreferencesScope prefScope, String nodeId, String name, String value) {
        final StylesheetPreferencesKey stylesheetPreferencesKey = this.getStylesheetPreferencesKey(request, prefScope);
        final IStylesheetDescriptor stylesheetDescriptor = stylesheetPreferencesKey.stylesheetDescriptor;
        final ILayoutAttributeDescriptor layoutAttributeDescriptor = stylesheetDescriptor.getLayoutAttributeDescriptor(name);
        if (layoutAttributeDescriptor == null) {
            logger.warn("Attempted to set layout attribute {}={} on node with ID=\"{}\" but no such stylesheet parameter is defined in stylesheet descriptor {}. It will be ignored.", new Object[] {name, value, nodeId, stylesheetDescriptor.getName()});
            return null;
        }
       
        if (this.compareValues(value, layoutAttributeDescriptor.getDefaultValue())) {
            //Value matches the default value, remove the attribute
            return this.removeLayoutAttribute(request, prefScope, nodeId, name);
        }
       
        final IStylesheetUserPreferences distributedStylesheetUserPreferences = this.getDistributedStylesheetUserPreferences(request, prefScope);
        if (distributedStylesheetUserPreferences != null) {
            final String defaultValue = distributedStylesheetUserPreferences.getLayoutAttribute(nodeId, name);
            if (this.compareValues(value, defaultValue)) {
                //Value matches the DLM preferences value, remove the value
                return this.removeLayoutAttribute(request, prefScope, nodeId, name);
            }
        }
       
        final Scope scope = this.getWriteScope(request, prefScope, stylesheetPreferencesKey, layoutAttributeDescriptor);
        switch (scope) {
            case PERSISTENT: {
                IStylesheetUserPreferences stylesheetUserPreferences = this.getStylesheetUserPreferences(request, stylesheetPreferencesKey);
                if (stylesheetUserPreferences == null) {
                    stylesheetUserPreferences = this.stylesheetUserPreferencesDao.createStylesheetUserPreferences(stylesheetDescriptor, stylesheetPreferencesKey.person, stylesheetPreferencesKey.userProfile);
                    this.clearStylesheetUserPreferencesCache(request, stylesheetPreferencesKey);
                }
               
                final String oldValue = stylesheetUserPreferences.setLayoutAttribute(nodeId, name, value);
                this.stylesheetUserPreferencesDao.storeStylesheetUserPreferences(stylesheetUserPreferences);
                return oldValue;
            }
            default: {
               
                //Determine the mutex to use for accessing the nodeAttributes map
                final Object mutex;
                switch (scope) {
                    case REQUEST: {
                        mutex = PortalWebUtils.getRequestAttributeMutex(request);
                        break;
                    }
                    case SESSION: {
                        final HttpSession session = request.getSession();
                        mutex = WebUtils.getSessionMutex(session);
                        break;
                    }
                    default: {
                        mutex = new Object();
                        break;
                    }
                }
               
                //Get/Create the nodeAttributes map
                Map<String, String> nodeAttributes;
                synchronized (mutex) {
                    nodeAttributes = this.getDataValue(request, stylesheetPreferencesKey, scope, LAYOUT_ATTRIBUTES_KEY, nodeId);
                    if (nodeAttributes == null) {
                        nodeAttributes = new ConcurrentHashMap<String, String>();
                        this.putDataValue(request, stylesheetPreferencesKey, scope, LAYOUT_ATTRIBUTES_KEY, nodeId, nodeAttributes);
                    }
                }
               
                return nodeAttributes.put(name, value);
            }
        }
    }

    @Transactional
    @Override
    public String removeLayoutAttribute(HttpServletRequest request, PreferencesScope prefScope, String nodeId, String name) {
        final StylesheetPreferencesKey stylesheetPreferencesKey = this.getStylesheetPreferencesKey(request, prefScope);
        final IStylesheetDescriptor stylesheetDescriptor = stylesheetPreferencesKey.stylesheetDescriptor;
        final ILayoutAttributeDescriptor layoutAttributeDescriptor = stylesheetDescriptor.getLayoutAttributeDescriptor(name);
        if (layoutAttributeDescriptor == null) {
            logger.warn("Attempted to remove layout attribute {} for ID=\"{}\" but no such stylesheet parameter is defined in stylesheet descriptor {}. It will be ignored.", new Object[] {name, nodeId, stylesheetDescriptor.getName()});
            return null;
        }
       
        final Scope scope = this.getWriteScope(request, prefScope, stylesheetPreferencesKey, layoutAttributeDescriptor);
        switch (scope) {
            case PERSISTENT: {
                final IStylesheetUserPreferences stylesheetUserPreferences = this.getStylesheetUserPreferences(request, stylesheetPreferencesKey);
                if (stylesheetUserPreferences == null) {
                    break;
                }
               
                final String oldValue = stylesheetUserPreferences.removeLayoutAttribute(nodeId, name);
                if (oldValue != null) {
                    this.stylesheetUserPreferencesDao.storeStylesheetUserPreferences(stylesheetUserPreferences);
                    return oldValue;
                }
            }
            default: {
                final Map<String, String> nodeAttributes = this.getDataValue(request, stylesheetPreferencesKey, scope, LAYOUT_ATTRIBUTES_KEY, nodeId);
                if (nodeAttributes == null) {
                    break;
                }
               
                final String oldValue = nodeAttributes.remove(name);
                if (oldValue != null) {
                    return oldValue;
                }
            }
        }
       
        final IStylesheetUserPreferences distributedStylesheetUserPreferences = this.getDistributedStylesheetUserPreferences(request, prefScope);
        if (distributedStylesheetUserPreferences != null) {
            return distributedStylesheetUserPreferences.removeLayoutAttribute(nodeId, name);
        }
       
        return null;
    }

    @Override
    public Iterable<String> getAllLayoutAttributeNodeIds(HttpServletRequest request, PreferencesScope prefScope) {
        final StylesheetPreferencesKey stylesheetPreferencesKey = this.getStylesheetPreferencesKey(request, prefScope);
       
        final LinkedHashSet<String> allNodeIds = new LinkedHashSet<String>();
       
        final IStylesheetUserPreferences stylesheetUserPreferences = this.getStylesheetUserPreferences(request, stylesheetPreferencesKey);
        if (stylesheetUserPreferences != null) {
            allNodeIds.addAll(stylesheetUserPreferences.getAllLayoutAttributeNodeIds());
        }
       
        final HttpSession session = request.getSession(false);
        if (session != null) {
            final Map<String, Map<String, String>> sessionLayoutAttributes = getSessionLayoutAttributes(session, stylesheetPreferencesKey);
            if (sessionLayoutAttributes != null) {
                allNodeIds.addAll(sessionLayoutAttributes.keySet());
            }
           
        }

        final Map<String, Map<String, String>> requestLayoutAttributes = getRequestLayoutAttributes(request, stylesheetPreferencesKey);
        if (requestLayoutAttributes != null) {
            allNodeIds.addAll(requestLayoutAttributes.keySet());
        }
       
        final IStylesheetUserPreferences distributedStylesheetUserPreferences = this.getDistributedStylesheetUserPreferences(request, prefScope);
        if (distributedStylesheetUserPreferences != null) {
            allNodeIds.addAll(distributedStylesheetUserPreferences.getAllLayoutAttributeNodeIds());
        }
       
        return allNodeIds;
    }
   
    @Override
    public Map<String, String> getAllNodesAndValuesForAttribute(HttpServletRequest request, PreferencesScope prefScope, String name) {
        final StylesheetPreferencesKey stylesheetPreferencesKey = this.getStylesheetPreferencesKey(request, prefScope);
        final IStylesheetUserPreferences stylesheetUserPreferences = this.getStylesheetUserPreferences(request, stylesheetPreferencesKey);

        final Builder<String, String> result = ImmutableMap.builder();
       
        final IStylesheetUserPreferences distributedStylesheetUserPreferences = this.getDistributedStylesheetUserPreferences(request, prefScope);
        if (distributedStylesheetUserPreferences != null) {
            final Map<String, String> allNodesAndValuesForAttribute = distributedStylesheetUserPreferences.getAllNodesAndValuesForAttribute(name);
            result.putAll(allNodesAndValuesForAttribute);
        }
       
        if (stylesheetUserPreferences != null) {
            final Map<String, String> allNodesAndValuesForAttribute = stylesheetUserPreferences.getAllNodesAndValuesForAttribute(name);
            result.putAll(allNodesAndValuesForAttribute);
        }
       
        final HttpSession session = request.getSession(false);
        if (session != null) {
            //nodeId, name, value
            final Map<String, Map<String, String>> sessionLayoutAttributes = getSessionLayoutAttributes(session, stylesheetPreferencesKey);
            getAllNodesAndValuesForAttribute(sessionLayoutAttributes, name, result);
        }

        final Map<String, Map<String, String>> requestLayoutAttributes = getRequestLayoutAttributes(request, stylesheetPreferencesKey);
        if (requestLayoutAttributes != null) {
            getAllNodesAndValuesForAttribute(requestLayoutAttributes, name, result);
        }

        return result.build();
    }

    protected void getAllNodesAndValuesForAttribute(Map<String, Map<String, String>> layoutAttributes, String name, Builder<String, String> result) {
        if (layoutAttributes == null) {
            return;
        }
       
        for (Map.Entry<String, Map<String, String>> layoutNodeAttributesEntry : layoutAttributes.entrySet()) {
            //name, value
            final Map<String, String> layoutNodeAttribute = layoutNodeAttributesEntry.getValue();
            final String value = layoutNodeAttribute.get(name);
            if (value != null) {
                final String nodeId = layoutNodeAttributesEntry.getKey();
                result.put(nodeId, value);
            }
        }
    }
   
    @Override
    public <P extends Populator<String, String>> P populateLayoutAttributes(HttpServletRequest request,
            PreferencesScope prefScope, String nodeId, P layoutAttributes) {
        final StylesheetPreferencesKey stylesheetPreferencesKey = this.getStylesheetPreferencesKey(request, prefScope);
        final IStylesheetDescriptor stylesheetDescriptor = stylesheetPreferencesKey.stylesheetDescriptor;
       
        //Get the scoped sources once
        final IStylesheetUserPreferences stylesheetUserPreferences = this.getStylesheetUserPreferences(request, stylesheetPreferencesKey);
        final Map<String, Map<String, String>> sessionLayoutAttributes;
        final HttpSession session = request.getSession(false);
        if (session == null) {
            sessionLayoutAttributes = null;
        }
        else {
            sessionLayoutAttributes = getSessionLayoutAttributes(session, stylesheetPreferencesKey);
        }
        final Map<String, Map<String, String>> requestLayoutAttributes = getRequestLayoutAttributes(request, stylesheetPreferencesKey);
       
        final IStylesheetUserPreferences distributedStylesheetUserPreferences = this.getDistributedStylesheetUserPreferences(request, prefScope);
        if (distributedStylesheetUserPreferences != null) {
            distributedStylesheetUserPreferences.populateLayoutAttributes(nodeId, layoutAttributes);
        }
       
        //Try getting each layout attribute to populate the Map
        for (final ILayoutAttributeDescriptor layoutAttributeDescriptor : stylesheetDescriptor.getLayoutAttributeDescriptors()) {
            final String name = layoutAttributeDescriptor.getName();

            String value;
            final Scope scope = layoutAttributeDescriptor.getScope();
            switch (scope) {
                case PERSISTENT: {
                    if (stylesheetUserPreferences == null) {
                        value = null;
                        break;
                    }
                   
                    value = stylesheetUserPreferences.getLayoutAttribute(nodeId, name);
                    break;
                }
                case SESSION: {
                    if (sessionLayoutAttributes == null) {
                        value = null;
                        break;
                    }

                    final Map<String, String> nodeAttributes = sessionLayoutAttributes.get(nodeId);
                    if (nodeAttributes == null) {
                        value = null;
                        break;
                    }
                   
                    value = nodeAttributes.get(name);
                    break;
                }
                case REQUEST: {
                    if (requestLayoutAttributes == null) {
                        value = null;
                        break;
                    }
                   
                    final Map<String, String> nodeAttributes = requestLayoutAttributes.get(nodeId);
                    if (nodeAttributes == null) {
                        value = null;
                        break;
                    }
                   
                    value = nodeAttributes.get(name);
                    break;
                }
                default: {
                    value = null;
                    break;
                }
            }
           
            //Don't add unset properties
            if (value == null) {
                continue;
            }
           
            //If the value is equal to the default value remove the property and return null
            if (this.compareValues(value, layoutAttributeDescriptor.getDefaultValue())) {
                this.removeLayoutAttribute(request, prefScope, nodeId, name);
                continue;
            }
           
            layoutAttributes.put(name, value);
        }
       
        return layoutAttributes;
    }

    @Transactional
    @Override
    public void clearLayoutAttributes(HttpServletRequest request, PreferencesScope prefScope, String nodeId) {
        final StylesheetPreferencesKey stylesheetPreferencesKey = this.getStylesheetPreferencesKey(request, prefScope);
       
        final IStylesheetUserPreferences stylesheetUserPreferences = this.getStylesheetUserPreferences(request, stylesheetPreferencesKey);
        if (stylesheetUserPreferences != null) {
            stylesheetUserPreferences.clearLayoutAttributes(nodeId);
            this.stylesheetUserPreferencesDao.storeStylesheetUserPreferences(stylesheetUserPreferences);
        }
       
        final HttpSession session = request.getSession(false);
        if (session != null) {
            final Map<String, Map<String, String>> sessionLayoutAttributes = getSessionLayoutAttributes(session, stylesheetPreferencesKey);
            if (sessionLayoutAttributes != null) {
                sessionLayoutAttributes.remove(nodeId);
            }
           
        }

        final Map<String, Map<String, String>> requestLayoutAttributes = getRequestLayoutAttributes(request, stylesheetPreferencesKey);
        if (requestLayoutAttributes != null) {
            requestLayoutAttributes.remove(nodeId);
        }
    }

    @Transactional
    @Override
    public void clearAllLayoutAttributes(HttpServletRequest request, PreferencesScope prefScope) {
        final StylesheetPreferencesKey stylesheetPreferencesKey = this.getStylesheetPreferencesKey(request, prefScope);
       
        final IStylesheetUserPreferences stylesheetUserPreferences = this.getStylesheetUserPreferences(request, stylesheetPreferencesKey);
        if (stylesheetUserPreferences != null) {
            stylesheetUserPreferences.clearAllLayoutAttributes();
            this.stylesheetUserPreferencesDao.storeStylesheetUserPreferences(stylesheetUserPreferences);
        }
       
        final HttpSession session = request.getSession(false);
        if (session != null) {
            session.removeAttribute(LAYOUT_ATTRIBUTES_KEY + stylesheetPreferencesKey.toString());
        }
       
        request.removeAttribute(LAYOUT_ATTRIBUTES_KEY + stylesheetPreferencesKey.toString());
    }
}
TOP

Related Classes of org.jasig.portal.layout.StylesheetUserPreferencesServiceImpl$StylesheetPreferencesKey

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.