You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			686 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			686 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| //------------------------------------------------------------------------------
 | |
| // <copyright file="WebPartPersonalization.cs" company="Microsoft">
 | |
| //     Copyright (c) Microsoft Corporation.  All rights reserved.
 | |
| // </copyright>
 | |
| //------------------------------------------------------------------------------
 | |
| 
 | |
| namespace System.Web.UI.WebControls.WebParts {
 | |
| 
 | |
|     using System;
 | |
|     using System.Collections;
 | |
|     using System.Collections.Specialized;
 | |
|     using System.ComponentModel;
 | |
|     using System.Configuration;
 | |
|     using System.Configuration.Provider;
 | |
|     using System.Security.Principal;
 | |
|     using System.Web;
 | |
|     using System.Web.Configuration;
 | |
|     using System.Web.UI;
 | |
|     using System.Web.Util;
 | |
|     using System.Web.Hosting;
 | |
| 
 | |
|     [TypeConverterAttribute(typeof(EmptyStringExpandableObjectConverter))]
 | |
|     public class WebPartPersonalization {
 | |
| 
 | |
|         public static readonly WebPartUserCapability ModifyStateUserCapability = new WebPartUserCapability("modifyState");
 | |
|         public static readonly WebPartUserCapability EnterSharedScopeUserCapability = new WebPartUserCapability("enterSharedScope");
 | |
| 
 | |
|         private WebPartManager _owner;
 | |
| 
 | |
|         // Properties
 | |
|         private bool _enabled;
 | |
|         private string _providerName;
 | |
|         private PersonalizationScope _initialScope;
 | |
| 
 | |
|         // Computed state
 | |
|         private bool _initialized;
 | |
|         private bool _initializedSet;
 | |
|         private PersonalizationProvider _provider;
 | |
|         private PersonalizationScope _currentScope;
 | |
|         private IDictionary _userCapabilities;
 | |
|         private PersonalizationState _personalizationState;
 | |
|         private bool _scopeToggled;
 | |
|         private bool _shouldResetPersonalizationState;
 | |
| 
 | |
|         /// <devdoc>
 | |
|         /// </devdoc>
 | |
|         public WebPartPersonalization(WebPartManager owner) {
 | |
|             if (owner == null) {
 | |
|                 throw new ArgumentNullException("owner");
 | |
|             }
 | |
| 
 | |
|             _owner = owner;
 | |
| 
 | |
|             _enabled = true;
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         /// Indicates whether the current user has the permissions to switch
 | |
|         /// into shared personalization scope.
 | |
|         /// </devdoc>
 | |
|         [
 | |
|         Browsable(false),
 | |
|         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
 | |
|         ]
 | |
|         public bool CanEnterSharedScope {
 | |
|             get {
 | |
|                 // We cannot cache this value, since UserCapabilities is protected virtual,
 | |
|                 // and could return a different value at any time
 | |
|                 IDictionary userCapabilities = UserCapabilities;
 | |
|                 bool canEnterSharedScope = (userCapabilities != null) &&
 | |
|                     (userCapabilities.Contains(WebPartPersonalization.EnterSharedScopeUserCapability));
 | |
|                 return canEnterSharedScope;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         /// </devdoc>
 | |
|         [
 | |
|         DefaultValue(true),
 | |
|         NotifyParentProperty(true),
 | |
|         WebSysDescription(SR.WebPartPersonalization_Enabled)
 | |
|         ]
 | |
|         public virtual bool Enabled {
 | |
|             get {
 | |
|                 return _enabled;
 | |
|             }
 | |
|             set {
 | |
|                 if (!WebPartManager.DesignMode && _initializedSet && (value != Enabled)) {
 | |
|                     throw new InvalidOperationException(
 | |
|                         SR.GetString(SR.WebPartPersonalization_MustSetBeforeInit, "Enabled", "WebPartPersonalization"));
 | |
|                 }
 | |
| 
 | |
|                 _enabled = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // Returns true if the current user in the current scope on the current page has personalization data
 | |
|         [
 | |
|         Browsable(false),
 | |
|         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
 | |
|         ]
 | |
|         public virtual bool HasPersonalizationState {
 | |
|             get {
 | |
|                 if (_provider == null) {
 | |
|                     throw new InvalidOperationException(SR.GetString(SR.WebPartPersonalization_CantUsePropertyBeforeInit,
 | |
|                                                         "HasPersonalizationState", "WebPartPersonalization"));
 | |
|                 }
 | |
| 
 | |
|                 Page page = WebPartManager.Page;
 | |
|                 if (page == null) {
 | |
|                     throw new InvalidOperationException(SR.GetString(SR.PropertyCannotBeNull, "WebPartManager.Page"));
 | |
|                 }
 | |
| 
 | |
|                 HttpRequest request = page.RequestInternal;
 | |
|                 if (request == null) {
 | |
|                     throw new InvalidOperationException(SR.GetString(SR.PropertyCannotBeNull, "WebPartManager.Page.Request"));
 | |
|                 }
 | |
| 
 | |
|                 PersonalizationStateQuery query = new PersonalizationStateQuery();
 | |
|                 query.PathToMatch = request.AppRelativeCurrentExecutionFilePath;
 | |
|                 if (Scope == PersonalizationScope.User && request.IsAuthenticated) {
 | |
|                     query.UsernameToMatch = page.User.Identity.Name;
 | |
|                 }
 | |
| 
 | |
|                 return (_provider.GetCountOfState(Scope, query) > 0);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         /// Allows changing the initial personalization scope that is given
 | |
|         /// preference when requesting the page on its first request.
 | |
|         /// This must be set before personalization data is loaded into the
 | |
|         /// WebPartManager.
 | |
|         /// </devdoc>
 | |
|         [
 | |
|         DefaultValue(PersonalizationScope.User),
 | |
|         NotifyParentProperty(true),
 | |
|         WebSysDescription(SR.WebPartPersonalization_InitialScope)
 | |
|         ]
 | |
|         public virtual PersonalizationScope InitialScope {
 | |
|             get {
 | |
|                 return _initialScope;
 | |
|             }
 | |
|             set {
 | |
|                 if ((value < PersonalizationScope.User) || (value > PersonalizationScope.Shared)) {
 | |
|                     throw new ArgumentOutOfRangeException("value");
 | |
|                 }
 | |
| 
 | |
|                 if (!WebPartManager.DesignMode && _initializedSet && (value != InitialScope)) {
 | |
|                     throw new InvalidOperationException(
 | |
|                         SR.GetString(SR.WebPartPersonalization_MustSetBeforeInit, "InitialScope", "WebPartPersonalization"));
 | |
|                 }
 | |
| 
 | |
|                 _initialScope = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         /// </devdoc>
 | |
|         [
 | |
|         Browsable(false),
 | |
|         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
 | |
|         ]
 | |
|         public bool IsEnabled {
 | |
|             get {
 | |
|                 return IsInitialized;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         /// Indicates whether personalization state has been loaded. Properties of this
 | |
|         /// object cannot be saved once this object is initialized.
 | |
|         /// </devdoc>
 | |
|         [
 | |
|         Browsable(false),
 | |
|         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
 | |
|         ]
 | |
|         protected bool IsInitialized {
 | |
|             get {
 | |
|                 return _initialized;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         /// Determines if personalization and the ability to modify personalization state is enabled
 | |
|         /// in the current request. This depends on whether a user is authenticated for this request,
 | |
|         /// and if that user has the rights to modify personalization state.
 | |
|         /// To check if just personalization is enabled at all, the IsEnabled property
 | |
|         /// should be used.
 | |
|         /// </devdoc>
 | |
|         [
 | |
|         Browsable(false),
 | |
|         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
 | |
|         ]
 | |
|         public bool IsModifiable {
 | |
|             get {
 | |
|                 // We cannot cache this value, since UserCapabilities is protected virtual,
 | |
|                 // and could return a different value at any time
 | |
|                 IDictionary userCapabilities = UserCapabilities;
 | |
|                 bool isModifiable = (userCapabilities != null) &&
 | |
|                     (userCapabilities.Contains(WebPartPersonalization.ModifyStateUserCapability));
 | |
|                 return isModifiable;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         /// </devdoc>
 | |
|         [
 | |
|         DefaultValue(""),
 | |
|         NotifyParentProperty(true),
 | |
|         WebSysDescription(SR.WebPartPersonalization_ProviderName)
 | |
|         ]
 | |
|         public virtual string ProviderName {
 | |
|             get {
 | |
|                 return (_providerName != null) ? _providerName : String.Empty;
 | |
|             }
 | |
|             set {
 | |
|                 if (!WebPartManager.DesignMode && _initializedSet &&
 | |
|                     !String.Equals(value, ProviderName, StringComparison.Ordinal)) {
 | |
|                     throw new InvalidOperationException(
 | |
|                         SR.GetString(SR.WebPartPersonalization_MustSetBeforeInit, "ProviderName", "WebPartPersonalization"));
 | |
|                 }
 | |
| 
 | |
|                 _providerName = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [
 | |
|         Browsable(false),
 | |
|         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
 | |
|         ]
 | |
|         public PersonalizationScope Scope {
 | |
|             get {
 | |
|                 return _currentScope;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         internal bool ScopeToggled {
 | |
|             get {
 | |
|                 return _scopeToggled;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // True if the personalization data was reset this request.  If so, we will not save data
 | |
|         // at the end of the request.
 | |
|         protected bool ShouldResetPersonalizationState {
 | |
|             get {
 | |
|                 return _shouldResetPersonalizationState;
 | |
|             }
 | |
|             set {
 | |
|                 _shouldResetPersonalizationState = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         protected virtual IDictionary UserCapabilities {
 | |
|             get {
 | |
|                 if (_userCapabilities == null) {
 | |
|                     _userCapabilities = new HybridDictionary();
 | |
|                 }
 | |
|                 return _userCapabilities;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         protected WebPartManager WebPartManager {
 | |
|             get {
 | |
|                 return _owner;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         /// </devdoc>
 | |
|         protected internal virtual void ApplyPersonalizationState() {
 | |
|             if (IsEnabled) {
 | |
|                 EnsurePersonalizationState();
 | |
|                 _personalizationState.ApplyWebPartManagerPersonalization();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         /// </devdoc>
 | |
|         protected internal virtual void ApplyPersonalizationState(WebPart webPart) {
 | |
|             if (webPart == null) {
 | |
|                 throw new ArgumentNullException("webPart");
 | |
|             }
 | |
| 
 | |
|             if (IsEnabled) {
 | |
|                 EnsurePersonalizationState();
 | |
|                 _personalizationState.ApplyWebPartPersonalization(webPart);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // Helper method used by CopyPersonalizationState()
 | |
|         private void ApplyPersonalizationState(Control control, PersonalizationInfo info) {
 | |
|             ITrackingPersonalizable trackingPersonalizable = control as ITrackingPersonalizable;
 | |
|             IPersonalizable customPersonalizable = control as IPersonalizable;
 | |
| 
 | |
|             if (trackingPersonalizable != null) {
 | |
|                 trackingPersonalizable.BeginLoad();
 | |
|             }
 | |
| 
 | |
|             // If customPersonalizable is null, then info.CustomProperties should also be null
 | |
|             Debug.Assert(!(customPersonalizable == null && info.CustomProperties != null));
 | |
| 
 | |
|             if (customPersonalizable != null && info.CustomProperties != null && info.CustomProperties.Count > 0) {
 | |
|                 customPersonalizable.Load(info.CustomProperties);
 | |
|             }
 | |
| 
 | |
|             if (info.Properties != null && info.Properties.Count > 0) {
 | |
|                 BlobPersonalizationState.SetPersonalizedProperties(control, info.Properties);
 | |
|             }
 | |
| 
 | |
|             if (trackingPersonalizable != null) {
 | |
|                 trackingPersonalizable.EndLoad();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         protected virtual void ChangeScope(PersonalizationScope scope) {
 | |
|             PersonalizationProviderHelper.CheckPersonalizationScope(scope);
 | |
| 
 | |
|             if (scope == _currentScope) {
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             if ((scope == PersonalizationScope.Shared) && (!CanEnterSharedScope)) {
 | |
|                 throw new InvalidOperationException(SR.GetString(SR.WebPartPersonalization_CannotEnterSharedScope));
 | |
|             }
 | |
| 
 | |
|             _currentScope = scope;
 | |
|             _scopeToggled = true;
 | |
|         }
 | |
| 
 | |
|         // Extracts the personalization state from webPartA, and applies it to webPartB.
 | |
|         // Assumes that webPartA and webPartB are the same type.  If the WebParts are GenericWebParts,
 | |
|         // then copies the personalization state from the ChildControl of webPartA to the
 | |
|         // ChildControl of webPartB.
 | |
|         protected internal virtual void CopyPersonalizationState(WebPart webPartA, WebPart webPartB) {
 | |
|             if (webPartA == null) {
 | |
|                 throw new ArgumentNullException("webPartA");
 | |
|             }
 | |
|             if (webPartB == null) {
 | |
|                 throw new ArgumentNullException("webPartB");
 | |
|             }
 | |
|             if (webPartA.GetType() != webPartB.GetType()) {
 | |
|                 throw new ArgumentException(SR.GetString(SR.WebPartPersonalization_SameType, "webPartA", "webPartB"));
 | |
|             }
 | |
| 
 | |
|             CopyPersonalizationState((Control)webPartA, (Control)webPartB);
 | |
| 
 | |
|             GenericWebPart genericWebPartA = webPartA as GenericWebPart;
 | |
|             GenericWebPart genericWebPartB = webPartB as GenericWebPart;
 | |
|             // Assert that the GenericWebParts are either both null or both non-null
 | |
|             Debug.Assert((genericWebPartA == null) == (genericWebPartB == null));
 | |
|             if (genericWebPartA != null && genericWebPartB != null) {
 | |
|                 Control childControlA = genericWebPartA.ChildControl;
 | |
|                 Control childControlB = genericWebPartB.ChildControl;
 | |
| 
 | |
|                 if (childControlA == null) {
 | |
|                     throw new ArgumentException(SR.GetString(SR.PropertyCannotBeNull, "ChildControl"), "webPartA");
 | |
|                 }
 | |
|                 if (childControlB == null) {
 | |
|                     throw new ArgumentException(SR.GetString(SR.PropertyCannotBeNull, "ChildControl"), "webPartB");
 | |
|                 }
 | |
|                 if (childControlA.GetType() != childControlB.GetType()) {
 | |
|                     throw new ArgumentException(SR.GetString(SR.WebPartPersonalization_SameType, "webPartA.ChildControl", "webPartB.ChildControl"));
 | |
|                 }
 | |
| 
 | |
|                 CopyPersonalizationState(childControlA, childControlB);
 | |
|             }
 | |
| 
 | |
|             // IPersonalizable.IsDirty should always be false on the new WebPart, since the only data
 | |
|             // on the new WebPart was loaded via personalization, which should not cause the control
 | |
|             // to be dirty.  However, we want to save the IPersonalizable data on this request, so
 | |
|             // we call SetDirty() to force the IPersonalizable data to be saved.
 | |
|             SetDirty(webPartB);
 | |
|         }
 | |
| 
 | |
|         private void CopyPersonalizationState(Control controlA, Control controlB) {
 | |
|             PersonalizationInfo info = ExtractPersonalizationState(controlA);
 | |
|             ApplyPersonalizationState(controlB, info);
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         /// </devdoc>
 | |
|         private void DeterminePersonalizationProvider() {
 | |
|             string providerName = ProviderName;
 | |
|             if (String.IsNullOrEmpty(providerName)) {
 | |
|                 // Use the default provider
 | |
|                 _provider = PersonalizationAdministration.Provider;
 | |
|                 // The default provider can never be null
 | |
|                 Debug.Assert(_provider != null);
 | |
|             }
 | |
|             else {
 | |
|                 // Look for a provider with the specified name
 | |
|                 PersonalizationProvider provider = PersonalizationAdministration.Providers[providerName];
 | |
|                 if (provider != null) {
 | |
|                     _provider = provider;
 | |
|                 }
 | |
|                 else {
 | |
|                     throw new ProviderException(
 | |
|                         SR.GetString(SR.WebPartPersonalization_ProviderNotFound, providerName));
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         /// </devdoc>
 | |
|         public void EnsureEnabled(bool ensureModifiable) {
 | |
|             bool value = (ensureModifiable ? IsModifiable : IsEnabled);
 | |
| 
 | |
|             if (!value) {
 | |
|                 string message;
 | |
|                 if (ensureModifiable) {
 | |
|                     message = SR.GetString(SR.WebPartPersonalization_PersonalizationNotModifiable);
 | |
|                 }
 | |
|                 else {
 | |
|                     message = SR.GetString(SR.WebPartPersonalization_PersonalizationNotEnabled);
 | |
|                 }
 | |
|                 throw new InvalidOperationException(message);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void EnsurePersonalizationState() {
 | |
|             if (_personalizationState == null) {
 | |
|                 throw new InvalidOperationException(SR.GetString(SR.WebPartPersonalization_PersonalizationStateNotLoaded));
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         /// </devdoc>
 | |
|         protected internal virtual void ExtractPersonalizationState() {
 | |
|             // If we reset the personalization data on this request, we should not extract data since
 | |
|             // it will not be saved.
 | |
|             if (IsEnabled && !ShouldResetPersonalizationState) {
 | |
|                 EnsurePersonalizationState();
 | |
|                 _personalizationState.ExtractWebPartManagerPersonalization();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         /// </devdoc>
 | |
|         protected internal virtual void ExtractPersonalizationState(WebPart webPart) {
 | |
|             // If we reset the personalization data on this request, we should not extract data since
 | |
|             // it will not be saved.
 | |
|             if (IsEnabled && !ShouldResetPersonalizationState) {
 | |
|                 EnsurePersonalizationState();
 | |
|                 _personalizationState.ExtractWebPartPersonalization(webPart);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // Helper method used by CopyPersonalizationState()
 | |
|         private PersonalizationInfo ExtractPersonalizationState(Control control) {
 | |
|             ITrackingPersonalizable trackingPersonalizable = control as ITrackingPersonalizable;
 | |
|             IPersonalizable customPersonalizable = control as IPersonalizable;
 | |
| 
 | |
|             if (trackingPersonalizable != null) {
 | |
|                 trackingPersonalizable.BeginSave();
 | |
|             }
 | |
| 
 | |
|             PersonalizationInfo info = new PersonalizationInfo();
 | |
|             if (customPersonalizable != null) {
 | |
|                 info.CustomProperties = new PersonalizationDictionary();
 | |
|                 customPersonalizable.Save(info.CustomProperties);
 | |
|             }
 | |
|             info.Properties = BlobPersonalizationState.GetPersonalizedProperties(control, PersonalizationScope.Shared);
 | |
| 
 | |
|             if (trackingPersonalizable != null) {
 | |
|                 trackingPersonalizable.EndSave();
 | |
|             }
 | |
| 
 | |
|             return info;
 | |
|         }
 | |
| 
 | |
|         // Returns the AuthorizationFilter string for a WebPart before it is instantiated
 | |
|         // Returns null if there is no personalized value for AuthorizationFilter
 | |
|         protected internal virtual string GetAuthorizationFilter(string webPartID) {
 | |
|             if (String.IsNullOrEmpty(webPartID)) {
 | |
|                 throw ExceptionUtil.ParameterNullOrEmpty("webPartID");
 | |
|             }
 | |
| 
 | |
|             EnsureEnabled(false);
 | |
|             EnsurePersonalizationState();
 | |
|             return _personalizationState.GetAuthorizationFilter(webPartID);
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         /// </devdoc>
 | |
|         internal void LoadInternal() {
 | |
|             if (Enabled) {
 | |
|                 _currentScope = Load();
 | |
|                 _initialized = true;
 | |
|             }
 | |
|             _initializedSet = true;
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         /// Loads personalization information from its storage, and computes the initial personalization
 | |
|         /// scope. This method determines the provider type to be used, and the current user's capabilities.
 | |
|         /// </devdoc>
 | |
|         protected virtual PersonalizationScope Load() {
 | |
|             if (!Enabled) {
 | |
|                 throw new InvalidOperationException(SR.GetString(SR.WebPartPersonalization_PersonalizationNotEnabled));
 | |
|             }
 | |
| 
 | |
|             // Determine the provider early, as it is needed to continue execution.
 | |
|             // Provider is used to detect user's capabilities, load personalization state
 | |
|             // and determine initial scope.
 | |
|             DeterminePersonalizationProvider();
 | |
|             Debug.Assert(_provider != null);
 | |
| 
 | |
|             Page page = WebPartManager.Page;
 | |
|             if (page == null) {
 | |
|                 throw new InvalidOperationException(SR.GetString(SR.PropertyCannotBeNull, "WebPartManager.Page"));
 | |
|             }
 | |
| 
 | |
|             HttpRequest request = page.RequestInternal;
 | |
|             if (request == null) {
 | |
|                 throw new InvalidOperationException(SR.GetString(SR.PropertyCannotBeNull, "WebPartManager.Page.Request"));
 | |
|             }
 | |
| 
 | |
|             // Ask the provider to load information about what are the capabilities of
 | |
|             // the current user
 | |
|             if (request.IsAuthenticated) {
 | |
|                 _userCapabilities = _provider.DetermineUserCapabilities(WebPartManager);
 | |
|             }
 | |
| 
 | |
|             // A derived WebPartPersonalization can have ignoreCurrentUser to be true.
 | |
|             _personalizationState = _provider.LoadPersonalizationState(WebPartManager, /* ignoreCurrentUser */ false);
 | |
|             if (_personalizationState == null) {
 | |
|                 // We can't assume that _personalizationState will be non-null, because
 | |
|                 // it depends on the provider implementation.
 | |
|                 throw new ProviderException(SR.GetString(SR.WebPartPersonalization_CannotLoadPersonalization));
 | |
|             }
 | |
| 
 | |
|             return _provider.DetermineInitialScope(WebPartManager, _personalizationState);
 | |
|         }
 | |
| 
 | |
|         // Resets the personalization data for the current user in the current scope on the current page
 | |
|         public virtual void ResetPersonalizationState() {
 | |
|             EnsureEnabled(/* ensureModifiable */ true);
 | |
| 
 | |
|             if (_provider == null) {
 | |
|                 throw new InvalidOperationException(SR.GetString(SR.WebPartPersonalization_CantCallMethodBeforeInit,
 | |
|                                                     "ResetPersonalizationState", "WebPartPersonalization"));
 | |
|             }
 | |
| 
 | |
|             _provider.ResetPersonalizationState(WebPartManager);
 | |
|             ShouldResetPersonalizationState = true;
 | |
| 
 | |
|             Page page = WebPartManager.Page;
 | |
|             if (page == null) {
 | |
|                 throw new InvalidOperationException(SR.GetString(SR.PropertyCannotBeNull, "WebPartManager.Page"));
 | |
|             }
 | |
| 
 | |
|             // Transfer execution to a new instance of the same page.  The new page will execute
 | |
|             // after personalization data has been reset.
 | |
|             TransferToCurrentPage(page);
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         /// </devdoc>
 | |
|         internal void SaveInternal() {
 | |
|             if (IsModifiable) {
 | |
|                 Save();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         /// Saves personalization information back to its storage if necessary.
 | |
|         /// </devdoc>
 | |
|         protected virtual void Save() {
 | |
|             EnsureEnabled(/* ensureModifiable */ true);
 | |
| 
 | |
|             EnsurePersonalizationState();
 | |
| 
 | |
|             if (_provider == null) {
 | |
|                 throw new InvalidOperationException(SR.GetString(SR.WebPartPersonalization_CantCallMethodBeforeInit,
 | |
|                                                     "Save", "WebPartPersonalization"));
 | |
|             }
 | |
| 
 | |
|             // If we reset the personalization data on this request, we should not save data to the
 | |
|             // DB on this request.  It is likely we would not save data anyway, since the data probably
 | |
|             // did not change since the last request, but there are some scenarios where the data could
 | |
|             // have changed (like a WebPart using personalization as a cache).
 | |
|             if (_personalizationState.IsDirty && !ShouldResetPersonalizationState) {
 | |
|                 _provider.SavePersonalizationState(_personalizationState);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         /// </devdoc>
 | |
|         protected internal virtual void SetDirty() {
 | |
|             if (IsEnabled) {
 | |
|                 EnsurePersonalizationState();
 | |
|                 _personalizationState.SetWebPartManagerDirty();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         /// </devdoc>
 | |
|         protected internal virtual void SetDirty(WebPart webPart) {
 | |
|             if (IsEnabled) {
 | |
|                 EnsurePersonalizationState();
 | |
|                 _personalizationState.SetWebPartDirty(webPart);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         /// </devdoc>
 | |
|         public virtual void ToggleScope() {
 | |
|             EnsureEnabled(/* ensureModifiable */ false);
 | |
| 
 | |
|             Page page = WebPartManager.Page;
 | |
|             if (page == null) {
 | |
|                 throw new InvalidOperationException(SR.GetString(SR.PropertyCannotBeNull, "WebPartManager.Page"));
 | |
|             }
 | |
|             if (page.IsExportingWebPart) {
 | |
|                 // If the page is exporting, the page determines the desired scope, and it is not meaningful
 | |
|                 // to toggle the scope. Note that we no-op the call, rather than throwing because
 | |
|                 // that would require exposing a CanToggleScope property, require page developers
 | |
|                 // to check for it. Furthermore, we don't guarantee ToggleScope does toggle
 | |
|                 // (eg. in the case of absense of user capability to enter shared scope), so
 | |
|                 // simply no-op'ing isn't terribly bad...
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             Page previousPage = page.PreviousPage;
 | |
|             if ((previousPage != null) &&
 | |
|                 (previousPage.IsCrossPagePostBack == false)) {
 | |
|                 WebPartManager previousWebPartManager = WebPartManager.GetCurrentWebPartManager(previousPage);
 | |
| 
 | |
|                 if ((previousWebPartManager != null) && (previousWebPartManager.Personalization.ScopeToggled)) {
 | |
|                     // Looks like some sort of infinite recursion is going on
 | |
|                     // and we're toggling again. Like the previous case, we're
 | |
|                     // going to no-op and protect ourselves from "----" code...
 | |
|                     return;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if (_currentScope == PersonalizationScope.Shared) {
 | |
|                 ChangeScope(PersonalizationScope.User);
 | |
|             }
 | |
|             else {
 | |
|                 ChangeScope(PersonalizationScope.Shared);
 | |
|             }
 | |
| 
 | |
|             // Transfer execution to a new instance of the same page.  The new page will detect the scope
 | |
|             // it should run in, when it begins to load personalization data.
 | |
|             TransferToCurrentPage(page);
 | |
|         }
 | |
| 
 | |
|         // Transfers execution to a new instance of the same page. We need to clear the form collection,
 | |
|         // since it should not carry over to the page in the new scope (i.e. ViewState). If the form
 | |
|         // method is GET, then we must not include the query string, since the entire form collection
 | |
|         // is in the query string.  If the form method is POST (or there is no form), then we must
 | |
|         // include the query string, since the developer could be using the query string to drive the
 | |
|         // logic of their page (VSWhidbey 444385 and 527117).
 | |
|         private void TransferToCurrentPage(Page page) {
 | |
|             HttpRequest request = page.RequestInternal;
 | |
|             if (request == null) {
 | |
|                 throw new InvalidOperationException(SR.GetString(SR.PropertyCannotBeNull, "WebPartManager.Page.Request"));
 | |
|             }
 | |
| 
 | |
|             string path = request.CurrentExecutionFilePath;
 | |
|             if (page.Form == null || String.Equals(page.Form.Method, "post", StringComparison.OrdinalIgnoreCase)) {
 | |
|                 string queryString = page.ClientQueryString;
 | |
|                 if (!String.IsNullOrEmpty(queryString)) {
 | |
|                     path += "?" + queryString;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             IScriptManager scriptManager = page.ScriptManager;
 | |
|             if ((scriptManager != null) && scriptManager.IsInAsyncPostBack) {
 | |
|                 request.Response.Redirect(path);
 | |
|             }
 | |
|             else {
 | |
|                 page.Server.Transfer(path, /* preserveForm */ false);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private sealed class PersonalizationInfo {
 | |
|             public IDictionary Properties;
 | |
|             public PersonalizationDictionary CustomProperties;
 | |
|         }
 | |
|     }
 | |
| }
 |