//------------------------------------------------------ // // Public Methods // //------------------------------------------------------ #region Public Methods /// <summary> /// This method returns the list of selected PackageRelationships as per the /// given criteria, from a part in the Package provided /// </summary> /// <param name="package">Package object from which we get the relationsips</param> /// <returns></returns> /// <exception cref="ArgumentNullException">If package parameter is null</exception> public List<PackageRelationship> Select(Package package) { if (package == null) { throw new ArgumentNullException("package"); } List<PackageRelationship> relationships = new List<PackageRelationship>(0); switch (SelectorType) { case PackageRelationshipSelectorType.Id: if (SourceUri.Equals(PackUriHelper.PackageRootUri)) { if (package.RelationshipExists(SelectionCriteria)) relationships.Add(package.GetRelationship(SelectionCriteria)); } else { if (package.PartExists(SourceUri)) { PackagePart part = package.GetPart(SourceUri); if (part.RelationshipExists(SelectionCriteria)) relationships.Add(part.GetRelationship(SelectionCriteria)); } } break; case PackageRelationshipSelectorType.Type: if (SourceUri.Equals(PackUriHelper.PackageRootUri)) { foreach (PackageRelationship r in package.GetRelationshipsByType(SelectionCriteria)) relationships.Add(r); } else { if (package.PartExists(SourceUri)) { foreach (PackageRelationship r in package.GetPart(SourceUri).GetRelationshipsByType(SelectionCriteria)) relationships.Add(r); } } break; default: //Debug.Assert is fine here since the parameters have already been validated. And all the properties are //readonly Debug.Assert(false, "This option should never be called"); break; } return relationships; }
private void Apply(Package package, string filename, bool installed) { using (var setPkg = Package.Open(filename, FileMode.Open, FileAccess.ReadWrite)) { // Extract information about the target set var defRelationship = setPkg.GetRelationshipsByType("http://schemas.octgn.org/set/definition").First(); var definition = setPkg.GetPart(defRelationship.TargetUri); Set set; using (var reader = XmlReader.Create(definition.GetStream(), xmlSettings)) { reader.ReadToFollowing("set"); // <?xml ... ?> set = new Set(filename, reader, game.repository); // Check if the set game matches the patch if (set.Game != game) return; } // Check if there is a patch for this set string relationId = "S" + set.Id.ToString("N"); if (!package.RelationshipExists(relationId)) return; var patchPart = package.GetPart(package.GetRelationship(relationId).TargetUri); XDocument patchDoc; using (var stream = patchPart.GetStream()) patchDoc = XDocument.Load(stream); // Check if the set is at least the required version for patching if (set.Version < patchDoc.Root.Attr<Version>("minVersion")) return; if (set.Version > patchDoc.Root.Attr<Version>("maxVersion")) return; if (installed) game.DeleteSet(game.Sets.Single(s => s.packageName == filename)); // Process the set foreach (XElement action in patchDoc.Root.Elements()) switch (action.Name.LocalName) { case "new": { Uri targetUri = new Uri(action.Attr<string>("targetUri"), UriKind.Relative); string relationshipId = action.Attr<string>("relationshipId"); string contentType = action.Attr<string>("contentType"); PackagePart part = setPkg.PartExists(targetUri) ? setPkg.GetPart(targetUri) : setPkg.CreatePart(targetUri, contentType, CompressionOption.Normal); using (var targetStream = part.GetStream(FileMode.Create, FileAccess.Write)) using (var srcStream = package.GetPart(patchPart.GetRelationship(relationshipId).TargetUri).GetStream()) srcStream.CopyTo(targetStream); break; } case "newrel": { Uri partUri = new Uri(action.Attr<string>("partUri"), UriKind.Relative); string relationshipId = action.Attr<string>("relationshipId"); Uri targetUri = new Uri(action.Attr<string>("targetUri"), UriKind.Relative); string relationshipType = action.Attr<string>("relationshipType"); PackagePart part = setPkg.GetPart(partUri); if (part.RelationshipExists(relationshipId)) part.DeleteRelationship(relationshipId); part.CreateRelationship(targetUri, TargetMode.Internal, relationshipType, relationshipId); break; } default: throw new InvalidFileFormatException("Unknown patch action: " + action.Name); } } OnProgress(string.Format("{0} patched.", System.IO.Path.GetFileName(filename))); if (installed) try { game.InstallSet(filename); } catch (Exception ex) { OnProgress(string.Format("{0} can't be re-installed.\nDetails: {1}", filename, ex.Message), true); } }
/// <summary> /// This method returns the list of selected PackageRelationships as per the /// given criteria, from a part in the Package provided /// </summary> /// <param name="package">Package object from which we get the relationships</param> /// <returns></returns> /// <exception cref="ArgumentNullException">If package parameter is null</exception> public List <PackageRelationship> Select(Package package) { if (package == null) { throw new ArgumentNullException(nameof(package)); } List <PackageRelationship> relationships = new List <PackageRelationship>(0); switch (SelectorType) { case PackageRelationshipSelectorType.Id: if (SourceUri.Equals(PackUriHelper.PackageRootUri)) { if (package.RelationshipExists(SelectionCriteria)) { relationships.Add(package.GetRelationship(SelectionCriteria)); } } else { if (package.PartExists(SourceUri)) { PackagePart part = package.GetPart(SourceUri); if (part.RelationshipExists(SelectionCriteria)) { relationships.Add(part.GetRelationship(SelectionCriteria)); } } } break; case PackageRelationshipSelectorType.Type: if (SourceUri.Equals(PackUriHelper.PackageRootUri)) { foreach (PackageRelationship r in package.GetRelationshipsByType(SelectionCriteria)) { relationships.Add(r); } } else { if (package.PartExists(SourceUri)) { foreach (PackageRelationship r in package.GetPart(SourceUri).GetRelationshipsByType(SelectionCriteria)) { relationships.Add(r); } } } break; default: //Debug.Assert is fine here since the parameters have already been validated. And all the properties are //readonly Debug.Assert(false, "This option should never be called"); break; } return(relationships); }