private void SetupCallbacks() { try { if (_feelingsContainer != null) { _feelingsContainer.Click += FeelingsContainer_Click; } if (_feelingsImage != null) { _feelingsImage.Click += FeelingsContainer_Click; } if (_feelingsText != null) { _feelingsText.Click += FeelingsContainer_Click; } if (_healthContainer != null) { _healthContainer.Click += HealthContainer_Click; } if (_healthImage != null) { _healthImage.Click += HealthContainer_Click; } if (_healthText != null) { _healthText.Click += HealthContainer_Click; } if (_reactionsContainer != null) { _reactionsContainer.Click += ReactionsContainer_Click; } if (_reactionsImage != null) { _reactionsImage.Click += ReactionsContainer_Click; } if (_reactionsText != null) { _reactionsText.Click += ReactionsContainer_Click; } if (_fantasiesContainer != null) { _fantasiesContainer.Click += FantasiesContainer_Click; } if (_fantasiesImage != null) { _fantasiesImage.Click += FantasiesContainer_Click; } if (_fantasiesText != null) { _fantasiesText.Click += FantasiesContainer_Click; } if (_attitudesContainer != null) { _attitudesContainer.Click += AttitudesContainer_Click; } if (_attitudesImage != null) { _attitudesImage.Click += AttitudesContainer_Click; } if (_attitudesText != null) { _attitudesText.Click += AttitudesContainer_Click; } if (_relationshipsContainer != null) { _relationshipsContainer.Click += RelationshipsContainer_Click; } if (_relationshipsImage != null) { _relationshipsImage.Click += RelationshipsContainer_Click; } if (_relationshipsText != null) { _relationshipsText.Click += RelationshipsContainer_Click; } if (_done != null) { _done.Click += Done_Click; } } catch (Exception e) { Log.Error(TAG, "SetupCallbacks: Exception - " + e.Message); if (GlobalData.ShowErrorDialog) { ErrorDisplay.ShowErrorAlert(this, e, "Setting up Callbacks", "TreatmentStructuredPlanHelpActivity.SetupCallbacks"); } } }
protected StorytellerFailureException(string message, Exception innerException, ErrorDisplay display = ErrorDisplay.markdown) : base(message, innerException) { ErrorDisplay = display; }
private void SetActionIcons(IMenu menu) { try { ConstantsAndTypes.ScreenSize screenSize = SystemHelper.GetScreenSize(); //get references to each of the menu items var itemAdd = menu.FindItem(Resource.Id.reactionsActionAdd); var itemRemove = menu.FindItem(Resource.Id.reactionsActionRemove); var itemHelp = menu.FindItem(Resource.Id.reactionsActionHelp); switch (screenSize) { case ConstantsAndTypes.ScreenSize.Normal: if (itemAdd != null) { itemAdd.SetIcon(Resource.Drawable.ic_add_circle_outline_white_24dp); } if (itemRemove != null) { itemRemove.SetIcon(Resource.Drawable.ic_delete_white_24dp); } if (itemHelp != null) { itemHelp.SetIcon(Resource.Drawable.ic_help_white_24dp); } break; case ConstantsAndTypes.ScreenSize.Large: if (itemAdd != null) { itemAdd.SetIcon(Resource.Drawable.ic_add_circle_outline_white_36dp); } if (itemRemove != null) { itemRemove.SetIcon(Resource.Drawable.ic_delete_white_36dp); } if (itemHelp != null) { itemHelp.SetIcon(Resource.Drawable.ic_help_white_36dp); } break; case ConstantsAndTypes.ScreenSize.ExtraLarge: if (itemAdd != null) { itemAdd.SetIcon(Resource.Drawable.ic_add_circle_outline_white_48dp); } if (itemRemove != null) { itemRemove.SetIcon(Resource.Drawable.ic_delete_white_48dp); } if (itemHelp != null) { itemHelp.SetIcon(Resource.Drawable.ic_help_white_48dp); } break; } } catch (Exception e) { Log.Error(TAG, "SetActionIcons: Exception - " + e.Message); if (GlobalData.ShowErrorDialog) { ErrorDisplay.ShowErrorAlert(this, e, "Setting Action Icons", "StructuredPlanReactions.SetActionIcons"); } } }
public override View GetView(int position, View convertView, ViewGroup parent) { try { if (convertView == null) { if (_activity != null) { convertView = _activity.LayoutInflater.Inflate(Resource.Layout.ContactListItem, parent, false); } else if (parent != null) { LayoutInflater inflater = (LayoutInflater)parent.Context.GetSystemService(Context.LayoutInflaterService); convertView = inflater.Inflate(Resource.Layout.ContactListItem, parent, false); } else { return(convertView); } } _contactPhotoImage = convertView.FindViewById <ImageView>(Resource.Id.imgContactPhoto); _contactName = convertView.FindViewById <TextView>(Resource.Id.txtContactName); _contactTelephoneNumber = convertView.FindViewById <TextView>(Resource.Id.txtContactTelephoneNumber); _contactEmail = convertView.FindViewById <TextView>(Resource.Id.txtContactEmailAddress); if (_contactName != null) { if (!string.IsNullOrEmpty(_contacts[position].ContactName)) { _contactName.Text = _contacts[position].ContactName.Trim(); } else { _contactName.Text = ""; } } if (_contactTelephoneNumber != null) { if (!string.IsNullOrEmpty(_contacts[position].ContactTelephoneNumber)) { _contactTelephoneNumber.Text = _contacts[position].ContactTelephoneNumber.Trim(); } else { _contactTelephoneNumber.Text = ""; } } if (_contactEmail != null) { if (!string.IsNullOrEmpty(_contacts[position].ContactEmail)) { _contactEmail.Text = _contacts[position].ContactEmail.Trim(); } else { _contactEmail.Text = ""; } } if (_contactPhotoImage != null) { if (_contacts[position].ContactPhoto == null) { _contactPhotoImage.SetImageResource(Resource.Drawable.Moods2); } else { _contactPhotoImage.SetImageBitmap(_contacts[position].ContactPhoto); } } var parentHeldSelectedItemIndex = ((ContactActivity)_activity).GetSelectedItemIndex(); if (position == parentHeldSelectedItemIndex) { convertView.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); _contactName.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); _contactTelephoneNumber.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); _contactPhotoImage.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); _contactEmail.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); } else { convertView.SetBackgroundDrawable(null); _contactName.SetBackgroundDrawable(null); _contactTelephoneNumber.SetBackgroundDrawable(null); _contactPhotoImage.SetBackgroundDrawable(null); _contactEmail.SetBackgroundDrawable(null); } return(convertView); } catch (Exception e) { Log.Error(TAG, "GetView: Exception - " + e.Message); if (_activity != null) { if (GlobalData.ShowErrorDialog) { ErrorDisplay.ShowErrorAlert(_activity, e, "Getting Contacts View", "ContactsUserListAdapter.GetView"); } } return(null); } }
public override void OnDragDrop(DiagramDragEventArgs diagramDragEventArgs) { // came from model explorer? ModelElement element = (diagramDragEventArgs.Data.GetData("Sawczyn.EFDesigner.EFModel.ModelClass") as ModelElement) ?? (diagramDragEventArgs.Data.GetData("Sawczyn.EFDesigner.EFModel.ModelEnum") as ModelElement); if (element != null) { ShapeElement newShape = AddExistingModelElement(this, element); if (newShape != null) { using (Transaction t = element.Store.TransactionManager.BeginTransaction("Moving pasted shapes")) { if (newShape is NodeShape nodeShape) { nodeShape.Location = diagramDragEventArgs.MousePosition; } t.Commit(); } } } else { if (IsDroppingExternal) { DisableDiagramRules(); Cursor prev = Cursor.Current; Cursor.Current = Cursors.WaitCursor; List <ModelElement> newElements = null; try { try { // add to the model string[] filenames; if (diagramDragEventArgs.Data.GetData("Text") is string concatenatedFilenames) { filenames = concatenatedFilenames.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); } else if (diagramDragEventArgs.Data.GetData("FileDrop") is string[] droppedFilenames) { filenames = droppedFilenames; } else { ErrorDisplay.Show(Store, "Unexpected error dropping files. Please create an issue in Github."); return; } string[] existingFiles = filenames.Where(File.Exists).ToArray(); newElements = FileDropHelper.HandleMultiDrop(Store, existingFiles).ToList(); string[] missingFiles = filenames.Except(existingFiles).ToArray(); if (missingFiles.Any()) { if (missingFiles.Length > 1) { missingFiles[missingFiles.Length - 1] = "and " + missingFiles[missingFiles.Length - 1]; } ErrorDisplay.Show(Store, $"Can't find files {string.Join(", ", missingFiles)}"); } } finally { // TODO: how to add shapes to the current diagram without taking forever? The trick is disabling line routing, but how? #region Come back to this later //if (newElements != null) //{ // add to the active diagram //int elementCount = newElements.Count; //List<ShapeElement> newShapes = new List<ShapeElement>(); //using (Transaction t = Store.TransactionManager.BeginTransaction("adding diagram elements")) //{ // for (int index = 0; index < elementCount; index++) // { // ModelElement newElement = newElements[index]; // StatusDisplay.Show($"Adding element {index + 1} of {elementCount}"); // ForceAddShape = true; // FixUpAllDiagrams.FixUp(this, newElement); // newShapes.Add(newElement.GetFirstShapeElement()); // ForceAddShape = false; // } // t.Commit(); //} //using (Transaction t = Store.TransactionManager.BeginTransaction("adding diagram links")) //{ // for (int index = 0; index < elementCount; index++) // { // ModelElement newElement = newElements[index]; // StatusDisplay.Show($"Linking {index + 1} of {elementCount}"); // // find all element links that are attached to our element where the ends are in the diagram but the link isn't already in the diagram // List<ElementLink> elementLinks = Store.GetAll<ElementLink>() // .Where(link => link.LinkedElements.Contains(newElement) // && link.LinkedElements.All(linkedElement => DisplayedElements.Contains(linkedElement)) // && !DisplayedElements.Contains(link)) // .ToList(); // foreach (ElementLink elementLink in elementLinks) // { // BinaryLinkShape linkShape = CreateChildShape(elementLink) as BinaryLinkShape; // newShapes.Add(linkShape); // NestedChildShapes.Add(linkShape); // switch (elementLink) // { // case Association a: // linkShape.FromShape = a.Source.GetFirstShapeElement() as NodeShape; // linkShape.ToShape = a.Target.GetFirstShapeElement() as NodeShape; // break; // case Generalization g: // linkShape.FromShape = g.Subclass.GetFirstShapeElement() as NodeShape; // linkShape.ToShape = g.Superclass.GetFirstShapeElement() as NodeShape; // break; // } // } // } // AutoLayoutShapeElements(newShapes); // t.Commit(); //} //} #endregion IsDroppingExternal = false; } } finally { EnableDiagramRules(); Cursor.Current = prev; MessageDisplay.Show(newElements == null || !newElements.Any() ? "Import dropped files: no new elements added" : BuildMessage(newElements)); StatusDisplay.Show(""); } } else { try { base.OnDragDrop(diagramDragEventArgs); } catch (ArgumentException) { // ignore. byproduct of multiple diagrams } } } StatusDisplay.Show(""); Invalidate(); string BuildMessage(List <ModelElement> newElements) { int classCount = newElements.OfType <ModelClass>().Count(); int propertyCount = newElements.OfType <ModelClass>().SelectMany(c => c.Attributes).Count(); int enumCount = newElements.OfType <ModelEnum>().Count(); List <string> messageParts = new List <string>(); if (classCount > 0) { messageParts.Add($"{classCount} classes"); } if (propertyCount > 0) { messageParts.Add($"{propertyCount} properties"); } if (enumCount > 0) { messageParts.Add($"{enumCount} enums"); } return($"Import dropped files: added {(messageParts.Count > 1 ? string.Join(", ", messageParts.Take(messageParts.Count - 1)) + " and " + messageParts.Last() : messageParts.First())}"); } }
public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e) { base.ElementPropertyChanged(e); ModelEnumValue element = (ModelEnumValue)e.ModelElement; if (element.IsDeleted) { return; } ModelEnum modelEnum = element.Enum; Store store = element.Store; Transaction current = store.TransactionManager.CurrentTransaction; if (current.IsSerializing || ModelRoot.BatchUpdating) { return; } if (Equals(e.NewValue, e.OldValue)) { return; } string errorMessage = null; switch (e.DomainProperty.Name) { case "Name": string newName = (string)e.NewValue; Match match = Regex.Match(newName, @"(.+)\s*=\s*(\d+)"); if (match != Match.Empty) { newName = match.Groups[1].Value; element.Value = match.Groups[2].Value; } if (string.IsNullOrWhiteSpace(newName) || !CodeGenerator.IsValidLanguageIndependentIdentifier(newName)) { errorMessage = $"{modelEnum.Name}.{newName}: Name must be a valid .NET identifier"; } else if (modelEnum.Values.Except(new[] { element }).Any(v => v.Name == newName)) { errorMessage = $"{modelEnum.Name}.{newName}: Name already in use"; } else { // find ModelAttributes where the default value is this ModelEnumValue and change it to the new name foreach (ModelAttribute modelAttribute in store.GetAll <ModelAttribute>().Where(a => a.InitialValue == $"{modelEnum.Name}.{(string)e.OldValue}")) { string[] parts = modelAttribute.InitialValue.Split('.'); parts[1] = newName; modelAttribute.InitialValue = string.Join(".", parts); } } break; case "Value": string newValue = (string)e.NewValue; if (newValue != null) { bool badValue = false; switch (modelEnum.ValueType) { case EnumValueType.Int16: badValue = !short.TryParse(newValue, out short _); break; case EnumValueType.Int32: badValue = !int.TryParse(newValue, out int _); break; case EnumValueType.Int64: badValue = !long.TryParse(newValue, out long _); break; } if (badValue) { errorMessage = $"Invalid value for {modelEnum.Name}. Must be {modelEnum.ValueType}."; } else { bool hasDuplicates = modelEnum.Values.Any(x => x != element && x.Value == newValue); if (hasDuplicates) { errorMessage = $"Value {newValue} is already present in {modelEnum.Name}. Can't have duplicate values."; } } } break; } if (errorMessage != null) { current.Rollback(); ErrorDisplay.Show(store, errorMessage); } }
private void ProcessEnum([NotNull] EnumDeclarationSyntax enumDecl, NamespaceDeclarationSyntax namespaceDecl = null) { if (enumDecl == null) { throw new ArgumentNullException(nameof(enumDecl)); } ModelRoot modelRoot = Store.ModelRoot(); string enumName = enumDecl.Identifier.Text; if (namespaceDecl == null && enumDecl.Parent is NamespaceDeclarationSyntax enumDeclParent) { namespaceDecl = enumDeclParent; } string namespaceName = namespaceDecl?.Name?.ToString() ?? modelRoot.Namespace; if (Store.Get <ModelClass>().Any(c => c.Name == enumName) || Store.Get <ModelEnum>().Any(c => c.Name == enumName)) { ErrorDisplay.Show($"'{enumName}' already exists in model."); // ReSharper disable once ExpressionIsAlwaysNull return; } Transaction tx = Store.TransactionManager.CurrentTransaction == null ? Store.TransactionManager.BeginTransaction() : null; try { ModelEnum result = new ModelEnum(Store , new PropertyAssignment(ModelEnum.NameDomainPropertyId, enumName) , new PropertyAssignment(ModelEnum.NamespaceDomainPropertyId, namespaceName) , new PropertyAssignment(ModelEnum.IsFlagsDomainPropertyId, enumDecl.HasAttribute("Flags"))); SimpleBaseTypeSyntax baseTypeSyntax = enumDecl.DescendantNodes().OfType <SimpleBaseTypeSyntax>().FirstOrDefault(); if (baseTypeSyntax != null) { switch (baseTypeSyntax.Type.ToString()) { case "Int16": case "short": result.ValueType = EnumValueType.Int16; break; case "Int32": case "int": result.ValueType = EnumValueType.Int32; break; case "Int64": case "long": result.ValueType = EnumValueType.Int64; break; default: WarningDisplay.Show($"Could not resolve value type for '{enumName}'. The enum will default to an Int32 value type."); break; } } XMLDocumentation xmlDocumentation; foreach (EnumMemberDeclarationSyntax enumValueDecl in enumDecl.DescendantNodes().OfType <EnumMemberDeclarationSyntax>()) { ModelEnumValue enumValue = new ModelEnumValue(Store, new PropertyAssignment(ModelEnumValue.NameDomainPropertyId, enumValueDecl.Identifier.ToString())); EqualsValueClauseSyntax valueDecl = enumValueDecl.DescendantNodes().OfType <EqualsValueClauseSyntax>().FirstOrDefault(); if (valueDecl != null) { enumValue.Value = valueDecl.Value.ToString(); } xmlDocumentation = new XMLDocumentation(enumValueDecl); enumValue.Summary = xmlDocumentation.Summary; enumValue.Description = xmlDocumentation.Description; result.Values.Add(enumValue); } xmlDocumentation = new XMLDocumentation(enumDecl); result.Summary = xmlDocumentation.Summary; result.Description = xmlDocumentation.Description; modelRoot.Enums.Add(result); } catch { tx = null; throw; } finally { tx?.Commit(); } }
public override View GetView(int position, View convertView, ViewGroup parent) { try { if (convertView == null) { if (_activity != null) { convertView = _activity.LayoutInflater.Inflate(Resource.Layout.ProblemSolvingListItem, parent, false); } else if (parent != null) { LayoutInflater inflater = (LayoutInflater)parent.Context.GetSystemService(Context.LayoutInflaterService); convertView = inflater.Inflate(Resource.Layout.ProblemSolvingListItem, parent, false); } else { return(convertView); } } if (convertView != null) { _position = position; GetFieldComponents(convertView); SetupCallbacks(); if (_problemText != null) { _problemText.Text = _problemList[position].ProblemText.Trim(); } else { Log.Error(TAG, "GetView: _problemText is NULL!"); } if (_problemDetail != null) { _problemDetail.Tag = _problemList[position].ProblemID.ToString() + ":" + _problemList[position].ProblemText.Trim(); } else { Log.Error(TAG, "GetView: _problemDetail is NULL!"); } if (_steps != null) { _steps.Text = GetStepsCountInProblem(position).ToString(); } else { Log.Error(TAG, "GetView: _steps is NULL!"); } if (_ideas != null) { _ideas.Text = GetIdeasCountInProblem(position).ToString(); } else { Log.Error(TAG, "GetView: _ideas is NULL!"); } if (_prosAndCons != null) { _prosAndCons.Text = GetProsAndConsCountInProblem(position).ToString(); } else { Log.Error(TAG, "GetView: _prosAndCons is NULL!"); } //has problem been solved? SeeIfProblemWasSolved(convertView, position); if (position == ((ProblemSolvingActivity)_activity).GetSelectedItemIndex()) { convertView.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); if (_problemSolvingListItemLabel != null) { _problemSolvingListItemLabel.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); } if (_problemText != null) { _problemText.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); } if (_steps != null) { _steps.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); } if (_ideas != null) { _ideas.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); } if (_prosAndCons != null) { _prosAndCons.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); } if (_problemSolved != null) { _problemSolved.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); } if (_problemDetail != null) { _problemDetail.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); } } else { convertView.SetBackgroundDrawable(null); if (_problemSolvingListItemLabel != null) { _problemSolvingListItemLabel.SetBackgroundDrawable(null); } if (_problemText != null) { _problemText.SetBackgroundDrawable(null); } if (_steps != null) { _steps.SetBackgroundDrawable(null); } if (_ideas != null) { _ideas.SetBackgroundDrawable(null); } if (_prosAndCons != null) { _prosAndCons.SetBackgroundDrawable(null); } if (_problemSolved != null) { _problemSolved.SetBackgroundDrawable(null); } if (_problemDetail != null) { _problemDetail.SetBackgroundDrawable(null); } } } else { Log.Error(TAG, "GetView: view is NULL!"); } return(convertView); } catch (Exception e) { Log.Error(TAG, "GetView: Exception - " + e.Message); if (GlobalData.ShowErrorDialog) { ErrorDisplay.ShowErrorAlert(_activity, e, _activity.GetString(Resource.String.ErrorProblemSolvingListGetView), "ProblemSolvingListAdapter.GetView"); } return(convertView); } }
public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e) { base.ElementPropertyChanged(e); ModelEnum element = (ModelEnum)e.ModelElement; if (element.IsDeleted) { return; } Store store = element.Store; Transaction currentTransaction = store.TransactionManager.CurrentTransaction; if (currentTransaction.IsSerializing) { return; } if (Equals(e.NewValue, e.OldValue)) { return; } string errorMessage = null; switch (e.DomainProperty.Name) { case "Name": if (currentTransaction.Name.ToLowerInvariant() == "paste") { return; } if (string.IsNullOrWhiteSpace(element.Name) || !CodeGenerator.IsValidLanguageIndependentIdentifier(element.Name)) { errorMessage = "Name must be a valid .NET identifier"; } else if (store.GetAll <ModelClass>().Any(x => x.FullName == element.FullName)) { errorMessage = "Enum name already in use by a class"; } else if (store.GetAll <ModelEnum>().Except(new[] { element }).Any(x => x.FullName == element.FullName)) { errorMessage = "Enum name already in use by another enum"; } else { // rename type names for ModelAttributes that reference this enum foreach (ModelAttribute modelAttribute in store.GetAll <ModelAttribute>().Where(a => a.Type == (string)e.OldValue)) { modelAttribute.Type = element.Name; if (!string.IsNullOrEmpty(modelAttribute.InitialValue)) { string[] parts = modelAttribute.InitialValue.Split('.'); parts[0] = (string)e.NewValue; modelAttribute.InitialValue = string.Join(".", parts); } } } break; case "Namespace": if (currentTransaction.Name.ToLowerInvariant() != "paste") { errorMessage = CommonRules.ValidateNamespace(element.Namespace, CodeGenerator.IsValidLanguageIndependentIdentifier); } break; case "IsFlags": element.SetFlagValues(); break; case "ValueType": EnumValueType newValueType = (EnumValueType)e.NewValue; List <ModelAttribute> modelAttributes = store.ElementDirectory .AllElements .OfType <ModelAttribute>() .Where(a => a.Type == element.Name && a.IsIdentity) .ToList(); if (modelAttributes.Any()) { string classList = string.Join(", ", modelAttributes.Select(a => a.ModelClass.Name + "." + a.Name)); errorMessage = $"Can't change {element.Name} value type to {newValueType}. It's not a valid identity type, and {element.Name} is used as an identity type in {classList}"; } break; } if (errorMessage != null) { currentTransaction.Rollback(); ErrorDisplay.Show(store, errorMessage); } }
private void SetActionIcons(IMenu menu) { try { ConstantsAndTypes.ScreenSize screenSize = SystemHelper.GetScreenSize(); //get references to each of the menu items var itemExpand = menu.FindItem(Resource.Id.ActivitiesActionExpand); var itemCollapse = menu.FindItem(Resource.Id.ActivitiesActionCollapse); var itemHelp = menu.FindItem(Resource.Id.ActivitiesActionHelp); switch (screenSize) { case ConstantsAndTypes.ScreenSize.Normal: if (itemExpand != null) { itemExpand.SetIcon(Resource.Drawable.expand); } if (itemCollapse != null) { itemCollapse.SetIcon(Resource.Drawable.collapse); } if (itemHelp != null) { itemHelp.SetIcon(Resource.Drawable.ic_help_white_24dp); } break; case ConstantsAndTypes.ScreenSize.Large: if (itemExpand != null) { itemExpand.SetIcon(Resource.Drawable.expand); } if (itemCollapse != null) { itemCollapse.SetIcon(Resource.Drawable.collapse); } if (itemHelp != null) { itemHelp.SetIcon(Resource.Drawable.ic_help_white_36dp); } break; case ConstantsAndTypes.ScreenSize.ExtraLarge: if (itemExpand != null) { itemExpand.SetIcon(Resource.Drawable.expand); } if (itemCollapse != null) { itemCollapse.SetIcon(Resource.Drawable.collapse); } if (itemHelp != null) { itemHelp.SetIcon(Resource.Drawable.ic_help_white_48dp); } break; } } catch (Exception e) { Log.Error(TAG, "SetActionIcons: Exception - " + e.Message); if (GlobalData.ShowErrorDialog) { ErrorDisplay.ShowErrorAlert(this, e, "Setting Action Icons", "MedicationActivity.SetActionIcons"); } } }
public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e) { base.ElementPropertyChanged(e); ModelAttribute element = (ModelAttribute)e.ModelElement; if (element.IsDeleted) { return; } ModelClass modelClass = element.ModelClass; ModelRoot modelRoot = element.Store.ModelRoot(); Store store = element.Store; Transaction current = store.TransactionManager.CurrentTransaction; if (current.IsSerializing) { return; } if (Equals(e.NewValue, e.OldValue)) { return; } List <string> errorMessages = EFCoreValidator.GetErrors(element).ToList(); switch (e.DomainProperty.Name) { case "AutoProperty": { if (element.AutoProperty) { element.PersistencePoint = PersistencePointType.Property; } } break; case "IdentityType": { if (element.IsIdentity) { if (element.IdentityType == IdentityType.None) { errorMessages.Add($"{modelClass.Name}.{element.Name}: Identity properties must have an identity type defined"); } else { element.AutoProperty = true; } } else { element.IdentityType = IdentityType.None; } } break; case "ImplementNotify": { if (element.IsIdentity) { element.ImplementNotify = false; } if (element.ImplementNotify) { element.AutoProperty = false; } } break; case "Indexed": { if (element.IsIdentity) { element.Indexed = true; } if (element.IsConcurrencyToken) { element.Indexed = false; } if (element.Indexed) { element.Persistent = true; } } break; case "InitialValue": { string newInitialValue = (string)e.NewValue; // if the property is an Enum and the user just typed the name of the Enum value without the Enum type name, help them out if (element.ModelClass.ModelRoot.Enums.Any(x => x.Name == element.Type) && !newInitialValue.Contains(".")) { newInitialValue = element.InitialValue = $"{element.Type}.{newInitialValue}"; } if (!element.IsValidInitialValue(null, newInitialValue)) { errorMessages.Add($"{modelClass.Name}.{element.Name}: {newInitialValue} isn't a valid value for {element.Type}"); } } break; case "IsConcurrencyToken": { bool newIsConcurrencyToken = (bool)e.NewValue; if (newIsConcurrencyToken) { element.IsIdentity = false; element.Persistent = true; element.Required = true; element.Type = "Binary"; } } break; case "IsIdentity": { bool newIsIdentity = (bool)e.NewValue; if (newIsIdentity) { if (element.ModelClass.IsDependentType) { errorMessages.Add($"{modelClass.Name}.{element.Name}: Can't make {element.Name} an identity because {modelClass.Name} is a dependent type and can't have an identity property."); } else { if (!modelRoot.ValidIdentityAttributeTypes.Contains(element.Type)) { errorMessages.Add($"{modelClass.Name}.{element.Name}: Properties of type {element.Type} can't be used as identity properties."); } else { element.IsConcurrencyToken = false; element.Indexed = true; element.IndexedUnique = true; element.Persistent = true; element.Required = true; if (element.IdentityType == IdentityType.None) { element.IdentityType = IdentityType.AutoGenerated; } } } } else { element.IdentityType = IdentityType.None; } } break; case "MinLength": { Int32Nullable newMinLength = (Int32Nullable)e.NewValue; if (element.Type != "String") { element.MinLength = null; } if (newMinLength < 0) { errorMessages.Add($"{modelClass.Name}.{element.Name}: MinLength must be blank, zero or a positive number"); } } break; case "MaxLength": { Int32Nullable newMaxLength = (Int32Nullable)e.NewValue; if (element.Type != "String") { element.MaxLength = null; } if (newMaxLength < 0) { errorMessages.Add($"{modelClass.Name}.{element.Name}: MaxLength must be blank, zero or a positive number"); } } break; case "Name": { string newName = (string)e.NewValue; if (string.IsNullOrEmpty(newName)) { errorMessages.Add("Name must be a valid .NET identifier"); } else { ParseResult fragment; try { fragment = ModelAttribute.Parse(modelRoot, newName); if (fragment == null) { errorMessages.Add($"{modelClass.Name}: Could not parse entry '{newName}'"); } else { if (string.IsNullOrEmpty(fragment.Name) || !CodeGenerator.IsValidLanguageIndependentIdentifier(fragment.Name)) { errorMessages.Add($"{modelClass.Name}: Property name '{fragment.Name}' isn't a valid .NET identifier"); } else if (modelClass.AllAttributes.Except(new[] { element }).Any(x => x.Name == fragment.Name)) { errorMessages.Add($"{modelClass.Name}: Property name '{fragment.Name}' already in use"); } else if (modelClass.AllNavigationProperties().Any(p => p.PropertyName == fragment.Name)) { errorMessages.Add($"{modelClass.Name}: Property name '{fragment.Name}' already in use"); } else { element.Name = fragment.Name; if (fragment.Type != null) { element.Type = fragment.Type; } if (fragment.Required != null) { element.Required = fragment.Required.Value; } element.MaxLength = fragment.MaxLength; element.MinLength = fragment.MinLength; if (fragment.InitialValue != null) { element.InitialValue = fragment.InitialValue; } if (fragment.IsIdentity) { element.IsIdentity = true; // don't reset to false if not entered as part of name } } } } catch (Exception exception) { errorMessages.Add($"{modelClass.Name}: Could not parse entry '{newName}': {exception.Message}"); } } } break; case "PersistencePoint": { if ((PersistencePointType)e.NewValue == PersistencePointType.Field) { element.AutoProperty = false; } } break; case "Persistent": { bool newPersistent = (bool)e.NewValue; if (!newPersistent) { element.IsIdentity = false; element.Indexed = false; element.IndexedUnique = false; element.IdentityType = IdentityType.None; element.IsConcurrencyToken = false; element.Virtual = false; } } break; case "ReadOnly": { if (!element.Persistent || element.SetterVisibility != SetterAccessModifier.Public) { element.ReadOnly = false; } } break; case "Required": { bool newRequired = (bool)e.NewValue; if (!newRequired) { if (element.IsIdentity || element.IsConcurrencyToken) { element.Required = true; } } } break; case "Type": { string newType = (string)e.NewValue; if (element.IsIdentity) { if (!modelRoot.ValidIdentityAttributeTypes.Contains(ModelAttribute.ToCLRType(newType))) { errorMessages.Add($"{modelClass.Name}.{element.Name}: Properties of type {newType} can't be used as identity properties."); } else { element.Required = true; element.Persistent = true; } } if (newType != "String") { element.MaxLength = (int?)null; element.MinLength = (int?)null; element.StringType = HTML5Type.None; } else { if (!element.IsValidInitialValue(newType)) { element.InitialValue = null; } } if (element.IsConcurrencyToken) { element.Type = "Binary"; } if (!element.SupportsInitialValue) { element.InitialValue = null; } } break; } errorMessages = errorMessages.Where(m => m != null).ToList(); if (errorMessages.Any()) { current.Rollback(); ErrorDisplay.Show(string.Join("\n", errorMessages)); } }
public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e) { base.ElementPropertyChanged(e); Association element = (Association)e.ModelElement; if (element.IsDeleted) { return; } Store store = element.Store; Transaction current = store.TransactionManager.CurrentTransaction; if (current.IsSerializing) { return; } if (Equals(e.NewValue, e.OldValue)) { return; } List <string> errorMessages = EFCoreValidator.GetErrors(element).ToList(); BidirectionalAssociation bidirectionalAssociation = element as BidirectionalAssociation; switch (e.DomainProperty.Name) { case "Persistent": UpdateDisplayForPersistence(element); break; case "SourceCustomAttributes": if (bidirectionalAssociation != null && !string.IsNullOrWhiteSpace(bidirectionalAssociation.SourceCustomAttributes)) { bidirectionalAssociation.SourceCustomAttributes = $"[{bidirectionalAssociation.SourceCustomAttributes.Trim('[', ']')}]"; CheckSourceForDisplayText(bidirectionalAssociation); } break; case "SourceDeleteAction": DeleteAction sourceDeleteAction = (DeleteAction)e.NewValue; UpdateDisplayForCascadeDelete(element, sourceDeleteAction); break; case "SourceDisplayText": if (bidirectionalAssociation != null) { CheckSourceForDisplayText(bidirectionalAssociation); } break; case "SourceMultiplicity": Multiplicity sourceMultiplicity = (Multiplicity)e.NewValue; // change unidirectional source cardinality // if target is dependent // source cardinality is 0..1 or 1 if (element.Target.IsDependentType && sourceMultiplicity == Multiplicity.ZeroMany) { errorMessages.Add($"Can't have a 0..* association from {element.Target.Name} to dependent type {element.Source.Name}"); break; } if ((sourceMultiplicity == Multiplicity.One && element.TargetMultiplicity == Multiplicity.One) || (sourceMultiplicity == Multiplicity.ZeroOne && element.TargetMultiplicity == Multiplicity.ZeroOne)) { if (element.SourceRole != EndpointRole.NotSet) { element.SourceRole = EndpointRole.NotSet; } if (element.TargetRole != EndpointRole.NotSet) { element.TargetRole = EndpointRole.NotSet; } } else { SetEndpointRoles(element); } UpdateDisplayForCascadeDelete(element, null, null, sourceMultiplicity); break; case "SourcePropertyName": string sourcePropertyNameErrorMessage = ValidateAssociationIdentifier(element, element.Target, (string)e.NewValue); if (EFModelDiagram.IsDropping && sourcePropertyNameErrorMessage != null) { element.Delete(); } else { errorMessages.Add(sourcePropertyNameErrorMessage); } break; case "SourceRole": if (element.Source.IsDependentType) { element.SourceRole = EndpointRole.Dependent; element.TargetRole = EndpointRole.Principal; } else if (!SetEndpointRoles(element)) { if (element.SourceRole == EndpointRole.Dependent && element.TargetRole != EndpointRole.Principal) { element.TargetRole = EndpointRole.Principal; } else if (element.SourceRole == EndpointRole.Principal && element.TargetRole != EndpointRole.Dependent) { element.TargetRole = EndpointRole.Dependent; } } break; case "TargetCustomAttributes": if (!string.IsNullOrWhiteSpace(element.TargetCustomAttributes)) { element.TargetCustomAttributes = $"[{element.TargetCustomAttributes.Trim('[', ']')}]"; CheckTargetForDisplayText(element); } break; case "TargetDisplayText": CheckTargetForDisplayText(element); break; case "TargetDeleteAction": DeleteAction targetDeleteAction = (DeleteAction)e.NewValue; UpdateDisplayForCascadeDelete(element, null, targetDeleteAction); break; case "TargetMultiplicity": Multiplicity newTargetMultiplicity = (Multiplicity)e.NewValue; // change unidirectional target cardinality // if target is dependent // target cardinality must be 0..1 or 1 if (element.Target.IsDependentType && newTargetMultiplicity == Multiplicity.ZeroMany) { errorMessages.Add($"Can't have a 0..* association from {element.Source.Name} to dependent type {element.Target.Name}"); break; } if ((element.SourceMultiplicity == Multiplicity.One && newTargetMultiplicity == Multiplicity.One) || (element.SourceMultiplicity == Multiplicity.ZeroOne && newTargetMultiplicity == Multiplicity.ZeroOne)) { if (element.SourceRole != EndpointRole.NotSet) { element.SourceRole = EndpointRole.NotSet; } if (element.TargetRole != EndpointRole.NotSet) { element.TargetRole = EndpointRole.NotSet; } } else { SetEndpointRoles(element); } UpdateDisplayForCascadeDelete(element, null, null, null, newTargetMultiplicity); break; case "TargetPropertyName": // if we're creating an association via drag/drop, it's possible the existing property name // is the same as the default property name. The default doesn't get created until the transaction is // committed, so the drop's action will cause a name clash. Remove the clashing property, but // only if drag/drop. string targetPropertyNameErrorMessage = ValidateAssociationIdentifier(element, element.Source, (string)e.NewValue); if (EFModelDiagram.IsDropping && targetPropertyNameErrorMessage != null) { element.Delete(); } else { errorMessages.Add(targetPropertyNameErrorMessage); } break; case "TargetRole": if (element.Target.IsDependentType) { element.SourceRole = EndpointRole.Principal; element.TargetRole = EndpointRole.Dependent; } else if (!SetEndpointRoles(element)) { if (element.TargetRole == EndpointRole.Dependent && element.SourceRole != EndpointRole.Principal) { element.SourceRole = EndpointRole.Principal; } else if (element.TargetRole == EndpointRole.Principal && element.SourceRole != EndpointRole.Dependent) { element.SourceRole = EndpointRole.Dependent; } } break; } errorMessages = errorMessages.Where(m => m != null).ToList(); if (errorMessages.Any()) { current.Rollback(); ErrorDisplay.Show(string.Join("\n", errorMessages)); } }
private ModelClass ProcessClass([NotNull] ClassDeclarationSyntax classDecl, NamespaceDeclarationSyntax namespaceDecl = null) { ModelClass result = null; if (classDecl == null) { throw new ArgumentNullException(nameof(classDecl)); } ModelRoot modelRoot = Store.ModelRoot(); string className = classDecl.Identifier.Text; if (namespaceDecl == null && classDecl.Parent is NamespaceDeclarationSyntax classDeclParent) { namespaceDecl = classDeclParent; } if (Store.Get <ModelEnum>().Any(c => c.Name == className)) { ErrorDisplay.Show($"'{className}' already exists in model as an Enum."); // ReSharper disable once ExpressionIsAlwaysNull return(result); } if (classDecl.TypeParameterList != null) { ErrorDisplay.Show($"Can't add generic class '{className}'."); // ReSharper disable once ExpressionIsAlwaysNull return(result); } Transaction tx = Store.TransactionManager.CurrentTransaction == null ? Store.TransactionManager.BeginTransaction() : null; List <string> customInterfaces = new List <string>(); try { ModelClass superClass = null; result = Store.Get <ModelClass>().FirstOrDefault(c => c.Name == className); // Base classes and interfaces // Check these first. If we need to add new models, we want the base class already in the store if (classDecl.BaseList != null) { foreach (BaseTypeSyntax type in classDecl.BaseList.Types) { string baseName = type.ToString(); // Do we know this is an interface? if (KnownInterfaces.Contains(baseName) || superClass != null || result?.Superclass != null) { customInterfaces.Add(baseName); if (!KnownInterfaces.Contains(baseName)) { KnownInterfaces.Add(baseName); } continue; } // is it inheritance or an interface? superClass = modelRoot.Classes.FirstOrDefault(c => c.Name == baseName); // if it's not in the model, we just don't know. Ask the user if (superClass == null && (KnownClasses.Contains(baseName) || QuestionDisplay.Show($"For class {className}, is {baseName} the base class?") == true)) { superClass = new ModelClass(Store, new PropertyAssignment(ModelClass.NameDomainPropertyId, baseName)); modelRoot.Classes.Add(superClass); } else { customInterfaces.Add(baseName); KnownInterfaces.Add(baseName); } } } if (result == null) { result = new ModelClass(Store, new PropertyAssignment(ModelClass.NameDomainPropertyId, className)) { Namespace = namespaceDecl?.Name?.ToString() ?? modelRoot.Namespace, IsAbstract = classDecl.DescendantNodes().Any(n => n.Kind() == SyntaxKind.AbstractKeyword) }; modelRoot.Classes.Add(result); } if (superClass != null) { result.Superclass = superClass; } if (result.CustomInterfaces != null) { customInterfaces.AddRange(result.CustomInterfaces .Split(',') .Where(i => !String.IsNullOrEmpty(i)) .Select(i => i.Trim())); } if (customInterfaces.Contains("INotifyPropertyChanged")) { result.ImplementNotify = true; customInterfaces.Remove("INotifyPropertyChanged"); } if (result.Superclass != null && customInterfaces.Contains(result.Superclass.Name)) { customInterfaces.Remove(result.Superclass.Name); } result.CustomInterfaces = customInterfaces.Any() ? String.Join(",", customInterfaces.Distinct()) : null; XMLDocumentation xmlDocumentation = new XMLDocumentation(classDecl); result.Summary = xmlDocumentation.Summary; result.Description = xmlDocumentation.Description; } catch { tx = null; throw; } finally { tx?.Commit(); } return(result); }
/// <inheritdoc /> public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e) { base.ElementPropertyChanged(e); ModelAttribute element = (ModelAttribute)e.ModelElement; if (element.IsDeleted) { return; } ModelClass modelClass = element.ModelClass; ModelRoot modelRoot = element.Store.ModelRoot(); Store store = element.Store; Transaction current = store.TransactionManager.CurrentTransaction; if (current.IsSerializing || ModelRoot.BatchUpdating) { return; } if (Equals(e.NewValue, e.OldValue)) { return; } List <string> errorMessages = new List <string>(); switch (e.DomainProperty.Name) { case "AutoProperty": { if (element.AutoProperty) { //element.PersistencePoint = PersistencePointType.Property; element.ImplementNotify = false; } else { if (string.IsNullOrEmpty(element.BackingFieldName)) { element.BackingFieldName = $"_{element.Name.ToCamelCase()}"; } } } break; case "IdentityType": { if (element.IsIdentity) { if (element.IdentityType == IdentityType.None) { errorMessages.Add($"{modelClass.Name}.{element.Name}: Identity properties must have an identity type defined"); } foreach (Association association in element.ModelClass.LocalNavigationProperties() .Where(nav => nav.AssociationObject.Dependent == element.ModelClass) .Select(nav => nav.AssociationObject) .Where(a => !string.IsNullOrWhiteSpace(a.FKPropertyName) && a.FKPropertyName.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Any(n => n.Trim() == element.Name))) { foreach (ModelAttribute attribute in association.GetFKAutoIdentityErrors()) { errorMessages.Add($"{association.Source.Name} <=> {association.Target.Name}: FK property {attribute.Name} in {association.Dependent.FullName} is an auto-generated identity. Migration will fail."); } } } else { element.IdentityType = IdentityType.None; } } break; case "ImplementNotify": { if (element.IsIdentity) { element.ImplementNotify = false; } if (element.ImplementNotify) { element.AutoProperty = false; } } break; case "Indexed": { if (element.IsIdentity) { element.Indexed = true; } if (element.IsConcurrencyToken) { element.Indexed = false; } if (element.Indexed) { element.Persistent = true; } } break; case "InitialValue": { string newInitialValue = (string)e.NewValue; if (string.IsNullOrEmpty(newInitialValue)) { break; } // if the property is an Enum and the user just typed the name of the Enum value without the Enum type name, help them out if (element.ModelClass.ModelRoot.Enums.Any(x => x.Name == element.Type) && !newInitialValue.Contains(".")) { newInitialValue = element.InitialValue = $"{element.Type}.{newInitialValue}"; } if (!element.IsValidInitialValue(null, newInitialValue)) { errorMessages.Add($"{modelClass.Name}.{element.Name}: {newInitialValue} isn't a valid value for {element.Type}"); } } break; case "IsAbstract": { if ((bool)e.NewValue) { modelClass.IsAbstract = true; } } break; case "IsConcurrencyToken": { bool newIsConcurrencyToken = (bool)e.NewValue; if (newIsConcurrencyToken) { element.IsIdentity = false; element.Persistent = true; element.Required = true; element.Type = "Binary"; } } break; case "IsIdentity": { if ((bool)e.NewValue) { if (element.ModelClass.IsDependentType) { if (!modelRoot.IsEFCore5Plus) { errorMessages.Add($"{modelClass.Name}.{element.Name}: Can't make {element.Name} an identity because {modelClass.Name} is a dependent type and can't have an identity property."); } } else { if (!modelRoot.IsValidIdentityAttributeType(element.Type)) { errorMessages.Add($"{modelClass.Name}.{element.Name}: Properties of type {element.Type} can't be used as identity properties."); } else { element.IsConcurrencyToken = false; element.Indexed = true; element.IndexedUnique = true; element.Persistent = true; element.Required = true; if (element.IdentityType == IdentityType.None) { element.IdentityType = IdentityType.AutoGenerated; } } } foreach (Association association in element.ModelClass.LocalNavigationProperties() .Where(nav => nav.AssociationObject.Dependent == element.ModelClass) .Select(nav => nav.AssociationObject) .Where(a => !string.IsNullOrWhiteSpace(a.FKPropertyName) && a.FKPropertyName.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Any(n => n.Trim() == element.Name))) { association.GetFKAutoIdentityErrors(); } } else { element.IdentityType = IdentityType.None; } } break; case "MinLength": { int minLengthValue = (int)e.NewValue; if (element.Type != "String") { element.MinLength = 0; } else if (minLengthValue < 0) { errorMessages.Add($"{modelClass.Name}.{element.Name}: MinLength must be zero or a positive number"); } else if (element.MaxLength > 0 && minLengthValue > element.MaxLength) { errorMessages.Add($"{modelClass.Name}.{element.Name}: MinLength cannot be greater than MaxLength"); } } break; case "MaxLength": { if (element.Type != "String") { element.MaxLength = null; } else { int?maxLengthValue = (int?)e.NewValue; if (maxLengthValue > 0 && element.MinLength > maxLengthValue) { errorMessages.Add($"{modelClass.Name}.{element.Name}: MinLength cannot be greater than MaxLength"); } } } break; case "Name": { if (string.IsNullOrEmpty(element.Name) || !CodeGenerator.IsValidLanguageIndependentIdentifier(element.Name)) { errorMessages.Add($"{modelClass.Name}: Property name '{element.Name}' isn't a valid .NET identifier"); } if (modelClass.AllAttributes.Except(new[] { element }).Any(x => x.Name == element.Name) || modelClass.AllNavigationProperties().Any(p => p.PropertyName == element.Name)) { errorMessages.Add($"{modelClass.Name}: Property name '{element.Name}' already in use"); } } break; case "Persistent": { bool newPersistent = (bool)e.NewValue; if (!newPersistent) { element.IsIdentity = false; element.Indexed = false; element.IndexedUnique = false; element.IdentityType = IdentityType.None; element.IsConcurrencyToken = false; element.Virtual = false; } } break; case "ReadOnly": { if (!element.Persistent || element.SetterVisibility != SetterAccessModifier.Public) { element.ReadOnly = false; } } break; case "Required": { bool newRequired = (bool)e.NewValue; if (!newRequired) { if (element.IsIdentity || element.IsConcurrencyToken) { element.Required = true; } } } break; case "Type": { string newType = (string)e.NewValue; if (element.IsIdentity) { if (!modelRoot.IsValidIdentityAttributeType(ModelAttribute.ToCLRType(newType))) { errorMessages.Add($"{modelClass.Name}.{element.Name}: Properties of type {newType} can't be used as identity properties."); } else { element.Required = true; element.Persistent = true; // Change type of any foreign key pointing to this class IEnumerable <Association> participatingAssociations = element.ModelClass.LocalNavigationProperties() .Where(nav => nav.AssociationObject.Dependent == element.ModelClass) .Select(nav => nav.AssociationObject) .Where(a => !string.IsNullOrWhiteSpace(a.FKPropertyName) && a.FKPropertyName.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Any(n => n.Trim() == element.Name)); foreach (Association association in participatingAssociations) { AssociationChangedRules.FixupForeignKeys(association); } } } if (newType != "String") { element.MaxLength = null; element.MinLength = 0; element.StringType = HTML5Type.None; } else { if (!element.IsValidInitialValue(newType)) { element.InitialValue = null; } } if (element.IsConcurrencyToken) { element.Type = "Binary"; } if (!element.SupportsInitialValue) { element.InitialValue = null; } } break; } errorMessages = errorMessages.Where(m => m != null).ToList(); if (errorMessages.Any()) { current.Rollback(); ErrorDisplay.Show(store, string.Join("\n", errorMessages)); } }
public override View GetView(int position, View convertView, ViewGroup parent) { try { if (convertView == null) { if (_activity != null) { convertView = _activity.LayoutInflater.Inflate(Resource.Layout.ProblemSolvingIdeasListItem, parent, false); } else if (parent != null) { LayoutInflater inflater = (LayoutInflater)parent.Context.GetSystemService(Context.LayoutInflaterService); convertView = inflater.Inflate(Resource.Layout.ProblemSolvingIdeasListItem, parent, false); } else { return(convertView); } } if (convertView != null) { GetFieldComponents(convertView); SetupCallbacks(); if (_problemIdea != null) { _problemIdea.Text = _problemIdeaList[position].ProblemIdeaText.Trim(); } else { Log.Error(TAG, "GetView: _problemIdea is NULL!"); } if (_toProsAndCons != null) { _toProsAndCons.Tag = _problemID.ToString() + ":" + _problemStepID.ToString() + ":" + _problemIdeaList[position].ProblemIdeaID.ToString() + ":" + _problemIdeaList[position].ProblemIdeaText.Trim(); } else { Log.Error(TAG, "GetView: _toProsAndCons is NULL!"); } if (position == ((ProblemSolvingIdeasActivity)_activity).GetSelectedItemIndex()) { convertView.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); if (_problemIdea != null) { _problemIdea.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); } } else { convertView.SetBackgroundDrawable(null); if (_problemIdea != null) { _problemIdea.SetBackgroundDrawable(null); } } } else { Log.Error(TAG, "GetView: view is NULL!"); } return(convertView); } catch (Exception e) { Log.Error(TAG, "GetView: Exception: " + e.Message); if (GlobalData.ShowErrorDialog) { ErrorDisplay.ShowErrorAlert(_activity, e, _activity.GetString(Resource.String.ErrorProblemSolvingIdeasListGetView), "ProblemSolvingIdeasListAdapter.GetView"); } return(convertView); } }
//internal static bool IsProcessingChange => ProcessingChangeCount > 0; ///// <summary> ///// Number of times the ElementPropertyChanged method has been recursed into ///// </summary> //private static int ProcessingChangeCount { get; set; } /// <inheritdoc /> public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e) { base.ElementPropertyChanged(e); Association element = (Association)e.ModelElement; if (element.IsDeleted) { return; } Store store = element.Store; Transaction current = store.TransactionManager.CurrentTransaction; if (current.IsSerializing || ModelRoot.BatchUpdating) { return; } if (Equals(e.NewValue, e.OldValue)) { return; } List <string> errorMessages = EFCoreValidator.GetErrors(element).ToList(); BidirectionalAssociation bidirectionalAssociation = element as BidirectionalAssociation; using (Transaction inner = store.TransactionManager.BeginTransaction("Association ElementPropertyChanged")) { bool doForeignKeyFixup = false; switch (e.DomainProperty.Name) { case "FKPropertyName": { if (element.Store.ModelRoot().EntityFrameworkVersion == EFVersion.EF6 && element.SourceMultiplicity != Multiplicity.ZeroMany && element.TargetMultiplicity != Multiplicity.ZeroMany) { element.FKPropertyName = null; doForeignKeyFixup = true; } else { ValidateForeignKeyNames(element, errorMessages); } if (!errorMessages.Any()) { doForeignKeyFixup = true; } } break; case "SourceCustomAttributes": if (bidirectionalAssociation != null && !string.IsNullOrWhiteSpace(bidirectionalAssociation.SourceCustomAttributes)) { bidirectionalAssociation.SourceCustomAttributes = $"[{bidirectionalAssociation.SourceCustomAttributes.Trim('[', ']')}]"; CheckSourceForDisplayText(bidirectionalAssociation); } break; case "SourceDisplayText": if (bidirectionalAssociation != null) { CheckSourceForDisplayText(bidirectionalAssociation); } break; case "SourceMultiplicity": Multiplicity currentSourceMultiplicity = (Multiplicity)e.NewValue; Multiplicity priorSourceMultiplicity = (Multiplicity)e.OldValue; // change unidirectional source cardinality // if target is dependent // source cardinality is 0..1 or 1 if (element.Target.IsDependentType && currentSourceMultiplicity == Multiplicity.ZeroMany) { errorMessages.Add($"Can't have a 0..* association from {element.Target.Name} to dependent type {element.Source.Name}"); break; } if ((currentSourceMultiplicity == Multiplicity.One && element.TargetMultiplicity == Multiplicity.One) || (currentSourceMultiplicity == Multiplicity.ZeroOne && element.TargetMultiplicity == Multiplicity.ZeroOne)) { if (element.SourceRole != EndpointRole.NotSet) { element.SourceRole = EndpointRole.NotSet; } if (element.TargetRole != EndpointRole.NotSet) { element.TargetRole = EndpointRole.NotSet; } } else { SetEndpointRoles(element); } // cascade delete behavior could now be illegal. Reset to default element.SourceDeleteAction = DeleteAction.Default; element.TargetDeleteAction = DeleteAction.Default; if (element.Dependent == null) { element.FKPropertyName = null; doForeignKeyFixup = true; } if (element.Store.ModelRoot().EntityFrameworkVersion == EFVersion.EF6 && element.SourceMultiplicity != Multiplicity.ZeroMany && element.TargetMultiplicity != Multiplicity.ZeroMany) { element.FKPropertyName = null; doForeignKeyFixup = true; } if (((priorSourceMultiplicity == Multiplicity.ZeroOne || priorSourceMultiplicity == Multiplicity.ZeroMany) && currentSourceMultiplicity == Multiplicity.One) || ((currentSourceMultiplicity == Multiplicity.ZeroOne || currentSourceMultiplicity == Multiplicity.ZeroMany) && priorSourceMultiplicity == Multiplicity.One)) { doForeignKeyFixup = true; } break; case "SourcePropertyName": string sourcePropertyNameErrorMessage = ValidateAssociationIdentifier(element, element.Target, (string)e.NewValue); if (EFModelDiagram.IsDroppingExternal && sourcePropertyNameErrorMessage != null) { element.Delete(); } else { errorMessages.Add(sourcePropertyNameErrorMessage); } break; case "SourceRole": if (element.SourceRole == EndpointRole.NotApplicable) { element.SourceRole = EndpointRole.NotSet; } if (element.Source.IsDependentType) { element.SourceRole = EndpointRole.Dependent; element.TargetRole = EndpointRole.Principal; } else if (!SetEndpointRoles(element)) { if (element.SourceRole == EndpointRole.Dependent && element.TargetRole != EndpointRole.Principal) { element.TargetRole = EndpointRole.Principal; } else if (element.SourceRole == EndpointRole.Principal && element.TargetRole != EndpointRole.Dependent) { element.TargetRole = EndpointRole.Dependent; } } doForeignKeyFixup = true; break; case "TargetCustomAttributes": if (!string.IsNullOrWhiteSpace(element.TargetCustomAttributes)) { element.TargetCustomAttributes = $"[{element.TargetCustomAttributes.Trim('[', ']')}]"; CheckTargetForDisplayText(element); } break; case "TargetDisplayText": CheckTargetForDisplayText(element); break; case "TargetMultiplicity": Multiplicity currentTargetMultiplicity = (Multiplicity)e.NewValue; Multiplicity priorTargetMultiplicity = (Multiplicity)e.OldValue; // change unidirectional target cardinality // if target is dependent // target cardinality must be 0..1 or 1 if (element.Target.IsDependentType && currentTargetMultiplicity == Multiplicity.ZeroMany) { errorMessages.Add($"Can't have a 0..* association from {element.Source.Name} to dependent type {element.Target.Name}"); break; } if ((element.SourceMultiplicity == Multiplicity.One && currentTargetMultiplicity == Multiplicity.One) || (element.SourceMultiplicity == Multiplicity.ZeroOne && currentTargetMultiplicity == Multiplicity.ZeroOne)) { if (element.SourceRole != EndpointRole.NotSet) { element.SourceRole = EndpointRole.NotSet; } if (element.TargetRole != EndpointRole.NotSet) { element.TargetRole = EndpointRole.NotSet; } } else { SetEndpointRoles(element); } // cascade delete behavior could now be illegal. Reset to default element.SourceDeleteAction = DeleteAction.Default; element.TargetDeleteAction = DeleteAction.Default; if (element.Dependent == null) { element.FKPropertyName = null; doForeignKeyFixup = true; } if (element.Store.ModelRoot().EntityFrameworkVersion == EFVersion.EF6 && element.SourceMultiplicity != Multiplicity.ZeroMany && element.TargetMultiplicity != Multiplicity.ZeroMany) { element.FKPropertyName = null; doForeignKeyFixup = true; } if (((priorTargetMultiplicity == Multiplicity.ZeroOne || priorTargetMultiplicity == Multiplicity.ZeroMany) && currentTargetMultiplicity == Multiplicity.One) || ((currentTargetMultiplicity == Multiplicity.ZeroOne || currentTargetMultiplicity == Multiplicity.ZeroMany) && priorTargetMultiplicity == Multiplicity.One)) { doForeignKeyFixup = true; } break; case "TargetPropertyName": // if we're creating an association via drag/drop, it's possible the existing property name // is the same as the default property name. The default doesn't get created until the transaction is // committed, so the drop's action will cause a name clash. Remove the clashing property, but // only if drag/drop. string targetPropertyNameErrorMessage = ValidateAssociationIdentifier(element, element.Source, (string)e.NewValue); if (EFModelDiagram.IsDroppingExternal && targetPropertyNameErrorMessage != null) { element.Delete(); } else { errorMessages.Add(targetPropertyNameErrorMessage); } break; case "TargetRole": if (element.TargetRole == EndpointRole.NotApplicable) { element.TargetRole = EndpointRole.NotSet; } if (element.Target.IsDependentType && (element.SourceRole != EndpointRole.Principal || element.TargetRole != EndpointRole.Dependent)) { element.SourceRole = EndpointRole.Principal; element.TargetRole = EndpointRole.Dependent; doForeignKeyFixup = true; } else if (!SetEndpointRoles(element)) { if (element.TargetRole == EndpointRole.Dependent && element.SourceRole != EndpointRole.Principal) { element.SourceRole = EndpointRole.Principal; doForeignKeyFixup = true; } else if (element.TargetRole == EndpointRole.Principal && element.SourceRole != EndpointRole.Dependent) { element.SourceRole = EndpointRole.Dependent; doForeignKeyFixup = true; } } break; } if (doForeignKeyFixup) { FixupForeignKeys(element); } inner.Commit(); element.RedrawItem(); } errorMessages = errorMessages.Where(m => m != null).ToList(); if (errorMessages.Any()) { current.Rollback(); ErrorDisplay.Show(store, string.Join("\n", errorMessages)); } }
public void UploadExtensionLibraryAsync(string selectedFileName, byte[] fileContents, ObservableCollection <string> assemblies, object userState) { Uri uri = CreateRestRequest("Extensions/Upload"); var assembliesString = assemblies != null?string.Join(",", assemblies) : null; var content = new MultipartFormDataContent(); var ms = new MemoryStream(fileContents); var fileContent = new StreamContent(ms); // Specify the content disposition and content type - without this the form data will not // be included in the Request object in .NET 2.0 app pools fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "\"files\"", FileName = "\"" + selectedFileName + "\"" }; fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/x-silverlight-app"); content.Add(fileContent); var stringContent = new StringContent(assembliesString); // Need to specify the content disposition and content type for .NET 2.0 compatibility here, too stringContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "\"assemblies\"" }; stringContent.Headers.ContentType = new MediaTypeHeaderValue("text/plain"); content.Add(stringContent); var client = new HttpClient(); client.PostAsync(uri, content).ContinueWith(t => { stringContent.Dispose(); fileContent.Dispose(); ms.Dispose(); content.Dispose(); if (t.IsCanceled) { return; } if (t.Exception != null) { var errorDisplay = new ErrorDisplay(); // Attempt to get the stack trace with IL offsets string stackTraceIL = t.Exception.StackTraceIL(); ErrorData data = new ErrorData() { Message = t.Exception.Message, StackTrace = !string.IsNullOrEmpty(stackTraceIL) ? stackTraceIL : t.Exception.StackTrace }; errorDisplay.DataContext = data; // Size the error UI double width = Application.Current.RootVisual.RenderSize.Width * 0.67; errorDisplay.Width = width > errorDisplay.MaxWidth ? errorDisplay.MaxWidth : width; errorDisplay.Completed += (o, a) => BuilderApplication.Instance.HideWindow(errorDisplay); // Show the error BuilderApplication.Instance.ShowWindow(Strings.ErrorOccured, errorDisplay, false, null, null); } if (UploadExtensionLibraryCompleted != null) { UploadExtensionLibraryCompleted(this, new UploadExtensionLibraryCompletedEventArgs() { Error = t.Exception, UserState = userState, }); } }, TaskScheduler.FromCurrentSynchronizationContext()); }
public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e) { base.ElementPropertyChanged(e); Generalization element = (Generalization)e.ModelElement; if (element.IsDeleted) { return; } Store store = element.Store; Transaction current = store.TransactionManager.CurrentTransaction; if (current.IsSerializing || ModelRoot.BatchUpdating) { return; } if (Equals(e.NewValue, e.OldValue)) { return; } switch (e.DomainProperty.Name) { case "Superclass": case "Subclass": if (!element.IsInCircularInheritance()) { ErrorDisplay.Show(store, $"{element.Subclass.Name} -> {element.Superclass.Name}: That inheritance link would cause a circular reference."); current.Rollback(); return; } if (element.Superclass != null) { List <string> superclassPropertyNames = element.Superclass .AllAttributes .Select(a => a.Name) .Union(element.Superclass .AllNavigationProperties() .Select(a => a.PropertyName)) .ToList(); List <string> nameClashes = element.Subclass .Attributes .Where(a => superclassPropertyNames.Contains(a.Name)) .Select(a => a.Name) .Union(element.Subclass .LocalNavigationProperties() .Where(p => p.PropertyName != null && superclassPropertyNames.Contains(p.PropertyName)) .Select(p => p.PropertyName)) .ToList(); // the Add rule removes the subclass Id property if it's causing a name class, but we won't do that in the change rule if (nameClashes.Any()) { string nameClashList = string.Join("\n ", nameClashes); ErrorDisplay.Show(store, $"{element.Subclass.Name} -> {element.Superclass.Name}: That inheritance link would cause name clashes. Resolve the following before setting the inheritance:\n " + nameClashList); current.Rollback(); } } break; } }
public bool Process(string filename) { if (string.IsNullOrEmpty(filename)) { throw new ArgumentNullException(nameof(filename)); } try { // read the file string fileContents = File.ReadAllText(filename); // parse the contents SyntaxTree tree = CSharpSyntaxTree.ParseText(fileContents); if (tree.GetRoot() is CompilationUnitSyntax root) { List <ClassDeclarationSyntax> classDecls = root.DescendantNodes().OfType <ClassDeclarationSyntax>().Where(classDecl => classDecl.BaseList == null || classDecl.BaseList.Types.FirstOrDefault()?.ToString() != "DbContext").ToList(); List <EnumDeclarationSyntax> enumDecls = root.DescendantNodes().OfType <EnumDeclarationSyntax>().ToList(); if (!classDecls.Any() && !enumDecls.Any()) { WarningDisplay.Show($"Couldn't find any classes or enums to add to the model in {filename}"); return(false); } // keep this order: enums, classes, class properties foreach (EnumDeclarationSyntax enumDecl in enumDecls) { ProcessEnum(enumDecl); } List <ModelClass> processedClasses = new List <ModelClass>(); List <ClassDeclarationSyntax> badClasses = new List <ClassDeclarationSyntax>(); foreach (ClassDeclarationSyntax classDecl in classDecls) { ModelClass modelClass = ProcessClass(classDecl); if (modelClass == null) { badClasses.Add(classDecl); } else { processedClasses.Add(modelClass); } } // process last so all classes and enums are already in the model foreach (ClassDeclarationSyntax classDecl in classDecls.Except(badClasses)) { ProcessProperties(classDecl); } // now that all the properties are in, go through the classes again and ensure identities are present based on convention // ReSharper disable once LoopCanBePartlyConvertedToQuery foreach (ModelClass modelClass in processedClasses.Where(c => !c.AllIdentityAttributes.Any())) { // no identity attribute. Only look in current class for attributes that could be identity by convention List <ModelAttribute> identitiesByConvention = modelClass.Attributes.Where(a => a.Name == "Id" || a.Name == $"{modelClass.Name}Id").ToList(); // if both 'Id' and '[ClassName]Id' are present, don't do anything since we don't know which to make the identity if (identitiesByConvention.Count == 1) { using (Transaction transaction = Store.TransactionManager.BeginTransaction("Add identity")) { identitiesByConvention[0].IsIdentity = true; transaction.Commit(); } } } } } catch { ErrorDisplay.Show("Error interpreting " + filename); return(false); } return(true); }
private static void ProcessClass([NotNull] Store store, [NotNull] ClassDeclarationSyntax classDecl, NamespaceDeclarationSyntax namespaceDecl = null) { if (store == null) { throw new ArgumentNullException(nameof(store)); } if (classDecl == null) { throw new ArgumentNullException(nameof(classDecl)); } ModelRoot modelRoot = store.ElementDirectory.AllElements.OfType <ModelRoot>().FirstOrDefault(); string className = classDecl.Identifier.Text; if (namespaceDecl == null && classDecl.Parent is NamespaceDeclarationSyntax classDeclParent) { namespaceDecl = classDeclParent; } if (store.ElementDirectory.AllElements.OfType <ModelEnum>().Any(c => c.Name == className)) { ErrorDisplay.Show($"'{className}' already exists in model as an Enum."); return; } if (classDecl.TypeParameterList != null) { ErrorDisplay.Show($"Can't add generic class '{className}'."); return; } Transaction tx = store.TransactionManager.CurrentTransaction == null ? store.TransactionManager.BeginTransaction() : null; try { ModelClass superClass = null; List <string> customInterfaces = new List <string>(); ModelClass modelClass = store.ElementDirectory.AllElements.OfType <ModelClass>().FirstOrDefault(c => c.Name == className); // Base classes and interfaces // Check these first. If we need to add new models, we want the base class already in the store if (classDecl.BaseList != null) { foreach (BaseTypeSyntax type in classDecl.BaseList.Types) { string baseName = type.ToString(); // INotifyPropertyChanged is special. We know it's an interface, and it'll turn into a class property later if (baseName == "INotifyPropertyChanged" || superClass != null || modelClass?.Superclass != null) { customInterfaces.Add(baseName); continue; } // is it inheritance or an interface? superClass = modelRoot.Types.OfType <ModelClass>().FirstOrDefault(c => c.Name == baseName); // if it's not in the model, we just don't know. Ask the user if (superClass == null && QuestionDisplay.Show($"For class {className}, is {baseName} the base class?") == true) { superClass = new ModelClass(store, new PropertyAssignment(ModelClass.NameDomainPropertyId, baseName)); modelRoot.Types.Add(superClass); } else { customInterfaces.Add(baseName); } } } if (modelClass == null) { modelClass = new ModelClass(store, new PropertyAssignment(ModelClass.NameDomainPropertyId, className)) { Namespace = namespaceDecl?.Name?.ToString() ?? modelRoot.Namespace , IsAbstract = classDecl.DescendantNodes().Any(n => n.Kind() == SyntaxKind.AbstractKeyword) }; modelRoot.Types.Add(modelClass); } if (superClass != null) { modelClass.Superclass = superClass; } if (modelClass.CustomInterfaces != null) { customInterfaces.AddRange(modelClass.CustomInterfaces .Split(',') .Where(i => !string.IsNullOrEmpty(i)) .Select(i => i.Trim())); } if (customInterfaces.Contains("INotifyPropertyChanged")) { modelClass.ImplementNotify = true; customInterfaces.Remove("INotifyPropertyChanged"); } if (modelClass.Superclass != null && customInterfaces.Contains(modelClass.Superclass.Name)) { customInterfaces.Remove(modelClass.Superclass.Name); } modelClass.CustomInterfaces = customInterfaces.Any() ? string.Join(",", customInterfaces.Distinct()) : null; XMLDocumentation xmlDocumentation = new XMLDocumentation(classDecl); modelClass.Summary = xmlDocumentation.Summary; modelClass.Description = xmlDocumentation.Description; } catch { tx = null; throw; } finally { tx?.Commit(); } }
private ModelClass ProcessClass([NotNull] ClassDeclarationSyntax classDecl, NamespaceDeclarationSyntax namespaceDecl = null) { ModelClass result; if (classDecl == null) { throw new ArgumentNullException(nameof(classDecl)); } ModelRoot modelRoot = Store.ModelRoot(); string className = classDecl.Identifier.Text.Split(':').LastOrDefault(); if (!ValidateInput()) { return(null); } Transaction tx = Store.TransactionManager.CurrentTransaction == null ? Store.TransactionManager.BeginTransaction() : null; List <string> customInterfaces = new List <string>(); try { result = Store.Get <ModelClass>().FirstOrDefault(c => c.Name == className); if (result == null) { result = new ModelClass(Store , new PropertyAssignment(ModelClass.NameDomainPropertyId, className) , new PropertyAssignment(ModelClass.NamespaceDomainPropertyId, namespaceDecl?.Name?.ToString() ?? modelRoot.Namespace) , new PropertyAssignment(ModelClass.IsAbstractDomainPropertyId, classDecl.DescendantNodes().Any(n => n.Kind() == SyntaxKind.AbstractKeyword))); modelRoot.Classes.Add(result); } ModelClass superClass = FindSuperClass(); if (superClass != null) { result.Superclass = superClass; } if (result.CustomInterfaces != null) { customInterfaces.AddRange(result.CustomInterfaces .Split(',') .Where(i => !string.IsNullOrEmpty(i)) .Select(i => i.Trim())); } if (customInterfaces.Contains("INotifyPropertyChanged")) { result.ImplementNotify = true; customInterfaces.Remove("INotifyPropertyChanged"); } if (result.Superclass != null && customInterfaces.Contains(result.Superclass.Name)) { customInterfaces.Remove(result.Superclass.Name); } result.CustomInterfaces = customInterfaces.Any() ? string.Join(",", customInterfaces.Distinct()) : null; AttributeSyntax tableAttribute = classDecl.GetAttribute("Table"); if (tableAttribute != null) { result.TableName = tableAttribute.GetAttributeArguments().First().Expression.ToString().Trim('"'); string schemaName = tableAttribute.GetNamedArgumentValue("Schema"); if (schemaName != null) { result.DatabaseSchema = schemaName; } } XMLDocumentation xmlDocumentation = new XMLDocumentation(classDecl); result.Summary = xmlDocumentation.Summary; result.Description = xmlDocumentation.Description; tx?.Commit(); } catch { tx?.Rollback(); throw; } return(result); ModelClass FindSuperClass() { ModelClass superClass = null; // Base classes and interfaces // Check these first. If we need to add new models, we want the base class already in the store IEnumerable <BaseTypeSyntax> baseTypes = (classDecl.BaseList?.Types ?? Enumerable.Empty <BaseTypeSyntax>()); foreach (string baseName in baseTypes.Select(type => type.ToString().Split(':').Last())) { // Do we know this is an interface? if (KnownInterfaces.Contains(baseName) || superClass != null || result.Superclass != null) { customInterfaces.Add(baseName); if (!KnownInterfaces.Contains(baseName)) { KnownInterfaces.Add(baseName); } continue; } // is it inheritance or an interface? superClass = modelRoot.Classes.FirstOrDefault(c => c.Name == baseName); // if it's not in the model, we just don't know. Ask the user if (superClass == null && (KnownClasses.Contains(baseName) || QuestionDisplay.Show($"For class {className}, is {baseName} the base class?") == true)) { string[] nameparts = baseName.Split('.'); superClass = nameparts.Length == 1 ? new ModelClass(Store, new PropertyAssignment(ModelClass.NameDomainPropertyId, nameparts.Last())) : new ModelClass(Store , new PropertyAssignment(ModelClass.NameDomainPropertyId, nameparts.Last()) , new PropertyAssignment(ModelClass.NamespaceDomainPropertyId, string.Join(".", nameparts.Take(nameparts.Length - 1)))); modelRoot.Classes.Add(superClass); } else { customInterfaces.Add(baseName); KnownInterfaces.Add(baseName); } } return(superClass); } bool ValidateInput() { if (className == null) { ErrorDisplay.Show("Can't find class name"); return(false); } if (namespaceDecl == null && classDecl.Parent is NamespaceDeclarationSyntax classDeclParent) { namespaceDecl = classDeclParent; } if (Store.Get <ModelEnum>().Any(c => c.Name == className)) { ErrorDisplay.Show($"'{className}' already exists in model as an Enum."); return(false); } if (classDecl.TypeParameterList != null) { ErrorDisplay.Show($"Can't add generic class '{className}'."); return(false); } return(true); } }
private static bool DoHandleDrop([NotNull] Store store, [NotNull] string filename) { if (store == null) { throw new ArgumentNullException(nameof(store)); } if (filename == null) { throw new ArgumentNullException(nameof(filename)); } try { if (string.IsNullOrEmpty(filename)) { return(false); } // read the file string fileContents = File.ReadAllText(filename); // parse the contents SyntaxTree tree = CSharpSyntaxTree.ParseText(fileContents); if (tree.GetRoot() is CompilationUnitSyntax root) { List <ClassDeclarationSyntax> classDecls = root.DescendantNodes().OfType <ClassDeclarationSyntax>().Where(classDecl => classDecl.BaseList == null || classDecl.BaseList.Types.FirstOrDefault()?.ToString() != "DbContext").ToList(); List <EnumDeclarationSyntax> enumDecls = root.DescendantNodes().OfType <EnumDeclarationSyntax>().ToList(); if (!classDecls.Any() && !enumDecls.Any()) { WarningDisplay.Show("Couldn't find any classes or enums to add to the model"); return(false); } // keep this order: enums, classes, class properties foreach (EnumDeclarationSyntax enumDecl in enumDecls) { ProcessEnum(store, enumDecl); } foreach (ClassDeclarationSyntax classDecl in classDecls) { ProcessClass(store, classDecl); } // process last so all classes and enums are already in the model foreach (ClassDeclarationSyntax classDecl in classDecls) { ProcessProperties(store, classDecl); } } } catch { ErrorDisplay.Show("Error interpretting " + filename); return(false); } return(true); }
public override View GetView(int position, View convertView, ViewGroup parent) { try { if (convertView == null) { if (_activity != null) { convertView = _activity.LayoutInflater.Inflate(Resource.Layout.ProblemSolvingProsAndConsListItem, parent, false); } else if (parent != null) { LayoutInflater inflater = (LayoutInflater)parent.Context.GetSystemService(Context.LayoutInflaterService); convertView = inflater.Inflate(Resource.Layout.ProblemSolvingProsAndConsListItem, parent, false); } else { return(convertView); } } if (convertView != null) { GetFieldComponents(convertView); if (_proAndConText != null) { _proAndConText.Text = _problemProAndConList[position].ProblemProAndConText.Trim(); } else { Log.Error(TAG, "GetView: _proAndConText is NULL!"); } if (_proAndConType != null) { _proAndConType.Text = StringHelper.ProConTypeForConstant(_problemProAndConList[position].ProblemProAndConType); } else { Log.Error(TAG, "GetView: _proAndConType is NULL!"); } if (position == ((ProblemSolvingProsAndConsActivity)_activity).GetSelectedItemIndex()) { convertView.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); if (_problemSolvingProsAndConsTypeLabel != null) { _problemSolvingProsAndConsTypeLabel.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); } if (_proAndConText != null) { _proAndConText.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); } if (_proAndConType != null) { _proAndConType.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); } } else { convertView.SetBackgroundDrawable(null); if (_problemSolvingProsAndConsTypeLabel != null) { _problemSolvingProsAndConsTypeLabel.SetBackgroundDrawable(null); } if (_proAndConText != null) { _proAndConText.SetBackgroundDrawable(null); } if (_proAndConType != null) { _proAndConType.SetBackgroundDrawable(null); } } } else { Log.Error(TAG, "GetView: view is NULL!"); } return(convertView); } catch (Exception e) { Log.Error(TAG, "GetView: Exception: " + e.Message); if (GlobalData.ShowErrorDialog) { ErrorDisplay.ShowErrorAlert(_activity, e, _activity.GetString(Resource.String.ErrorProblemSolvingProsAndConsGetView), "ProblemSolvingProsAndConsListAdapter.GetView"); } return(convertView); } }
protected override void OnInit(EventArgs e) { base.OnInit(e); //Check if has rights to edit //switch (SessionManager.LoggedUser.Role.InternalID) //{ // case (int)RoleTypes.SystemAdministrator: // break; // default: // Response.Redirect("~/Default.aspx"); // break; //} // *** On callbacks we don't need to populate any data since they are // *** raw method calls. Callback routes to parser from here if (Callback.IsCallback) { return; } Response.Expires = 0; if (!Manager.IsLocalizationTable(null)) { ErrorDisplay.ShowError(Res("ResourceTableDoesntExist")); btnCreateTable.Visible = true; return; } GetResourceSet(); DataTable dt = Manager.GetAllResourceIds(ResourceSet); if (dt == null) { ErrorDisplay.ShowError("Couldn't load resources: " + Manager.ErrorMessage); return; } lstResourceIds.DataSource = dt; lstResourceIds.DataValueField = "ResourceId"; lstResourceIds.DataBind(); if (lstResourceIds.Items.Count > 0) { lstResourceIds.SelectedIndex = 0; } dt = Manager.GetAllLocaleIds(ResourceSet); if (dt == null) { ErrorDisplay.ShowError("Couldn't load resources: " + Manager.ErrorMessage); return; } foreach (DataRow row in dt.Rows) { string Code = row["LocaleId"] as string; CultureInfo ci = CultureInfo.GetCultureInfo(Code.Trim()); if (Code != "") { row["Language"] = ci.DisplayName + " (" + ci.Name + ")"; } else { row["Language"] = "Invariant"; } } lstLanguages.DataSource = dt; lstLanguages.DataValueField = "LocaleId"; lstLanguages.DataTextField = "Language"; lstLanguages.DataBind(); if (lstLanguages.Items.Count > 0) { lstLanguages.SelectedIndex = 0; } else { lstLanguages.Items.Add(new ListItem("Invariant", "")); } }
protected StorytellerFailureException(ErrorDisplay display = ErrorDisplay.markdown) { ErrorDisplay = display; }
public override View GetView(int position, View convertView, ViewGroup parent) { try { if (convertView == null) { if (_activity != null) { convertView = _activity.LayoutInflater.Inflate(Resource.Layout.StructuredPlanHealthListItem, parent, false); } else if (parent != null) { LayoutInflater inflater = (LayoutInflater)parent.Context.GetSystemService(Context.LayoutInflaterService); convertView = inflater.Inflate(Resource.Layout.StructuredPlanHealthListItem, parent, false); } else { return(convertView); } } GetFieldComponents(convertView); if (_health != null) { if (_aspect != null) { _aspect.Text = _health[position].Aspect.Trim(); } if (_importance != null) { _importance.Text = _health[position].Importance.ToString(); } if (_reaction != null) { _reaction.Text = StringHelper.ReactionTypeForConstant(_health[position].Type); } } var parentHeldPosition = ((StructuredPlanHealth)_activity).GetSelectedItemIndex(); if (position == parentHeldPosition) { convertView.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); if (_aspect != null) { _aspect.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); } if (_importance != null) { _importance.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); } if (_reaction != null) { _reaction.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); } if (_strengthLabel != null) { _strengthLabel.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); } if (_reactionLabel != null) { _reactionLabel.SetBackgroundColor(Color.Argb(255, 19, 75, 127)); } } return(convertView); } catch (Exception e) { Log.Error(TAG, "GetView: Exception - " + e.Message); if (_activity != null) { if (GlobalData.ShowErrorDialog) { ErrorDisplay.ShowErrorAlert(_activity, e, _activity.GetString(Resource.String.ErrorStructuredPlanHealthListGetView), "StructuredPlanHealthListAdapter.GetView"); } } return(convertView); } }
protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data) { int reactionsID = -1; string to = ""; int strength = -1; ConstantsAndTypes.REACTION_TYPE reaction = ConstantsAndTypes.REACTION_TYPE.Positive; ConstantsAndTypes.ACTION_TYPE intention = ConstantsAndTypes.ACTION_TYPE.Maintain; string actionOf = ""; base.OnActivityResult(requestCode, resultCode, data); if (resultCode == Result.Ok) { try { if (data.HasExtra("reactionsID")) { reactionsID = data.GetIntExtra("reactionsID", -1); } if (data.HasExtra("to")) { to = data.GetStringExtra("to"); } if (data.HasExtra("strength")) { strength = data.GetIntExtra("strength", -1); } if (data.HasExtra("reaction")) { reaction = (ConstantsAndTypes.REACTION_TYPE)data.GetIntExtra("reaction", -1); } if (data.HasExtra("intention")) { intention = (ConstantsAndTypes.ACTION_TYPE)data.GetIntExtra("intention", -1); } if (data.HasExtra("actionOf")) { actionOf = data.GetStringExtra("actionOf"); } Reactions reactionItem = null; if (reactionsID == -1) { //new item reactionItem = new Reactions(); reactionItem.IsNew = true; reactionItem.IsDirty = false; } else { reactionItem = GlobalData.StructuredPlanReactions.Find(react => react.ReactionsID == reactionsID); reactionItem.IsNew = false; reactionItem.IsDirty = true; } reactionItem.ToWhat = to; reactionItem.Action = intention; reactionItem.ActionOf = actionOf; reactionItem.Strength = strength; reactionItem.Type = reaction; reactionItem.Save(); if (reactionsID == -1) { GlobalData.StructuredPlanReactions.Add(reactionItem); } UpdateAdapter(); } catch (Exception e) { Log.Error(TAG, "ConfirmPlanItemAddition: Exception - " + e.Message); if (GlobalData.ShowErrorDialog) { ErrorDisplay.ShowErrorAlert(this, e, GetString(Resource.String.ErrorStructuredPlanReactionsConfirm), "StructuredPlanReactions.ConfirmPlanItemAddition"); } } } if (resultCode == Result.Canceled) { Toast.MakeText(this, Resource.String.StructuredplanNoChangesToast, ToastLength.Short).Show(); } }
public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e) { base.ElementPropertyChanged(e); ModelClass element = (ModelClass)e.ModelElement; ModelRoot modelRoot = element.ModelRoot; if (element.IsDeleted) { return; } Store store = element.Store; Transaction current = store.TransactionManager.CurrentTransaction; if (current.IsSerializing || ModelRoot.BatchUpdating) { return; } if (Equals(e.NewValue, e.OldValue)) { return; } List <string> errorMessages = new List <string>(); switch (e.DomainProperty.Name) { case "BaseClass": { if (element.IsDependentType) { errorMessages.Add($"Can't give {element.Name} a base class since it's a dependent type"); } break; } case "CustomInterfaces": { if (modelRoot.ShowInterfaceIndicators) { PresentationHelper.UpdateClassDisplay(element); } break; } case "DbSetName": { string newDbSetName = (string)e.NewValue; if (element.IsDependentType) { if (!string.IsNullOrEmpty(newDbSetName)) { element.DbSetName = string.Empty; } } else { if (string.IsNullOrEmpty(newDbSetName)) { element.DbSetName = MakeDefaultTableAndSetName(element.Name); } if (current.Name.ToLowerInvariant() != "paste" && (string.IsNullOrWhiteSpace(newDbSetName) || !CodeGenerator.IsValidLanguageIndependentIdentifier(newDbSetName))) { errorMessages.Add($"DbSet name '{newDbSetName}' isn't a valid .NET identifier."); } else if (store.GetAll <ModelClass>() .Except(new[] { element }) .Any(x => x.DbSetName == newDbSetName)) { errorMessages.Add($"DbSet name '{newDbSetName}' already in use"); } } break; } case "ImplementNotify": { bool newImplementNotify = (bool)e.NewValue; if (newImplementNotify) { List <string> nameList = element.Attributes.Where(x => x.AutoProperty).Select(x => x.Name).ToList(); if (nameList.Any()) { string names = nameList.Count > 1 ? string.Join(", ", nameList.Take(nameList.Count - 1)) + " and " + nameList.Last() : nameList.First(); string verb = nameList.Count > 1 ? "is an autoproperty" : "are autoproperties"; WarningDisplay.Show($"{names} {verb}, so will not participate in INotifyPropertyChanged messages"); } } PresentationHelper.UpdateClassDisplay(element); break; } case "IsAbstract": { bool newIsAbstract = (bool)e.NewValue; if (newIsAbstract && element.IsDependentType) { errorMessages.Add($"Can't make {element.Name} abstract since it's a dependent type"); break; } PresentationHelper.UpdateClassDisplay(element); break; } case "IsDatabaseView": { bool newIsView = (bool)e.NewValue; if (newIsView) { if (element.IsDependentType) { errorMessages.Add($"Can't base {element.Name} off a view since it's a dependent type"); break; } if (element.IsQueryType) { errorMessages.Add($"Can't base {element.Name} off a view since it's a query type"); break; } if (string.IsNullOrEmpty(element.ViewName)) { element.ViewName = element.TableName; } if (string.IsNullOrEmpty(element.ViewName)) { element.ViewName = MakeDefaultTableAndSetName(element.Name); } if (modelRoot.IsEFCore5Plus) { VerifyKeylessTypeEFCore5(); } else { VerifyKeylessType(); } } break; } case "IsDependentType": { if (element.IsDependentType) { if (element.IsDatabaseView) { errorMessages.Add($"Can't make {element.Name} a dependent class since it's backed by a database view"); break; } if (element.IsQueryType) { errorMessages.Add($"Can't make {element.Name} a dependent class since it's a query type"); break; } if (element.BaseClass != null) { errorMessages.Add($"Can't make {element.Name} a dependent class since it has a base class"); break; } string subclasses = string.Join(", ", store.GetAll <Generalization>().Where(g => g.Superclass == element).Select(g => g.Subclass.Name)); if (!string.IsNullOrEmpty(subclasses)) { errorMessages.Add($"Can't make {element.Name} a dependent class since it has subclass(es) {subclasses}"); break; } if (element.IsAbstract) { errorMessages.Add($"Can't make {element.Name} a dependent class since it's abstract"); break; } List <Association> principalAssociations = store.GetAll <Association>().Where(a => a.Principal == element).ToList(); if (principalAssociations.Any()) { string badAssociations = string.Join(", ", principalAssociations.Select(a => a.GetDisplayText())); errorMessages.Add($"Can't make {element.Name} a dependent class since it's the principal end in: {badAssociations}"); break; } List <UnidirectionalAssociation> entityTargets = store.GetAll <UnidirectionalAssociation>().Where(a => a.Source == element && !a.Target.IsDependentType).ToList(); if (entityTargets.Any()) { string badAssociations = string.Join(", ", entityTargets.Select(a => a.GetDisplayText())); errorMessages.Add($"Can't make {element.Name} a dependent class since it has unidirectional associations to entities in: {badAssociations}"); break; } List <BidirectionalAssociation> bidirectionalAssociations = store.GetAll <BidirectionalAssociation>().Where(a => a.Source == element || a.Target == element).ToList(); if (bidirectionalAssociations.Any()) { if (!modelRoot.IsEFCore5Plus) { string badAssociations = string.Join(", ", entityTargets.Select(a => a.GetDisplayText())); errorMessages.Add($"Can't make {element.Name} a dependent class since it has bidirectional associations in: {badAssociations}"); break; } bidirectionalAssociations = bidirectionalAssociations.Where(a => (a.Source == element && a.TargetMultiplicity != Multiplicity.One) || (a.Target == element && a.SourceMultiplicity != Multiplicity.One)) .ToList(); if (bidirectionalAssociations.Any()) { string badAssociations = string.Join(", ", entityTargets.Select(a => a.GetDisplayText())); errorMessages.Add($"Can't make {element.Name} a dependent class since it has bidirectional associations without 1 or 0/1 ownership multiplicity in: {badAssociations}. The other end must be a single, required reference."); break; } } if (element.ModelRoot.EntityFrameworkVersion == EFVersion.EF6 || element.ModelRoot.GetEntityFrameworkPackageVersionNum() < 2.2) { if (store.GetAll <Association>().Any(a => a.Target == element && a.TargetMultiplicity == Multiplicity.ZeroMany)) { errorMessages.Add($"Can't make {element.Name} a dependent class since it's the target of a 0..* association"); break; } foreach (UnidirectionalAssociation association in Association.GetLinksToTargets(element).OfType <UnidirectionalAssociation>()) { if (association.SourceMultiplicity == Multiplicity.ZeroMany) { association.SourceMultiplicity = Multiplicity.ZeroOne; } if (association.TargetMultiplicity == Multiplicity.ZeroMany) { association.TargetMultiplicity = Multiplicity.ZeroOne; } association.TargetRole = EndpointRole.Dependent; } element.TableName = string.Empty; } foreach (ModelAttribute modelAttribute in element.AllAttributes.Where(a => a.IsIdentity)) { modelAttribute.IsIdentity = false; } element.DbSetName = string.Empty; } else { element.DbSetName = MakeDefaultTableAndSetName(element.Name); element.TableName = MakeDefaultTableAndSetName(element.Name); } // Remove any foreign keys in any incoming or outgoing associations foreach (Association association in Association.GetLinksToTargets(element).Union(Association.GetLinksToSources(element)).Distinct()) { association.FKPropertyName = null; } PresentationHelper.UpdateClassDisplay(element); break; } case "IsPropertyBag": { if (element.Superclass != null && !element.Superclass.IsPropertyBag) { element.Superclass.IsPropertyBag = true; } if (element.Subclasses.Any()) { foreach (ModelClass subclass in element.Subclasses) { subclass.IsPropertyBag = true; } } PresentationHelper.UpdateClassDisplay(element); break; } case "IsQueryType": { if ((bool)e.NewValue) { if (element.IsDependentType) { errorMessages.Add($"Can't make {element.Name} a query type since it's a dependent class"); break; } if (modelRoot.EntityFrameworkVersion == EFVersion.EF6) { element.IsQueryType = false; } else if (modelRoot.IsEFCore5Plus) { VerifyKeylessTypeEFCore5(); } else { VerifyKeylessType(); } } break; } case "Name": { if (current.Name.ToLowerInvariant() == "paste") { return; } if (string.IsNullOrWhiteSpace(element.Name) || !CodeGenerator.IsValidLanguageIndependentIdentifier(element.Name)) { errorMessages.Add("Name must be a valid .NET identifier"); } else if (store.GetAll <ModelClass>().Except(new[] { element }).Any(x => x.FullName == element.FullName)) { errorMessages.Add($"Class name '{element.FullName}' already in use by another class"); } else if (store.GetAll <ModelEnum>().Any(x => x.FullName == element.FullName)) { errorMessages.Add($"Class name '{element.FullName}' already in use by an enum"); } else if (!string.IsNullOrEmpty((string)e.OldValue)) { string oldDefaultName = MakeDefaultTableAndSetName((string)e.OldValue); string newDefaultName = MakeDefaultTableAndSetName(element.Name); if (element.DbSetName == oldDefaultName) { element.DbSetName = newDefaultName; } if (element.TableName == oldDefaultName) { element.TableName = newDefaultName; } } break; } case "Namespace": { string newNamespace = (string)e.NewValue; if (current.Name.ToLowerInvariant() != "paste") { errorMessages.Add(CommonRules.ValidateNamespace(newNamespace, CodeGenerator.IsValidLanguageIndependentIdentifier)); } break; } case "TableName": { if (!element.IsDatabaseView) { string newTableName = (string)e.NewValue; if (element.IsDependentType) { if (!modelRoot.IsEFCore5Plus && !string.IsNullOrEmpty(newTableName)) { element.TableName = string.Empty; } } else { if (string.IsNullOrEmpty(newTableName)) { element.TableName = MakeDefaultTableAndSetName(element.Name); } if (store.GetAll <ModelClass>() .Except(new[] { element }) .Any(x => x.TableName == newTableName)) { errorMessages.Add($"Table name '{newTableName}' already in use"); } } } break; } case "ViewName": { if (element.IsDatabaseView) { string newViewName = (string)e.NewValue; if (element.IsDependentType) { if (!modelRoot.IsEFCore5Plus && !string.IsNullOrEmpty(newViewName)) { element.TableName = string.Empty; } } else { if (string.IsNullOrEmpty(newViewName)) { element.TableName = MakeDefaultTableAndSetName(element.Name); } if (store.GetAll <ModelClass>() .Except(new[] { element }) .Any(x => x.TableName == newViewName)) { errorMessages.Add($"Table name '{newViewName}' already in use"); } } } break; } } errorMessages = errorMessages.Where(m => m != null).ToList(); if (errorMessages.Any()) { current.Rollback(); ErrorDisplay.Show(store, string.Join("\n", errorMessages)); } void VerifyKeylessTypeEFCore5() { // TODO: Find definitive documentation on query type restrictions in EFCore5+ // Restrictions: // ================================= // Cannot have a key defined. List <string> allIdentityAttributeNames = element.AllIdentityAttributeNames.ToList(); if (allIdentityAttributeNames.Any()) { errorMessages.Add($"{element.Name} can't be mapped to a Sql query since it has identity attribute(s) {string.Join(", ", allIdentityAttributeNames)}. Set their 'Is Identity' property to false first."); } // Only support a subset of navigation mapping capabilities, specifically: // - They may never act as the principal end of a relationship. string badAssociations = string.Join(", " , store.ElementDirectory.AllElements .OfType <Association>() .Where(a => a.Principal == element) .Select(a => a.GetDisplayText())); if (!string.IsNullOrEmpty(badAssociations)) { errorMessages.Add($"{element.Name} can't be mapped to a Sql query since it is the principal end of association(s) {badAssociations}."); } // - They may not have navigations to owned entities badAssociations = string.Join(", " , store.ElementDirectory.AllElements .OfType <Association>() .Where(a => (a is UnidirectionalAssociation && a.Source == element && a.Target.IsDependentType) || (a is BidirectionalAssociation b && b.Source == element && b.Target.IsDependentType) || (a is BidirectionalAssociation c && c.Target == element && c.Source.IsDependentType)) .Select(a => a.GetDisplayText())); if (!string.IsNullOrEmpty(badAssociations)) { errorMessages.Add($"{element.Name} can't be mapped to a Sql query since it has association(s) to dependent type(s) in {badAssociations}."); } // - Entities cannot contain navigation properties to query types. badAssociations = string.Join(", " , store.ElementDirectory.AllElements .OfType <Association>() .Where(a => (a is UnidirectionalAssociation && a.Source == element && a.Target.IsQueryType) || (a is BidirectionalAssociation b && b.Source == element && b.Target.IsQueryType) || (a is BidirectionalAssociation c && c.Target == element && c.Source.IsQueryType)) .Select(a => a.GetDisplayText())); if (!string.IsNullOrEmpty(badAssociations)) { errorMessages.Add($"{element.Name} can't be mapped to a Sql query since it has association to sql-mapped type(s) in {badAssociations}."); } // - They can only contain reference navigation properties pointing to regular entities. badAssociations = string.Join(", " , store.ElementDirectory.AllElements .OfType <Association>() .Where(a => (a is UnidirectionalAssociation && a.Source == element && a.TargetMultiplicity == Multiplicity.ZeroMany) || (a is BidirectionalAssociation b && b.Source == element && b.TargetMultiplicity == Multiplicity.ZeroMany) || (a is BidirectionalAssociation c && c.Target == element && c.SourceMultiplicity == Multiplicity.ZeroMany)) .Select(a => a.GetDisplayText())); if (!string.IsNullOrEmpty(badAssociations)) { errorMessages.Add($"{element.Name} can't be mapped to a Sql query since it has zero-to-many association(s) in {badAssociations}. Only to-one or to-zero-or-one associations are allowed. "); } } void VerifyKeylessType() { // Restrictions: // ================================= // Cannot have a key defined. List <string> allIdentityAttributeNames = element.AllIdentityAttributeNames.ToList(); if (allIdentityAttributeNames.Any()) { errorMessages.Add($"{element.Name} can't be mapped to a Sql query since it has identity attribute(s) {string.Join(", ", allIdentityAttributeNames)}. Set their 'Is Identity' property to false first."); } // Only support a subset of navigation mapping capabilities, specifically: // - They may never act as the principal end of a relationship. string badAssociations = string.Join(", " , store.ElementDirectory.AllElements .OfType <Association>() .Where(a => a.Principal == element) .Select(a => a.GetDisplayText())); if (!string.IsNullOrEmpty(badAssociations)) { errorMessages.Add($"{element.Name} can't be mapped to a Sql query since it is the principal end of association(s) {badAssociations}."); } // - They may not have navigations to owned entities badAssociations = string.Join(", " , store.ElementDirectory.AllElements .OfType <Association>() .Where(a => (a is UnidirectionalAssociation && a.Source == element && a.Target.IsDependentType) || (a is BidirectionalAssociation b && b.Source == element && b.Target.IsDependentType) || (a is BidirectionalAssociation c && c.Target == element && c.Source.IsDependentType)) .Select(a => a.GetDisplayText())); if (!string.IsNullOrEmpty(badAssociations)) { errorMessages.Add($"{element.Name} can't be mapped to a Sql query since it has association(s) to dependent type(s) in {badAssociations}."); } // - Entities cannot contain navigation properties to query types. badAssociations = string.Join(", " , store.ElementDirectory.AllElements .OfType <Association>() .Where(a => (a is UnidirectionalAssociation && a.Source == element && a.Target.IsQueryType) || (a is BidirectionalAssociation b && b.Source == element && b.Target.IsQueryType) || (a is BidirectionalAssociation c && c.Target == element && c.Source.IsQueryType)) .Select(a => a.GetDisplayText())); if (!string.IsNullOrEmpty(badAssociations)) { errorMessages.Add($"{element.Name} can't be mapped to a Sql query since it has association to sql-mapped type(s) in {badAssociations}."); } // - They can only contain reference navigation properties pointing to regular entities. badAssociations = string.Join(", " , store.ElementDirectory.AllElements .OfType <Association>() .Where(a => (a is UnidirectionalAssociation && a.Source == element && a.TargetMultiplicity == Multiplicity.ZeroMany) || (a is BidirectionalAssociation b && b.Source == element && b.TargetMultiplicity == Multiplicity.ZeroMany) || (a is BidirectionalAssociation c && c.Target == element && c.SourceMultiplicity == Multiplicity.ZeroMany)) .Select(a => a.GetDisplayText())); if (!string.IsNullOrEmpty(badAssociations)) { errorMessages.Add($"{element.Name} can't be mapped to a Sql query since it has zero-to-many association(s) in {badAssociations}. Only to-one or to-zero-or-one associations are allowed. "); } } }
public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e) { base.ElementPropertyChanged(e); Association element = (Association)e.ModelElement; if (element.IsDeleted) { return; } Store store = element.Store; Transaction current = store.TransactionManager.CurrentTransaction; if (current.IsSerializing || ModelRoot.BatchUpdating) { return; } if (Equals(e.NewValue, e.OldValue)) { return; } List <string> errorMessages = EFCoreValidator.GetErrors(element).ToList(); BidirectionalAssociation bidirectionalAssociation = element as BidirectionalAssociation; switch (e.DomainProperty.Name) { case "FKPropertyName": { string fkPropertyName = e.NewValue?.ToString(); bool fkPropertyError = false; if (!string.IsNullOrEmpty(fkPropertyName)) { string tag = $"({element.Source.Name}:{element.Target.Name})"; if (element.Dependent == null) { errorMessages.Add($"{tag} can't have foreign keys defined; no dependent role found"); break; } int propertyCount = element.ForeignKeyPropertyNames.Length; int identityCount = element.Principal.AllIdentityAttributes.Count(); if (propertyCount != identityCount) { errorMessages.Add($"{tag} foreign key must have zero or {identityCount} {(identityCount == 1 ? "property" : "properties")} defined, since " + $"{element.Principal.Name} has {identityCount} identity properties; found {propertyCount} instead"); fkPropertyError = true; } foreach (string propertyName in element.ForeignKeyPropertyNames) { if (!CodeGenerator.IsValidLanguageIndependentIdentifier(propertyName)) { errorMessages.Add($"{tag} FK property name '{propertyName}' isn't a valid .NET identifier"); fkPropertyError = true; } if (element.Dependent.AllAttributes.Except(element.Dependent.Attributes).Any(a => a.Name == propertyName)) { errorMessages.Add($"{tag} FK property name '{propertyName}' is used in a base class of {element.Dependent.Name}"); fkPropertyError = true; } } if (!fkPropertyError) { // remove any locks on the attributes that were foreign keys string[] oldValues = e.OldValue?.ToString().Split(',') ?? new string[0]; foreach (string oldValue in oldValues) { element.Dependent.Attributes.FirstOrDefault(a => a.Name == oldValue)?.SetLocks(Locks.None); } element.EnsureForeignKeyAttributes(); // add delete locks to the attributes that are now foreign keys // ReSharper disable once LoopCanBePartlyConvertedToQuery foreach (string propertyName in element.ForeignKeyPropertyNames) { ModelAttribute fkAttribute = element.Dependent.Attributes.FirstOrDefault(a => a.Name == propertyName); if (fkAttribute != null) { fkAttribute.SetLocks(Locks.None); fkAttribute.Summary = $"Foreign key for {element.GetDisplayText()}"; fkAttribute.SetLocks(Locks.Delete); } } } } else { // foreign key was removed // remove locks string[] oldValues = e.OldValue?.ToString().Split(',') ?? new string[0]; // ReSharper disable once LoopCanBePartlyConvertedToQuery foreach (string oldValue in oldValues) { ModelAttribute attribute = element.Dependent.Attributes.FirstOrDefault(a => a.Name == oldValue); if (attribute != null) { attribute.Summary = null; attribute.SetLocks(Locks.None); } } } } break; case "SourceCustomAttributes": if (bidirectionalAssociation != null && !string.IsNullOrWhiteSpace(bidirectionalAssociation.SourceCustomAttributes)) { bidirectionalAssociation.SourceCustomAttributes = $"[{bidirectionalAssociation.SourceCustomAttributes.Trim('[', ']')}]"; CheckSourceForDisplayText(bidirectionalAssociation); } break; case "SourceDisplayText": if (bidirectionalAssociation != null) { CheckSourceForDisplayText(bidirectionalAssociation); } break; case "SourceMultiplicity": Multiplicity sourceMultiplicity = (Multiplicity)e.NewValue; // change unidirectional source cardinality // if target is dependent // source cardinality is 0..1 or 1 if (element.Target.IsDependentType && sourceMultiplicity == Multiplicity.ZeroMany) { errorMessages.Add($"Can't have a 0..* association from {element.Target.Name} to dependent type {element.Source.Name}"); break; } if ((sourceMultiplicity == Multiplicity.One && element.TargetMultiplicity == Multiplicity.One) || (sourceMultiplicity == Multiplicity.ZeroOne && element.TargetMultiplicity == Multiplicity.ZeroOne)) { if (element.SourceRole != EndpointRole.NotSet) { element.SourceRole = EndpointRole.NotSet; } if (element.TargetRole != EndpointRole.NotSet) { element.TargetRole = EndpointRole.NotSet; } } else { SetEndpointRoles(element); } // cascade delete behavior could now be illegal. Reset to default element.SourceDeleteAction = DeleteAction.Default; element.TargetDeleteAction = DeleteAction.Default; break; case "SourcePropertyName": string sourcePropertyNameErrorMessage = ValidateAssociationIdentifier(element, element.Target, (string)e.NewValue); if (EFModelDiagram.IsDropping && sourcePropertyNameErrorMessage != null) { element.Delete(); } else { errorMessages.Add(sourcePropertyNameErrorMessage); } break; case "SourceRole": if (element.Source.IsDependentType) { element.SourceRole = EndpointRole.Dependent; element.TargetRole = EndpointRole.Principal; } else if (!SetEndpointRoles(element)) { if (element.SourceRole == EndpointRole.Dependent && element.TargetRole != EndpointRole.Principal) { element.TargetRole = EndpointRole.Principal; } else if (element.SourceRole == EndpointRole.Principal && element.TargetRole != EndpointRole.Dependent) { element.TargetRole = EndpointRole.Dependent; } } break; case "TargetCustomAttributes": if (!string.IsNullOrWhiteSpace(element.TargetCustomAttributes)) { element.TargetCustomAttributes = $"[{element.TargetCustomAttributes.Trim('[', ']')}]"; CheckTargetForDisplayText(element); } break; case "TargetDisplayText": CheckTargetForDisplayText(element); break; case "TargetMultiplicity": Multiplicity newTargetMultiplicity = (Multiplicity)e.NewValue; // change unidirectional target cardinality // if target is dependent // target cardinality must be 0..1 or 1 if (element.Target.IsDependentType && newTargetMultiplicity == Multiplicity.ZeroMany) { errorMessages.Add($"Can't have a 0..* association from {element.Source.Name} to dependent type {element.Target.Name}"); break; } if ((element.SourceMultiplicity == Multiplicity.One && newTargetMultiplicity == Multiplicity.One) || (element.SourceMultiplicity == Multiplicity.ZeroOne && newTargetMultiplicity == Multiplicity.ZeroOne)) { if (element.SourceRole != EndpointRole.NotSet) { element.SourceRole = EndpointRole.NotSet; } if (element.TargetRole != EndpointRole.NotSet) { element.TargetRole = EndpointRole.NotSet; } } else { SetEndpointRoles(element); } // cascade delete behavior could now be illegal. Reset to default element.SourceDeleteAction = DeleteAction.Default; element.TargetDeleteAction = DeleteAction.Default; break; case "TargetPropertyName": // if we're creating an association via drag/drop, it's possible the existing property name // is the same as the default property name. The default doesn't get created until the transaction is // committed, so the drop's action will cause a name clash. Remove the clashing property, but // only if drag/drop. string targetPropertyNameErrorMessage = ValidateAssociationIdentifier(element, element.Source, (string)e.NewValue); if (EFModelDiagram.IsDropping && targetPropertyNameErrorMessage != null) { element.Delete(); } else { errorMessages.Add(targetPropertyNameErrorMessage); } break; case "TargetRole": if (element.Target.IsDependentType) { element.SourceRole = EndpointRole.Principal; element.TargetRole = EndpointRole.Dependent; } else if (!SetEndpointRoles(element)) { if (element.TargetRole == EndpointRole.Dependent && element.SourceRole != EndpointRole.Principal) { element.SourceRole = EndpointRole.Principal; } else if (element.TargetRole == EndpointRole.Principal && element.SourceRole != EndpointRole.Dependent) { element.SourceRole = EndpointRole.Dependent; } } break; } errorMessages = errorMessages.Where(m => m != null).ToList(); if (errorMessages.Any()) { current.Rollback(); ErrorDisplay.Show(string.Join("\n", errorMessages)); } }
public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e) { base.ElementPropertyChanged(e); ModelClass element = (ModelClass)e.ModelElement; Store store = element.Store; Transaction current = store.TransactionManager.CurrentTransaction; if (current.IsSerializing) { return; } if (Equals(e.NewValue, e.OldValue)) { return; } List <string> errorMessages = EFCoreValidator.GetErrors(element).ToList(); switch (e.DomainProperty.Name) { case "IsDependentType": bool newIsDependentType = (bool)e.NewValue; if (newIsDependentType) { if (element.IsAbstract) { errorMessages.Add($"Can't make {element.Name} a dependent class since it's abstract"); break; } // dependent type can't be source in an association if (store.ElementDirectory.AllElements.OfType <UnidirectionalAssociation>() .Any(a => a.Source == element)) { errorMessages.Add($"Can't make {element.Name} a dependent class since it references other classes"); break; } if (store.ElementDirectory.AllElements.OfType <BidirectionalAssociation>() .Any(a => a.Source == element || a.Target == element)) { errorMessages.Add($"Can't make {element.Name} a dependent class since it's in a bidirectional association"); break; } if (store.ElementDirectory.AllElements.OfType <BidirectionalAssociation>() .Any(a => a.Target == element && a.TargetMultiplicity == Multiplicity.ZeroMany)) { errorMessages.Add($"Can't make {element.Name} a dependent class since it's the target of a 0..* association"); break; } foreach (ModelAttribute modelAttribute in element.AllAttributes.Where(a => a.IsIdentity)) { modelAttribute.IsIdentity = false; } foreach (UnidirectionalAssociation association in Association.GetLinksToTargets(element).OfType <UnidirectionalAssociation>()) { if (association.SourceMultiplicity == Multiplicity.ZeroMany) { association.SourceMultiplicity = Multiplicity.ZeroOne; } if (association.TargetMultiplicity == Multiplicity.ZeroMany) { association.TargetMultiplicity = Multiplicity.ZeroOne; } association.TargetRole = EndpointRole.Dependent; } element.TableName = string.Empty; element.DbSetName = string.Empty; } else { element.DbSetName = MakeDefaultName(element.Name); element.TableName = MakeDefaultName(element.Name); } PresentationHelper.ColorShapeOutline(element); break; case "IsAbstract": bool newIsAbstract = (bool)e.NewValue; if (newIsAbstract && element.IsDependentType) { errorMessages.Add($"Can't make {element.Name} abstract since it's a dependent type"); break; } PresentationHelper.ColorShapeOutline(element); break; case "ImplementNotify": bool newImplementNotify = (bool)e.NewValue; if (newImplementNotify) { foreach (ModelAttribute attribute in element.Attributes.Where(x => x.AutoProperty)) { WarningDisplay.Show($"{element.Name}.{attribute.Name} is an autoproperty, so will not participate in INotifyPropertyChanged messages"); } } PresentationHelper.ColorShapeOutline(element); break; case "TableName": string newTableName = (string)e.NewValue; if (element.IsDependentType) { if (!string.IsNullOrEmpty(newTableName)) { element.TableName = string.Empty; } } else { if (string.IsNullOrEmpty(newTableName)) { element.TableName = MakeDefaultName(element.Name); } if (store.ElementDirectory.AllElements.OfType <ModelClass>() .Except(new[] { element }) .Any(x => x.TableName == newTableName)) { errorMessages.Add($"Table name '{newTableName}' already in use"); } } break; case "DbSetName": string newDbSetName = (string)e.NewValue; if (element.IsDependentType) { if (!string.IsNullOrEmpty(newDbSetName)) { element.DbSetName = string.Empty; } } else { if (string.IsNullOrEmpty(newDbSetName)) { element.DbSetName = MakeDefaultName(element.Name); } if (current.Name.ToLowerInvariant() != "paste" && (string.IsNullOrWhiteSpace(newDbSetName) || !CodeGenerator.IsValidLanguageIndependentIdentifier(newDbSetName))) { errorMessages.Add($"DbSet name '{newDbSetName}' isn't a valid .NET identifier."); } else if (store.ElementDirectory.AllElements.OfType <ModelClass>() .Except(new[] { element }) .Any(x => x.DbSetName == newDbSetName)) { errorMessages.Add($"DbSet name '{newDbSetName}' already in use"); } } break; case "Name": string newName = (string)e.NewValue; if (current.Name.ToLowerInvariant() != "paste" && (string.IsNullOrWhiteSpace(newName) || !CodeGenerator.IsValidLanguageIndependentIdentifier(newName))) { errorMessages.Add($"Class name '{newName}' isn't a valid .NET identifier."); } else if (store.ElementDirectory .AllElements .OfType <ModelClass>() .Except(new[] { element }) .Any(x => x.Name == newName)) { errorMessages.Add($"Class name '{newName}' already in use by another class"); } else if (store.ElementDirectory .AllElements .OfType <ModelEnum>() .Any(x => x.Name == newName)) { errorMessages.Add($"Class name '{newName}' already in use by an enum"); } else if (!string.IsNullOrEmpty((string)e.OldValue)) { string oldDefaultName = MakeDefaultName((string)e.OldValue); string newDefaultName = MakeDefaultName(newName); if (element.DbSetName == oldDefaultName) { element.DbSetName = newDefaultName; } if (element.TableName == oldDefaultName) { element.TableName = newDefaultName; } } break; case "Namespace": string newNamespace = (string)e.NewValue; if (current.Name.ToLowerInvariant() != "paste") { errorMessages.Add(CommonRules.ValidateNamespace(newNamespace, CodeGenerator.IsValidLanguageIndependentIdentifier)); } break; } errorMessages = errorMessages.Where(m => m != null).ToList(); if (errorMessages.Any()) { current.Rollback(); ErrorDisplay.Show(string.Join("\n", errorMessages)); } }