blob: 2cf8040e573a91dfbe3f16023fa488f15165c6b9 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
//------------------------------------------------------------------------------
// <copyright file="XmlSchemaExternal.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
namespace System.Xml.Schema {
using System.Collections;
using System.ComponentModel;
using System.Diagnostics;
using System.Xml.Serialization;
// Case insensitive file name key for use in a hashtable.
internal class ChameleonKey {
internal string targetNS;
internal Uri chameleonLocation;
// Original schema (used for reference equality only)
// stored only when the chameleonLocation is an empty URI in which case the location
// is not a good enough identification of the schema
internal XmlSchema originalSchema;
int hashCode;
/// <summary>
/// Creates a new chameleon key - an identification for a chameleon schema instance
/// </summary>
/// <param name="ns">The target namespace of the instance of the chameleon schema</param>
/// <param name="originalSchema">The original (chameleon) schema (the one without the target namespace).
/// This is used to get the location (base uri) and to identify the schema.</param>
public ChameleonKey(string ns, XmlSchema originalSchema) {
targetNS = ns;
chameleonLocation = originalSchema.BaseUri;
if (chameleonLocation.OriginalString.Length == 0) {
// Only store the original schema when the location is empty URI
// by doing this we effectively allow multiple chameleon schemas for the same target namespace
// and URI, but that only makes sense for empty URI (not specified)
this.originalSchema = originalSchema;
}
}
public override int GetHashCode() {
if (hashCode == 0) {
hashCode = targetNS.GetHashCode() + chameleonLocation.GetHashCode() +
(originalSchema == null ? 0 : originalSchema.GetHashCode());
}
return hashCode;
}
public override bool Equals(object obj) {
if (Ref.ReferenceEquals(this,obj)) {
return true;
}
ChameleonKey cKey = obj as ChameleonKey;
if (cKey != null) {
// We want to compare the target NS and the schema location.
// If the location is empty (but only then) we also want to compare the original schema instance.
// As noted above the originalSchema is null if the chameleonLocation is non-empty. As a result we
// can simply compare the reference to the original schema always (regardless of the schemalocation).
Debug.Assert((chameleonLocation.OriginalString.Length == 0 && originalSchema != null)
|| (chameleonLocation.OriginalString.Length != 0 && originalSchema == null));
return this.targetNS.Equals(cKey.targetNS) && this.chameleonLocation.Equals(cKey.chameleonLocation) &&
Ref.ReferenceEquals(originalSchema, cKey.originalSchema);
}
return false;
}
}
}
|