private static void LoadLibrary(Program program, string libraryName, bool isKnown) { lock (program.Catalog.Libraries) { try { Schema.Library library = program.Catalog.Libraries[libraryName]; VersionNumber currentVersion = ((ServerCatalogDeviceSession)program.CatalogDeviceSession).GetCurrentLibraryVersion(libraryName); if (program.Catalog.LoadedLibraries.Contains(library.Name)) { throw new Schema.SchemaException(Schema.SchemaException.Codes.LibraryAlreadyLoaded, libraryName); } bool isLoaded = false; bool areAssembliesRegistered = false; Schema.LoadedLibrary loadedLibrary = null; try { loadedLibrary = new Schema.LoadedLibrary(libraryName); loadedLibrary.Owner = program.CatalogDeviceSession.ResolveUser(((ServerCatalogDeviceSession)program.CatalogDeviceSession).GetLibraryOwner(libraryName)); // Ensure that each required library is loaded foreach (Schema.LibraryReference reference in library.Libraries) { Schema.Library requiredLibrary = program.Catalog.Libraries[reference.Name]; if (!VersionNumber.Compatible(reference.Version, requiredLibrary.Version)) { throw new Schema.SchemaException(Schema.SchemaException.Codes.LibraryVersionMismatch, reference.Name, reference.Version.ToString(), requiredLibrary.Version.ToString()); } if (!program.Catalog.LoadedLibraries.Contains(reference.Name)) { if (!requiredLibrary.IsSuspect) { LoadLibrary(program, reference.Name, isKnown); } else { throw new Schema.SchemaException(Schema.SchemaException.Codes.RequiredLibraryNotLoaded, libraryName, reference.Name); } } loadedLibrary.RequiredLibraries.Add(program.CatalogDeviceSession.ResolveLoadedLibrary(reference.Name)); program.Catalog.OperatorResolutionCache.Clear(loadedLibrary.GetNameResolutionPath(program.ServerProcess.ServerSession.Server.SystemLibrary)); loadedLibrary.ClearNameResolutionPath(); } program.ServerProcess.ServerSession.Server.DoLibraryLoading(library.Name); try { // RegisterAssemblies RegisterLibraryFiles(program, library, loadedLibrary); areAssembliesRegistered = true; program.CatalogDeviceSession.InsertLoadedLibrary(loadedLibrary); loadedLibrary.AttachLibrary(); try { ((ServerCatalogDeviceSession)program.CatalogDeviceSession).SetLibraryOwner(loadedLibrary.Name, loadedLibrary.Owner.ID); } catch (Exception registerException) { loadedLibrary.DetachLibrary(); throw registerException; } isLoaded = true; // If we reach this point, a subsequent exception must unload the library if (library.IsSuspect) { library.IsSuspect = false; library.SaveInfoToFile(Path.Combine(library.GetInstanceLibraryDirectory(((Server.Server)program.ServerProcess.ServerSession.Server).InstanceDirectory), Schema.LibraryUtility.GetInfoFileName(library.Name))); } } finally { program.ServerProcess.ServerSession.Server.DoLibraryLoaded(library.Name); } } catch (Exception exception) { program.ServerProcess.ServerSession.Server.LogError(exception); library.IsSuspect = true; library.SuspectReason = ExceptionUtility.DetailedDescription(exception); library.SaveInfoToFile(Path.Combine(library.GetInstanceLibraryDirectory(((Server.Server)program.ServerProcess.ServerSession.Server).InstanceDirectory), Schema.LibraryUtility.GetInfoFileName(library.Name))); if (isLoaded) { UnregisterLibrary(program, libraryName, false); } else if (areAssembliesRegistered) { UnregisterLibraryAssemblies(program, loadedLibrary); } throw; } ((ServerCatalogDeviceSession)program.CatalogDeviceSession).SetCurrentLibraryVersion(library.Name, currentVersion); // Once a library has loaded, record the version number program.Catalog.Libraries.DoLibraryLoaded(program, library.Name); } catch { if (program.ServerProcess.ServerSession.Server.State == ServerState.Started) { throw; } } } }
public static void RegisterLibrary(Program program, string libraryName, bool withReconciliation) { int saveReconciliationState = program.ServerProcess.SuspendReconciliationState(); try { if (!withReconciliation) { program.ServerProcess.DisableReconciliation(); } try { lock (program.Catalog.Libraries) { Schema.Library library = program.Catalog.Libraries[libraryName]; Schema.LoadedLibrary loadedLibrary = program.CatalogDeviceSession.ResolveLoadedLibrary(library.Name, false); if (loadedLibrary != null) { throw new Schema.SchemaException(Schema.SchemaException.Codes.LibraryAlreadyRegistered, libraryName); } loadedLibrary = new Schema.LoadedLibrary(libraryName); loadedLibrary.Owner = program.Plan.User; // Ensure that each required library is registered foreach (Schema.LibraryReference reference in library.Libraries) { CheckCircularLibraryReference(program, library, reference.Name); EnsureLibraryRegistered(program, reference, withReconciliation); loadedLibrary.RequiredLibraries.Add(program.CatalogDeviceSession.ResolveLoadedLibrary(reference.Name)); program.Catalog.OperatorResolutionCache.Clear(loadedLibrary.GetNameResolutionPath(program.ServerProcess.ServerSession.Server.SystemLibrary)); loadedLibrary.ClearNameResolutionPath(); } ((Server.Server)program.ServerProcess.ServerSession.Server).DoLibraryLoading(library.Name); try { // Register the assemblies RegisterLibraryFiles(program, library, loadedLibrary); program.CatalogDeviceSession.InsertLoadedLibrary(loadedLibrary); loadedLibrary.AttachLibrary(); try { // Set the current library to the newly registered library Schema.LoadedLibrary currentLibrary = program.Plan.CurrentLibrary; program.ServerProcess.ServerSession.CurrentLibrary = loadedLibrary; try { // run the register.d4 script if it exists in the library // catalog objects created in this script are part of this library string registerFileName = Path.Combine(library.GetLibraryDirectory(((Server.Server)program.ServerProcess.ServerSession.Server).LibraryDirectory), RegisterFileName); if (File.Exists(registerFileName)) { try { using (StreamReader reader = new StreamReader(registerFileName)) { program.ServerProcess.ServerSession.Server.RunScript ( program.ServerProcess, reader.ReadToEnd(), libraryName, new DAE.Debug.DebugLocator(String.Format(RegisterDocumentLocator, libraryName), 1, 1) ); } } catch (Exception exception) { throw new RuntimeException(RuntimeException.Codes.LibraryRegistrationFailed, exception, libraryName); } } ((ServerCatalogDeviceSession)program.CatalogDeviceSession).SetCurrentLibraryVersion(library.Name, library.Version); ((ServerCatalogDeviceSession)program.CatalogDeviceSession).SetLibraryOwner(loadedLibrary.Name, loadedLibrary.Owner.ID); if (library.IsSuspect) { library.IsSuspect = false; library.SaveInfoToFile(Path.Combine(library.GetInstanceLibraryDirectory(((Server.Server)program.ServerProcess.ServerSession.Server).InstanceDirectory), GetInfoFileName(library.Name))); } } catch { program.ServerProcess.ServerSession.CurrentLibrary = currentLibrary; throw; } } catch { loadedLibrary.DetachLibrary(); throw; } program.Catalog.Libraries.DoLibraryLoaded(program, library.Name); } finally { ((Server.Server)program.ServerProcess.ServerSession.Server).DoLibraryLoaded(libraryName); } } } finally { if (!withReconciliation) { program.ServerProcess.EnableReconciliation(); } } } finally { program.ServerProcess.ResumeReconciliationState(saveReconciliationState); } }