/// <include file='doc\XmlSchemaSet.uex' path='docs/doc[@for="XmlSchemaSet.Compile"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public void Compile() {
if (schemas.Count == 0) {
ClearTables(); //Clear any previously present compiled state left by calling just Remove() on the set
return;
}
if (isCompiled) {
return;
}
lock (InternalSyncObject) {
if (!isCompiled) { //Locking before checking isCompiled to avoid problems with double locking
Compiler compiler = new Compiler(nameTable, eventHandler, schemaForSchema, compilationSettings);
SchemaInfo newCompiledInfo = new SchemaInfo();
int schemaIndex = 0;
if (!compileAll) { //if we are not compiling everything again, Move the pre-compiled schemas to the compiler's tables
compiler.ImportAllCompiledSchemas(this);
}
try { //First thing to do in the try block is to acquire locks since finally will try to release them.
//If we dont accuire the locks first, and an exception occurs in the code before the locking code, then Threading.SynchronizationLockException will be thrown
//when attempting to release it in the finally block
XmlSchema currentSchema;
XmlSchema xmlNSSchema = Preprocessor.GetBuildInSchema();
for (schemaIndex = 0; schemaIndex < schemas.Count; schemaIndex++) {
currentSchema = (XmlSchema)schemas.GetByIndex(schemaIndex);
//Lock schema to be compiled
Monitor.Enter(currentSchema);
if (!currentSchema.IsPreprocessed) {
SendValidationEvent(new XmlSchemaException(Res.Sch_SchemaNotPreprocessed, string.Empty), XmlSeverityType.Error);
isCompiled = false;
return;
}
if (currentSchema.IsCompiledBySet) {
if (!compileAll) {
continue;
}
else if ((object)currentSchema == (object)xmlNSSchema) { // prepare for xml namespace schema without cleanup
compiler.Prepare(currentSchema, false);
continue;
}
}
compiler.Prepare(currentSchema, true);
}
isCompiled = compiler.Execute(this, newCompiledInfo);
if (isCompiled) {
compileAll = false;
newCompiledInfo.Add(cachedCompiledInfo, eventHandler); //Add all the items from the old to the new compiled object
cachedCompiledInfo = newCompiledInfo; //Replace the compiled info in the set after successful compilation
}
}
finally {
//Release locks on all schemas
XmlSchema currentSchema;
if (schemaIndex == schemas.Count) {
schemaIndex--;
}
for (int i = schemaIndex; i >= 0; i--) {
currentSchema = (XmlSchema)schemas.GetByIndex(i);
if (currentSchema == Preprocessor.GetBuildInSchema()) { //dont re-set compiled flags for xml namespace schema
Monitor.Exit(currentSchema);
continue;
}
currentSchema.IsCompiledBySet = isCompiled;
Monitor.Exit(currentSchema);
}
}
}
}
return;
}