org.rhq.enterprise.server.auth.prefs.SubjectPreferencesCacheBean.java Source code

Java tutorial

Introduction

Here is the source code for org.rhq.enterprise.server.auth.prefs.SubjectPreferencesCacheBean.java

Source

/*
 * RHQ Management Platform
 * Copyright (C) 2005-2012 Red Hat, Inc.
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
package org.rhq.enterprise.server.auth.prefs;

import java.util.HashMap;
import java.util.Map;

import javax.ejb.ConcurrencyManagement;
import javax.ejb.ConcurrencyManagementType;
import javax.ejb.EJB;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.Singleton;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.common.EntityManagerFacadeLocal;
import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal;

@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
@Singleton
@TransactionAttribute(TransactionAttributeType.SUPPORTS)
public class SubjectPreferencesCacheBean implements SubjectPreferencesCacheLocal {

    protected final Log log = LogFactory.getLog(SubjectPreferencesCacheBean.class);

    private Map<Integer, Configuration> subjectPreferences;

    @EJB
    private SubjectManagerLocal subjectManager;

    @EJB
    private EntityManagerFacadeLocal entityManagerFacade;

    @EJB
    private ConfigurationManagerLocal configurationManager;

    public SubjectPreferencesCacheBean() {
        subjectPreferences = new HashMap<Integer, Configuration>();
    }

    private void load(int subjectId) {
        // if subject ID is 0, it probably means this is a new LDAP user that needs to be registered
        if (subjectId != 0 && !subjectPreferences.containsKey(subjectId)) {
            try {
                Subject subject = subjectManager.loadUserConfiguration(subjectId);
                Configuration configuration = subject.getUserConfiguration();
                subjectPreferences.put(subjectId, configuration);
            } catch (Throwable t) {
                log.warn("Can not get preferences for subject[id=" + subjectId + "], subject does not exist yet");
            }
        }
    }

    @Override
    @Lock(LockType.READ)
    public PropertySimple getUserProperty(int subjectId, String propertyName) {
        load(subjectId);

        Configuration config = subjectPreferences.get(subjectId);
        if (config == null) {
            return null;
        }

        PropertySimple prop = config.getSimple(propertyName);
        if (prop == null) {
            return null;
        }

        return new PropertySimple(propertyName, prop.getStringValue());
    }

    @Override
    @Lock(LockType.WRITE)
    public void setUserProperty(int subjectId, String propertyName, String value) {
        load(subjectId);

        Configuration config = subjectPreferences.get(subjectId);
        if (config == null) {
            return;
        }

        PropertySimple prop = config.getSimple(propertyName);
        if (prop == null) {
            prop = new PropertySimple(propertyName, value);
            config.put(prop); // add new to collection
            mergeProperty(prop);
        } else if (prop.getStringValue() == null || !prop.getStringValue().equals(value)) {
            prop.setStringValue(value);
            mergeProperty(prop);
        }
    }

    private void mergeProperty(PropertySimple prop) {
        // merge will persist if property doesn't exist (i.e., id = 0)
        PropertySimple mergedProperty = entityManagerFacade.merge(prop); // only merge changes
        if (prop.getId() == 0) {
            // so subsequent merges do not continue re-persisting property as new
            prop.setId(mergedProperty.getId());
        }
    }

    @Override
    @Lock(LockType.WRITE)
    public void unsetUserProperty(int subjectId, String propertyName) {
        load(subjectId);

        Configuration config = subjectPreferences.get(subjectId);
        if (config == null) {
            return;
        }

        Property property = config.remove(propertyName);
        // it's possible property was already removed, and thus this operation becomes a no-op to the backing store
        if (property != null && property.getId() != 0) {
            try {
                configurationManager.deleteProperties(new int[] { property.getId() });
            } catch (Throwable t) {
                log.error("Could not remove " + property, t);
            }
        }
    }

    /**
     * @param subjectId the subject to get preferences of
     * @return the <b>COPY</b> of the configuration object - changes done to that instance will not be reflected in the persisted
     * preferences
     */
    @Override
    @Lock(LockType.READ)
    public Configuration getPreferences(int subjectId) {
        load(subjectId);

        Configuration config = subjectPreferences.get(subjectId);
        if (config == null) {
            return new Configuration();
        } else {
            return config.deepCopy();
        }
    }

    @Override
    @Lock(LockType.WRITE)
    public void clearConfiguration(int subjectId) {
        if (log.isTraceEnabled()) {
            log.trace("Removing PreferencesCache For " + subjectId);
        }
        subjectPreferences.remove(subjectId);
    }
}