private void DispatchLoadToExtensions() { if (Hierarchy != null) { var projectItem = VsUtils.GetProjectItem(Hierarchy, ItemId); if (projectItem != null) { var fileContents = VSHelpers.GetTextFromVsTextLines(VsBuffer); string newBufferContents; List <ExtensionError> extensionErrors; if (StandaloneXmlModelProvider.TryGetBufferViaExtensions( projectItem, fileContents, out newBufferContents, out extensionErrors)) { if (VSHelpers.CheckOutFilesIfEditable(ServiceProvider, new[] { FileName })) { VsUtils.SetTextForVsTextLines(VsBuffer, newBufferContents); } else { ErrorListHelper.LogExtensionErrors( new List <ExtensionError> { new ExtensionError( string.Format( CultureInfo.CurrentCulture, Resources.ExtensionError_SourceControlLock, Path.GetFileName(FileName)), ErrorCodes.ExtensionsError_BufferNotEditable, ExtensionErrorSeverity.Error) }, projectItem); } } } } }
private void ProcessErrors(IList <EdmSchemaError> schemaErrors, Uri projectItemUri, EFArtifact artifact) { // since we will inevitably add *all* errors from the artifact set into the error list, we can easily // clear the entire error list here even though we just validate the CSDL. var errorList = ErrorListHelper.GetSingleDocErrorList(projectItemUri); if (errorList != null) { errorList.Clear(); } if (artifact == null) { Debug.Fail("Where is the artifact? We should have created it at least through the temporary model manager"); return; } // we have to remove both the RMV and SFG CSDL errors to prevent duplicates artifact.ArtifactSet.RemoveErrorsForArtifact(artifact, ErrorClass.Runtime_CSDL); // add all CSDL-based SFG errors to the artifact set if (schemaErrors.Count > 0) { foreach (var error in schemaErrors) { // construct an ErrorInfo with correct line/column number and add it to the artifact set. Note that the CodeGen EdmSchemaError line // refers to the line of the error inside the CSDL, so to get the line of the error in the edmx file we have to offset it by the line // number where the conceptual model begins. var edmxErrorLine = error.Line + artifact.ConceptualModel().GetLineNumber(); var efobject = artifact.FindEFObjectForLineAndColumn(edmxErrorLine, error.Column); var errorInfo = new ErrorInfo( GetErrorInfoSeverity(error), error.Message, efobject, error.ErrorCode, ErrorClass.Runtime_CSDL); artifact.ArtifactSet.AddError(errorInfo); } } // get all the ErrorInfos for this artifact and add it to the error list var artifactSet = artifact.ArtifactSet; Debug.Assert(artifactSet != null, "Where is the artifact set for this artifact?"); if (artifactSet != null) { var errors = artifactSet.GetArtifactOnlyErrors(artifact); if (errors.Count > 0) { // resolve the hierarchy and item id for adding to the error list var hierarchy = VSHelpers.GetVsHierarchy(ProjectItem.ContainingProject, Services.ServiceProvider); var itemId = VsUtils.GetProjectItemId(hierarchy, ProjectItem); Debug.Assert(hierarchy != null, "Why isn't there a hierarchy associated with this project item?"); Debug.Assert(itemId != VSConstants.VSITEMID_NIL, "There should be an item ID associated with this project item"); if (hierarchy != null && itemId != VSConstants.VSITEMID_NIL) { ErrorListHelper.AddErrorInfosToErrorList(errors, hierarchy, itemId); } } } }
protected override void ClearErrorList(Uri oldUri, Uri newUri) { // clear out the error list so after the rename the errors are bound to the correct artifacts ErrorListHelper.ClearErrorsForDocAcrossLists(newUri); // for a save-as the errors are associated with the oldUri ErrorListHelper.ClearErrorsForDocAcrossLists(oldUri); }
// <summary> // This will do analysis to determine if a document should be opened // only in the XmlEditor. // </summary> internal override void DetermineIfArtifactIsDesignerSafe() { VsUtils.EnsureProvider(this); base.DetermineIfArtifactIsDesignerSafe(); // // TODO: we need to figure out how to deal with errors from the wizard. // when we clear the error list below, we lose errors that we put into the error // list when running the wizard. // // // Now update the VS error list with all of the errors we want to display, which are now in the EFArtifactSet. // var errorInfos = ArtifactSet.GetAllErrors(); if (errorInfos.Count > 0) { var currentProject = VSHelpers.GetProjectForDocument(Uri.LocalPath, PackageManager.Package); if (currentProject != null) { var hierarchy = VsUtils.GetVsHierarchy(currentProject, Services.ServiceProvider); if (hierarchy != null) { var fileFinder = new VSFileFinder(Uri.LocalPath); fileFinder.FindInProject(hierarchy); Debug.Assert(fileFinder.MatchingFiles.Count <= 1, "Unexpected count of matching files in project"); // if the EDMX file is not part of the project. if (fileFinder.MatchingFiles.Count == 0) { var docData = VSHelpers.GetDocData(PackageManager.Package, Uri.LocalPath) as IEntityDesignDocData; ErrorListHelper.AddErrorInfosToErrorList(errorInfos, docData.Hierarchy, docData.ItemId); } else { foreach (var vsFileInfo in fileFinder.MatchingFiles) { if (vsFileInfo.Hierarchy == VsUtils.GetVsHierarchy(currentProject, Services.ServiceProvider)) { var errorList = ErrorListHelper.GetSingleDocErrorList(vsFileInfo.Hierarchy, vsFileInfo.ItemId); if (errorList != null) { errorList.Clear(); ErrorListHelper.AddErrorInfosToErrorList(errorInfos, vsFileInfo.Hierarchy, vsFileInfo.ItemId); } else { Debug.Fail("errorList is null!"); } } } } } } } }
// // Construct and initialize a new parsing session, using the given lexer. // // Also sets up error provision infrastructure, so that exceptions thrown // during the parsing process can be routed to the VS UI (as IntelliSense // errors or other "fix me" hints). // public ParseSession(LexSession lexer) { Lexer = lexer; var helper = new ErrorListHelper(); ErrorProvider = new ErrorListProvider(helper); ErrorProvider.ProviderName = "Epoch Language"; ErrorProvider.ProviderGuid = new Guid(VsPackage.PackageGuid); }
/// <summary> /// Initialization of the package; this method is called right after the package is sited, so this is the place /// where you can put all the initialization code that rely on services provided by VisualStudio. /// </summary> protected override void Initialize() { // Get directory of the currently opened solution. var dte2 = (DTE2)Package.GetGlobalService(typeof(SDTE)); if (dte2 != null) { // Init linter. TsLint.Init(dte2); // Init Error List helper. ErrorListHelper.Init(this); } base.Initialize(); }
/// <summary> /// When the user builds through the command line, we only load the necessary, non-UI functionality: /// 1. Xml Editor package for XLinq tree /// 2. Model Manager /// 3. Connection Manager and listener /// 4. Error List, and notifications that perform our specialized validation on build /// </summary> private void InitializeForCommandLineBuilds() { PackageManager.Package = this; _dispatcher = Dispatcher.CurrentDispatcher; // make sure that we can load the XML Editor package var vsShell = (IVsShell)GetService(typeof(SVsShell)); if (vsShell != null) { var editorPackageGuid = CommonPackageConstants.xmlEditorPackageGuid; IVsPackage editorPackage; NativeMethods.ThrowOnFailure(vsShell.LoadPackage(ref editorPackageGuid, out editorPackage)); } ErrorListHelper.RegisterForNotifications(); }
protected override void Initialize() { base.Initialize(); AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainAssemblyResolve; try { RegisterProjectFactory(new ClojureProjectFactory(this)); RegisterCommandMenuService(); HideAllClojureEditorMenuCommands(); EnableTokenizationOfNewClojureBuffers(); SetupNewClojureBuffersWithSpacingOptions(); EnableMenuCommandsOnNewClojureBuffers(); ShowClojureProjectMenuCommands(); _errorListHelper = new ErrorListHelper(); Thread delayedStartup = new Thread(() => { try { EnableSettingOfRuntimePathForNewClojureProjectsOnFirstInstall(); UnzipRuntimes(); HippieCompletionSource.Initialize(this); _metadata = new Metadata(); // SlowLoadingProcess for the 1st time. } catch (Exception e) { MessageBox.Show(string.Format("Unhandled Exception loading vsClojure : {0}{1}Stack Trace: {2}", e.Message, System.Environment.NewLine, e.StackTrace)); } }); delayedStartup.IsBackground = true; delayedStartup.Start(); } catch (Exception e) { MessageBox.Show(string.Format("Unhandled Exception loading vsClojure : {0}{1}Stack Trace: {2}", e.Message, System.Environment.NewLine, e.StackTrace)); } }
public void RunFinished() { if (_edmxItem == null) { return; } var fileExtension = Path.GetExtension(_edmxItem.FileNames[1]); Debug.Assert( _activeSolutionProject.Equals(_edmxItem.ContainingProject), "ActiveSolutionProject is not the EDMX file's containing project"); using (new VsUtils.HourglassHelper()) { var package = PackageManager.Package; Window window = null; try { ConfigFileUtils.UpdateConfig(_modelBuilderSettings); // save the model generated in the wizard UI. if (_modelBuilderSettings.GenerationOption == ModelGenerationOption.GenerateFromDatabase) { var writingModelWatch = new Stopwatch(); writingModelWatch.Start(); var mbe = _modelBuilderSettings.ModelBuilderEngine; if (!string.Equals(fileExtension, EntityDesignArtifact.EXTENSION_EDMX, StringComparison.OrdinalIgnoreCase)) { // convert the file if this isn't EDMX var edmxFileInfo = new FileInfo(_edmxItem.FileNames[1]); var conversionContext = new ModelConversionContextImpl( _edmxItem.ContainingProject, _edmxItem, edmxFileInfo, _modelBuilderSettings.TargetSchemaVersion, mbe.Model); VSArtifact.DispatchToConversionExtensions( EscherExtensionPointManager.LoadModelConversionExtensions(), fileExtension, conversionContext, loading: false); File.WriteAllText(edmxFileInfo.FullName, conversionContext.OriginalDocument); } else { // we need to use XmlWriter to output so that XmlDeclaration is preserved. using (var modelWriter = XmlWriter.Create( _edmxItem.FileNames[1], new XmlWriterSettings { Indent = true })) { mbe.Model.WriteTo(modelWriter); } } writingModelWatch.Stop(); VsUtils.LogOutputWindowPaneMessage( _edmxItem.ContainingProject, string.Format( CultureInfo.CurrentCulture, Properties.Resources.WritingModelTimeMsg, writingModelWatch.Elapsed)); // now add errors ErrorListHelper.LogWizardErrors(mbe.Errors, _edmxItem); } // set the ItemType for the generated .edmx file if (_modelBuilderSettings.VSApplicationType != VisualStudioProjectSystem.Website && string.Equals( fileExtension, EntityDesignArtifact.EXTENSION_EDMX, StringComparison.OrdinalIgnoreCase)) { _edmxItem.Properties.Item(ItemTypePropertyName).Value = EntityDeployBuildActionName; } // now open created file in VS using default viewer try { window = _edmxItem.Open(Constants.vsViewKindPrimary); Debug.Assert(window != null, "Unable to get window for created edmx file"); } catch (ObjectDisposedException) { PackageManager.Package.ModelGenErrorCache.RemoveErrors(_edmxItem.get_FileNames(1)); } } finally { package.ModelGenErrorCache.RemoveErrors(_edmxItem.FileNames[1]); } // Construct an editing context and make all final edits that require the file is opened. var edmxFileUri = new Uri(_edmxItem.FileNames[1]); var designArtifact = package.ModelManager.GetNewOrExistingArtifact( edmxFileUri, new VSXmlModelProvider(package, package)) as EntityDesignArtifact; Debug.Assert( designArtifact != null, "artifact should be of type EntityDesignArtifact but received type " + designArtifact.GetType().FullName); Debug.Assert( designArtifact.StorageModel != null, "designArtifact StorageModel cannot be null for Uri " + edmxFileUri.AbsolutePath); Debug.Assert( designArtifact.ConceptualModel != null, "designArtifact ConceptualModel cannot be null for Uri " + edmxFileUri.AbsolutePath); if (designArtifact != null && designArtifact.StorageModel != null && designArtifact.ConceptualModel != null) { var designerSafeBeforeAddingTemplates = designArtifact.IsDesignerSafe; var editingContext = package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(designArtifact.Uri); Debug.Assert(editingContext != null, "Null EditingContext for artifact " + edmxFileUri.AbsolutePath); if (editingContext != null) { // Add DbContext templates when generation is GenerateFromDatabase. (connection is configured) if (_modelBuilderSettings.GenerationOption == ModelGenerationOption.GenerateFromDatabase) { new DbContextCodeGenerator().AddDbContextTemplates( _edmxItem, _modelBuilderSettings.UseLegacyProvider); } // Create FunctionImports for every new Function var cp = PrepareCommandsAndIntegrityChecks(_modelBuilderSettings, editingContext, designArtifact); if (DbContextCodeGenerator.TemplateSupported(_edmxItem.ContainingProject, package)) { // Add command setting CodeGenerationStrategy to "None" for EmptyModel. (connection is not yet configured) // NOTE: For EmptyModel, the templates will be added after the connection is configured. // (i.e. during "Generate Database from Model" or "Refresh from Database") if (_modelBuilderSettings.GenerationOption == ModelGenerationOption.EmptyModel) { var cmd = EdmUtils.SetCodeGenStrategyToNoneCommand(designArtifact); if (cmd != null) { if (cp == null) { var cpc = new CommandProcessorContext( editingContext, EfiTransactionOriginator.CreateNewModelId, Resources.Tx_SetCodeGenerationStrategy); cp = new CommandProcessor(cpc, cmd); } else { cp.EnqueueCommand(cmd); } } } } else { // Templates not supported, add reference to SDE. (.NET Framework 3.5) VsUtils.AddProjectReference(_edmxItem.ContainingProject, "System.Data.Entity"); } if (cp != null) { cp.Invoke(); } // save the artifact to make it look as though updates were part of creation _edmxItem.Save(); if (_modelBuilderSettings.GenerationOption == ModelGenerationOption.GenerateFromDatabase && !designerSafeBeforeAddingTemplates) { // If the artifact became safe after adding references we need to reload it (this can happen // on .NET Framework 4 where we would originally create a v3 edmx if the user selected EF6 - // the artifact will be flagged as invalid since there is no runtime which could handle v3 // but after we added references to EF6 the artifacts becomes valid and need to be reloaded). designArtifact.DetermineIfArtifactIsDesignerSafe(); if (designArtifact.IsDesignerSafe) { Debug.Assert(!designArtifact.IsDirty, "Reloading dirty artifact - changes will be lost."); // Since the artifact was originally not valid we did not create the diagram for it. // Using ReloadDocData will cause the diagram to be recreated. Note we don't need to // reload the artifact itself since it has not changed. ((DocData) VSHelpers.GetDocData(package, designArtifact.Uri.LocalPath)).ReloadDocData(0); } } } if (window != null) { window.Activate(); } } } }
internal string DispatchSaveToExtensions( IServiceProvider serviceProvider, ProjectItem projectItem, string fileContents, Lazy <IModelConversionExtension, IEntityDesignerConversionData>[] converters, Lazy <IModelTransformExtension>[] serializers) { Debug.Assert(projectItem != null, "projectItem != null"); Debug.Assert(fileContents != null, "bufferText != null"); Debug.Assert(serializers != null && converters != null, "extensions must not be null"); Debug.Assert(serializers.Any() || converters.Any(), "at least one extension expected"); ModelTransformContextImpl transformContext = null; ModelConversionContextImpl conversionContext = null; try { var original = XDocument.Parse(fileContents, LoadOptions.PreserveWhitespace); var targetSchemaVersion = EdmUtils.GetEntityFrameworkVersion(projectItem.ContainingProject, serviceProvider); Debug.Assert(targetSchemaVersion != null, "we should not get here for Misc projects"); transformContext = new ModelTransformContextImpl(projectItem, targetSchemaVersion, original); // call the extensions that can save EDMX files first (even if we aren't going to end up in an EDMX file, let them process) VSArtifact.DispatchToSerializationExtensions(serializers, transformContext, loading: false); // get the extension of the file being loaded (might not be EDMX); this API will include the preceeding "." var fileInfo = new FileInfo(FileName); var fileExtension = fileInfo.Extension; // now if this is not an EDMX file, hand off to the extension who can convert it to the writable content if (!string.Equals(fileExtension, EntityDesignArtifact.ExtensionEdmx, StringComparison.OrdinalIgnoreCase)) { // the current document coming from the serializers becomes our original conversionContext = new ModelConversionContextImpl( projectItem.ContainingProject, projectItem, fileInfo, targetSchemaVersion, transformContext.CurrentDocument); // we aren't loading an EDMX file, so call the extensions who can process this file extension // when this finishes, then output should be a valid EDMX document VSArtifact.DispatchToConversionExtensions(converters, fileExtension, conversionContext, false); // we are done saving, so get bufferText from the OriginalDocument // TODO use Utf8StringWriter here somehow? return(conversionContext.OriginalDocument); } else { // we are saving an EDMX file, so get bufferText from the XDocument using (var writer = new Utf8StringWriter()) { transformContext.CurrentDocument.Save(writer, SaveOptions.None); return(writer.ToString()); } } } catch (XmlException) { // Don't do anything here. We will want to gracefully step out of the extension loading // and let the core designer handle this. return(fileContents); } finally { var errorList = ErrorListHelper.GetExtensionErrorList(serviceProvider); errorList.Clear(); // log any errors if (conversionContext != null) { if (conversionContext.Errors.Count > 0) { ErrorListHelper.LogExtensionErrors(conversionContext.Errors, projectItem); } conversionContext.Dispose(); } if (transformContext != null) { if (transformContext.Errors.Count > 0) { ErrorListHelper.LogExtensionErrors(transformContext.Errors, projectItem); } transformContext.Dispose(); } } }
public bool CreateAndLoadBuffer() { DestroyBuffer(); var pkg = PackageManager.Package as Package; IServiceProvider serviceProvider = pkg; var textLinesType = typeof(VSTextManagerInterop.IVsTextLines); var riid = textLinesType.GUID; var clsid = typeof(VSTextManagerInterop.VsTextBufferClass).GUID; _underlyingBuffer = pkg.CreateInstance(ref clsid, ref riid, textLinesType); Debug.Assert(_underlyingBuffer != null, "Failure while creating buffer."); var buffer = _underlyingBuffer as VSTextManagerInterop.IVsTextLines; Debug.Assert(buffer != null, "Why does buffer not implement IVsTextLines?"); var ows = buffer as IObjectWithSite; if (ows != null) { ows.SetSite(serviceProvider.GetService(typeof(IOleServiceProvider))); } // We want to set the LanguageService SID explicitly to the XML Language Service. // We need turn off GUID_VsBufferDetectLangSID before calling LoadDocData so that the // TextBuffer does not do the work to detect the LanguageService SID from the file extension. var userData = buffer as VSTextManagerInterop.IVsUserData; if (userData != null) { var VsBufferDetectLangSID = new Guid("{17F375AC-C814-11d1-88AD-0000F87579D2}"); //GUID_VsBufferDetectLangSID; VSErrorHandler.ThrowOnFailure(userData.SetData(ref VsBufferDetectLangSID, false)); } var langSid = CommonPackageConstants.xmlEditorLanguageService; VSErrorHandler.ThrowOnFailure(buffer.SetLanguageServiceID(ref langSid)); var persistDocData = buffer as IVsPersistDocData; if (persistDocData != null) { persistDocData.LoadDocData(FileName); var artifactUri = new Uri(FileName); var artifact = PackageManager.Package.ModelManager.GetArtifact(artifactUri); if (artifact != null && artifact.IsCodeGenArtifact) { var standaloneProvider = artifact.XmlModelProvider as StandaloneXmlModelProvider; if (standaloneProvider.ExtensionErrors == null || standaloneProvider.ExtensionErrors.Count == 0) { // If there is a cached code gen artifact, it will have loaded its text buffer using extensions already. // Therefore we can grab the text buffer from that artifact for our docdata buffer, and dispose the // code gen artifact since it's using a XmlProvider that is standalone and won't be supported by the // designer. var projectItem = VsUtils.GetProjectItem(Hierarchy, ItemId); if (projectItem != null) { if (VSHelpers.CheckOutFilesIfEditable(ServiceProvider, new[] { FileName })) { string artifactText = null; using (var writer = new Utf8StringWriter()) { artifact.XDocument.Save(writer, SaveOptions.None); artifactText = writer.ToString(); } if (!String.IsNullOrWhiteSpace(artifactText)) { VsUtils.SetTextForVsTextLines(VsBuffer, artifactText); } } else { ErrorListHelper.LogExtensionErrors( new List <ExtensionError> { new ExtensionError( string.Format( CultureInfo.CurrentCulture, Resources.ExtensionError_SourceControlLock, Path.GetFileName(FileName)), ErrorCodes.ExtensionsError_BufferNotEditable, ExtensionErrorSeverity.Error) }, projectItem); } } PackageManager.Package.ModelManager.ClearArtifact(artifactUri); } else { // If the extensions ran into errors whilst loading, we'll need to re-run extensions anyway so we ignore the cache PackageManager.Package.ModelManager.ClearArtifact(artifactUri); DispatchLoadToExtensions(); } } else { DispatchLoadToExtensions(); } } // DSL exposes the FileNameChanged event which we subscribe to so we can update the moniker inside // the text buffer, which is required to update our model as well as keep the XmlModel in sync. FileNameChanged += OnFileNameChanged; RegisterUndoTracking(); return(true); }
internal static void UpdateModelFromDatabase(EntityDesignArtifact artifact) { VsUtils.EnsureProvider(artifact); var project = VSHelpers.GetProjectForDocument(artifact.Uri.LocalPath, PackageManager.Package); var serviceProvider = Services.ServiceProvider; // set up ModelBuilderSettings for startMode=PerformDatabaseConfigAndSelectTables ModelBuilderWizardForm.WizardMode startMode; ModelBuilderSettings settings; ModelBuilderEngine.SetupSettingsAndModeForDbPages( serviceProvider, project, artifact, true, ModelBuilderWizardForm.WizardMode.PerformDatabaseConfigAndSelectTables, ModelBuilderWizardForm.WizardMode.PerformSelectTablesOnly, out startMode, out settings); settings.WizardKind = WizardKind.UpdateModel; // use existing storage namespace as new storage namespace if (null != artifact.StorageModel() && null != artifact.StorageModel().Namespace && !string.IsNullOrEmpty(artifact.StorageModel().Namespace.Value)) { settings.StorageNamespace = artifact.StorageModel().Namespace.Value; } // use existing model namespace as new model namespace (this only affects the temporary // artifact but there is a situation where the C-side EntityContainer has been given the // same name as the default model namespace where not setting this causes the temporary // artifact to be unreadable because of symbol clashes) if (null != artifact.ConceptualModel() && null != artifact.ConceptualModel().Namespace && !string.IsNullOrEmpty(artifact.ConceptualModel().Namespace.Value)) { settings.ModelNamespace = artifact.ConceptualModel().Namespace.Value; } settings.ModelBuilderEngine = new UpdateModelFromDatabaseModelBuilderEngine(); // call the ModelBuilderWizardForm var form = new ModelBuilderWizardForm(serviceProvider, settings, startMode); try { form.Start(); } catch (Exception e) { VsUtils.ShowErrorDialog( string.Format( CultureInfo.CurrentCulture, Resources.ModelObjectItemWizard_UnexpectedExceptionHasOccurred, e.Message)); return; } // if Wizard was cancelled or the user hit 'X' to close window // no need for any further action if (form.WizardCancelled || !form.WizardFinished) { return; } // Update the app. or web.config, register build providers etc ConfigFileUtils.UpdateConfig(settings); // clear all previous errors for this document first ErrorListHelper.ClearErrorsForDocAcrossLists(settings.Artifact.Uri); // log any errors that occurred during model-gen to the error list ErrorListHelper.LogUpdateModelWizardErrors(settings.ModelBuilderEngine.Errors, settings.Artifact.Uri.LocalPath); // use form.ModelBuilderSettings to look at accumulated info and // take appropriate action var editingContext = PackageManager.Package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(artifact.Uri); var shouldReloadArtifact = ProcessAccumulatedInfo(editingContext, artifact, settings); // If database was configured, add DbContext templates if (startMode == ModelBuilderWizardForm.WizardMode.PerformDatabaseConfigAndSelectTables) { var edmxItem = VsUtils.GetProjectItemForDocument(artifact.Uri.LocalPath, serviceProvider); new DbContextCodeGenerator().AddDbContextTemplates(edmxItem, settings.UseLegacyProvider); } // We can reload only after we added EF references to the project otherwise we would get a watermark // saying that the schema version does not match the referenced EF version which would not be true. // If we reload becuase there was an extension that potentially modified the artifact then it does not matter. if (shouldReloadArtifact) { artifact.ReloadArtifact(); artifact.IsDirty = true; } }
protected override void Initialize() { base.Initialize(); // for command line builds we only have a minimal set of functionality to only support building if (IsBuildingFromCommandLine) { InitializeForCommandLineBuilds(); } else { // HACK HACK -- find a better place to do this. EFModelErrorTaskNavigator.DslDesignerOnNavigate = DSLDesignerNavigationHelper.NavigateTo; // -- HostContext.Instance.LogUpdateModelWizardErrorAction = ErrorListHelper.LogUpdateModelWizardError; PackageManager.Package = this; _dispatcher = Dispatcher.CurrentDispatcher; // make sure that we can load the XML Editor package var vsShell = (IVsShell)GetService(typeof(SVsShell)); if (vsShell != null) { var editorPackageGuid = CommonPackageConstants.xmlEditorPackageGuid; IVsPackage editorPackage; NativeMethods.ThrowOnFailure(vsShell.LoadPackage(ref editorPackageGuid, out editorPackage)); } _documentFrameMgr = new EntityDesignDocumentFrameMgr(PackageManager.Package); _modelChangeEventListener = new ModelChangeEventListener(); _guidsCache = new AggregateProjectTypeGuidCache(); _modelGenErrorCache = new ModelGenErrorCache(); _connectionManager = new ConnectionManager(); AddToolWindow(typeof(MappingDetailsWindow)); // Register for VS Events ErrorListHelper.RegisterForNotifications(); // Add the handler to show our Explorer. This is for the top-level 'Entity Data Model Browser' command that is added to the // 'View' main menu. This is different from the 'Model Browser' command on the designer context menu. _viewExplorerCmd = AddCommand( ShowExplorerWindow, ShowExplorerWindow_BeforeQueryStatus, MicrosoftDataEntityDesignCommands.ViewExplorer); // Add the handler to show our MappingDesigner. This is for the top-level 'Entity Data Model Mapping Details' command that is added // to the 'View' main menu. This is different from the 'Mapping Details' command on the designer context menu. _viewMappingCmd = AddCommand( ShowMappingDetailsWindow, ShowMappingDetailsWindow_BeforeQueryStatus, MicrosoftDataEntityDesignCommands.ViewMapping); // Subscribe to Project's target framework retargeting var projectRetargetingService = GetService(typeof(SVsTrackProjectRetargeting)) as IVsTrackProjectRetargeting; Debug.Assert(null != projectRetargetingService, "TrackProjectRetargeting service is null"); _trackProjectRetargetingEventsCookie = 0; if (projectRetargetingService != null) { projectRetargetingService.AdviseTrackProjectRetargetingEvents(this, out _trackProjectRetargetingEventsCookie); } // There is no SQL CE support dev12 onward, so removing the references #if (VS11) // Subscribe to the SQL CE and SqlDatabaseFile upgrade services var sqlCeUpgradeService = GetGlobalService(typeof(IVsSqlCeUpgradeService)) as IVsSqlCeUpgradeService; #endif var sqlDatabaseFileUpgradeService = GetGlobalService(typeof(IVsSqlDatabaseFileUpgradeService)) as IVsSqlDatabaseFileUpgradeService; #if (VS12ORNEWER) if (sqlDatabaseFileUpgradeService == null) #else if (sqlCeUpgradeService == null || sqlDatabaseFileUpgradeService == null) #endif { // attempt to start IVsSqlCeUpgradeService and IVsSqlDatabaseFileUpgradeService BootstrapVSDesigner(); #if (VS11) if (sqlCeUpgradeService == null) { sqlCeUpgradeService = GetGlobalService(typeof(IVsSqlCeUpgradeService)) as IVsSqlCeUpgradeService; } #endif if (sqlDatabaseFileUpgradeService == null) { sqlDatabaseFileUpgradeService = GetGlobalService(typeof(IVsSqlDatabaseFileUpgradeService)) as IVsSqlDatabaseFileUpgradeService; } } #if (VS11) Debug.Assert(null != sqlCeUpgradeService, "sqlCeUpgradeService service is null"); if (sqlCeUpgradeService != null) { sqlCeUpgradeService.OnUpgradeProject += EdmUtils.SqlCeUpgradeService_OnUpgradeProject; } #endif Debug.Assert(null != sqlDatabaseFileUpgradeService, "sqlDatabaseFileUpgradeService service is null"); if (sqlDatabaseFileUpgradeService != null) { sqlDatabaseFileUpgradeService.OnUpgradeProject += EdmUtils.SqlDatabaseFileUpgradeService_OnUpgradeProject; } } }
protected override void Dispose(bool disposing) { try { // HACK HACK -- change when the hack is removed above EFModelErrorTaskNavigator.DslDesignerOnNavigate = null; // -- // always dispose and null out items that use VS resources _viewExplorerCmd = null; _viewMappingCmd = null; if (_explorerWindow != null) { _explorerWindow.Dispose(); _explorerWindow = null; } if (_mappingDetailsWindow != null) { // don't need to call this, the MDF takes care of this one //_mappingDetailsWindow.Dispose(); _mappingDetailsWindow = null; } // remove all errors ErrorListHelper.RemoveAll(); // Unregister for VS Events ErrorListHelper.UnregisterForNotifications(); // dispose of our classes in reverse order than we created them if (_connectionManager != null) { _connectionManager.Dispose(); _connectionManager = null; } if (_modelChangeEventListener != null) { _modelChangeEventListener.Dispose(); _modelChangeEventListener = null; } if (_documentFrameMgr != null) { _documentFrameMgr.Dispose(); _documentFrameMgr = null; } _modelManager.Dispose(); #if (VS11) // UnSubscribe from the SQL CE upgrade service var sqlCeUpgradeService = GetGlobalService(typeof(IVsSqlCeUpgradeService)) as IVsSqlCeUpgradeService; if (sqlCeUpgradeService != null) { sqlCeUpgradeService.OnUpgradeProject -= EdmUtils.SqlCeUpgradeService_OnUpgradeProject; } #endif // UnSubscribe from the SqlDatabaseFile upgrade service var sqlDatabaseFileUpgradeService = GetGlobalService(typeof(IVsSqlDatabaseFileUpgradeService)) as IVsSqlDatabaseFileUpgradeService; if (sqlDatabaseFileUpgradeService != null) { sqlDatabaseFileUpgradeService.OnUpgradeProject -= EdmUtils.SqlDatabaseFileUpgradeService_OnUpgradeProject; } // clear out any static references PackageManager.Package = null; Services.ServiceProvider = null; _dispatcher = null; } finally { base.Dispose(disposing); } }
protected override void ClearErrorList(IVsHierarchy pHier, uint ItemID) { ErrorListHelper.ClearErrorsForDocAcrossLists(pHier, ItemID); }
internal static bool UpdateEdmxAndEnvironment(ModelBuilderSettings settings) { var artifact = settings.Artifact as EntityDesignArtifact; if (artifact == null) { Debug.Fail("In trying to UpdateEdmxAndEnvironment(), No Artifact was found in the ModelBuilderSettings"); return(false); } // Update the app. or web.config, register build providers etc ConfigFileHelper.UpdateConfig(settings); if (settings.SsdlStringReader != null && settings.MslStringReader != null) { // Create the XmlReaders for the ssdl and msl text var ssdlXmlReader = XmlReader.Create(settings.SsdlStringReader); var mslXmlReader = XmlReader.Create(settings.MslStringReader); // Set up our post event to clear out the error list var cmd = new ReplaceSsdlAndMslCommand(ssdlXmlReader, mslXmlReader); cmd.PostInvokeEvent += (o, e) => { var errorList = ErrorListHelper.GetSingleDocErrorList(e.CommandProcessorContext.Artifact.Uri); if (errorList != null) { errorList.Clear(); } }; // Update the model (all inside 1 transaction so we don't get multiple undo's/redo's) var editingContext = PackageManager.Package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(settings.Artifact.Uri); var cpc = new CommandProcessorContext( editingContext, EfiTransactionOriginator.GenerateDatabaseScriptFromModelId, Resources.Tx_GenerateDatabaseScriptFromModel); var cp = new CommandProcessor(cpc, cmd); var addUseLegacyProviderCommand = ModelHelper.CreateSetDesignerPropertyValueCommandFromArtifact( cpc.Artifact, OptionsDesignerInfo.ElementName, OptionsDesignerInfo.AttributeUseLegacyProvider, settings.UseLegacyProvider.ToString()); if (addUseLegacyProviderCommand != null) { cp.EnqueueCommand(addUseLegacyProviderCommand); } // When the user had a v2 edmx file (it can happen when creating a new empty model in a project targeting // .NET Framework 4 and the project does not have refereces to any of EF dlls) and selected EF6 in // the "create database from model" wizard we need to update the artifact to use v3 schemas otherwise // there will be a watermark saying that the edmx is not correct for the EF version and needs to be updated. // We only want to run this command if the version really changed to avoid the overhead. if (artifact.SchemaVersion != settings.TargetSchemaVersion) { cp.EnqueueCommand(new RetargetXmlNamespaceCommand(artifact, settings.TargetSchemaVersion)); } cp.Invoke(); } // First let's get the canonical file path since DTE needs this if (!string.IsNullOrEmpty(settings.DdlFileName) && settings.DdlStringReader != null) { var canonicalFilePath = string.Empty; try { var fi = new FileInfo(settings.DdlFileName); canonicalFilePath = fi.FullName; } catch (Exception e) { Debug.Fail( "We should have caught this exception '" + e.Message + "' immediately after the user clicked the 'Finish' button"); VsUtils.ShowErrorDialog( String.Format( CultureInfo.CurrentCulture, ModelWizard.Properties.Resources.ErrorCouldNotParseDdlFileName, settings.DdlFileName, e.Message)); return(false); } // Output the DDL file, catch any Exceptions, display them, and revert // back to the last page of the wizard. try { OutputDdl(canonicalFilePath, settings.DdlStringReader); } catch (Exception e) { if (e.InnerException == null) { VsUtils.ShowErrorDialog( String.Format( CultureInfo.CurrentCulture, Resources.DatabaseCreation_ErrorWritingDdl, canonicalFilePath, e.Message)); } else { VsUtils.ShowErrorDialog( String.Format( CultureInfo.CurrentCulture, Resources.DatabaseCreation_ErrorWritingDdlWithInner, canonicalFilePath, e.Message, e.InnerException.Message)); } return(false); } // Add DDL file to the project if it is inside the project string relativePath; if (VsUtils.TryGetRelativePathInProject(settings.Project, canonicalFilePath, out relativePath)) { AddDDLFileToProject(settings.Project, canonicalFilePath); } // Open the DDL file if it is not already open IVsUIHierarchy hier; uint itemId; IVsWindowFrame frame; if (VsShellUtilities.IsDocumentOpen( Services.ServiceProvider, canonicalFilePath, Guid.Empty, out hier, out itemId, out frame) == false) { VsShellUtilities.OpenDocument(Services.ServiceProvider, canonicalFilePath); } } return(true); }
private static bool ProcessAccumulatedInfo( EditingContext editingContext, EntityDesignArtifact existingArtifact, ModelBuilderSettings settings) { var schemaVersionChanged = existingArtifact.SchemaVersion != settings.TargetSchemaVersion; EntityDesignModelManager tempModelManager = null; FileInfo tempEdmxFile = null; Uri tempEdmxFileUri = null; try { // set up new temporary ModelManager // NOTE: use an EFArtifact with VSArtifactSet. This is so we get the in-vs behavior of artifact sets, // but don't rely on VS loading the model into the RDT, etc.. tempModelManager = new EntityDesignModelManager(new EFArtifactFactory(), new VSArtifactSetFactory()); tempEdmxFile = ConstructTempEdmxFile(settings); tempEdmxFileUri = new Uri(tempEdmxFile.FullName, UriKind.Absolute); var tempArtifactBasedOnDatabase = tempModelManager.GetNewOrExistingArtifact(tempEdmxFileUri, new VanillaXmlModelProvider()); // if a model generation extension has changed the model, ensure that it is // valid before we start to process it if (settings.HasExtensionChangedModel) { ValidateArtifact(tempModelManager, tempArtifactBasedOnDatabase, WizardKind.Generate); } // Note: later we want the diagram shapes and connectors to be created in the current active diagram // so set TransactionContext appropriately. EfiTransactionContext transactionContext = null; var contextItem = editingContext.Items.GetValue <DiagramManagerContextItem>(); if (contextItem != null && contextItem.DiagramManager != null) { var activeDiagram = contextItem.DiagramManager.ActiveDiagram; if (activeDiagram != null) { transactionContext = new EfiTransactionContext(); transactionContext.Add( EfiTransactionOriginator.TransactionOriginatorDiagramId, new DiagramContextItem(activeDiagram.DiagramId)); } } // clear search if active (Note: in Model.Tests it is OK for below to be null) var explorerInfo = editingContext.Items.GetValue <ExplorerWindow.ExplorerInfo>(); if (explorerInfo != null) { var explorerFrame = explorerInfo._explorerFrame; if (explorerFrame != null) { if (explorerFrame.SearchIsActive) { explorerFrame.ResetSearchCommand.Execute(null); } } } var cpc = new CommandProcessorContext( editingContext, EfiTransactionOriginator.UpdateModelFromDatabaseId, Resources.Tx_UpdateModelFromDatabase, null, transactionContext); if (schemaVersionChanged) { // changing namespaces must be done in a separate transaction otherwise XmlEditor // will not pick-up changes made to xml after namespaces are changed CommandProcessor.InvokeSingleCommand( cpc, new RetargetXmlNamespaceCommand(existingArtifact, settings.TargetSchemaVersion)); } // Update the existing artifact based on tempArtifactBasedOnDatabase var commands = new List <Command>(); var cmd = new UpdateModelFromDatabaseCommand(tempArtifactBasedOnDatabase); commands.Add(cmd); // set up our post event to clear out the error list cmd.PostInvokeEvent += (o, e) => { var errorList = ErrorListHelper.GetSingleDocErrorList(e.CommandProcessorContext.Artifact.Uri); if (errorList != null) { errorList.Clear(); } }; DesignerInfo designerInfo; if (existingArtifact.DesignerInfo().TryGetDesignerInfo(OptionsDesignerInfo.ElementName, out designerInfo)) { var optionsDesignerInfo = designerInfo as OptionsDesignerInfo; Debug.Assert(optionsDesignerInfo != null, "expected non-null optionsDesignerInfo"); if (optionsDesignerInfo != null) { // pluralization checkbox AddUpdateDesignerPropertyCommand( optionsDesignerInfo.CheckPluralizationInWizard, OptionsDesignerInfo.AttributeEnablePluralization, settings.UsePluralizationService, optionsDesignerInfo, commands); // include FKs in model checkbox AddUpdateDesignerPropertyCommand( optionsDesignerInfo.CheckIncludeForeignKeysInModel, OptionsDesignerInfo.AttributeIncludeForeignKeysInModel, settings.IncludeForeignKeysInModel, optionsDesignerInfo, commands); // ensure UseLegacyProvider is set AddUpdateDesignerPropertyCommand( optionsDesignerInfo.UseLegacyProvider, OptionsDesignerInfo.AttributeUseLegacyProvider, settings.UseLegacyProvider, optionsDesignerInfo, commands); } } // create a new FunctionImport for every new Function created (whether composable or not) // (or delete Functions if ProgressDialog did not finish successfully) // Note: this must take place as a DelegateCommand as ProcessStoredProcedureReturnTypeInformation() // can depend on finding the existing Functions to delete. And it won't find them until the // ReplaceSsdlCommand within UpdateModelFromDatabaseCommand has executed. var createMatchingFunctionImportsDelegateCommand = new DelegateCommand( () => { var functionImportCommands = new List <Command>(); ProgressDialogHelper.ProcessStoredProcedureReturnTypeInformation( existingArtifact, settings.NewFunctionSchemaProcedures, functionImportCommands, true); if (functionImportCommands.Count > 0) { new CommandProcessor(cpc, functionImportCommands) .Invoke(); } }); commands.Add(createMatchingFunctionImportsDelegateCommand); // if needed, create a command to dispatch any extensions if (EscherExtensionPointManager.LoadModelGenerationExtensions().Length > 0) { var dispatchCommand = new DispatchToExtensionsCommand(settings); commands.Add(dispatchCommand); } // do all the work here in one transaction new CommandProcessor(cpc, commands) .Invoke(); // if an extension has changed the model, do a full reload if (schemaVersionChanged || settings.HasExtensionChangedModel) { return(true); } else { // reset the is-designer safe flag - this can be set incorrectly when the document is reloaded after ssdl has been updated, // but csdl & msl haven't. Here, the model is correct, but we need to get views to refresh themselves after we // reset the is-designer-safe flag. // Perf note: reloading the artifact can take some time - so only reload if IsDesignerSafe has changed var isDesignerSafeBefore = existingArtifact.IsDesignerSafe; existingArtifact.DetermineIfArtifactIsDesignerSafe(); var isDesignerSafeAfter = existingArtifact.IsDesignerSafe; if (isDesignerSafeAfter != isDesignerSafeBefore) { existingArtifact.FireArtifactReloadedEvent(); } } } finally { // remove tempArtifactBasedOnDatabase to dispose EFObject's properly if (tempEdmxFileUri != null && tempModelManager != null) { tempModelManager.ClearArtifact(tempEdmxFileUri); } // dispose of our temp model manager if (tempModelManager != null) { tempModelManager.Dispose(); } // delete temporary file if (tempEdmxFile != null && tempEdmxFile.Exists) { try { tempEdmxFile.Delete(); } catch (IOException) { // do nothing if delete fails } } } return(false); }
internal static bool TryGetBufferViaExtensions( IServiceProvider serviceProvider, ProjectItem projectItem, string fileContents, Lazy <IModelConversionExtension, IEntityDesignerConversionData>[] converters, Lazy <IModelTransformExtension>[] serializers, out string documentViaExtensions, out List <ExtensionError> errors) { Debug.Assert(serviceProvider != null, "serviceProvider != null"); Debug.Assert(projectItem != null, "projectItem != null"); Debug.Assert(VsUtils.EntityFrameworkSupportedInProject(projectItem.ContainingProject, serviceProvider, false)); Debug.Assert(serializers != null && converters != null, "extensions must not be null"); Debug.Assert(serializers.Any() || converters.Any(), "at least one extension expected"); errors = new List <ExtensionError>(); documentViaExtensions = ""; ModelConversionContextImpl conversionContext = null; ModelTransformContextImpl transformContext = null; try { var targetSchemaVersion = EdmUtils.GetEntityFrameworkVersion(projectItem.ContainingProject, serviceProvider); Debug.Assert(targetSchemaVersion != null, "should not get here for a Misc project"); // get the extension of the file being loaded (might not be EDMX); this API will include the preceding "." var filePath = projectItem.get_FileNames(1); var fileExtension = Path.GetExtension(filePath); XDocument originalDocument = null; // see if we are loading an EDMX file or not, and if we have any converters if (!string.Equals( fileExtension, EntityDesignArtifact.ExtensionEdmx, StringComparison.OrdinalIgnoreCase)) { conversionContext = new ModelConversionContextImpl( projectItem.ContainingProject, projectItem, new FileInfo(filePath), targetSchemaVersion, fileContents); // we aren't loading an EDMX file, so call the extensions who can process this file extension // when this finishes, then output should be a valid EDMX document VSArtifact.DispatchToConversionExtensions(converters, fileExtension, conversionContext, true); // we are done with the non-EDMX extensions so CurrentDocument will be a valid EDMX document // create the serialization context for further extensions to act on transformContext = new ModelTransformContextImpl( projectItem, targetSchemaVersion, conversionContext.CurrentDocument); } else { // we are loading an EDMX file, we can parse file contents into an XDocument try { originalDocument = XDocument.Parse(fileContents, LoadOptions.PreserveWhitespace); transformContext = new ModelTransformContextImpl( projectItem, targetSchemaVersion, originalDocument); } catch (XmlException) { // If there's an error here, don't do anything. We will want to gracefully step out of the extension loading // since the designer itself won't load. } } if (transformContext != null && originalDocument != null) { // now dispatch to those that want to work on EDMX files VSArtifact.DispatchToSerializationExtensions(serializers, transformContext, true); // TODO: this does not seem to be correct if severity is Message or Warning if (transformContext.Errors.Count == 0) { // see if any extension changed things. Note that we need to compare the serialization of // the XDocuments together since the original buffer may have different whitespace after creating the XDocument. // TODO: Why not use XNode.DeepEquals()? string newBufferContents; using (var currentDocWriter = new Utf8StringWriter()) { transformContext.CurrentDocument.Save(currentDocWriter, SaveOptions.None); newBufferContents = currentDocWriter.ToString(); } string originalBufferContents; using (var originalDocWriter = new Utf8StringWriter()) { originalDocument.Save(originalDocWriter, SaveOptions.None); originalBufferContents = originalDocWriter.ToString(); } if (!string.Equals(originalBufferContents, newBufferContents, StringComparison.Ordinal)) { documentViaExtensions = newBufferContents; return(true); } } else { errors.AddRange(transformContext.Errors); return(false); } } } finally { var errorList = ErrorListHelper.GetExtensionErrorList(serviceProvider); errorList.Clear(); // log any errors if (conversionContext != null && conversionContext.Errors.Count > 0) { ErrorListHelper.LogExtensionErrors(conversionContext.Errors, projectItem); } if (transformContext != null && transformContext.Errors.Count > 0) { ErrorListHelper.LogExtensionErrors(transformContext.Errors, projectItem); } } return(false); }