Example #1
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 #2
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);
        }