/// <summary> /// Protected constructor for the abstract Base class. /// This is the current contract between the subclass and the base class /// If we decide some registration mechanism then this might change /// /// NOTE : If you are using this constructor from your subclass or passing a null /// for the content type parameter, be sure to implement the GetContentTypeCore /// method, as that will be called to get the content type value. This is provided /// to enable lazy initialization of the ContentType property. /// /// </summary> /// <param name="package">Package in which this part is being created</param> /// <param name="partUri">uri of the part</param> /// <param name="contentType">Content Type of the part, can be null if the value /// is unknown at the time of construction. However the value has to be made /// available anytime the ContentType property is called. A null value only indicates /// that the value will be provided later. Every PackagePart must have a valid /// Content Type</param> /// <param name="compressionOption">compression option for this part</param> /// <exception cref="ArgumentNullException">If parameter "package" is null</exception> /// <exception cref="ArgumentNullException">If parameter "partUri" is null</exception> /// <exception cref="ArgumentOutOfRangeException">If CompressionOption enumeration [compressionOption] does not have one of the valid values</exception> /// <exception cref="ArgumentException">If parameter "partUri" does not conform to the valid partUri syntax</exception> protected PackagePart(Package package, Uri partUri, string contentType, CompressionOption compressionOption) { if (package == null) { throw new ArgumentNullException("package"); } if (partUri == null) { throw new ArgumentNullException("partUri"); } Package.ThrowIfCompressionOptionInvalid(compressionOption); _uri = PackUriHelper.ValidatePartUri(partUri); _container = package; if (contentType == null) { _contentType = null; } else { _contentType = new ContentType(contentType); } _requestedStreams = null; _compressionOption = compressionOption; _isRelationshipPart = PackUriHelper.IsRelationshipPartUri(partUri); }
/// <summary> /// Add new relationship to the Collection /// </summary> /// <param name="targetUri">target</param> /// <param name="targetMode">Enumeration indicating the base uri for the target uri</param> /// <param name="relationshipType">relationship type that uniquely defines the role of the relationship</param> /// <param name="id">String that conforms to the xsd:ID datatype. Unique across the source's relationships. /// Null OK (ID will be generated).</param> /// <param name="parsing">Indicates whether the add call is made while parsing existing relationships /// from a relationship part, or we are adding a new relationship</param> private PackageRelationship Add(Uri targetUri, TargetMode targetMode, string relationshipType, string id, bool parsing) { if (targetUri == null) { throw new ArgumentNullException("targetUri"); } if (relationshipType == null) { throw new ArgumentNullException("relationshipType"); } ThrowIfInvalidRelationshipType(relationshipType); //Verify if the Enum value is valid if (targetMode < TargetMode.Internal || targetMode > TargetMode.External) { throw new ArgumentOutOfRangeException("targetMode"); } // don't accept absolute Uri's if targetMode is Internal. if (targetMode == TargetMode.Internal && targetUri.IsAbsoluteUri) { throw new ArgumentException(SR.RelationshipTargetMustBeRelative, "targetUri"); } // don't allow relationships to relationships // This check should be made for following cases // 1. Uri is absolute and it is pack Uri // 2. Uri is NOT absolute and its target mode is internal (or NOT external) // Note: if the target is absolute uri and its not a pack scheme then we cannot determine if it is a rels part // Note: if the target is relative uri and target mode is external, we cannot determine if it is a rels part if ((!targetUri.IsAbsoluteUri && targetMode != TargetMode.External) || (targetUri.IsAbsoluteUri && targetUri.Scheme == PackUriHelper.UriSchemePack)) { Uri resolvedUri = GetResolvedTargetUri(targetUri, targetMode); //GetResolvedTargetUri returns a null if the target mode is external and the //target Uri is a packUri with no "part" component, so in that case we know that //its not a relationship part. if (resolvedUri != null) { if (PackUriHelper.IsRelationshipPartUri(resolvedUri)) { throw new ArgumentException(SR.RelationshipToRelationshipIllegal, "targetUri"); } } } // Generate an ID if id is null. Throw exception if neither null nor a valid unique xsd:ID. if (id == null) { id = GenerateUniqueRelationshipId(); } else { ValidateUniqueRelationshipId(id); } //Ensure the relationship part EnsureRelationshipPart(); // create and add PackageRelationship relationship = new PackageRelationship(_package, _sourcePart, targetUri, targetMode, relationshipType, id); _relationships.Add(relationship); //If we are adding relationships as a part of Parsing the underlying relationship part, we should not set //the dirty flag to false. _dirty = !parsing; return(relationship); }