Package er.corebusinesslogic

Source Code of er.corebusinesslogic.ERCoreUserPreferences

/*
* Copyright (C) NetStruxr, Inc. All rights reserved.
*
* This software is published under the terms of the NetStruxr
* Public Software License version 0.5, a copy of which has been
* included with this distribution in the LICENSE.NPL file.  */
package er.corebusinesslogic;

import java.util.Enumeration;

import org.apache.commons.lang.ObjectUtils;
import org.apache.log4j.Logger;

import com.webobjects.eocontrol.EOEditingContext;
import com.webobjects.eocontrol.EOEnterpriseObject;
import com.webobjects.eocontrol.EOKeyValueArchiver;
import com.webobjects.eocontrol.EOKeyValueUnarchiver;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSForwardException;
import com.webobjects.foundation.NSKeyValueCoding;
import com.webobjects.foundation.NSNotification;
import com.webobjects.foundation.NSNotificationCenter;
import com.webobjects.foundation.NSPropertyListSerialization;
import com.webobjects.foundation.NSSelector;

import er.extensions.batching.ERXBatchNavigationBar;
import er.extensions.components.ERXSortOrder;
import er.extensions.eof.ERXConstant;
import er.extensions.eof.ERXEC;
import er.extensions.eof.ERXEOControlUtilities;
import er.extensions.foundation.ERXProperties;
import er.extensions.foundation.ERXRetainer;
import er.extensions.foundation.ERXValueUtilities;

/**
*
* @property er.corebusinesslogic.ERCoreUserPreferences.handlerClassName
*/
public class ERCoreUserPreferences implements NSKeyValueCoding {

    //  ===========================================================================
    //  Class Constant(s)
    //  ---------------------------------------------------------------------------   
   
    /** Logging support */
    public static final Logger log = Logger.getLogger(ERCoreUserPreferences.class);

    /** EOEncoding key */
    private final static String VALUE="_V";

    /** Notification that is posted when preferences change */
    public final static String PreferenceDidChangeNotification = "PreferenceChangedNotification";

    //  ===========================================================================
    //  Class Variable(s)
    //  ---------------------------------------------------------------------------   

    /** caches the singleton user preference object */
    private static ERCoreUserPreferences _userPreferences;

    //  ===========================================================================
    //  Class Method(s)
    //  ---------------------------------------------------------------------------

    /**
     * Gets the singleton instance for interacting with
     * the user preference system.
     * @return single instance of the user preferences
     */
    public static ERCoreUserPreferences userPreferences() {
        if (_userPreferences == null) {
          _userPreferences = new ERCoreUserPreferences();
        }
        return _userPreferences;
    }
   
    //  ===========================================================================
    //  Instance Method(s)
    //  ---------------------------------------------------------------------------   

    /**
     * Registers notification handlers for user preference notifications. These
     * are mainly used within the context of D2W pages.
     */
    public void registerHandlers() {
        log.debug("Registering preference handlers");
        Object handler = null;
        String handlerClassName = ERXProperties.stringForKey("er.corebusinesslogic.ERCoreUserPreferences.handlerClassName");
        if (handlerClassName != null) {
          try {
            handler = Class.forName(handlerClassName).newInstance();
          }
          catch (Exception e) {
            throw NSForwardException._runtimeExceptionForThrowable(e);
          }
        }
        if (handler == null) {
          handler = new _UserPreferenceHandler();
        }
        ERXRetainer.retain(handler);       
    }
   
    protected NSArray preferences(EOEditingContext ec) {
        ERCoreUserInterface user = (ERCoreUserInterface)ERCoreBusinessLogic.actor(ec);
        return user!=null ? user.preferences() : NSArray.EmptyArray;
    }

    protected EOEnterpriseObject preferenceRecordForKey(String key, EOEditingContext ec) {
        EOEnterpriseObject result=null;
        if (key != null) {
            if (log.isDebugEnabled())
                log.debug("Preference value for Key = "+key);
            for (Enumeration e = preferences(ec).objectEnumerator(); e.hasMoreElements();) {
                EOEnterpriseObject pref = (EOEnterpriseObject)e.nextElement();
                String prefKey = (String)pref.valueForKey("key");
                if (log.isDebugEnabled()) {
                    log.debug("prefKey \"" + prefKey + "\"");  
                }
                if (prefKey != null && prefKey.equals(key)) {
                    result = pref;
                    break;
                }
            }
        }
        return result;
    }

    protected String encodedValue(Object value) {
        EOKeyValueArchiver archiver = new EOKeyValueArchiver();
        archiver.encodeObject(value,VALUE);
        String encodedValue = NSPropertyListSerialization.stringFromPropertyList(archiver.dictionary());
        return encodedValue;
    }

    protected Object decodedValue(String encodedValue) {
        NSDictionary d = (NSDictionary )NSPropertyListSerialization.propertyListFromString(encodedValue);
        EOKeyValueUnarchiver u = new EOKeyValueUnarchiver(d);
        return u.decodeObjectForKey(VALUE);
    }   
   
    //  ===========================================================================
    //  Implementation of NSKeyValueCoding
    //  ---------------------------------------------------------------------------   
   
    // FIXME -- unarchiving - archiving probably could use optimization
    public Object valueForKey(String key) {
        Object result=null;
        EOEditingContext ec = ERXEC.newEditingContext();
        ec.lock();
        try {
            EOEnterpriseObject pref = preferenceRecordForKey(key, ec);
            if (pref != null) {
                String encodedValue = (String)pref.valueForKey("value");
                if(encodedValue !=null) {
                    result = decodedValue(encodedValue);
                }
            }
        } catch(RuntimeException ex) {
          log.error("Error while getting preference " + key +  ": " + ex);
        } finally {
            ec.unlock();
        }
        ec.dispose();
        if (log.isDebugEnabled())
            log.debug("Prefs vfk " + key + " = " + result);
        return result;
    }

    public void takeValueForKey(Object value, String key) {
        // we first make sure there is no cruft left
        // !! locking is turned off on the value attribute of UserPreference
        // so that if a user opens two sessions they don't get locking failures
        // this is OK for display style prefs (how many items, how they are sorted)
        // but might not be for more behavior-style prefs!!
        EOEditingContext ec = ERXEC.newEditingContext();
        ec.lock();
        try {
            EOEnterpriseObject pref = preferenceRecordForKey(key, ec);
            ERCoreUserInterface u = (ERCoreUserInterface)ERCoreBusinessLogic.actor(ec);
            if (pref != null) {
                if (value != null) {
                    String encodedValue = encodedValue(value);
                    if (ObjectUtils.notEqual(encodedValue, pref.valueForKey("value"))) {
                        if (log.isDebugEnabled())
                            log.debug("Updating preference "+u+": "+key+"="+encodedValue);
                        pref.takeValueForKey(encodedValue,"value");
                    }
                } else {
                    if (log.isDebugEnabled())
                        log.debug("Removing preference "+u+": "+key);
                    ec.deleteObject(pref);
                }
            } else if (value!=null) {
                pref = ERXEOControlUtilities.createAndInsertObject(ec, "ERCPreference");
                u.newPreference(pref);
                // done this way to not force you to sub-class our User entity
                pref.takeValueForKey(ERXEOControlUtilities.primaryKeyObjectForObject((EOEnterpriseObject)u),"userID");
                pref.takeValueForKey(key,"key");
                pref.takeValueForKey(encodedValue(value),"value");
                if (log.isDebugEnabled())
                    log.debug("Creating preference "+u+": "+key+" - "+value+" -- "+encodedValue(value));
            }
            if (ec.hasChanges()) {
                ec.saveChanges();
            }
        } catch(RuntimeException ex) {
          log.error("Error while setting preference " + key +  ": " + ex);
        } finally {
            ec.unlock();
        }
        ec.dispose();
        NSNotificationCenter.defaultCenter().postNotification(PreferenceDidChangeNotification,
                                                              new NSDictionary(value, key));
    }

    public boolean booleanValueForKey(String key) {
        return booleanValueForKeyWithDefault(key, false);
    }

    public boolean booleanValueForKeyWithDefault(String key, boolean def) {
        return ERXValueUtilities.booleanValueWithDefault(valueForKey(key), def);
    }

    public static class _UserPreferenceHandler {
        public _UserPreferenceHandler() {
            NSNotificationCenter.defaultCenter().addObserver(this, new NSSelector("handleBatchSizeChange", ERXConstant.NotificationClassArray), ERXBatchNavigationBar.BatchSizeChanged, null);
            NSNotificationCenter.defaultCenter().addObserver(this, new NSSelector("handleSortOrderingChange", ERXConstant.NotificationClassArray), ERXSortOrder.SortOrderingChanged, null);
        }
     
        public void handleBatchSizeChange(NSNotification n) { handleChange("batchSize", n); }
        public void handleSortOrderingChange(NSNotification n) { handleChange("sortOrdering", n); }

        public void handleChange(String prefName, NSNotification n) {
            if (ERCoreBusinessLogic.actor() != null) {
                NSKeyValueCoding context=(NSKeyValueCoding)n.userInfo().objectForKey("d2wContext");
                if (context!=null && context.valueForKey("pageConfiguration") != null) {
                    userPreferences().takeValueForKey(n.object(),
                                                      prefName+"."+(String)context.valueForKey("pageConfiguration"));
                }
            }
        }
    }
}
TOP

Related Classes of er.corebusinesslogic.ERCoreUserPreferences

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.