Example #1
0
        internal void Rebind(Stream newOriginal)
        {
            if (newOriginal == null)
            {
                throw new ArgumentNullException("newOriginal");
            }

            // close this as we will open a new one
            _originalPackage.Value.Close();
            _trashCan.Add(_originalPackage.Value);
            _isDirty = false;

            Package newPackage = Package.Open(newOriginal, FileMode.Open, FileAccess.Read);

            // remap parts for people who keep references around after we rebind
            foreach (PackagePart part in newPackage.GetParts())
            {
                Uri normalizedPartUri = PackUriHelper.GetNormalizedPartUri(part.Uri);
                if (_activeParts.ContainsKey(normalizedPartUri))
                {
                    _activeParts[normalizedPartUri].Target = newPackage.GetPart(part.Uri);
                }
            }

            _originalPackage.Value = newPackage;
        }
Example #2
0
        //-------------------------------------------------------------------------
        // Protected Methods - Package Overrides
        //-------------------------------------------------------------------------

        /// <summary>
        /// Creates a new PackagePart.
        /// </summary>
        /// <remarks>
        /// When creating a new PackagePart we must:
        ///    a) ensure the part does not exist in package
        ///    b) ensure there is a writable package
        ///    c) create a temp part
        ///    d) update active part reference to the temp part
        ///
        /// What if a PackagePart with the same Uri already exists?
        ///   Package.CreatePart checks for this.
        ///
        /// Do we need to worry about updating relationships and other parts?
        ///   Relationships are a part and are thus intrinsically handled.
        /// </remarks>
        /// <param name="partUri">Uri for the part to create.</param>
        /// <param name="contentType">Content type string.</param>
        /// <param name="compressionOption">Compression options.</param>
        /// <returns>A new PackagePart.</returns>
        protected override PackagePart CreatePartCore(
            Uri partUri, string contentType, CompressionOption compressionOption)
        {
            // Skipping parameter validation as it is done by CreatePart.

            EnsureTempPackage();

            // the underlying temp package does all the physical work
            PackagePart result = _tempPackage.Value.CreatePart(
                partUri, contentType, compressionOption);

            Uri normalizedPartUri = PackUriHelper.GetNormalizedPartUri(partUri);

            result = new WriteableOnDemandPackagePart(
                this, result, TempPackagePartFactory);

            _activeParts.Add(normalizedPartUri, (WriteableOnDemandPackagePart)result);

            Trace.SafeWrite(
                Trace.Packaging,
                "New part {0}({1})#{2} created.",
                result.Uri,
                result.ContentType,
                result.GetHashCode());

            return(result);
        }
Example #3
0
        /// <summary>
        /// Deletes a PackagePart.
        /// </summary>
        /// <remarks>
        /// When deleting a PackagePart we must:
        ///   a) ensure there is a writable package
        ///   b) remove the temp part
        ///
        /// What if the part was already deleted?
        /// What if delete is the first operation?
        ///   Then a relationship part in the temorary package would be active;
        ///   and the case(s) would be handled by Package.DeletePart.
        ///
        /// What if delete is called after a part is created / edited?
        ///   No different then the other cases.
        ///
        /// What if we call DeletePart on temp Package?
        ///   Unsure why relationships are not updated twice; once by base
        ///   accessing relationship part, then a second when the underlying
        ///   implementor does for Package.DeletePart.
        ///
        /// Note: We should explore only cleaning up the stream; as the rest is
        /// likely handed by base interacting with the relationship parts.
        /// </remarks>
        /// <param name="partUri">Uri for the part to delete.</param>
        protected override void DeletePartCore(Uri partUri)
        {
            // Skipping parameter validation as it is done by CreatePart.
            if (_tempPackage.Value.PartExists(partUri))
            {
                _tempPackage.Value.DeletePart(partUri);

                Trace.SafeWrite(Trace.Packaging, "Part {0} deleted.", partUri);
            }

            Uri normalizedPartUri = PackUriHelper.GetNormalizedPartUri(partUri);

            if (_activeParts.ContainsKey(normalizedPartUri))
            {
                _activeParts.Remove(normalizedPartUri);
            }
        }
Example #4
0
        /// <summary>
        /// Returns an existing PackagePart.
        /// </summary>
        /// <remarks>
        /// When getting an existing PackagePart we must:
        ///   a) Create a proxy (WriteableOnDemandPackagePart) if there is not
        ///      already one; if there is we just return it.
        ///   b) We must return the same instance of the proxy for any request
        ///      for that part, as new instances will not have any way of
        ///      knowing which internal part is 'active' (original/temp) within
        ///      the proxy.
        ///
        /// What if the part does not exist?
        /// What if the part has been deleted?
        ///   These cases are handled by Package.GetPart.
        ///
        /// What if the part ends up being edited?
        ///   That is the reason for the proxy, on edit the internal reference
        ///   will be updated to the temp object and it will service the call.
        ///
        /// What if a part has already been edited?
        ///   That is why we must return the active part.
        /// </remarks>
        /// <param name="partUri">The Uri of the part to return.</param>
        /// <returns>An existing PackagePart.</returns>
        protected override PackagePart GetPartCore(Uri partUri)
        {
            // Skipping parameter validation as it is done by CreatePart.

            PackagePart result = null;

            Uri normalizedPartUri = PackUriHelper.GetNormalizedPartUri(partUri);

#if DEBUG
            if (_activeParts.ContainsKey(normalizedPartUri))
            {
                Trace.SafeWrite(
                    Trace.Packaging,
                    "WARNING: GetPartCore called multiple times for {0}.",
                    partUri);
            }
#endif

            // We can get the part from three places, which we check in this order:
            // 1) Our saved list of active parts. It's important to get it from
            //    here if possible because all references should point to a single
            //    instance of our WriteableOnDemandPackagePart class.
            // 2) The temp package. If there is a change to a part it will be here,
            //    and we want to return the user's changes.
            // 3) The original package.

            // Even if the part exists in our list of active parts, as part of our
            // contract with the Packaging team we still must use PartExists to
            // check if the part is actually present in either the temporary or the
            // original package. If the part does not exist in either the original
            // or the temporary package, this method will return null.

            bool canGetFromTempPackage =
                (_tempPackage.Value != null) && (_tempPackage.Value.PartExists(partUri));
            bool canGetFromOriginalPackage =
                canGetFromTempPackage ? false : _originalPackage.Value.PartExists(partUri);

            if (_activeParts.ContainsKey(normalizedPartUri) &&
                (canGetFromTempPackage || canGetFromOriginalPackage))
            {
                result = _activeParts[normalizedPartUri];
            }
            else if (canGetFromTempPackage)
            {
                result = _tempPackage.Value.GetPart(partUri);

                result = new WriteableOnDemandPackagePart(
                    this, result, TempPackagePartFactory);

                _activeParts.Add(normalizedPartUri, (WriteableOnDemandPackagePart)result);

                Trace.SafeWrite(
                    Trace.Packaging,
                    "GetPartCore returned {0}({1})#{2} a temp part.",
                    partUri,
                    result.ContentType,
                    result.GetHashCode());
            }
            else if (canGetFromOriginalPackage)
            {
                PackagePart original = _originalPackage.Value.GetPart(partUri);
                result = new WriteableOnDemandPackagePart(
                    this, original, TempPackagePartFactory);

                _activeParts.Add(normalizedPartUri, (WriteableOnDemandPackagePart)result);

                Trace.SafeWrite(
                    Trace.Packaging,
                    "GetPartCore returned {0}({1})#{2} a new proxy.",
                    partUri,
                    result.ContentType,
                    result.GetHashCode());
            }

            return(result);
        }
 public void ReserveUri(string contentType, Uri partUri)
 {
     GetNextSequenceNumber(contentType);
     AddToReserveUri(PackUriHelper.GetNormalizedPartUri(partUri));
 }
Example #6
0
 public void GetNormalizedPartUriTest3()
 {
     Assert.AreEqual(new Uri(a.ToString().ToUpperInvariant(), UriKind.Relative), PackUriHelper.GetNormalizedPartUri(a));
 }
Example #7
0
 public void GetNormalizedPartUriTest2()
 {
     PackUriHelper.GetNormalizedPartUri(null);
 }
Example #8
0
 public void GetNormalisedPartUritest4()
 {
     PackUriHelper.GetNormalizedPartUri(part1);
 }
Example #9
0
        public void GetNormalizedPartUriTest()
        {
            Uri uri = new Uri("/test.com".ToUpperInvariant(), UriKind.Relative);

            Assert.IsTrue(uri == PackUriHelper.GetNormalizedPartUri(uri));
        }