/// <summary>
 ///     - base calls to DiagramDocView : ModelingDocView : ModelingWindowPane
 ///     if (this.CurrentDiagram != null) -> this.CountShapes
 ///     else calls to ModelingWindowPane
 /// </summary>
 /// <returns></returns>
 protected override uint CountAllObjects()
 {
     if (IsArtifactDesignerSafe() == false &&
         EdmUtils.ShouldShowByRefDebugHelpers() == false)
     {
         return(0);
     }
     else
     {
         // the scope of this 'all' list should be the selectable shapes in the designer
         // so let the base class count these
         var count = base.CountAllObjects();
         if (count > (EntityDesignerDiagram.IMPLICIT_AUTO_LAYOUT_CEILING / 2))
         {
             // if there are too many objects, just tell the system that we have 1 item
             // which will cause only the selected item to show up in the drop-down list on top
             // of the property window
             return(1);
         }
         else
         {
             return(count);
         }
     }
 }
Exemple #2
0
        private string GetUniqueModelNamespace()
        {
            using (new VsUtils.HourglassHelper())
            {
                var existingNamespaces = InitializeExistingNamespaces(Wizard.Project);

                // set the storage target to the initial catalog but if we're targeting a database project
                // then set it to the database name which is by definition unique.
                var storageTarget = Wizard.ModelBuilderSettings.InitialCatalog;

                // set the default name for the Model Namespace
                string trialNamespace;
                if (String.IsNullOrEmpty(storageTarget))
                {
                    trialNamespace = ModelConstants.DefaultModelNamespace;
                }
                else
                {
                    trialNamespace = EdmUtils.ConstructValidModelNamespace(
                        storageTarget + ModelConstants.DefaultModelNamespace,
                        ModelConstants.DefaultModelNamespace);
                }

                return(EdmUtils.ConstructUniqueNamespace(trialNamespace, existingNamespaces));
            } // restore cursor
        }
Exemple #3
0
        // virtual for testing
        public virtual XmlDocument LoadConfig()
        {
            var configFilePath = GetConfigPath();

            if (configFilePath != null)
            {
                // attempt to construct the config xml from the doc data if it is available
                try
                {
                    var textLines = _vsHelpers.GetDocData(_serviceProvider, configFilePath) as IVsTextLines;
                    return(textLines != null
                        ? EdmUtils.SafeLoadXmlFromString(
                               VSHelpers.GetTextFromVsTextLines(textLines), preserveWhitespace : true)
                        : EdmUtils.SafeLoadXmlFromPath(configFilePath));
                }
                catch (XmlException e)
                {
                    VsUtils.LogStandardError(
                        String.Format(
                            CultureInfo.CurrentCulture,
                            Resources.VSUtils_ExceptionParsingXml,
                            configFilePath,
                            e.Message),
                        configFilePath,
                        e.LineNumber,
                        e.LinePosition);

                    throw;
                }
            }

            return(null);
        }
        /// <summary>
        ///     The implementation of VsShell.ISelectionContainer.GetObjects in
        ///     ModelingWindowPane calls either GetSelectedObjects() or GetAllObjects()
        ///     - base calls to ModelingWindowPane
        /// </summary>
        /// <returns></returns>
        protected override void GetSelectedObjects(uint count, object[] objects)
        {
            // call the base class version first; objects will be populated with a
            // collection of DSL ModelElements
            base.GetSelectedObjects(count, objects);

            if (IsArtifactDesignerSafe() == false)
            {
                if (EdmUtils.ShouldShowByRefDebugHelpers())
                {
                    if (Context != null)
                    {
                        var artifact = EditingContextManager.GetArtifact(Context) as EntityDesignArtifact;
                        if (artifact != null)
                        {
                            // Show at least the EFEntityModelDescriptor so we can see the by-reference property extensions
                            // for the hydrated model
                            var descriptor =
                                (ObjectDescriptor)TypeDescriptor.CreateInstance(null, typeof(EFEntityModelDescriptor), null, null);
                            descriptor.Initialize(artifact.ConceptualModel, Context, true);
                            objects[0] = descriptor;
                        }
                    }
                }
                else
                {
                    for (var i = 0; i < objects.Length; i++)
                    {
                        objects[i] = null;
                    }
                }
            }
            // only show properties for single selection
            else
            {
                // now change this into an array of our item descriptors.
                var selectedModelObjects = ConvertDslModelElementArrayToItemDescriptors(objects, false);

                // if there are more than 1 selected object, convert the item descriptors to linked-item-descriptors.
                // This is so that property update can be done in 1 transaction.
                if (selectedModelObjects.Count > 1)
                {
                    var tempSelectedModelObjects = new ArrayList();
                    var contextItem = new LinkedDescriptorContextItem();
                    foreach (var customTypeDescriptor in selectedModelObjects.ToArray().OfType <ICustomTypeDescriptor>())
                    {
                        tempSelectedModelObjects.Add(new LinkedPropertyTypeDescriptor(customTypeDescriptor, contextItem));
                    }
                    selectedModelObjects = tempSelectedModelObjects;
                }

                // if the lengths are not the same, then there are items (like compartments)
                // that are being selected, so don't change the object array
                if (objects.Length == selectedModelObjects.Count)
                {
                    selectedModelObjects.CopyTo(objects, 0);
                }
            }
        }
Exemple #5
0
        private static ICollection <string> GetReferencesFromTemplateForProject(Project project)
        {
            ICollection <string> referenceFileNames = new List <string>();
            var solution2 = project.DTE.Solution as Solution2;

            if (null != solution2)
            {
                // get the itemTemplate vstemplate zip file name based on the type of project and language
                string itemTemplateZipFile = null;
                var    projectKind         = VsUtils.GetProjectKind(project);
                if (projectKind == VsUtils.ProjectKind.CSharp)
                {
                    itemTemplateZipFile = EntityDesigner.Utils.Constants.AdoNetEntityDataModelCSharp;
                }
                else if (projectKind == VsUtils.ProjectKind.VB)
                {
                    itemTemplateZipFile = EntityDesigner.Utils.Constants.AdoNetEntityDataModelVB;
                }
                else if (projectKind == VsUtils.ProjectKind.Web)
                {
                    if (VsUtils.IsWebSiteVBProject(project))
                    {
                        itemTemplateZipFile = EntityDesigner.Utils.Constants.AdoNetEntityDataModelAspNetVB;
                    }
                    else if (VsUtils.IsWebSiteCSharpProject(project))
                    {
                        itemTemplateZipFile = EntityDesigner.Utils.Constants.AdoNetEntityDataModelAspNetCSharp;
                    }
                }

                // use the solution to get the path of the item template, look at the XML, and find all references.
                if (itemTemplateZipFile != null)
                {
                    var itemTemplatePath = solution2.GetProjectItemTemplate(itemTemplateZipFile, project.Kind);
                    if (!String.IsNullOrEmpty(itemTemplatePath))
                    {
                        try
                        {
                            var xmlDocument = EdmUtils.SafeLoadXmlFromPath(itemTemplatePath);
                            var nsmgr       = new XmlNamespaceManager(xmlDocument.NameTable);
                            nsmgr.AddNamespace("vst", "http://schemas.microsoft.com/developer/vstemplate/2005");
                            var referenceNodeList =
                                xmlDocument.SelectNodes(
                                    "/vst:VSTemplate/vst:TemplateContent/vst:References/vst:Reference/vst:Assembly", nsmgr);
                            foreach (XmlElement referenceNode in referenceNodeList)
                            {
                                referenceFileNames.Add(referenceNode.InnerText);
                            }
                        }
                        catch
                        {
                            // leave it up to the build process to pick up the errors
                        }
                    }
                }
            }

            return(referenceFileNames);
        }
Exemple #6
0
        public string GetInitialModelContents(Version targetSchemaVersion)
        {
            Debug.Assert(
                EntityFrameworkVersion.IsValidVersion(targetSchemaVersion),
                "invalid schema version");

            return(EdmUtils.CreateEdmxString(targetSchemaVersion, string.Empty, string.Empty, string.Empty));
        }
Exemple #7
0
 public void GetInitialModelContents_returns_contents()
 {
     foreach (var targetSchemaVersion in EntityFrameworkVersion.GetAllVersions())
     {
         Assert.Equal(
             EdmUtils.CreateEdmxString(targetSchemaVersion, string.Empty, string.Empty, string.Empty),
             new InitialModelContentsFactory().GetInitialModelContents(targetSchemaVersion));
     }
 }
        protected virtual ModelGenerationExtensionContext CreateContext()
        {
            Debug.Assert(VsUtils.EntityFrameworkSupportedInProject(_project, PackageManager.Package, allowMiscProject: false));

            var targetSchemaVersion = EdmUtils.GetEntityFrameworkVersion(_project, PackageManager.Package);

            return(new ModelGenerationExtensionContextImpl(
                       _project, targetSchemaVersion, _currentXDocument, _fromDatabaseDocument, WizardKind));
        }
        protected override ModelGenerationExtensionContext CreateContext()
        {
            Debug.Assert(VsUtils.EntityFrameworkSupportedInProject(Project, PackageManager.Package, allowMiscProject: false));

            var targetSchemaVersion = EdmUtils.GetEntityFrameworkVersion(Project, PackageManager.Package);

            return(new UpdateModelFromDatabaseExtensionContextImpl(
                       Project, ProjectItem, targetSchemaVersion,
                       CurrentDocument, FromDatabaseDocument, OriginalDocument, UpdateModelDocument));
        }
Exemple #10
0
        internal static HashSet <string> InitializeExistingNamespaces(Project project)
        {
            var existingNamespaces = new HashSet <string>();

            if (project != null)
            {
                // find the namespace used in the CSDL section of each existing edmx file in the project
                var vsHierarchy = VsUtils.GetVsHierarchy(project, Services.ServiceProvider);
                var fileFinder  = new VSFileFinder(EntityDesignArtifact.ExtensionEdmx);
                fileFinder.FindInProject(vsHierarchy);

                foreach (var fileInfo in fileFinder.MatchingFiles)
                {
                    try
                    {
                        var xmlDocument = EdmUtils.SafeLoadXmlFromPath(fileInfo.Path);
                        foreach (var schemaVersion in EntityFrameworkVersion.GetAllVersions())
                        {
                            var nsMgr = SchemaManager.GetEdmxNamespaceManager(xmlDocument.NameTable, schemaVersion);

                            foreach (
                                XmlElement e in xmlDocument.SelectNodes("/edmx:Edmx/edmx:Runtime/edmx:ConceptualModels/csdl:Schema", nsMgr))
                            {
                                var namespaceValue = e.GetAttribute("Namespace");
                                if (!string.IsNullOrEmpty(namespaceValue))
                                {
                                    existingNamespaces.Add(namespaceValue);
                                }
                            }
                        }
                    }
                    // swallow various exceptions that come from reading the file or parsing xml
                    // We just skip this document in the event of an exception.
                    catch (IOException)
                    {
                    }
                    catch (UnauthorizedAccessException)
                    {
                    }
                    catch (NotSupportedException)
                    {
                    }
                    catch (SecurityException)
                    {
                    }
                    catch (XmlException)
                    {
                    }
                }
            }
            return(existingNamespaces);
        }
 /// <summary>
 ///     The implementation of VsShell.ISelectionContainer.CountObjects in
 ///     ModelingWindowPane calls either CountSelectedObjects() or CountAllObjects()
 ///     - base calls to ModelingWindowPane
 /// </summary>
 /// <returns></returns>
 protected override uint CountSelectedObjects()
 {
     if (!IsArtifactDesignerSafe() &&
         !EdmUtils.ShouldShowByRefDebugHelpers())
     {
         return(0);
     }
     else
     {
         // we can just call the base class because the count of selected designer elements
         // and their corresponding ItemDescriptors should be the same
         return(base.CountSelectedObjects());
     }
 }
Exemple #12
0
        /// <summary>
        ///     Set properties such as "Custom Tool" and "Item Type"
        /// </summary>
        internal static void SetProjectItemProperties(ProjectItem projectItem, VisualStudioProjectSystem applicationType)
        {
            // set the CustomTool property for the SingleFileGenerator
            EdmUtils.ToggleEdmxItemCustomToolProperty(projectItem, true);

            // set the ItemType property to "EntityDeploy".  This is the "build action" of the item.
            if (applicationType != VisualStudioProjectSystem.Website)
            {
                var prop = projectItem.Properties.Item(ModelObjectItemWizard.ItemTypePropertyName);
                if (prop != null)
                {
                    prop.Value = ModelObjectItemWizard.EntityDeployBuildActionName;
                }
            }
        }
Exemple #13
0
        /// <summary>
        ///     Creates a concrete implementation of ModelConversionExtensionContext, use this ctor when loading
        /// </summary>
        internal ModelConversionContextImpl(
            Project project, ProjectItem projectItem, FileInfo fileInfo, Version runtimeVersion, string original)
        {
            Debug.Assert(fileInfo != null, "fileInfo should not be null");
            Debug.Assert(runtimeVersion != null, "runtimeVersion should not be null");
            Debug.Assert(original != null, "original should not be null");

            _project             = project;
            _projectItem         = projectItem;
            _fileInfo            = fileInfo;
            _targetSchemaVersion = runtimeVersion;
            _current             = XDocument.Parse(EdmUtils.CreateEdmxString(runtimeVersion, String.Empty, String.Empty, String.Empty));
            _protectCurrent      = false;
            _original            = original;

            AddEventHandler();
        }
Exemple #14
0
        private static void AddMissingReferencesForWebsite(VSWebSite webSiteProject, ICollection <string> referenceFileNames)
        {
            // first convert the enumerable into a hash for quick lookup
            var websiteReferenceHash       = new HashSet <string>();
            var websiteReferenceEnumerator = webSiteProject.References.GetEnumerator();
            var netRefPath = EdmUtils.GetRuntimeAssemblyPath(webSiteProject.Project, Services.ServiceProvider);

            while (websiteReferenceEnumerator.MoveNext())
            {
                var assemblyReference = websiteReferenceEnumerator.Current as AssemblyReference;
                if (assemblyReference != null)
                {
                    websiteReferenceHash.Add(assemblyReference.Name);
                }
            }

            foreach (var referenceFileName in referenceFileNames)
            {
                if (!websiteReferenceHash.Contains(referenceFileName))
                {
                    // first try the GAC
                    try
                    {
                        webSiteProject.References.AddFromGAC(referenceFileName);
                    }
                    catch (FileNotFoundException)
                    {
                        // attempt to add the file from the net framework directory.
                        // TODO: We should check OOB DataFx Installation folder first before looking at .net framework folder.
                        // Tracked by bug: 740496
                        try
                        {
                            webSiteProject.References.AddFromFile(Path.Combine(netRefPath, referenceFileName));
                        }
                        catch (FileNotFoundException)
                        {
                            // can't do anything else; leave it up to the build process to pick up the
                            // errors and encourage the user to add the references manually.
                        }
                    }
                }
            }
        }
Exemple #15
0
        internal static bool ValidateNamespace(TextBox modelNamespaceTextBox, ModelBuilderSettings modelBuilderSettings)
        {
            if (!EdmUtils.IsValidModelNamespace(modelNamespaceTextBox.Text))
            {
                var s = ModelWizard.Properties.Resources.ConnectionStringNonValidIdentifier;
                VsUtils.ShowErrorDialog(String.Format(CultureInfo.CurrentCulture, s, modelNamespaceTextBox.Text));
                modelNamespaceTextBox.Focus();
                return(false);
            }

            // the Model Namespace and the Entity Container name must differ
            if (ModelBuilderWizardForm.ModelNamespaceAndEntityContainerNameSame(modelBuilderSettings))
            {
                var s = ModelWizard.Properties.Resources.NamespaceAndEntityContainerSame;
                VsUtils.ShowErrorDialog(String.Format(CultureInfo.CurrentCulture, s, modelBuilderSettings.AppConfigConnectionPropertyName));
                modelNamespaceTextBox.Focus();
                return(false);
            }
            return(true);
        }
Exemple #16
0
        int IVsEditorFactoryNotify.NotifyItemAdded(uint grfEFN, IVsHierarchy pHier, uint itemid, string pszMkDocument)
        {
            object o;
            var    hr = pHier.GetProperty(itemid, (int)__VSHPROPID.VSHPROPID_ExtObject, out o);

            if (NativeMethods.Succeeded(hr))
            {
                var projectItem = o as ProjectItem;
                if (projectItem != null &&
                    VsUtils.EntityFrameworkSupportedInProject(projectItem.ContainingProject, ServiceProvider, allowMiscProject: false))
                {
                    if (EdmUtils.IsDataServicesEdmx(projectItem.get_FileNames(1)))
                    {
                        // if the EDMX has a data services node, don't add the SingleFileGenerator, etc.
                        return(VSConstants.S_OK);
                    }

                    IOleServiceProvider oleSP;
                    pHier.GetSite(out oleSP);
                    using (var sp = new ServiceProvider(oleSP))
                    {
                        var appType = VsUtils.GetApplicationType(sp, projectItem.ContainingProject);

                        // set the project item properties
                        SetProjectItemProperties(projectItem, appType);
                    }

                    if (grfEFN != (uint)__EFNFLAGS.EFN_ClonedFromTemplate)
                    {
                        // we're not adding from template i.e. Add Existing Item
                        var referenceFileNames = GetReferencesFromTemplateForProject(projectItem.ContainingProject);
                        AddMissingReferences(projectItem, referenceFileNames);
                        AddBuildProvider(projectItem);
                    }
                }
            }

            return(VSConstants.S_OK);
        }
Exemple #17
0
        internal static bool ShowWarningDialogAndSaveDismissOption(
            string formattedTitle, string formattedMessage, string regKeyName, ButtonMode buttonMode)
        {
            var cancelled = true;

            var service = Services.ServiceProvider.GetService(typeof(IUIService)) as IUIService;

            Debug.Assert(service != null, "service should not be null");
            if (service != null)
            {
                using (var dialog = new DismissableWarningDialog(formattedTitle, formattedMessage, buttonMode))
                {
                    if (service.ShowDialog(dialog) == DialogResult.OK)
                    {
                        cancelled = false;
                        var showAgain = dialog.chkWarning.Checked == false;
                        EdmUtils.SaveUserSetting(regKeyName, showAgain.ToString());
                    }
                }
            }

            return(cancelled);
        }
        public override void OnActivated()
        {
            base.OnActivated();

            _onWorkflowCleanup = false;

            Debug.Assert(
                !Wizard.MovingNext || _workflowInstance == null,
                "Possible memory leak: We should have destroyed the old workflow instance when activating WizardPageDbGenSummary");

            if (_workflowInstance == null)
            {
                if (LocalDataUtil.IsSqlMobileConnectionString(Wizard.ModelBuilderSettings.DesignTimeProviderInvariantName))
                {
                    _ddlFileExtension = DatabaseGenerationEngine._sqlceFileExtension;
                }
                else
                {
                    _ddlFileExtension = DatabaseGenerationEngine._ddlFileExtension;
                }

                // Add in the DbConfig page before if we have found a connection
                if (Wizard.Mode == ModelBuilderWizardForm.WizardMode.PerformDBGenSummaryOnly &&
                    _addedDbConfigPage == false)
                {
                    Wizard.InsertPageBefore(Id, new WizardPageDbConfig(Wizard));
                    _addedDbConfigPage = true;
                }

                // Display the default path for the DDL
                var artifactProjectItem = VsUtils.GetProjectItemForDocument(
                    Wizard.ModelBuilderSettings.Artifact.Uri.LocalPath, PackageManager.Package);
                if (artifactProjectItem != null)
                {
                    txtSaveDdlAs.Text = DatabaseGenerationEngine.CreateDefaultDdlFileName(artifactProjectItem) + _ddlFileExtension;
                }

                // Disable all buttons except for Previous and Cancel
                Wizard.EnableButton(ButtonType.Previous, true);
                Wizard.EnableButton(ButtonType.Next, false);
                Wizard.EnableButton(ButtonType.Finish, false);
                Wizard.EnableButton(ButtonType.Cancel, true);

                // Display a status message
                ShowStatus(Properties.Resources.DbGenSummary_StatusDeterminingDDL);

                // Extract the XML from the EDMX file and convert it into an EdmItemCollection for the workflow
                EdmItemCollection edm = null;
                using (new VsUtils.HourglassHelper())
                {
                    IList <EdmSchemaError> schemaErrors;
                    edm = Wizard.ModelBuilderSettings.Artifact.GetEdmItemCollectionFromArtifact(out schemaErrors);

                    Debug.Assert(
                        edm != null && schemaErrors.Count == 0,
                        "EdmItemCollection schema errors found; we should have performed validation on the EdmItemCollection before instantiating the wizard.");
                }

                var existingSsdl = Wizard.ModelBuilderSettings.Artifact.GetSsdlAsString();
                var existingMsl  = Wizard.ModelBuilderSettings.Artifact.GetMslAsString();

                // Attempt to get the workflow path, template path, and database schema name from the artifact. If we don't find them, we'll use defaults.
                var workflowPath       = DatabaseGenerationEngine.GetWorkflowPathFromArtifact(Wizard.ModelBuilderSettings.Artifact);
                var templatePath       = DatabaseGenerationEngine.GetTemplatePathFromArtifact(Wizard.ModelBuilderSettings.Artifact);
                var databaseSchemaName = DatabaseGenerationEngine.GetDatabaseSchemaNameFromArtifact(Wizard.ModelBuilderSettings.Artifact);

                // Save off the SynchronizationContext so we can post methods to the UI event queue when
                // responding to workflow events (since they are executed in a separate thread)
                _synchronizationContext = SynchronizationContext.Current;

                // Invoke the Pipeline/Workflow. The Workflow engine will automatically wrap this in a background thread
                try
                {
                    using (new VsUtils.HourglassHelper())
                    {
                        var resolvedWorkflowFileInfo = DatabaseGenerationEngine.ResolveAndValidateWorkflowPath(
                            Wizard.Project,
                            workflowPath);

                        var resolvedDefaultPath = VsUtils.ResolvePathWithMacro(
                            null, DatabaseGenerationEngine.DefaultWorkflowPath,
                            new Dictionary <string, string>
                        {
                            { ExtensibleFileManager.EFTOOLS_USER_MACRONAME, ExtensibleFileManager.UserEFToolsDir.FullName },
                            { ExtensibleFileManager.EFTOOLS_VS_MACRONAME, ExtensibleFileManager.VSEFToolsDir.FullName }
                        });

                        // Display a security warning if the workflow path specified is different from the default
                        if (!resolvedWorkflowFileInfo.FullName.Equals(
                                Path.GetFullPath(resolvedDefaultPath), StringComparison.OrdinalIgnoreCase))
                        {
                            var displayCustomWorkflowWarning = true;
                            try
                            {
                                var customWorkflowWarningString = EdmUtils.GetUserSetting(RegKeyNameCustomWorkflowWarning);
                                if (false == String.IsNullOrEmpty(customWorkflowWarningString) &&
                                    false == Boolean.TryParse(customWorkflowWarningString, out displayCustomWorkflowWarning))
                                {
                                    displayCustomWorkflowWarning = true;
                                }
                                if (displayCustomWorkflowWarning)
                                {
                                    var cancelledDuringCustomWorkflowWarning = DismissableWarningDialog
                                                                               .ShowWarningDialogAndSaveDismissOption(
                                        Resources.DatabaseCreation_CustomWorkflowWarningTitle,
                                        Resources.DatabaseCreation_WarningCustomWorkflow,
                                        RegKeyNameCustomWorkflowWarning,
                                        DismissableWarningDialog.ButtonMode.OkCancel);
                                    if (cancelledDuringCustomWorkflowWarning)
                                    {
                                        HandleError(
                                            String.Format(
                                                CultureInfo.CurrentCulture, Resources.DatabaseCreation_CustomWorkflowCancelled,
                                                resolvedWorkflowFileInfo.FullName), false);
                                        return;
                                    }
                                }
                            }
                            catch (SecurityException e)
                            {
                                // We should at least alert the user of why this is failing so they can take steps to fix it.
                                VsUtils.ShowMessageBox(
                                    Services.ServiceProvider,
                                    String.Format(
                                        CultureInfo.CurrentCulture, Resources.ErrorReadingWritingUserSetting,
                                        RegKeyNameCustomWorkflowWarning, e.Message),
                                    OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                    OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
                                    OLEMSGICON.OLEMSGICON_WARNING);
                            }
                        }

                        _workflowInstance = DatabaseGenerationEngine.CreateDatabaseScriptGenerationWorkflow(
                            _synchronizationContext,
                            Wizard.Project,
                            Wizard.ModelBuilderSettings.Artifact.Uri.LocalPath,
                            resolvedWorkflowFileInfo,
                            templatePath,
                            edm,
                            existingSsdl,
                            existingMsl,
                            databaseSchemaName,
                            Wizard.ModelBuilderSettings.InitialCatalog,
                            Wizard.ModelBuilderSettings.RuntimeProviderInvariantName,
                            Wizard.ModelBuilderSettings.AppConfigConnectionString,
                            Wizard.ModelBuilderSettings.ProviderManifestToken,
                            Wizard.ModelBuilderSettings.Artifact.SchemaVersion,
                            _workflowInstance_WorkflowCompleted,
                            _workflowInstance_UnhandledException);
                    }

                    Wizard.ModelBuilderSettings.WorkflowInstance = _workflowInstance;

                    _workflowInstance.Run();
                }
                catch (Exception e)
                {
                    HandleError(e.Message, true);

                    if (_workflowInstance != null)
                    {
                        CleanupWorkflow();
                    }
                }
            }
        }
        internal override bool OnWizardFinish()
        {
            if (Wizard.ModelBuilderSettings.DdlStringReader != null)
            {
                // Make sure that the DDL filename is not null
                if (String.IsNullOrEmpty(txtSaveDdlAs.Text))
                {
                    VsUtils.ShowErrorDialog(Properties.Resources.ErrorDdlFileNameIsNull);
                    return(false);
                }

                // Resolve the project URI
                Uri  projectUri = null;
                bool projectHasFilename;
                var  projectFullName = VsUtils.GetProjectPathWithName(Wizard.Project, out projectHasFilename);

                try
                {
                    if (false == Uri.TryCreate(projectFullName, UriKind.Absolute, out projectUri) ||
                        projectUri == null)
                    {
                        VsUtils.ShowErrorDialog(
                            String.Format(CultureInfo.CurrentCulture, Properties.Resources.ErrorResolvingProjectFile, projectFullName));
                        return(false);
                    }
                }
                catch (UriFormatException)
                {
                    VsUtils.ShowErrorDialog(
                        String.Format(CultureInfo.CurrentCulture, Properties.Resources.ErrorResolvingProjectFile, projectFullName));
                }

                // Attempt to create a URI from the DDL path, either relative to the project URI or absolute.
                Uri ddlUri = null;
                try
                {
                    if (false == Uri.TryCreate(projectUri, txtSaveDdlAs.Text, out ddlUri) ||
                        ddlUri == null)
                    {
                        VsUtils.ShowErrorDialog(
                            String.Format(
                                CultureInfo.CurrentCulture, Properties.Resources.ErrorResolvingDdlFileNameException, txtSaveDdlAs.Text));
                        return(false);
                    }
                }
                catch (UriFormatException)
                {
                    VsUtils.ShowErrorDialog(
                        String.Format(
                            CultureInfo.CurrentCulture, Properties.Resources.ErrorResolvingDdlFileNameException, txtSaveDdlAs.Text));
                }

                var ddlFilePath = ddlUri.LocalPath;

                // Validate the file name
                try
                {
                    var ddlFileName = Path.GetFileName(ddlFilePath);
                    if (String.IsNullOrEmpty(ddlFileName))
                    {
                        VsUtils.ShowErrorDialog(
                            String.Format(CultureInfo.CurrentCulture, Properties.Resources.ErrorDdlPathNotFile, ddlFilePath));
                        return(false);
                    }

                    if (!VsUtils.IsValidFileName(ddlFileName))
                    {
                        VsUtils.ShowErrorDialog(String.Format(CultureInfo.CurrentCulture, Resources.ErrorNonValidFileName, ddlFilePath));
                        return(false);
                    }
                }
                catch (ArgumentException)
                {
                    VsUtils.ShowErrorDialog(
                        String.Format(CultureInfo.CurrentCulture, Properties.Resources.ErrorResolvingDdlFileNameException, ddlFilePath));
                    return(false);
                }

                // Add ".sql" if the extension is not already .sql
                if (!Path.GetExtension(ddlFilePath).Equals(_ddlFileExtension, StringComparison.OrdinalIgnoreCase))
                {
                    ddlFilePath += _ddlFileExtension;
                }

                // Now we should have a valid, non-null filename
                Debug.Assert(
                    !String.IsNullOrEmpty(ddlFilePath),
                    "DDL filename should either be not null or we should have handled an exception before continuing...");
                if (String.IsNullOrEmpty(ddlFilePath))
                {
                    VsUtils.ShowErrorDialog(Properties.Resources.ErrorDdlFileNameIsNull);
                    return(false);
                }

                // If the parent directory does not exist, then we do not proceed
                try
                {
                    var fileInfo      = new FileInfo(ddlFilePath);
                    var parentDirInfo = fileInfo.Directory;
                    if (parentDirInfo != null)
                    {
                        if (false == parentDirInfo.Exists)
                        {
                            VsUtils.ShowErrorDialog(
                                String.Format(CultureInfo.CurrentCulture, Properties.Resources.ErrorNoDdlParentDir, ddlFilePath));
                            return(false);
                        }
                    }
                }
                catch (Exception e)
                {
                    // various exceptions could occur here, such as PathTooLong or Security. In this case we will display an error.
                    VsUtils.ShowErrorDialog(
                        String.Format(
                            CultureInfo.CurrentCulture, Properties.Resources.ErrorCouldNotParseDdlFileName, ddlFilePath, e.Message));
                    return(false);
                }

                // Display the DDL Overwrite Warning Dialog
                if (File.Exists(ddlFilePath))
                {
                    var displayDdlOverwriteWarning = true;
                    try
                    {
                        var ddlOverwriteWarningString = EdmUtils.GetUserSetting(RegKeyNameDdlOverwriteWarning);
                        if (false == String.IsNullOrEmpty(ddlOverwriteWarningString) &&
                            false == Boolean.TryParse(ddlOverwriteWarningString, out displayDdlOverwriteWarning))
                        {
                            displayDdlOverwriteWarning = true;
                        }
                        if (displayDdlOverwriteWarning)
                        {
                            var cancelledDuringOverwriteDdl = DismissableWarningDialog.ShowWarningDialogAndSaveDismissOption(
                                Resources.DatabaseCreation_DDLOverwriteWarningTitle,
                                String.Format(CultureInfo.CurrentCulture, Resources.DatabaseCreation_WarningOverwriteDdl, ddlFilePath),
                                RegKeyNameDdlOverwriteWarning,
                                DismissableWarningDialog.ButtonMode.YesNo);
                            if (cancelledDuringOverwriteDdl)
                            {
                                return(false);
                            }
                        }
                    }
                    catch (SecurityException e)
                    {
                        // We should at least alert the user of why this is failing so they can take steps to fix it.
                        VsUtils.ShowMessageBox(
                            Services.ServiceProvider,
                            String.Format(
                                CultureInfo.CurrentCulture, Resources.ErrorReadingWritingUserSetting, RegKeyNameDdlOverwriteWarning,
                                e.Message),
                            OLEMSGBUTTON.OLEMSGBUTTON_OK,
                            OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
                            OLEMSGICON.OLEMSGICON_WARNING);
                    }
                }

                // At this point we will save off the DDL Filename into the wizard settings
                Wizard.ModelBuilderSettings.DdlFileName = ddlFilePath;
            }

            if ((Wizard.ModelBuilderSettings.SsdlStringReader != null ||
                 Wizard.ModelBuilderSettings.MslStringReader != null) &&
                (Wizard.ModelBuilderSettings.Artifact != null) &&
                (Wizard.ModelBuilderSettings.Artifact.StorageModel() != null) &&
                (!Wizard.ModelBuilderSettings.Artifact.StorageModel().IsEmpty))
            {
                // Display the SSDL/MSL Overwrite Warning Dialog
                var displayEdmxOverwriteWarning = true;
                try
                {
                    var edmxOverwriteWarningString = EdmUtils.GetUserSetting(RegKeyNameEdmxOverwriteWarning);
                    if (false == String.IsNullOrEmpty(edmxOverwriteWarningString) &&
                        false == Boolean.TryParse(edmxOverwriteWarningString, out displayEdmxOverwriteWarning))
                    {
                        displayEdmxOverwriteWarning = true;
                    }
                    if (displayEdmxOverwriteWarning)
                    {
                        var cancelledDuringOverwriteSsdl = DismissableWarningDialog.ShowWarningDialogAndSaveDismissOption(
                            Resources.DatabaseCreation_EdmxOverwriteWarningTitle,
                            Resources.DatabaseCreation_WarningOverwriteMappings,
                            RegKeyNameEdmxOverwriteWarning,
                            DismissableWarningDialog.ButtonMode.YesNo);
                        if (cancelledDuringOverwriteSsdl)
                        {
                            return(false);
                        }
                    }
                }
                catch (SecurityException e)
                {
                    // We should at least alert the user of why this is failing so they can take steps to fix it.
                    VsUtils.ShowMessageBox(
                        Services.ServiceProvider,
                        String.Format(
                            CultureInfo.CurrentCulture, Resources.ErrorReadingWritingUserSetting, RegKeyNameEdmxOverwriteWarning,
                            e.Message),
                        OLEMSGBUTTON.OLEMSGBUTTON_OK,
                        OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
                        OLEMSGICON.OLEMSGICON_WARNING);
                }
            }

            using (new VsUtils.HourglassHelper())
            {
                // Now we output the DDL, update app/web.config, update the edmx, and open the SQL file that gets produced
                return(DatabaseGenerationEngine.UpdateEdmxAndEnvironment(Wizard.ModelBuilderSettings));
            }
        }
Exemple #20
0
        internal static void EditFunctionImport(
            EditingContext editingContext,
            FunctionImport functionImport,
            StorageEntityModel sModel,
            ConceptualEntityModel cModel,
            ConceptualEntityContainer cContainer,
            object selectedObject,
            string originatingId)
        {
            Debug.Assert(editingContext != null, "editingContext should not be null");
            Debug.Assert(!string.IsNullOrEmpty(originatingId), "originatingId should not be null or empty");

            // show dialog appropriate to framework version
            var result = ShowNewFunctionImportDialog(
                functionImport.Function,
                functionImport.LocalName.Value,
                sModel,
                cModel,
                cContainer,
                DialogsResource.NewFunctionImportDialog_EditFunctionImportTitle,
                selectedObject);

            // if user selected OK on the dialog then create the FunctionImport
            if (DialogResult.OK == result.DialogResult)
            {
                var commands = new List <Command>();
                var cp       = new CommandProcessor(editingContext, originatingId, Resources.Tx_UpdateFunctionImport);
                CreateComplexTypeCommand createComplexTypeCommand = null;

                // Make the decision based on what is returned by the dialog.
                // If return type is a string and result schema is not null, that means the user would like to create a new complex type for the function import return.
                if (result.ReturnType is string &&
                    result.Schema != null)
                {
                    createComplexTypeCommand = CreateMatchingFunctionImportCommand.AddCreateComplexTypeCommands(
                        sModel, result.ReturnType as string, result.Schema.RawColumns, commands);
                }
                // If ReturnType is a complex type and result schema is not null, the complex type needs to be updated to be in sync with schema columns.
                else if (result.ReturnType is ComplexType &&
                         result.Schema != null)
                {
                    var complexType = result.ReturnType as ComplexType;
                    // Create Column properties dictionary. The keys will be either property's type-mapping column name if availabe or property's name.
                    var propertiesDictionary =
                        complexType.Properties().ToDictionary(p => EdmUtils.GetFunctionImportResultColumnName(functionImport, p));
                    CreateMatchingFunctionImportCommand.AddChangeComplexTypePropertiesCommands(
                        complexType, propertiesDictionary, result.Schema.RawColumns, commands);
                }

                // construct Dictionary mapping property name to column name for FunctionImportMapping
                IDictionary <string, string> mapPropertyNameToColumnName = null;
                if (result.Schema != null)
                {
                    mapPropertyNameToColumnName =
                        ModelHelper.ConstructComplexTypePropertyNameToColumnNameMapping(result.Schema.Columns.Select(c => c.Name).ToList());
                }

                // change the FunctionImport and FunctionImportMapping to match
                ChangeFunctionImportCommand cmdFuncImpSproc = null;
                // if result.IsComposable is true then set to True, but if false then use None if existing value is None, otherwise False
                var resultIsComposable = (result.IsComposable
                                              ? BoolOrNone.TrueValue
                                              : (BoolOrNone.NoneValue == functionImport.IsComposable.Value
                                                     ? BoolOrNone.NoneValue
                                                     : BoolOrNone.FalseValue));
                if (createComplexTypeCommand == null)
                {
                    cmdFuncImpSproc = new ChangeFunctionImportCommand(
                        cContainer, functionImport, result.Function, result.FunctionName, resultIsComposable, true, result.ReturnType);
                    // Create explicit function-import result type mapping if the return type is a complex type.
                    if (result.ReturnType is ComplexType)
                    {
                        cmdFuncImpSproc.PostInvokeEvent += (o, eventArgs) =>
                        {
                            if (functionImport != null &&
                                functionImport.FunctionImportMapping != null)
                            {
                                // CreateFunctionImportTypeMappingCommand will be no op function-import's return is unchanged.
                                CommandProcessor.InvokeSingleCommand(
                                    cp.CommandProcessorContext
                                    ,
                                    new CreateFunctionImportTypeMappingCommand(
                                        functionImport.FunctionImportMapping, result.ReturnType as ComplexType)
                                {
                                    CreateDefaultScalarProperties = true,
                                    PropertyNameToColumnNameMap   = mapPropertyNameToColumnName
                                });
                            }
                        };
                    }
                }
                else
                {
                    // Pass in the pre-req command to create complex type to the command.
                    cmdFuncImpSproc = new ChangeFunctionImportCommand(
                        cContainer, functionImport, result.Function, result.FunctionName,
                        resultIsComposable, createComplexTypeCommand);
                    // Create explicit function-import result type mapping if the return type is a complex type.
                    cmdFuncImpSproc.PostInvokeEvent += (o, eventArgs) =>
                    {
                        if (functionImport != null &&
                            functionImport.FunctionImportMapping != null)
                        {
                            CommandProcessor.InvokeSingleCommand(
                                cp.CommandProcessorContext,
                                new CreateFunctionImportTypeMappingCommand(
                                    functionImport.FunctionImportMapping, createComplexTypeCommand)
                            {
                                CreateDefaultScalarProperties = true,
                                PropertyNameToColumnNameMap   = mapPropertyNameToColumnName
                            });
                        }
                    };
                }
                commands.Add(cmdFuncImpSproc);
                commands.ForEach(x => cp.EnqueueCommand(x));
                cp.Invoke();
            }
        }
Exemple #21
0
        /// <summary>
        ///     This API supports the Entity Framework infrastructure and is not intended to be used directly from your code.
        /// </summary>
        /// <param name="automationObject"> This API supports the Entity Framework infrastructure and is not intended to be used directly from your code. </param>
        /// <param name="replacementsDictionary"> This API supports the Entity Framework infrastructure and is not intended to be used directly from your code. </param>
        /// <param name="runKind"> This API supports the Entity Framework infrastructure and is not intended to be used directly from your code. </param>
        /// <param name="customParams"> This API supports the Entity Framework infrastructure and is not intended to be used directly from your code. </param>
        public void RunStarted(
            object automationObject, Dictionary <string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams)
        {
            Project project = null;

            var dte = automationObject as DTE2;

            if (EdmxUri == null)
            {
                // Wizard not launched from Escher Designer
                project = VsUtils.GetActiveProject(dte);
                Debug.Assert(project != null, "Unable to retrieve ActiveSolutionProject from DTE");
            }
            else
            {
                // Try to get ProjectItem & project
                var projectItem = VsUtils.GetProjectItemForDocument(EdmxUri.LocalPath, Services.ServiceProvider);
                Debug.Assert(projectItem != null, "Unable to find project item for document");
                if (projectItem != null)
                {
                    // get the project that the input file is running in.
                    project = projectItem.ContainingProject;

                    // turn off code generation on the EDMX file
                    var editingContextMgr = PackageManager.Package.DocumentFrameMgr.EditingContextManager;

                    Debug.Assert(
                        editingContextMgr.DoesContextExist(EdmxUri),
                        "If the AddArtifactGeneratorWizard was launched from Escher, there should be an existing editing context");

                    if (editingContextMgr.DoesContextExist(EdmxUri))
                    {
                        var cpc = new CommandProcessorContext(
                            editingContextMgr.GetNewOrExistingContext(EdmxUri), EfiTransactionOriginator.AddNewArtifactGenerationItemId,
                            Resources.Tx_SetCodeGenerationStrategy);
                        var cmd = EdmUtils.SetCodeGenStrategyToNoneCommand(cpc.Artifact);
                        if (cmd != null)
                        {
                            CommandProcessor.InvokeSingleCommand(cpc, cmd);
                        }
                    }
                }
                else
                {
                    // Couldn't get projectItem for some reason, so default to the active project
                    project = VsUtils.GetActiveProject(dte);
                }

                // Wizard is launched from Escher Designer.  Name of the file in the designer is in the static EdmxUri property.
                var artifactProjectItem    = VsUtils.GetProjectItemForDocument(EdmxUri.LocalPath, Services.ServiceProvider);
                var edmxFilePathInTemplate = String.Empty;
                if (VsUtils.IsLinkProjectItem(artifactProjectItem))
                {
                    // In order to determine the filename that will be placed in the .tt file, we need to first determine the
                    // relative path of the *project item* to the root of the project, since the .tt file will be added as a sibling
                    // of the EDMX file and the project item itself is referencing a linked file. The scenario in mind is:
                    // ProjectRoot
                    //    '- FooFolder
                    //          '- Model.edmx (linked outside the project)
                    //          '- Model.tt <-- we want the .tt file here and the path in the template is relative to this location.
                    var parentItem = artifactProjectItem.Collection.Parent as ProjectItem;
                    var relativeProjectItemParentDir = String.Empty;
                    while (parentItem != null)
                    {
                        relativeProjectItemParentDir = Path.Combine(parentItem.Name, relativeProjectItemParentDir);
                        parentItem = parentItem.Collection.Parent as ProjectItem;
                    }

                    var projectDirectory = VsUtils.GetProjectRoot(project, Services.ServiceProvider);
                    if (projectDirectory != null)
                    {
                        var absoluteProjectItemParentDir = Path.Combine(projectDirectory.FullName, relativeProjectItemParentDir);

                        // Now we determine the relative path between the folder in the project that contains the ProjectItem and the actual path
                        // of the artifact.
                        var artifactParentDirInfo            = new DirectoryInfo(Path.GetDirectoryName(EdmxUri.LocalPath));
                        var absoluteProjectItemParentDirInfo = new DirectoryInfo(absoluteProjectItemParentDir);
                        var relativeDirPath = EdmUtils.GetRelativePath(artifactParentDirInfo, absoluteProjectItemParentDirInfo);
                        var fileName        = Path.GetFileName(EdmxUri.LocalPath);
                        edmxFilePathInTemplate = Path.Combine(relativeDirPath, fileName);
                    }
                }
                else
                {
                    var fi = new FileInfo(EdmxUri.LocalPath);
                    edmxFilePathInTemplate = fi.Name;
                }

                Debug.Assert(!String.IsNullOrEmpty(edmxFilePathInTemplate), "edmxFilePathInTemplate was found to be null or empty");

                replacementsDictionary.Add("$edmxInputFile$", edmxFilePathInTemplate);
            }
        }
        /// <summary>
        ///     Invoked by the VS Wizard framework when this page is entered.
        ///     Starts a background thread to retrieve table information to display
        /// </summary>
        public override void OnActivated()
        {
            base.OnActivated();

            _ssdlAggregator = new DatabaseConnectionSsdlAggregator(Wizard.ModelBuilderSettings);

            using (new VsUtils.HourglassHelper())
            {
                if (!_modelNamespaceInitialized)
                {
                    var existingNamespaces = InitializeExistingNamespaces(Wizard.Project);

                    // set the storage target to the initial catalog but if we're targeting a database project
                    // then set it to the database name which is by definition unique.
                    var storageTarget = Wizard.ModelBuilderSettings.InitialCatalog;

                    // set the default name for the Model Namespace
                    string trialNamespace;
                    if (String.IsNullOrEmpty(storageTarget))
                    {
                        trialNamespace = ModelConstants.DefaultModelNamespace;
                    }
                    else
                    {
                        trialNamespace = EdmUtils.ConstructValidModelNamespace(
                            storageTarget + ModelConstants.DefaultModelNamespace,
                            ModelConstants.DefaultModelNamespace);
                    }

                    modelNamespaceTextBox.Text = EdmUtils.ConstructUniqueNamespace(trialNamespace, existingNamespaces);
                }
            } // restore cursor

            Debug.Assert(
                Wizard.ModelBuilderSettings.DesignTimeConnectionString != null,
                "Unexpected null value for connection string");

            if (Wizard.ModelBuilderSettings.GenerationOption == ModelGenerationOption.GenerateFromDatabase &&
                (!Wizard.ModelBuilderSettings.DesignTimeConnectionString.Equals(_initializedDataConnection) ||
                 Wizard.ModelBuilderSettings.UseLegacyProvider != _initializedUsingLegacyProvider))
            {
                // Enable the treeView / labels and hide the database project label and textbox.
                databaseObjectTreeView.Visible = true;
                labelPrompt.Visible            = true;

                // Disable wizard navigation temporarily until the background thread completes
                Wizard.EnableButton(ButtonType.Previous, false);
                Wizard.EnableButton(ButtonType.Next, false);
                Wizard.EnableButton(ButtonType.Finish, false);

                // disable model namespace textbox
                modelNamespaceTextBox.Enabled = false;

                // Clear existing database objects
                Wizard.ModelBuilderSettings.DatabaseObjectFilters = null;
                databaseObjectTreeView.TreeViewControl.Nodes.Clear();

                // Put up a status message
                databaseObjectTreeView.ShowStatus(ModelWizard.Properties.Resources.SelectTablesPage_StatusRetrievingTablesText);

                // Get table names in a background thread
                _stopwatch.Reset();
                _stopwatch.Start();
                _bgWorkerPopulateTree.RunWorkerAsync(this);
            }
        }
Exemple #23
0
        public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
        {
            var baseProperties = base.GetProperties(attributes);

            // clear out dictionary, as we will rebuild it in this method
            _propertyDescriptorToOwner.Clear();

            if (RunningInVS)
            {
                // we only dispatch to extensions when we are running in VS.  This is because there is a dep on vS things like ProjectItem
                var el = WrappedItem as EFElement;
                Debug.Assert(el != null, "wrapped item is null");
                if (el != null)
                {
                    var currentSelectionOrNull = EscherExtensionPointManager.DetermineEntityDesignerSelection(el);

                    if (currentSelectionOrNull != null)
                    {
                        var currentSelection = (EntityDesignerSelection)currentSelectionOrNull;
                        Debug.Assert((int)currentSelection != 0, "unexpected value for current selection");
                        var extensions = EscherExtensionPointManager.LoadPropertyDescriptorExtensions();
                        if (extensions.Length > 0)
                        {
                            // Note that if the user adds an EDMX file to their project and chooses not to save the project file,
                            // the project item below can be null; it won't even exist in the miscellaneous files project.
                            var projectItem = VsUtils.GetProjectItemForDocument(el.Artifact.Uri.LocalPath, PackageManager.Package);
                            if (projectItem != null &&
                                VsUtils.EntityFrameworkSupportedInProject(
                                    projectItem.ContainingProject, PackageManager.Package, allowMiscProject: false))
                            {
                                var targetSchemaVersion =
                                    EdmUtils.GetEntityFrameworkVersion(projectItem.ContainingProject, PackageManager.Package);

                                //  Use MEF extensions to create "owner" objects that define new property descriptors to add into the property sheet.
                                //  TODO: We track 'visited factories' since have to load the App-DB contracts as well as the standard contracts, but
                                //        MEF also loads the standard contracts in addition to the App-DB contracts. Need to see if MEF can support
                                //        otherwise.
                                var propDescriptorOwners = new List <Object>();
                                var visitedFactories     = new HashSet <IEntityDesignerExtendedProperty>();
                                foreach (var ex in extensions)
                                {
                                    if (((int)ex.Metadata.EntityDesignerSelection & (int)currentSelection) == (int)currentSelection)
                                    {
                                        // Continue processing this extension
                                        var factory = ex.Value;
                                        if (factory != null &&
                                            !visitedFactories.Contains(factory))
                                        {
                                            visitedFactories.Add(factory);
                                            try
                                            {
                                                var extensionContext = new PropertyExtensionContextImpl(
                                                    EditingContext, projectItem, targetSchemaVersion,
                                                    factory.GetType().Assembly.GetName().GetPublicKeyToken());

                                                var xelem = el.XElement;
                                                var sem   = el as StorageEntityModel;
                                                if (currentSelection == EntityDesignerSelection.StorageModelEntityContainer &&
                                                    sem != null)
                                                {
                                                    xelem = sem.FirstEntityContainer.XElement;
                                                }

                                                var o = factory.CreateProperty(xelem, extensionContext);
                                                if (o != null)
                                                {
                                                    propDescriptorOwners.Add(o);
                                                }
                                            }
                                            catch (Exception e)
                                            {
                                                var exceptionMessage = VsUtils.ConstructInnerExceptionErrorMessage(e);
                                                var errorMessage     = String.Format(
                                                    CultureInfo.CurrentCulture, Resources.Extensibility_ErrorOccurredDuringCallToExtension,
                                                    factory.GetType().FullName, exceptionMessage);
                                                VsUtils.ShowErrorDialog(errorMessage);
                                            }
                                        }
                                    }
                                }

                                //
                                //  Create PropertyDescriptors over the new "owner"
                                //
                                foreach (var o in propDescriptorOwners)
                                {
                                    var props = TypeDescriptor.GetProperties(o, attributes, false);
                                    foreach (PropertyDescriptor pd in props)
                                    {
                                        var reflectedPropertyDescriptor = new ReflectedPropertyDescriptor(EditingContext, pd, o);
                                        if (reflectedPropertyDescriptor.IsBrowsable)
                                        {
                                            if (_propertyDescriptorToOwner.ContainsKey(reflectedPropertyDescriptor))
                                            {
                                                // handle degenerate error case where dictionary already contains key.  This shouldn't happen, but this is here just to be safe.
                                                Debug.Fail("_propertyDescriptor2Owner table already contains entry");
                                                _propertyDescriptorToOwner.Remove(reflectedPropertyDescriptor);
                                            }
                                            _propertyDescriptorToOwner.Add(reflectedPropertyDescriptor, o);
                                            baseProperties.Add(reflectedPropertyDescriptor);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(baseProperties);
        }
        public void RunStarted(
            object automationObject,
            Dictionary <string, string> replacementsDictionary,
            WizardRunKind runKind,
            object[] customParams)
        {
            // the dte is the handle into the VS environment
            var dte             = (DTE2)automationObject;
            var serviceProvider = new ServiceProvider((IOleServiceProvider)dte);

            // get the current project that the wizard is running in
            var project = VsUtils.GetActiveProject(dte);

            Debug.Assert(project != null, "Unable to retrieve ActiveSolutionProject from DTE");

            EnsureCanStartWizard(project, serviceProvider);

            // get file name the user chose
            string modelName;

            replacementsDictionary.TryGetValue("$rootname$", out modelName);

            Debug.Assert(modelName != null, "Unable to get $rootname$ from replacementsDictionary");

            modelName = SanitizeModelName(modelName);

            PopluateReplacementDictionary(project, replacementsDictionary, modelName);

            _modelBuilderSettings = new ModelBuilderSettings
            {
                VSApplicationType   = VsUtils.GetApplicationType(serviceProvider, project),
                WizardKind          = WizardKind.Generate,
                TargetSchemaVersion =
                    EdmUtils.GetEntityFrameworkVersion(project, serviceProvider, useLatestIfNoEF: false),
                NewItemFolder         = GetFolderNameForNewItems(dte, project),
                Project               = project,
                ModelName             = modelName,
                VsTemplatePath        = customParams[0] as string,
                ReplacementDictionary = replacementsDictionary
            };

            var form = new ModelBuilderWizardForm(
                serviceProvider,
                _modelBuilderSettings,
                ModelBuilderWizardForm.WizardMode.PerformAllFunctionality)
            {
                FileAlreadyExistsError = false
            };

            try
            {
                form.Start();
            }
            catch (Exception ex)
            {
                VsUtils.ShowErrorDialog(
                    string.Format(
                        CultureInfo.CurrentCulture,
                        Resources.ModelObjectItemWizard_UnexpectedExceptionHasOccurred,
                        ex.Message));

                ClearErrors();

                throw new WizardCancelledException();
            }


            // the form.FileAlreadyExistsError flag is set in the WizardPageStart. We do it because if we
            // threw this exception directly from the WizardPageStart it would be swallowed and the
            // "Add New Item" dialog would not show up. Throwing the exception from here will make
            // the "Add New Item" dialog re-appear which allows the user to enter a different model name.
            if (form.FileAlreadyExistsError)
            {
                Marshal.ThrowExceptionForHR(VSConstants.E_ABORT);
            }

            // if they cancelled or they didn't cancel, and we didn't log that Finish was pressed,
            // they must have hit the X or an exception happened so cancel
            if (form.WizardCancelled ||
                !form.WizardFinished)
            {
                ClearErrors();
                throw new WizardCancelledException();
            }

            Debug.Assert(ReferenceEquals(_modelBuilderSettings, form.ModelBuilderSettings));
        }
Exemple #25
0
        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();
                }
            }
        }
Exemple #26
0
        internal override bool IsXmlValid()
        {
            // If there is a VSXmlModelProvider, we should be able to find a docdata for it.
            // In any other case, it doesn't matter whether there is document data or not.
            var docData = VSHelpers.GetDocData(PackageManager.Package, Uri.LocalPath);

            Debug.Assert(
                !(XmlModelProvider is VSXmlModelProvider) || docData != null, "Using a VSXmlModelProvider but docData is null for Artifact!");

            try
            {
                XmlDocument xmldoc;
                if (docData != null)
                {
                    var textLines = VSHelpers.GetVsTextLinesFromDocData(docData);
                    Debug.Assert(textLines != null, "Failed to get IVSTextLines from docdata");

                    xmldoc = EdmUtils.SafeLoadXmlFromString(VSHelpers.GetTextFromVsTextLines(textLines));
                }
                else
                {
                    // If there is no docdata then attempt to create the XmlDocument from the internal
                    // XLinq tree in the artifact
                    xmldoc = new XmlDocument();
                    xmldoc.Load(XDocument.CreateReader());
                }
                // For the most part, the Edmx schema version of an artifact should be in sync with the schema version
                // that is compatible with the project's target framework; except when the user adds an existing edmx to a project (the version could be different).
                // For all cases, we always want to validate using the XSD's version that matches the artifact's version.
                var documentSchemaVersion = base.SchemaVersion;
                Debug.Assert(
                    EntityFrameworkVersion.IsValidVersion(documentSchemaVersion),
                    "The EF Schema Version is not valid. Value:"
                    + (documentSchemaVersion != null ? documentSchemaVersion.ToString() : "null"));

                // does the XML parse? If not, the load call below will throw
                if (EntityFrameworkVersion.IsValidVersion(documentSchemaVersion))
                {
                    var nsMgr = SchemaManager.GetEdmxNamespaceManager(xmldoc.NameTable, documentSchemaVersion);
                    // Do XSD validation on the document.
                    xmldoc.Schemas = EscherAttributeContentValidator.GetInstance(documentSchemaVersion).EdmxSchemaSet;
                    var svec = new SchemaValidationErrorCollector();

                    // remove runtime specific lines
                    // find the ConceptualModel Schema node
                    RemoveRunTimeNode(xmldoc, "/edmx:Edmx/edmx:Configurations", nsMgr);
                    RemoveRunTimeNode(xmldoc, "/edmx:Edmx/edmx:Runtime/edmx:ConceptualModels", nsMgr);
                    RemoveRunTimeNode(xmldoc, "/edmx:Edmx/edmx:Runtime/edmx:StorageModels", nsMgr);
                    RemoveRunTimeNode(xmldoc, "/edmx:Edmx/edmx:Runtime/edmx:Mappings", nsMgr);

                    xmldoc.Validate(svec.ValidationCallBack);

                    return(svec.ErrorCount == 0);
                }
            }
            catch
            {
            }

            return(false);
        }
        public void RunFinished()
        {
            if (_edmxItem == null)
            {
                if (_modelBuilderSettings.GenerationOption == ModelGenerationOption.EmptyModelCodeFirst ||
                    _modelBuilderSettings.GenerationOption == ModelGenerationOption.CodeFirstFromDatabase)
                {
                    Debug.Assert(
                        _modelBuilderSettings.ModelBuilderEngine == null ^
                        _modelBuilderSettings.GenerationOption == ModelGenerationOption.CodeFirstFromDatabase,
                        "Model should be null for Empty Model and not null CodeFirst from database");

                    AddCodeFirstItems();
                }

                return;
            }

            var fileExtension = Path.GetExtension(_edmxItem.FileNames[1]);

            Debug.Assert(
                _modelBuilderSettings.Project.Equals(_edmxItem.ContainingProject),
                "ActiveSolutionProject is not the EDMX file's containing project");
            using (new VsUtils.HourglassHelper())
            {
                var    package = PackageManager.Package;
                Window window  = null;

                try
                {
                    ConfigFileHelper.UpdateConfig(_modelBuilderSettings);

                    // save the model generated in the wizard UI.
                    if (_modelBuilderSettings.GenerationOption == ModelGenerationOption.GenerateFromDatabase)
                    {
                        var writingModelWatch = new Stopwatch();
                        writingModelWatch.Start();
                        var modelEdmx = ((EdmxModelBuilderEngine)_modelBuilderSettings.ModelBuilderEngine).Edmx;

                        if (!string.Equals(fileExtension, EntityDesignArtifact.ExtensionEdmx, 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,
                                modelEdmx);
                            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
                            }))
                            {
                                modelEdmx.WriteTo(modelWriter);
                            }
                        }

                        writingModelWatch.Stop();
                        VsUtils.LogOutputWindowPaneMessage(
                            _edmxItem.ContainingProject,
                            string.Format(
                                CultureInfo.CurrentCulture,
                                Properties.Resources.WritingModelTimeMsg,
                                writingModelWatch.Elapsed));
                    }

                    // set the ItemType for the generated .edmx file
                    if (_modelBuilderSettings.VSApplicationType != VisualStudioProjectSystem.Website &&
                        string.Equals(
                            fileExtension,
                            EntityDesignArtifact.ExtensionEdmx,
                            StringComparison.OrdinalIgnoreCase))
                    {
                        _edmxItem.Properties.Item(ItemTypePropertyName).Value = EntityDeployBuildActionName;
                    }

                    // now open created file in VS using default viewer
                    window = _edmxItem.Open(Constants.vsViewKindPrimary);
                    Debug.Assert(window != null, "Unable to get window for created edmx file");
                }
                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();
                    }
                }
            }
        }
Exemple #28
0
        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);
        }