File: System\Activities\InlinedLocationReference.cs
Project: ndp\cdf\src\NetFx40\System.Activities\System.Activities.csproj (System.Activities)
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
 
namespace System.Activities
{
    using System;
    using System.Activities.Expressions;
 
    class InlinedLocationReference : LocationReference, ILocationReferenceWrapper
    {
        LocationReference innerReference;
        Activity validAccessor;
        bool allowReads;
        bool allowWrites;
        bool allowGetLocation;
 
        public InlinedLocationReference(LocationReference innerReference, Activity validAccessor, ArgumentDirection accessDirection)
        {
            this.innerReference = innerReference;
            this.validAccessor = validAccessor;
            this.allowReads = accessDirection != ArgumentDirection.Out;
            this.allowWrites = accessDirection != ArgumentDirection.In;
        }
 
        public InlinedLocationReference(LocationReference innerReference, Activity validAccessor)
        {
            this.innerReference = innerReference;
            this.validAccessor = validAccessor;
            this.allowReads = true;
            this.allowWrites = true;
            this.allowGetLocation = true;
        }
 
        protected override string NameCore
        {
            get
            {
                return this.innerReference.Name;
            }
        }
        
        protected override Type TypeCore
        {
            get
            {
                return this.innerReference.Type;
            }
        }
 
        public override Location GetLocation(ActivityContext context)
        {
            if (context == null)
            {
                throw FxTrace.Exception.ArgumentNull("context");
            }
            ValidateAccessor(context);
            if (!this.allowGetLocation)
            {
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR.GetLocationOnPublicAccessReference(context.Activity)));
            }
            return GetLocationCore(context);
        }
 
        internal override Location GetLocationForRead(ActivityContext context)
        {
            ValidateAccessor(context);
            if (!this.allowReads)
            {
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR.ReadAccessToWriteOnlyPublicReference(context.Activity)));
            }
            return GetLocationCore(context);
        }
 
 
        internal override Location GetLocationForWrite(ActivityContext context)
        {
            ValidateAccessor(context);
            if (!this.allowWrites)
            {
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR.WriteAccessToReadOnlyPublicReference(context.Activity)));
            }
            return GetLocationCore(context);
        }
 
        void ValidateAccessor(ActivityContext context)
        {
            // We need to call ThrowIfDisposed explicitly since
            // context.Activity does not check isDisposed
            context.ThrowIfDisposed();
 
            if (!object.ReferenceEquals(context.Activity, this.validAccessor))
            {
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR.InlinedLocationReferenceOnlyAccessibleByOwner(context.Activity, this.validAccessor)));
            }
        }
 
        Location GetLocationCore(ActivityContext context)
        {
            try
            {
                context.AllowChainedEnvironmentAccess = true;
                return this.innerReference.GetLocation(context);
            }
            finally
            {
                context.AllowChainedEnvironmentAccess = false;
            }
        }
 
        LocationReference ILocationReferenceWrapper.LocationReference
        {
            get
            {
                return this.innerReference;
            }
        }
    }
}