forked from nhibernate/nhibernate-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMappingsQueue.cs
112 lines (98 loc) · 2.79 KB
/
MappingsQueue.cs
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NHibernate.Cfg
{
/// <summary>
/// Queues mapping files according to their dependency order.
/// </summary>
public class MappingsQueue
{
private readonly Queue availableEntries = new Queue();
private readonly HashSet<string> processedClassNames = new HashSet<string>();
private readonly List<MappingsQueueEntry> unavailableEntries = new List<MappingsQueueEntry>();
/// <summary>
/// Adds the specified document to the queue.
/// </summary>
public void AddDocument(NamedXmlDocument document)
{
var re = new MappingsQueueEntry(document, ClassExtractor.GetClassEntries(document.Document));
AddEntry(re);
}
/// <summary>
/// Gets a <see cref="NamedXmlDocument" /> that can now be processed (i.e.
/// that doesn't depend on classes not yet processed).
/// </summary>
/// <returns></returns>
public NamedXmlDocument GetNextAvailableResource()
{
if (availableEntries.Count == 0)
{
return null;
}
var entry = (MappingsQueueEntry) availableEntries.Dequeue();
AddProcessedClassNames(entry.ContainedClassNames);
return entry.Document;
}
/// <summary>
/// Checks that no unprocessed documents remain in the queue.
/// </summary>
public void CheckNoUnavailableEntries()
{
if (unavailableEntries.Count > 0)
{
throw new MappingException(FormatExceptionMessage(unavailableEntries));
}
}
private void AddProcessedClassNames(ICollection<string> classNames)
{
processedClassNames.UnionWith(classNames);
if (classNames.Count > 0)
{
ProcessUnavailableEntries();
}
}
private void AddEntry(MappingsQueueEntry re)
{
if (CanProcess(re))
{
availableEntries.Enqueue(re);
}
else
{
unavailableEntries.Add(re);
}
}
private void ProcessUnavailableEntries()
{
MappingsQueueEntry found;
while ((found = FindAvailableResourceEntry()) != null)
{
availableEntries.Enqueue(found);
unavailableEntries.Remove(found);
}
}
private MappingsQueueEntry FindAvailableResourceEntry()
{
return unavailableEntries.FirstOrDefault(CanProcess);
}
private bool CanProcess(MappingsQueueEntry ce)
{
return
ce.RequiredClassNames.All(
c => (processedClassNames.Contains(c.FullClassName) || processedClassNames.Contains(c.EntityName)));
}
private static string FormatExceptionMessage(IEnumerable<MappingsQueueEntry> resourceEntries)
{
var message = new StringBuilder(500);
message.Append("These classes referenced by 'extends' were not found:");
foreach (MappingsQueueEntry.RequiredEntityName className in
resourceEntries.SelectMany(resourceEntry => resourceEntry.RequiredClassNames))
{
message.Append('\n').Append(className);
}
return message.ToString();
}
}
}