+2008-11-04 Alan McGovern <amcgovern@novell.com>
+
+ * WindowsBase.dll.sources:
+ * System.IO.Packaging/Package.cs:
+ * System.IO.Packaging/ZipPackage.cs:
+ * System.IO.Packaging/PackUriHelper.cs:
+ * Test/System.IO.Packaging/FakePackage.cs:
+ * System.IO.Packaging/PackageProperties.cs:
+ * System.IO.Packaging/PackagePropertiesPart.cs: Complete the
+ implementation of loading/saving PackageProperties. NUnit tests now
+ pass.
+
2008-11-04 Alan McGovern <amcgovern@novell.com>
* System.IO.Packaging/PackagePropertiesPart.cs: No need to override
Check.PartUriIsValid (sourcePartUri);
Check.PartUriIsValid (targetUri);
- Console.WriteLine ("Merged to: {0}", new Uri (sourcePartUri, targetUri).OriginalString.Substring(7));
+ // Need to trim first 7 chars as they are: "file://"
return new Uri (new Uri(sourcePartUri, targetUri).OriginalString.Substring(7), UriKind.Relative);
}
}
internal const string RelationshipContentType = "application/vnd.openxmlformats-package.relationships+xml";
internal const string RelationshipNamespace = "http://schemas.openxmlformats.org/package/2006/relationships";
internal static readonly Uri RelationshipUri = new Uri ("/_rels/.rels", UriKind.Relative);
-
+
+ PackageProperties packageProperties;
PackagePartCollection partsCollection = new PackagePartCollection ();
Dictionary<string, PackageRelationship> relationships;
PackageRelationshipCollection relationshipsCollection = new PackageRelationshipCollection ();
}
public PackageProperties PackageProperties {
- get; private set;
+ get {
+ if (packageProperties == null) {
+ packageProperties = new PackagePropertiesPart ();
+ packageProperties.Package = this;
+ }
+ return packageProperties;
+ }
}
int RelationshipId {
// Nothing here needs to be disposed of
}
+ bool flushing = false;
public void Flush ()
{
- // I should have a dirty boolean
- if (FileOpenAccess != FileAccess.Read)
- FlushCore ();
+ if (FileOpenAccess == FileAccess.Read || flushing)
+ return;
+
+ flushing = true;
+
+ if (packageProperties != null)
+ packageProperties.Flush ();
+
+ FlushCore ();
+
+ flushing = false;
}
protected abstract void FlushCore ();
node.Attributes["Id"].Value.ToString (),
true);
}
+
+ foreach (PackageRelationship r in Relationships.Values) {
+ if (r.RelationshipType == System.IO.Packaging.PackageProperties.NSPackageProperties) {
+ PackagePart part = GetPart (r.TargetUri);
+ packageProperties = new PackagePropertiesPart ();
+ packageProperties.Package = this;
+ packageProperties.Part = part;
+ packageProperties.LoadFrom (part.GetStream ());
+ }
+ }
}
string NextId ()
{
- while (true)
- {
+ while (true) {
string s = RelationshipId.ToString ();
if (!Relationships.ContainsKey (s))
return s;
public abstract class PackageProperties : IDisposable
{
- internal const string NSProperties = "application/vnd.openxmlformats-package.core-properties+xml";
- const string NSDc = "http://purl.org/dc/elements/1.1/";
- const string NSDcTerms = "http://purl.org/dc/terms/";
- const string NSXsi = "http://www.w3.org/2001/XMLSchema-instance";
-
- protected PackageProperties ()
- {
- // Nothing
- }
+ internal const string NSPackageProperties = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
+ internal const string PackagePropertiesContentType = "application/vnd.openxmlformats-package.core-properties+xml";
- public void Dispose ()
- {
- Dispose (true);
- }
- protected virtual void Dispose (bool disposing)
+ static int uuid;
+
+ protected PackageProperties ()
{
- // Nothing
+
}
public abstract string Category { get; set; }
public abstract string LastModifiedBy { get; set; }
public abstract DateTime? LastPrinted { get; set; }
public abstract DateTime? Modified { get; set; }
+ internal Package Package { get; set; }
+ internal PackagePart Part { get; set; }
public abstract string Revision { get; set; }
public abstract string Subject { get; set; }
public abstract string Title { get; set; }
public abstract string Version { get; set; }
-
- internal void LoadFrom (Stream stream)
+
+
+ public void Dispose ()
{
- XmlDocument doc = new XmlDocument ();
- XmlNamespaceManager manager = new XmlNamespaceManager (doc.NameTable);
- doc.Load (stream);
+ Dispose (true);
+ }
- XmlNode node;
- if ((node = doc.SelectSingleNode ("prop:coreProperties/prop:category", manager)) != null)
- Category = node.InnerXml;
- if ((node = doc.SelectSingleNode ("prop:coreProperties/prop:contentStatus", manager)) != null)
- ContentStatus = node.InnerXml;
- if ((node = doc.SelectSingleNode ("prop:coreProperties/prop:contentType", manager)) != null)
- ContentType = node.InnerXml;
- if ((node = doc.SelectSingleNode ("prop:coreProperties/dcterms:created", manager)) != null)
- Created = DateTime.Parse (node.InnerXml);
- if ((node = doc.SelectSingleNode ("prop:coreProperties/dc:creator", manager)) != null)
- Creator = node.InnerXml;
- if ((node = doc.SelectSingleNode ("prop:coreProperties/dc:description", manager)) != null)
- Description = node.InnerXml;
- if ((node = doc.SelectSingleNode ("prop:coreProperties/dc:identifier", manager)) != null)
- Identifier = node.InnerXml;
- if ((node = doc.SelectSingleNode ("prop:coreProperties/prop:keywords", manager)) != null)
- Keywords = node.InnerXml;
- if ((node = doc.SelectSingleNode ("prop:coreProperties/dc:language", manager)) != null)
- Language = node.InnerXml;
- if ((node = doc.SelectSingleNode ("prop:coreProperties/prop:lastModifiedBy", manager)) != null)
- LastModifiedBy = node.InnerXml;
- if ((node = doc.SelectSingleNode ("prop:coreProperties/prop:lastPrinted", manager)) != null)
- LastPrinted = DateTime.Parse (node.InnerXml);
- if ((node = doc.SelectSingleNode ("prop:coreProperties/dcterms:modified", manager)) != null)
- Modified = DateTime.Parse (node.InnerXml);
- if ((node = doc.SelectSingleNode ("prop:coreProperties/prop:revision", manager)) != null)
- Revision = node.InnerXml;
- if ((node = doc.SelectSingleNode ("prop:coreProperties/dc:subject", manager)) != null)
- Subject = node.InnerXml;
- if ((node = doc.SelectSingleNode ("prop:coreProperties/dc:title", manager)) != null)
- Title = node.InnerXml;
- if ((node = doc.SelectSingleNode ("prop:coreProperties/prop:version", manager)) != null)
- Version = node.InnerXml;
+ protected virtual void Dispose (bool disposing)
+ {
+ // Nothing
}
- internal void WriteTo (Stream stream)
+ internal void Flush ()
{
- XmlDocument doc = new XmlDocument ();
- XmlNamespaceManager manager = new XmlNamespaceManager (doc.NameTable);
- manager.AddNamespace ("prop", NSProperties);
- manager.AddNamespace ("dc", NSDc);
- manager.AddNamespace ("dcterms", NSDcTerms);
- manager.AddNamespace ("xsi", NSXsi);
+ if (Part == null)
+ {
+ int id = System.Threading.Interlocked.Increment (ref uuid);
+ Uri uri = new Uri (string.Format ("/package/services/metadata/core-properties/{0}.psmdcp", id), UriKind.Relative);
+ Part = Package.CreatePart (uri, PackagePropertiesContentType);
+ PackageRelationship rel = Package.CreateRelationship (uri, TargetMode.Internal, NSPackageProperties);
+ }
- // Create XML declaration
- doc.AppendChild (doc.CreateXmlDeclaration ("1.0", "UTF-8", null));
+ using (Stream s = Part.GetStream ()) {
+ s.SetLength (0);
+
+ using (XmlTextWriter writer = new XmlTextWriter (s, System.Text.Encoding.UTF8))
+ WriteTo (writer);
+ }
+ }
+
+ internal virtual void LoadFrom (Stream stream)
+ {
- // Create root node with required namespace declarations
- XmlNode coreProperties = doc.AppendChild (doc.CreateNode (XmlNodeType.Element, "coreProperties", NSProperties));
- coreProperties.Attributes.Append (doc.CreateAttribute ("xmlns:dc")).Value = NSDc;
- coreProperties.Attributes.Append (doc.CreateAttribute ("xmlns:dcterms")).Value = NSDcTerms;
- coreProperties.Attributes.Append (doc.CreateAttribute ("xmlns:xsi")).Value = NSXsi;
+ }
- // Create the children
- coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "category", NSProperties)).InnerXml = "category";
- coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "contentStatus", NSProperties)).InnerXml = "Version";
- coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "contentType", NSProperties)).InnerXml = "";
- coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "dcterms", "created", NSDcTerms)).InnerXml = "Version";
- coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "dc", "creator", NSDc)).InnerXml = "Version";
- coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "dc", "description", NSDc)).InnerXml = "Version";
- coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "dc", "identifier", NSDc)).InnerXml = "Version";
- coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "keywords", NSProperties)).InnerXml = "Version";
- coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "dc", "language", NSDc)).InnerXml = "Version";
- coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "lastModifiedBy", NSProperties)).InnerXml = "Version";
- coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "lastPrinted", NSProperties)).InnerXml = "Version";
- XmlNode modified = coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "dcterms", "modified", NSDcTerms));
- coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "revision", NSProperties)).InnerXml = "Title";
- coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "dc", "subject", NSDc)).InnerXml = "Title";
- coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "dc", "title", NSDc)).InnerXml = "Title";
- coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "version", NSProperties)).InnerXml = "Title";
+ internal virtual void WriteTo (XmlTextWriter writer)
+ {
- XmlAttribute att = doc.CreateAttribute("xsi", "type", NSXsi);
- att.Value = "dcterms:W3CDTF";
- modified.Attributes.Append (att);
-
- doc.WriteContentTo (new XmlTextWriter (stream, System.Text.Encoding.UTF8));
}
}
}
\ No newline at end of file
//
using System;
+using System.Xml;
namespace System.IO.Packaging
{
class PackagePropertiesPart : PackageProperties
{
+ const string NSDc = "http://purl.org/dc/elements/1.1/";
+ const string NSDcTerms = "http://purl.org/dc/terms/";
+ const string NSXsi = "http://www.w3.org/2001/XMLSchema-instance";
+
+ string category;
+ string contentStatus;
+ string contentType;
+ DateTime? created;
+ string creator;
+ string description;
+ string identifier;
+ string keywords;
+ string language;
+ string lastModifiedBy;
+ DateTime? lastPrinted;
+ DateTime? modified;
+ string revision;
+ string subject;
+ string title;
+ string version;
+
+ public PackagePropertiesPart ()
+ {
+
+ }
+
public override string Category {
- get; set;
+ get {
+ return category;
+ }
+ set {
+ Package.CheckIsReadOnly ();
+ category = value;
+ }
}
-
public override string ContentStatus {
- get; set;
+ get {
+ return contentStatus;
+ }
+ set {
+ Package.CheckIsReadOnly ();
+ contentStatus = value;
+ }
}
-
public override string ContentType {
- get; set;
+ get {
+ return contentType;
+ }
+ set {
+ Package.CheckIsReadOnly ();
+ contentType = value;
+ }
}
-
- public override Nullable<DateTime> Created {
- get; set;
+ public override DateTime? Created {
+ get {
+ return created;
+ }
+ set {
+ Package.CheckIsReadOnly ();
+ created = value;
+ }
}
-
public override string Creator {
- get; set;
+ get {
+ return creator;
+ }
+ set {
+ Package.CheckIsReadOnly ();
+ creator = value;
+ }
}
-
public override string Description {
- get; set;
+ get {
+ return description;
+ }
+ set {
+ Package.CheckIsReadOnly ();
+ description = value;
+ }
}
-
public override string Identifier {
- get; set;
+ get {
+ return identifier;
+ }
+ set {
+ Package.CheckIsReadOnly ();
+ identifier = value;
+ }
}
-
public override string Keywords {
- get; set;
+ get {
+ return keywords;
+ }
+ set {
+ Package.CheckIsReadOnly ();
+ keywords = value;
+ }
}
-
public override string Language {
- get; set;
+ get {
+ return language;
+ }
+ set {
+ Package.CheckIsReadOnly ();
+ language = value;
+ }
}
-
public override string LastModifiedBy {
- get; set;
+ get {
+ return lastModifiedBy;
+ }
+ set {
+ Package.CheckIsReadOnly ();
+ lastModifiedBy = value;
+ }
}
-
- public override Nullable<DateTime> LastPrinted {
- get; set;
+ public override DateTime? LastPrinted {
+ get {
+ return lastPrinted;
+ }
+ set {
+ Package.CheckIsReadOnly ();
+ lastPrinted = value;
+ }
}
-
- public override Nullable<DateTime> Modified {
- get; set;
+ public override DateTime? Modified {
+ get {
+ return modified;
+ }
+ set {
+ Package.CheckIsReadOnly ();
+ modified = value;
+ }
}
-
public override string Revision {
- get; set;
+ get {
+ return revision;
+ }
+ set {
+ Package.CheckIsReadOnly ();
+ revision = value;
+ }
}
-
public override string Subject {
- get; set;
+ get {
+ return subject;
+ }
+ set {
+ Package.CheckIsReadOnly ();
+ subject = value;
+ }
}
-
public override string Title {
- get; set;
+ get {
+ return title;
+ }
+ set {
+ Package.CheckIsReadOnly ();
+ title = value;
+ }
}
-
public override string Version {
- get; set;
+ get {
+ return version;
+ }
+ set {
+ Package.CheckIsReadOnly ();
+ version = value;
+ }
+ }
+
+ internal override void LoadFrom (Stream stream)
+ {
+ XmlDocument doc = new XmlDocument ();
+ doc.Load (stream);
+
+ XmlNamespaceManager manager = new XmlNamespaceManager (doc.NameTable);
+ manager.AddNamespace ("prop", NSPackageProperties);
+ manager.AddNamespace ("dc", NSDc);
+ manager.AddNamespace ("dcterms", NSDcTerms);
+ manager.AddNamespace ("xsi", NSXsi);
+
+ XmlNode node;
+ if ((node = doc.SelectSingleNode ("prop:coreProperties/prop:category", manager)) != null)
+ category = node.InnerXml;
+ if ((node = doc.SelectSingleNode ("prop:coreProperties/prop:contentStatus", manager)) != null)
+ ContentStatus = node.InnerXml;
+ if ((node = doc.SelectSingleNode ("prop:coreProperties/prop:contentType", manager)) != null)
+ ContentType = node.InnerXml;
+ if ((node = doc.SelectSingleNode ("prop:coreProperties/dcterms:created", manager)) != null)
+ Created = DateTime.Parse (node.InnerXml);
+ if ((node = doc.SelectSingleNode ("prop:coreProperties/dc:creator", manager)) != null)
+ Creator = node.InnerXml;
+ if ((node = doc.SelectSingleNode ("prop:coreProperties/dc:description", manager)) != null)
+ Description = node.InnerXml;
+ if ((node = doc.SelectSingleNode ("prop:coreProperties/dc:identifier", manager)) != null)
+ Identifier = node.InnerXml;
+ if ((node = doc.SelectSingleNode ("prop:coreProperties/prop:keywords", manager)) != null)
+ Keywords = node.InnerXml;
+ if ((node = doc.SelectSingleNode ("prop:coreProperties/dc:language", manager)) != null)
+ Language = node.InnerXml;
+ if ((node = doc.SelectSingleNode ("prop:coreProperties/prop:lastModifiedBy", manager)) != null)
+ LastModifiedBy = node.InnerXml;
+ if ((node = doc.SelectSingleNode ("prop:coreProperties/prop:lastPrinted", manager)) != null)
+ LastPrinted = DateTime.Parse (node.InnerXml);
+ if ((node = doc.SelectSingleNode ("prop:coreProperties/dcterms:modified", manager)) != null)
+ Modified = DateTime.Parse (node.InnerXml);
+ if ((node = doc.SelectSingleNode ("prop:coreProperties/prop:revision", manager)) != null)
+ Revision = node.InnerXml;
+ if ((node = doc.SelectSingleNode ("prop:coreProperties/dc:subject", manager)) != null)
+ Subject = node.InnerXml;
+ if ((node = doc.SelectSingleNode ("prop:coreProperties/dc:title", manager)) != null)
+ Title = node.InnerXml;
+ if ((node = doc.SelectSingleNode ("prop:coreProperties/prop:version", manager)) != null)
+ Version = node.InnerXml;
+ }
+
+ internal override void WriteTo(XmlTextWriter writer)
+ {
+ XmlDocument doc = new XmlDocument ();
+ XmlNamespaceManager manager = new XmlNamespaceManager (doc.NameTable);
+ manager.AddNamespace ("prop", NSPackageProperties);
+ manager.AddNamespace ("dc", NSDc);
+ manager.AddNamespace ("dcterms", NSDcTerms);
+ manager.AddNamespace ("xsi", NSXsi);
+
+ // Create XML declaration
+ doc.AppendChild (doc.CreateXmlDeclaration ("1.0", "UTF-8", null));
+
+ // Create root node with required namespace declarations
+ XmlNode coreProperties = doc.AppendChild (doc.CreateNode (XmlNodeType.Element, "coreProperties", NSPackageProperties));
+ coreProperties.Attributes.Append (doc.CreateAttribute ("xmlns:dc")).Value = NSDc;
+ coreProperties.Attributes.Append (doc.CreateAttribute ("xmlns:dcterms")).Value = NSDcTerms;
+ coreProperties.Attributes.Append (doc.CreateAttribute ("xmlns:xsi")).Value = NSXsi;
+
+ // Create the children
+ coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "category", NSPackageProperties)).InnerXml = Category ?? "";
+ coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "contentStatus", NSPackageProperties)).InnerXml = ContentStatus ?? "";
+ coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "contentType", NSPackageProperties)).InnerXml = ContentType ?? "";
+ if (Created.HasValue)
+ coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "dcterms", "created", NSDcTerms)).InnerXml = Created.Value.ToString ();
+ coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "dc", "creator", NSDc)).InnerXml = Creator ?? "";
+ coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "dc", "description", NSDc)).InnerXml = Description ?? "";
+ coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "dc", "identifier", NSDc)).InnerXml = Identifier ?? "";
+ coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "keywords", NSPackageProperties)).InnerXml = Keywords ?? "";
+ coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "dc", "language", NSDc)).InnerXml = Language ?? "";
+ coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "lastModifiedBy", NSPackageProperties)).InnerXml = LastModifiedBy ?? "";
+ if (LastPrinted.HasValue)
+ coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "lastPrinted", NSPackageProperties)).InnerXml = LastPrinted.Value.ToString ();
+ coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "revision", NSPackageProperties)).InnerXml = Revision ?? "";
+ coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "dc", "subject", NSDc)).InnerXml = Subject ?? "";
+ coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "dc", "title", NSDc)).InnerXml = Title ?? "";
+ coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "version", NSPackageProperties)).InnerXml = Version ?? "";
+
+ if (Modified.HasValue)
+ {
+ XmlAttribute att = doc.CreateAttribute("xsi", "type", NSXsi);
+ att.Value = "dcterms:W3CDTF";
+
+ XmlNode modified = coreProperties.AppendChild (doc.CreateNode (XmlNodeType.Element, "dcterms", "modified", NSDcTerms));
+ modified.Attributes.Append (att);
+ modified.InnerXml = Modified.Value.ToString ();
+ }
+
+ doc.WriteContentTo (writer);
}
}
}
using (Stream s = archive.GetStream (ContentUri))
doc.Load (s);
- doc.WriteContentTo (new XmlTextWriter (Console.Out));
XmlNamespaceManager manager = new XmlNamespaceManager (doc.NameTable);
manager.AddNamespace ("content", ContentNamespace);
protected override void FlushCore ()
{
- throw new NotImplementedException ();
+ // Flush...
}
protected override PackagePart GetPartCore (Uri partUri)
System.IO.Packaging/PackagePart.cs
System.IO.Packaging/PackagePartCollection.cs
System.IO.Packaging/PackageProperties.cs
+System.IO.Packaging/PackagePropertiesPart.cs
System.IO.Packaging/PackageRelationship.cs
System.IO.Packaging/PackageRelationshipCollection.cs
System.IO.Packaging/PackageRelationshipSelector.cs