`

Preferences -- PreferenceValue example

阅读更多
package org.jboss.seam.wiki.core.preferences;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.*;
import org.jboss.seam.log.Log;
import org.jboss.seam.wiki.core.model.User;
import org.jboss.seam.wiki.core.plugin.WikiPluginMacro;
import org.jboss.seam.wiki.preferences.PreferenceProvider;
import org.jboss.seam.wiki.preferences.PreferenceValue;
import org.jboss.seam.wiki.preferences.PreferenceVisibility;
import org.jboss.seam.wiki.preferences.metamodel.PreferenceEntity;
import org.jboss.seam.wiki.preferences.metamodel.PreferenceRegistry;

import javax.persistence.EntityManager;
import java.io.Serializable;
import java.util.*;

/**
 * Implementation for the wiki, loads and stores <tt>WikiPreferenceValue</tt> objects.
 * <p>
 * This implementation tries to be as smart as possible and supports multi-level preference value overrides.
 * If you load values, they are automatically resolved for system, user, and instance levels. If a value is
 * present at system level but you want values for users, this implementation creates and returns those
 * missing values. It will also persist them if you call <tt>store()</tt> and <tt>flush()</tt>.
 * </p>
 * <p>
 * System and user-level values are loaded and stored in the database with the <tt>entityManager</tt>
 * persistence context. be careful to only flush it if you want to after you retrieved and modified
 * values with this provider.
 * </p>
 * <p>
 * Instance-level values are not stored in the database, they are marshalled by converting <tt>WikiMacro</tt>
 * (the instance this provider understands) parameters.
 * </p>
 *
 * @author Christian Bauer
 */
@Name("preferenceProvider")
@AutoCreate
@Scope(ScopeType.CONVERSATION)
public class WikiPreferenceProvider implements PreferenceProvider<User, WikiPluginMacro>, Serializable {

    @Logger Log log;

    @In
    EntityManager entityManager;

    @In
    PreferenceRegistry preferenceRegistry;

    // Queue in current conversation until flush()
    List<PreferenceValue> newValueHolders = new ArrayList<PreferenceValue>();

    public Set<PreferenceValue> loadValues(String preferenceEntityName,
                                           User user, WikiPluginMacro instance,
                                           List<PreferenceVisibility> visibilities) {

        log.debug("assembling preference values for '"
                    + preferenceEntityName
                    + "' and user '" + user
                    + "' and wiki macro ' " + instance + "'");

        PreferenceEntity entity = preferenceRegistry.getPreferenceEntitiesByName().get(preferenceEntityName);
        SortedSet<PreferenceValue> valueHolders = new TreeSet<PreferenceValue>();

        Set<PreferenceValue> systemValueHolders = null;
        if (visibilities.contains(PreferenceVisibility.SYSTEM)) {
            log.trace("retrieving SYSTEM preference values from database");

            systemValueHolders = loadSystemValues(preferenceEntityName);

            // Check if all SYSTEM-level properties were present in the database
            for (PreferenceEntity.Property systemVisibleProperty : entity.getPropertiesSystemVisible()) {
                WikiPreferenceValue newValueHolder = new WikiPreferenceValue(systemVisibleProperty);
                // If not, queue a new value holder (with a null "value") for that property and return it
                if (!systemValueHolders.contains(newValueHolder)) {
                    systemValueHolders.add(newValueHolder);
                    newValueHolders.add(newValueHolder);
                }
            }
            valueHolders.addAll(systemValueHolders);
        }

        Set<PreferenceValue> userValueHolders;
        if (visibilities.contains(PreferenceVisibility.USER)) {
            if (user == null)
                throw new IllegalArgumentException("can't load preferences for null user");
            log.trace("retrieving USER preference values from database");

            userValueHolders = loadUserValues(preferenceEntityName, user);

            // We need them when we iterate through missing properties next
            if (systemValueHolders == null) systemValueHolders = loadSystemValues(preferenceEntityName);

            // Check if all USER-level properties were present in the database
            for (PreferenceEntity.Property userVisibleProperty : entity.getPropertiesUserVisible()) {
                WikiPreferenceValue newValueHolder = new WikiPreferenceValue(userVisibleProperty);

                // If not, queue a new value for that property and return it
                if (!userValueHolders.contains(newValueHolder)) {
                    log.trace("creating new preference value for user, missing in database " + userVisibleProperty);
                    userValueHolders.add(newValueHolder);
                    newValueHolders.add(newValueHolder);

                    newValueHolder.setUser(user);

                    // We need a "value" for that property, let's check if we have a SYSTEM-level property we can take it from
                    if (userVisibleProperty.getVisibility().contains(PreferenceVisibility.SYSTEM) &&
                        systemValueHolders != null && systemValueHolders.contains(newValueHolder)) {
                        for (PreferenceValue systemValue : systemValueHolders) {
                            if (systemValue.equals(newValueHolder)) {
                                log.trace("taking the initial value from the SYSTEM-level setting");
                                newValueHolder.setValue(systemValue.getValue());
                                newValueHolder.setDirty(false); // New value isn't dirty, by definition
                            }
                        }
                    }
                    // If we don't have a value, well, then it's null (this is a property with USER and no SYSTEM visibility)
                }
            }

            // Override SYSTEM values
            valueHolders.removeAll(userValueHolders);
            valueHolders.addAll(userValueHolders);
        }

        if (visibilities.contains(PreferenceVisibility.INSTANCE)) {
            if (instance == null)
                throw new IllegalArgumentException("can't load preferences for null WikiMacro instance");
            log.trace("extracting INSTANCE preference values from " + instance);
            Set<PreferenceValue> instanceValues = loadInstanceValues(preferenceEntityName, instance);
            // Override SYSTEM and USER values
            valueHolders.removeAll(instanceValues);
            valueHolders.addAll(instanceValues);
        }

        return valueHolders;
    }

    public void storeValues(Set<PreferenceValue> valueHolders, User user, WikiPluginMacro instance) {
        // TODO: We don't care about the arguments, maybe instance later on when we marshall stuff into WikiMacro params

        // The new ones need to be checked if they are dirty and manually persisted
        for (PreferenceValue newPreferenceValue : newValueHolders) {
            if (newPreferenceValue.isDirty()) {
                log.debug("storing new preference value " + newPreferenceValue);
                entityManager.persist(newPreferenceValue);
            }
        }

        // The old ones are automatically checked for dirty state by Hibernate

    }

    public void deleteUserPreferenceValues(User user) {
        log.debug("deleting preferences of user: " + user);
        List<WikiPreferenceValue> values =
            entityManager.createQuery(
                            "select wp from WikiPreferenceValue wp" +
                            " where wp.user = :user"
                          ).setParameter("user", user)
                           .getResultList();
        for (WikiPreferenceValue value : values) {
            entityManager.remove(value);
        }
    }

    public void flush() {
        log.debug("flushing preference provider");
        entityManager.flush();

        // Reset queue
        newValueHolders = new ArrayList<PreferenceValue>();
    }


    /* ######################################### IMPLEMENTATION DETAILS ######################################### */

    private Set<PreferenceValue> loadSystemValues(String entityName) {
        List<WikiPreferenceValue> values =
            entityManager.createQuery(
                            "select wp from WikiPreferenceValue wp" +
                            " where wp.entityName = :name and wp.user is null"
                          ).setParameter("name", entityName)
                           .setHint("org.hibernate.cacheable", true)
                           .getResultList();
        setPropertyReferences(values, entityName, PreferenceVisibility.SYSTEM);
        return new HashSet(values);
    }

    private Set<PreferenceValue> loadUserValues(String entityName, User user) {
        if (user.getId() == null) return Collections.EMPTY_SET;
        List<WikiPreferenceValue> values =
            entityManager.createQuery(
                            "select wp from WikiPreferenceValue wp" +
                            " where wp.entityName = :name and wp.user = :user"
                          ).setParameter("name", entityName)
                           .setParameter("user", user)
                           .setHint("org.hibernate.cacheable", true)
                           .getResultList();
        setPropertyReferences(values, entityName, PreferenceVisibility.USER);
        return new HashSet(values);
    }

    private Set<PreferenceValue> loadInstanceValues(String entityName, WikiPluginMacro instance) {
        Set<PreferenceValue> valueHolders = new HashSet<PreferenceValue>();
        PreferenceEntity preferenceEntity = preferenceRegistry.getPreferenceEntitiesByName().get(entityName);
        for (Map.Entry<String, String> entry : instance.getParams().entrySet()) {
            log.trace("converting WikiMacro parameter into WikiPreferenceValue: " + entry.getKey());

            // TODO: Maybe we should log the following as DEBUG level, these occur when the user edits macro parameters

            PreferenceEntity.Property property = preferenceEntity.getPropertiesByName().get(entry.getKey());
            if (property == null) {
                log.info("can't convert unknown property as WikiMacro parameter: " + entry.getKey());
                continue;
            }
            if (!property.getVisibility().contains(PreferenceVisibility.INSTANCE)) {
                log.info("can't convert WikiMacro parameter, not overridable at INSTANCE level: " + entry.getKey());
                continue;
            }
            if (!instance.getMetadata().getParameters().contains(property)) {
                log.info("can't convert WikiMacro parameter, property is not configured: " + entry.getKey());
                continue;
            }
            WikiPreferenceValue value = new WikiPreferenceValue(property, entry.getValue());
            if (value.getValue() != null) {
                log.trace("converted WikiMacro parameter value into WikiPreferenceValue: " + value.getValue());
                valueHolders.add(value);
            } else {
                log.info("could not convert WikiMacro parameter value into WikiPreferenceValue: " + entry.getKey());
            }
        }
        return valueHolders;
    }

    private void setPropertyReferences(List<WikiPreferenceValue> valueHolders, String entityName, PreferenceVisibility visibility) {
        Iterator<WikiPreferenceValue> it = valueHolders.iterator();
        while (it.hasNext()) {
            WikiPreferenceValue wikiPreferenceValue = it.next();
            if (!setPropertyReference(wikiPreferenceValue, entityName, visibility)) {
                 it.remove(); // Kick out the value if we couldn't set a reference to the metamodel property
            }
        }
    }

    private boolean setPropertyReference(WikiPreferenceValue value, String entityName, PreferenceVisibility visibility) {
        PreferenceEntity entity = preferenceRegistry.getPreferenceEntitiesByName().get(entityName);
        if (entity == null) {
            log.warn("orphaned preference value found in database, please clean up: " + value);
            return false;
        }
        PreferenceEntity.Property property = entity.getPropertiesByName().get(value.getPropertyName());
        if (property == null) {
            log.warn("orphaned preference value found in database, please clean up: " + value);
            return false;
        }
        if (!property.getVisibility().contains(visibility)) {
            log.warn("database visibility " + visibility  + " is not allowed by property, please clean up: " + value);
            return false;
        }
        value.setPreferenceProperty(property);
        return true;
    }


}

分享到:
评论

相关推荐

    BURNINTEST--硬件检测工具

    number of Network Addresses specified in Preferences-&gt;Network will be the number of NICs tested. This will error faulty NICs that are not detected by the BurnInTest auto NIC detection mechanism. ...

    Mahout in Action

    similarity with a log-likelihood test 55 ■ Inferring preferences 56 4.4 Item-based recommendation 56 The algorithm 57 ■ Exploring the item-based recommender 58 4.5 Slope-one recommender 59 The ...

    plsqldev12.0.6.1832x32主程序+ v12中文包+keygen

    A new preference has been added: "Null value cell color for mandatory columns". This allows you to quickly identify mandatory columns when adding new records: The result set selection can now be ...

    plsqldev12.0.6.1832x64主程序+ v12中文包+keygen

    A new preference has been added: "Null value cell color for mandatory columns". This allows you to quickly identify mandatory columns when adding new records: The result set selection can now be ...

    数位板压力测试

    5.9. Manager Preference Data Functions 31 5.9.1. WTMgrExt 31 5.9.2. WTMgrCsrEnable 32 5.9.3. WTMgrCsrButtonMap 32 5.9.4. WTMgrCsrPressureBtnMarks (16-bit only) 33 5.9.5. WTMgrCsrPressureBtnMarksEx 33 ...

    PLSQL.Developer(X32) v12.0.1.1814主程序+ v11中文包+keygen

    A new preference has been added: "Null value cell color for mandatory columns". This allows you to quickly identify mandatory columns when adding new records: The result set selection can now be ...

    plsqldev12.0.4.1826x32主程序+ v12中文包+keygen

    A new preference has been added: "Null value cell color for mandatory columns". This allows you to quickly identify mandatory columns when adding new records: The result set selection can now be ...

    PLSQL.Developer(X64) v12.0.1.1814 主程序+ v11中文包+keygen

    A new preference has been added: "Null value cell color for mandatory columns". This allows you to quickly identify mandatory columns when adding new records: The result set selection can now be ...

    plsqldev12.0.4.1826x64主程序+ v12中文包+keygen

    A new preference has been added: "Null value cell color for mandatory columns". This allows you to quickly identify mandatory columns when adding new records: The result set selection can now be ...

    PLSQL.Developer v11.0.0.1762 主程序+ v10中文包+keygen

    The following preferences options have been added: Files/Format/Encoding: Save with BOM (Unicode Byte Order Mark) User Interface/Options: Maximum recent files User Interface/Code Assistant: Align ...

Global site tag (gtag.js) - Google Analytics