[WindowsBase] Don't treat special file [Content-Types].xml as a part, ends up as...
[mono.git] / mcs / class / WindowsBase / System.IO.Packaging / PackUriHelper.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2007 Novell, Inc. (http://www.novell.com)
21 //
22 // Authors:
23 //      Chris Toshok (toshok@ximian.com)
24 //
25
26 using System;
27
28 namespace System.IO.Packaging {
29
30         public static class PackUriHelper
31         {
32                 public static readonly string UriSchemePack = "pack";
33                 static readonly Uri PackSchemeUri = new Uri("pack://", UriKind.Absolute);
34                 
35                 static PackUriHelper ()
36                 {
37                         if (!UriParser.IsKnownScheme (UriSchemePack))
38                                 UriParser.Register (new PackUriParser (), UriSchemePack, -1);
39                 }
40                 
41                 public static int ComparePackUri (Uri firstPackUri, Uri secondPackUri)
42                 {
43                         // FIXME: Do i need to do validation that it is a pack:// uri?
44                         if (firstPackUri == null)
45                                 return secondPackUri == null ? 0 : -1;
46                         if (secondPackUri == null)
47                                 return 1;
48
49                         // FIXME: What exactly is compared. Lets assume originalstring
50                         return firstPackUri.OriginalString.CompareTo (secondPackUri.OriginalString);
51                 }
52
53                 public static int ComparePartUri (Uri firstPartUri, Uri secondPartUri)
54                 {
55                         // FIXME: Do i need to do validation that it is a part URI?
56                         if (firstPartUri == null)
57                                 return secondPartUri == null ? 0 : -1;
58                         if (secondPartUri == null)
59                                 return 1;
60
61                         return firstPartUri.OriginalString.CompareTo (secondPartUri.OriginalString);
62                 }
63
64                 public static Uri Create (Uri packageUri)
65                 {
66                         return Create (packageUri, null, null);
67                 }
68
69                 public static Uri Create (Uri packageUri, Uri partUri)
70                 {
71                         return Create (packageUri, partUri, null);
72                 }
73
74                 public static Uri Create (Uri packageUri, Uri partUri, string fragment)
75                 {
76                         Check.PackageUri (packageUri);
77                         Check.PackageUriIsValid (packageUri);
78                         
79                         if (partUri != null)
80                                 Check.PartUriIsValid (partUri);
81                         
82                         if (fragment != null && (fragment.Length == 0 || fragment[0] != '#'))
83                                 throw new ArgumentException ("Fragment", "Fragment must not be empty and must start with '#'");
84
85                         // FIXME: Validate that partUri is a valid one? Must be relative, must start with '/'
86
87                         // First replace the slashes, then escape the special characters
88                         string orig = packageUri.OriginalString.Replace ('/', ',');
89                         
90                         if (partUri != null)
91                                 orig += partUri.OriginalString;
92
93 //                      if (sb[sb.Length - 1] != '/')
94 //                              sb.Append ('/');
95
96                         if (fragment != null)
97                                 orig += fragment;
98                         
99                         return new Uri ("pack://" + orig);
100                 }
101
102                 public static Uri CreatePartUri (Uri partUri)
103                 {
104                         Check.PartUri (partUri);
105                         
106                         if (partUri.OriginalString[0] != '/')
107                                 partUri = new Uri("/" + partUri.ToString (), UriKind.Relative);
108                         return partUri;
109                 }
110
111                 public static Uri GetNormalizedPartUri (Uri partUri)
112                 {
113                         Check.PartUri (partUri);
114                         return new Uri (partUri.ToString ().ToUpperInvariant (), UriKind.Relative);
115                 }
116
117                 public static Uri GetPackageUri (Uri packUri)
118                 {
119                         //Check.PackUri (packUri);
120                         string s = packUri.Host.Replace (',', '/');
121                         return new Uri (s, UriKind.Relative);
122                 }
123
124                 public static Uri GetPartUri (Uri packUri)
125                 {
126                         throw new NotImplementedException ();
127                 }
128
129                 public static Uri GetRelationshipPartUri (Uri partUri)
130                 {
131                         Check.PartUri (partUri);
132                         Check.PartUriIsValid (partUri);
133                         
134                         int index = partUri.OriginalString.LastIndexOf ("/");
135                         string s = partUri.OriginalString.Substring (0, index);
136                         s += "/_rels" + partUri.OriginalString.Substring (index) + ".rels";
137                         return new Uri (s, UriKind.Relative);
138                 }
139
140                 public static Uri GetRelativeUri (Uri sourcePartUri, Uri targetPartUri)
141                 {
142                         //Check.SourcePartUri (sourcePartUri);
143                         //Check.TargetPartUri (targetPartUri);
144
145                         return sourcePartUri;
146                 }
147
148                 public static Uri GetSourcePartUriFromRelationshipPartUri (Uri relationshipPartUri)
149                 {
150                         //Check.RelationshipPartUri (relationshipPartUri);
151                         if (!IsRelationshipPartUri (relationshipPartUri))
152                                 throw new Exception  ("is not a relationship part!?");
153                         return null;
154                 }
155
156                 public static bool IsRelationshipPartUri (Uri partUri)
157                 {
158                         Check.PartUri (partUri);
159                         return partUri.OriginalString.StartsWith ("/_rels") && partUri.OriginalString.EndsWith (".rels");
160                 }
161
162                 public static Uri ResolvePartUri (Uri sourcePartUri, Uri targetUri)
163                 {
164                         Check.SourcePartUri (sourcePartUri);
165                         Check.TargetUri (targetUri);
166                         
167                         Check.PartUriIsValid (sourcePartUri);
168                         if (targetUri.IsAbsoluteUri)
169                                 throw new ArgumentException ("targetUri", "Absolute URIs are not supported");
170
171                         Uri uri = new Uri ("http://fake.com");
172                         uri = new Uri (uri, sourcePartUri);
173                         uri = new Uri (uri, targetUri);
174
175                         // Trim out 'http://fake.com'
176                         return new Uri (uri.OriginalString.Substring (15), UriKind.Relative); 
177                 }
178         }
179
180 }