public void TestMapDefinitionValidation() { var conn = CreateTestConnection(); var mdf = ObjectFactory.CreateMapDefinition(conn, "Test"); mdf.ResourceID = "Library://UnitTests/Test.MapDefinition"; var context = new ResourceValidationContext(conn.ResourceService, conn.FeatureService); var issues = ResourceValidatorSet.Validate(context, mdf, false); Assert.True(issues.Any(x => x.StatusCode == ValidationStatusCode.Warning_MapDefinition_MissingCoordinateSystem)); conn.ResourceService.SetResourceXmlData("Library://UnitTests/Layers/HydrographicPolygons.LayerDefinition", File.OpenRead("TestData/MappingService/UT_HydrographicPolygons.ldf")); var layer = mdf.AddLayer(null, "bar", "Library://UnitTests/Layers/HydrographicPolygons.LayerDefinition"); layer.Group = "foo"; //AddLayer no longer lets us put in bogus group names context = new ResourceValidationContext(conn.ResourceService, conn.FeatureService); issues = ResourceValidatorSet.Validate(context, mdf, false); Assert.True(issues.Any(x => x.StatusCode == ValidationStatusCode.Error_MapDefinition_LayerWithNonExistentGroup)); mdf.AddLayer(null, "bar", "Library://UnitTests/Layers/HydrographicPolygons.LayerDefinition"); context = new ResourceValidationContext(conn.ResourceService, conn.FeatureService); issues = ResourceValidatorSet.Validate(context, mdf, false); Assert.True(issues.Any(x => x.StatusCode == ValidationStatusCode.Error_MapDefinition_DuplicateLayerName)); var group = mdf.AddGroup("foo"); group.Group = "bar"; context = new ResourceValidationContext(conn.ResourceService, conn.FeatureService); issues = ResourceValidatorSet.Validate(context, mdf, false); Assert.True(issues.Any(x => x.StatusCode == ValidationStatusCode.Error_MapDefinition_GroupWithNonExistentGroup)); }
/// <summary> /// Validats the specified resources for common issues associated with this /// resource type /// </summary> /// <param name="context"></param> /// <param name="resource"></param> /// <param name="recurse"></param> /// <returns></returns> public virtual ValidationIssue[] Validate(ResourceValidationContext context, IResource resource, bool recurse) { if (!resource.GetResourceTypeDescriptor().Equals(this.SupportedResourceAndVersion)) return null; return ValidateBase(context, resource, recurse); }
/// <summary> /// Validats the specified resources for common issues associated with this /// resource type /// </summary> /// <param name="context"></param> /// <param name="resource"></param> /// <param name="recurse"></param> /// <returns></returns> public ValidationIssue[] Validate(ResourceValidationContext context, IResource resource, bool recurse) { Check.ArgumentNotNull(context, nameof(context)); if (context.IsAlreadyValidated(resource.ResourceID)) { return(null); } if (resource.ResourceType != ResourceTypes.DrawingSource.ToString()) { return(null); } var issues = new List <ValidationIssue>(); IDrawingSource dws = (IDrawingSource)resource; if (string.IsNullOrEmpty(dws.SourceName)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_DrawingSource_NoSourceDwf, Strings.DS_NoSourceSpecified)); } if (string.IsNullOrEmpty(dws.CoordinateSpace)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Information, ValidationStatusCode.Info_DrawingSource_NoCoordinateSpace, Strings.DS_NoCoordinateSpace)); } context.MarkValidated(resource.ResourceID); return(issues.ToArray()); }
/// <summary> /// Validats the specified resources for common issues associated with this /// resource type /// </summary> /// <param name="context"></param> /// <param name="resource"></param> /// <param name="recurse"></param> /// <returns></returns> public virtual ValidationIssue[] Validate(ResourceValidationContext context, IResource resource, bool recurse) { if (!resource.GetResourceTypeDescriptor().Equals(this.SupportedResourceAndVersion)) { return(null); } return(ValidateBase(context, resource, recurse)); }
/// <summary> /// Validates the specified items. /// </summary> /// <param name="context">The context.</param> /// <param name="items">The items.</param> /// <param name="recurse">if set to <c>true</c> [recurse].</param> /// <returns></returns> public static ValidationIssue[] Validate(ResourceValidationContext context, IEnumerable<IResource> items, bool recurse) { Check.NotNull(items, "items"); //NOXLATE var issues = new List<ValidationIssue>(); foreach (var item in items) { issues.AddRange(Validate(context, item, true)); } return issues.ToArray(); }
/// <summary> /// Validates the specified items. /// </summary> /// <param name="context">The context.</param> /// <param name="items">The items.</param> /// <param name="recurse">if set to <c>true</c> [recurse].</param> /// <returns></returns> public static ValidationIssue[] Validate(ResourceValidationContext context, IEnumerable <IResource> items, bool recurse) { Check.ArgumentNotNull(items, nameof(items)); var issues = new List <ValidationIssue>(); foreach (var item in items) { issues.AddRange(Validate(context, item, true)); } return(issues.ToArray()); }
/// <summary> /// Validats the specified resources for common issues associated with this /// resource type /// </summary> /// <param name="context"></param> /// <param name="resource"></param> /// <param name="recurse"></param> /// <returns></returns> public ValidationIssue[] Validate(ResourceValidationContext context, IResource resource, bool recurse) { Check.NotNull(context, "context"); //NOXLATE if (context.IsAlreadyValidated(resource.ResourceID)) return null; if (resource.ResourceType != ResourceTypes.PrintLayout) return null; //TODO: What problems could there possibly be? context.MarkValidated(resource.ResourceID); return new ValidationIssue[0]; }
/// <summary> /// Validats the specified resources for common issues associated with this /// resource type /// </summary> /// <param name="context"></param> /// <param name="resource"></param> /// <param name="recurse"></param> /// <returns></returns> protected ValidationIssue[] ValidateBase(ResourceValidationContext context, IResource resource, bool recurse) { Check.ArgumentNotNull(context, nameof(context)); if (context.IsAlreadyValidated(resource.ResourceID)) { return(null); } if (resource.ResourceType != ResourceTypes.SymbolDefinition.ToString()) { return(null); } var issues = new List <ValidationIssue>(); var symDef = (ISymbolDefinitionBase)resource; if (symDef.Type == SymbolDefinitionType.Simple) { var ssym = (ISimpleSymbolDefinition)symDef; issues.AddRange(ValidateSimpleSymbolDefinition(ssym, context)); } else if (symDef.Type == SymbolDefinitionType.Compound) { var csym = (ICompoundSymbolDefinition)symDef; foreach (var sym in csym.SimpleSymbol) { if (sym.Type == SimpleSymbolReferenceType.Inline) { var inline = (ISimpleSymbolInlineReference)sym; issues.AddRange(ValidateSimpleSymbolDefinition(inline.SimpleSymbolDefinition, context)); } else if (sym.Type == SimpleSymbolReferenceType.Library) { var res = context.GetResource(((ISimpleSymbolLibraryReference)sym).ResourceId); issues.AddRange(ValidateBase(context, res, false)); } } } context.MarkValidated(resource.ResourceID); return(issues.ToArray()); }
/// <summary> /// Validates the specified item using an existing validation context to skip over /// items already validated /// </summary> /// <param name="context"></param> /// <param name="item"></param> /// <param name="recurse"></param> /// <returns></returns> public static ValidationIssue[] Validate(ResourceValidationContext context, IResource item, bool recurse) { Check.ArgumentNotNull(item, nameof(item)); var issueSet = new ValidationResultSet(); if (!HasValidator(item.ResourceType, item.ResourceVersion)) { issueSet.AddIssue(new ValidationIssue(item, ValidationStatus.Warning, ValidationStatusCode.Warning_General_NoRegisteredValidatorForResource, string.Format(Strings.ERR_NO_REGISTERED_VALIDATOR, item.ResourceType, item.ResourceVersion))); } else { foreach (IResourceValidator v in m_validators) { //Ensure the current connection is set before validating v.Connection = context.Connection; if (!v.SupportedResourceAndVersion.Equals(item.GetResourceTypeDescriptor())) { continue; } try { ValidationIssue[] tmp = v.Validate(context, item, recurse); if (tmp != null) { issueSet.AddIssues(tmp); } } catch (Exception ex) { string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); if (ex is NullReferenceException) { msg = ex.ToString(); } issueSet.AddIssue(new ValidationIssue(item, ValidationStatus.Error, ValidationStatusCode.Error_General_ValidationError, string.Format(Strings.ErrorValidationGeneric, msg))); } } } return(issueSet.GetAllIssues()); }
/// <summary> /// Validats the specified resources for common issues associated with this /// resource type /// </summary> /// <param name="context"></param> /// <param name="resource"></param> /// <param name="recurse"></param> /// <returns></returns> public ValidationIssue[] Validate(ResourceValidationContext context, IResource resource, bool recurse) { Check.ArgumentNotNull(context, nameof(context)); if (context.IsAlreadyValidated(resource.ResourceID)) { return(null); } if (resource.ResourceType != ResourceTypes.SymbolLibrary.ToString()) { return(null); } //TODO: What problems could there possibly be? context.MarkValidated(resource.ResourceID); return(new ValidationIssue[0]); }
/// <summary> /// Validats the specified resources for common issues associated with this /// resource type /// </summary> /// <param name="context"></param> /// <param name="resource"></param> /// <param name="recurse"></param> /// <returns></returns> protected static ValidationIssue[] ValidateBase(ResourceValidationContext context, IResource resource, bool recurse) { Check.NotNull(context, "context"); //NOXLATE if (context.IsAlreadyValidated(resource.ResourceID)) return null; if (resource.ResourceType != ResourceTypes.SymbolDefinition) return null; var issues = new List<ValidationIssue>(); var symDef = (ISymbolDefinitionBase)resource; if (symDef.Type == SymbolDefinitionType.Simple) { var ssym = (ISimpleSymbolDefinition)symDef; issues.AddRange(ValidateSimpleSymbolDefinition(ssym, context)); } else if (symDef.Type == SymbolDefinitionType.Compound) { var csym = (ICompoundSymbolDefinition)symDef; foreach (var sym in csym.SimpleSymbol) { if (sym.Type == SimpleSymbolReferenceType.Inline) { var inline = (ISimpleSymbolInlineReference)sym; issues.AddRange(ValidateSimpleSymbolDefinition(inline.SimpleSymbolDefinition, context)); } else if (sym.Type == SimpleSymbolReferenceType.Library) { var res = context.GetResource(((ISimpleSymbolLibraryReference)sym).ResourceId); issues.AddRange(ValidateBase(context, res, false)); } } } context.MarkValidated(resource.ResourceID); return issues.ToArray(); }
/// <summary> /// Validats the specified resources for common issues associated with this /// resource type /// </summary> /// <param name="context"></param> /// <param name="resource"></param> /// <param name="recurse"></param> /// <returns></returns> public ValidationIssue[] Validate(ResourceValidationContext context, IResource resource, bool recurse) { Check.NotNull(context, "context"); //NOXLATE if (context.IsAlreadyValidated(resource.ResourceID)) return null; if (resource.ResourceType != ResourceTypes.DrawingSource) return null; var issues = new List<ValidationIssue>(); IDrawingSource dws = (IDrawingSource)resource; if (string.IsNullOrEmpty(dws.SourceName)) issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_DrawingSource_NoSourceDwf, Strings.DS_NoSourceSpecified)); if (string.IsNullOrEmpty(dws.CoordinateSpace)) issues.Add(new ValidationIssue(resource, ValidationStatus.Information, ValidationStatusCode.Info_DrawingSource_NoCoordinateSpace, Strings.DS_NoCoordinateSpace)); context.MarkValidated(resource.ResourceID); return issues.ToArray(); }
/// <summary> /// Validats the specified resources for common issues associated with this /// resource type /// </summary> /// <param name="context"></param> /// <param name="resource"></param> /// <param name="recurse"></param> /// <returns></returns> public ValidationIssue[] Validate(ResourceValidationContext context, IResource resource, bool recurse) { if (resource.ResourceType != OSGeo.MapGuide.MaestroAPI.ResourceTypes.ApplicationDefinition) return null; //TODO: Other items to check for // // - References to non-existent widgets // - MapWidget checks // - Ensure map id checks out // - Ensure context menu id checks out // - Verify containers of template are all referenced within this flexible layout // - Check required parameters of widgets are satisfied List<ValidationIssue> issues = new List<ValidationIssue>(); IApplicationDefinition fusionApp = resource as IApplicationDefinition; if (fusionApp.MapSet == null || fusionApp.MapSet.MapGroupCount == 0) issues.Add(new ValidationIssue(fusionApp, ValidationStatus.Error, ValidationStatusCode.Error_Fusion_MissingMap, string.Format(Strings.ADF_MapMissingError))); else { foreach (IMapGroup mapGroup in fusionApp.MapSet.MapGroups) { bool checkCmsProjection = false; List<IMapDefinition> mapDefsInGroup = new List<IMapDefinition>(); foreach (IMap map in mapGroup.Map) { if (IsCommercialOverlay(map)) { checkCmsProjection = true; } try { if (map.Type.ToLower() == "mapguide") //NOXLATE { var mdfId = map.GetMapDefinition(); if (string.IsNullOrEmpty(mdfId) || !resource.CurrentConnection.ResourceService.ResourceExists(mdfId)) { issues.Add(new ValidationIssue(fusionApp, ValidationStatus.Error, ValidationStatusCode.Error_Fusion_InvalidMap, string.Format(Strings.ADF_MapInvalidError, mapGroup.id))); } else { IMapDefinition mdef = (IMapDefinition)context.GetResource(mdfId); mapDefsInGroup.Add(mdef); IEnvelope mapEnv = ObjectFactory.CreateEnvelope(mdef.Extents.MinX, mdef.Extents.MinY, mdef.Extents.MaxX, mdef.Extents.MaxY); if (mapGroup.InitialView != null) { if (!mapEnv.Contains(mapGroup.InitialView.CenterX, mapGroup.InitialView.CenterY)) issues.Add(new ValidationIssue(mdef, ValidationStatus.Warning, ValidationStatusCode.Warning_Fusion_InitialViewOutsideMapExtents, string.Format(Strings.ADF_ViewOutsideMapExtents))); } if (recurse) { issues.AddRange(ResourceValidatorSet.Validate(context, mdef, recurse)); } } } } catch (Exception ex) { string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); issues.Add(new ValidationIssue(fusionApp, ValidationStatus.Error, ValidationStatusCode.Error_Fusion_MapValidationError, string.Format(Strings.ADF_MapValidationError, mapGroup.id, msg))); } } if (checkCmsProjection) { foreach (var mdf in mapDefsInGroup) { var wkt = mdf.CoordinateSystem; var csCode = resource.CurrentConnection.CoordinateSystemCatalog.ConvertWktToCoordinateSystemCode(wkt); if (csCode.ToUpper() != "WGS84.PSEUDOMERCATOR") //NOXLATE { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_Fusion_MapCoordSysIncompatibleWithCommericalLayers, string.Format(Strings.ADF_MapWithIncompatibleCommericalCs, mdf.ResourceID))); } } } } } //Check labels of referenced widgets foreach (var wset in fusionApp.WidgetSets) { foreach (var cnt in wset.Containers) { var menu = cnt as IMenu; if (menu != null) { ValidateWidgetReferencesForMenu(fusionApp, menu, issues, context, resource); } } } context.MarkValidated(resource.ResourceID); return issues.ToArray(); }
/// <summary> /// Performs base validation logic /// </summary> /// <param name="context"></param> /// <param name="resource"></param> /// <param name="recurse"></param> /// <returns></returns> protected static ValidationIssue[] ValidateBase(ResourceValidationContext context, IResource resource, bool recurse) { Check.ArgumentNotNull(context, nameof(context)); if (context.IsAlreadyValidated(resource.ResourceID)) { return(null); } if (resource.ResourceType != ResourceTypes.LoadProcedure.ToString()) { return(null); } if (resource.ResourceVersion != new Version(1, 0, 0)) { return(null); } var set = new ValidationResultSet(); var loadProc = (resource as ILoadProcedure).SubType; if (loadProc.Type == LoadType.Dwg) { set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LoadProcedure_DwgNotSupported, Strings.LPROC_DWGNotSupported)); return(set.GetAllIssues()); //all she wrote } if (loadProc.Type == LoadType.Raster) { set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LoadProcedure_RasterNotSupported, Strings.LPROC_RasterNotSupported)); return(set.GetAllIssues()); //all she wrote } if (loadProc.Type == LoadType.Sdf) { set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LoadProcedure_Sdf2OptionsNotSupported, Strings.LPROC_Sdf2OptionsNotSupported)); set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LoadProcedure_GeneralizationNotSupported, Strings.LPROC_GeneralizationNotSupported)); } if (loadProc.Type == LoadType.Shp) { set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LoadProcedure_ConvertToSdf3NotSupported, Strings.LPROC_ConvertToSdf3NotSupported)); set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LoadProcedure_GeneralizationNotSupported, Strings.LPROC_GeneralizationNotSupported)); } if (loadProc.Type == LoadType.Sqlite) { set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LoadProcedure_GeneralizationNotSupported, Strings.LPROC_GeneralizationNotSupported)); } var fproc = loadProc as IBaseLoadProcedure; if (fproc != null) { foreach (var fn in fproc.SourceFile) { if (!System.IO.File.Exists(fn)) { set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LoadProcedure_SourceFileNotFound, string.Format(Strings.LPROC_SourceFileNotFound, fn))); } } } context.MarkValidated(resource.ResourceID); return(set.GetAllIssues()); }
/// <summary> /// Validates the specified item using an existing validation context to skip over /// items already validated /// </summary> /// <param name="context"></param> /// <param name="item"></param> /// <param name="recurse"></param> /// <returns></returns> public static ValidationIssue[] Validate(ResourceValidationContext context, IResource item, bool recurse) { Check.NotNull(item, "item"); //NOXLATE var issueSet = new ValidationResultSet(); if (!HasValidator(item.ResourceType, item.ResourceVersion)) { issueSet.AddIssue(new ValidationIssue(item, ValidationStatus.Warning, ValidationStatusCode.Warning_General_NoRegisteredValidatorForResource, string.Format(Strings.ERR_NO_REGISTERED_VALIDATOR, item.ResourceType, item.ResourceVersion))); } else { foreach (IResourceValidator v in m_validators) { if (!v.SupportedResourceAndVersion.Equals(item.GetResourceTypeDescriptor())) continue; try { ValidationIssue[] tmp = v.Validate(context, item, recurse); if (tmp != null) issueSet.AddIssues(tmp); } catch (Exception ex) { string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); if (ex is NullReferenceException) msg = ex.ToString(); issueSet.AddIssue(new ValidationIssue(item, ValidationStatus.Error, ValidationStatusCode.Error_General_ValidationError, string.Format(Strings.ErrorValidationGeneric, msg))); } } } return issueSet.GetAllIssues(); }
/// <summary> /// Performs base validation logic /// </summary> /// <param name="context"></param> /// <param name="resource"></param> /// <param name="recurse"></param> /// <returns></returns> protected static ValidationIssue[] ValidateBase(ResourceValidationContext context, IResource resource, bool recurse) { Check.NotNull(context, "context"); //NOXLATE if (context.IsAlreadyValidated(resource.ResourceID)) return null; if (resource.ResourceType != OSGeo.MapGuide.MaestroAPI.ResourceTypes.WebLayout) return null; List<ValidationIssue> issues = new List<ValidationIssue>(); IWebLayout layout = resource as IWebLayout; if (layout.Map == null || layout.Map.ResourceId == null) { issues.Add(new ValidationIssue(layout, ValidationStatus.Error, ValidationStatusCode.Error_WebLayout_MissingMap, string.Format(Strings.WL_MissingMapError))); } else { //Check for duplicate command names var cmdSet = layout.CommandSet; Dictionary<string, ICommand> cmds = new Dictionary<string, ICommand>(); foreach (ICommand cmd in cmdSet.Commands) { if (cmds.ContainsKey(cmd.Name)) issues.Add(new ValidationIssue(layout, ValidationStatus.Error, ValidationStatusCode.Error_WebLayout_DuplicateCommandName, string.Format(Strings.WL_DuplicateCommandName, cmd.Name))); else cmds[cmd.Name] = cmd; } //Check for duplicate property references in search commands foreach (ICommand cmd in cmdSet.Commands) { if (cmd is ISearchCommand) { ISearchCommand search = (ISearchCommand)cmd; Dictionary<string, string> resColProps = new Dictionary<string, string>(); foreach (IResultColumn resCol in search.ResultColumns.Column) { if (resColProps.ContainsKey(resCol.Property)) issues.Add(new ValidationIssue(layout, ValidationStatus.Error, ValidationStatusCode.Error_WebLayout_DuplicateSearchCommandResultColumn, string.Format(Strings.WL_DuplicateSearchResultColumn, search.Name, resCol.Property))); else resColProps.Add(resCol.Property, resCol.Property); } } } //Check for command references to non-existent commands foreach (IUIItem item in layout.ContextMenu.Items) { if (item.Function == UIItemFunctionType.Command) { ICommandItem cmdRef = (ICommandItem)item; if (!cmds.ContainsKey(cmdRef.Command)) issues.Add(new ValidationIssue(layout, ValidationStatus.Error, ValidationStatusCode.Error_WebLayout_NonExistentContextMenuCommandReference, string.Format(Strings.WL_NonExistentMenuCommandReference, cmdRef.Command))); } } foreach (IUIItem item in layout.TaskPane.TaskBar.Items) { if (item.Function == UIItemFunctionType.Command) { ICommandItem cmdRef = (ICommandItem)item; if (!cmds.ContainsKey(cmdRef.Command)) issues.Add(new ValidationIssue(layout, ValidationStatus.Error, ValidationStatusCode.Error_WebLayout_NonExistentTaskPaneCommandReference, string.Format(Strings.WL_NonExistentTaskPaneCommandReference, cmdRef.Command))); } } foreach (IUIItem item in layout.ToolBar.Items) { if (item.Function == UIItemFunctionType.Command) { ICommandItem cmdRef = (ICommandItem)item; if (!cmds.ContainsKey(cmdRef.Command)) issues.Add(new ValidationIssue(layout, ValidationStatus.Error, ValidationStatusCode.Error_WebLayout_NonExistentToolbarCommandReference, string.Format(Strings.WL_NonExistentToolbarCommandReference, cmdRef.Command))); } } try { IMapDefinition mdef = (IMapDefinition)context.GetResource(layout.Map.ResourceId); if (layout.Map.InitialView != null) { var mapEnv = ObjectFactory.CreateEnvelope(mdef.Extents.MinX, mdef.Extents.MinY, mdef.Extents.MaxX, mdef.Extents.MaxY); if (!mapEnv.Contains(layout.Map.InitialView.CenterX, layout.Map.InitialView.CenterY)) issues.Add(new ValidationIssue(mdef, ValidationStatus.Warning, ValidationStatusCode.Warning_WebLayout_InitialViewOutsideMapExtents, string.Format(Strings.WL_StartViewOutsideExtentsWarning))); } if (recurse) { issues.AddRange(ResourceValidatorSet.Validate(context, mdef, true)); } } catch (Exception ex) { string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); issues.Add(new ValidationIssue(layout, ValidationStatus.Error, ValidationStatusCode.Error_WebLayout_Generic, string.Format(Strings.WL_MapValidationError, layout.Map.ResourceId, msg))); } } context.MarkValidated(resource.ResourceID); return issues.ToArray(); }
protected override ICollection<ValidationIssue> ValidateEditedResource() { string[] warnings; string[] errors; Func<ValidationIssue[]> validator = () => { ValidateXml(out errors, out warnings); var issues = new List<ValidationIssue>(); foreach (string err in errors) { issues.Add(new ValidationIssue(this.Resource, ValidationStatus.Error, ValidationStatusCode.Error_General_ValidationError, err)); } foreach (string warn in warnings) { issues.Add(new ValidationIssue(this.Resource, ValidationStatus.Warning, ValidationStatusCode.Warning_General_ValidationWarning, warn)); } //Put through ValidationResultSet to weed out redundant messages var set = new ValidationResultSet(issues); try { var res = ResourceTypeRegistry.Deserialize(editor.XmlContent); var context = new ResourceValidationContext(_edSvc.ResourceService, _edSvc.FeatureService); //We don't care about dependents, we just want to validate *this* resource var resIssues = ResourceValidatorSet.Validate(context, res, false); set.AddIssues(resIssues); } catch { //This can fail because the XML may be for something that Maestro does not offer a strongly-typed class for yet. //So the XML may be legit, just not for this version of Maestro that is doing the validating } //Only care about errors. Warnings and other types should not derail us from saving return set.GetAllIssues(ValidationStatus.Error); }; if (this.InvokeRequired) return (ValidationIssue[])this.Invoke(validator); else return validator(); }
/// <summary> /// Performs base resource validation /// </summary> /// <param name="context"></param> /// <param name="resource"></param> /// <param name="recurse"></param> /// <returns></returns> protected ValidationIssue[] ValidateBase(ResourceValidationContext context, IResource resource, bool recurse) { Check.ArgumentNotNull(context, nameof(context)); if (context.IsAlreadyValidated(resource.ResourceID)) { return(null); } if (resource.ResourceType != ResourceTypes.MapDefinition.ToString()) { return(null); } List <ValidationIssue> issues = new List <ValidationIssue>(); IMapDefinition mdef = resource as IMapDefinition; if (string.IsNullOrEmpty(mdef.CoordinateSystem)) { issues.Add(new ValidationIssue(mdef, ValidationStatus.Warning, ValidationStatusCode.Warning_MapDefinition_MissingCoordinateSystem, Strings.MDF_NoCoordinateSystem)); } foreach (IMapLayerGroup g in mdef.MapLayerGroup) { if (g.ShowInLegend && (g.LegendLabel == null || g.LegendLabel.Trim().Length == 0)) { issues.Add(new ValidationIssue(mdef, ValidationStatus.Information, ValidationStatusCode.Info_MapDefinition_GroupMissingLabelInformation, string.Format(Strings.MDF_GroupMissingLabelInformation, g.Name))); } else if (g.ShowInLegend && g.LegendLabel.Trim().ToLower() == "layer group") //NOXLATE { issues.Add(new ValidationIssue(mdef, ValidationStatus.Information, ValidationStatusCode.Info_MapDefinition_GroupHasDefaultLabel, string.Format(Strings.MDF_GroupHasDefaultLabelInformation, g.Name))); } if (!string.IsNullOrEmpty(g.Group)) { var grp = mdef.GetGroupByName(g.Group); if (grp == null) { issues.Add(new ValidationIssue(mdef, ValidationStatus.Error, ValidationStatusCode.Error_MapDefinition_GroupWithNonExistentGroup, string.Format(Strings.MDF_GroupWithNonExistentGroup, g.Name, g.Group))); } } } List <IBaseMapLayer> layers = new List <IBaseMapLayer>(); foreach (IBaseMapLayer l in mdef.MapLayer) { layers.Add(l); } if (mdef.BaseMap != null && mdef.BaseMap.HasGroups()) { if (mdef.BaseMap.ScaleCount == 0) { issues.Add(new ValidationIssue(mdef, ValidationStatus.Error, ValidationStatusCode.Error_MapDefinition_NoFiniteDisplayScales, Strings.MDF_NoFiniteDisplayScalesSpecified)); } foreach (IBaseMapGroup g in mdef.BaseMap.BaseMapLayerGroups) { foreach (IBaseMapLayer l in g.BaseMapLayer) { layers.Add(l); } } } Dictionary <string, IBaseMapLayer> nameCounter = new Dictionary <string, IBaseMapLayer>(); foreach (IBaseMapLayer l in layers) { if (nameCounter.ContainsKey(l.Name)) { issues.Add(new ValidationIssue(mdef, ValidationStatus.Warning, ValidationStatusCode.Error_MapDefinition_DuplicateLayerName, string.Format(Strings.MDF_LayerNameDuplicateWarning, l.Name, l.ResourceId, nameCounter[l.Name].ResourceId))); } else { nameCounter.Add(l.Name, l); } var ml = l as IMapLayer; if (ml != null && !string.IsNullOrEmpty(ml.Group)) { var grp = mdef.GetGroupByName(ml.Group); if (grp == null) { issues.Add(new ValidationIssue(mdef, ValidationStatus.Error, ValidationStatusCode.Error_MapDefinition_LayerWithNonExistentGroup, string.Format(Strings.MDF_LayerWithNonExistentGroup, ml.Name, ml.Group))); } } if (l.ShowInLegend && (string.IsNullOrEmpty(l.LegendLabel) || l.LegendLabel.Trim().Length == 0)) { issues.Add(new ValidationIssue(mdef, ValidationStatus.Information, ValidationStatusCode.Warning_MapDefinition_LayerMissingLegendLabel, string.Format(Strings.MDF_LayerMissingLabelInformation, l.Name))); } var mapEnv = ObjectFactory.CreateEnvelope(mdef.Extents.MinX, mdef.Extents.MinY, mdef.Extents.MaxX, mdef.Extents.MaxY); try { ILayerDefinition layer = null; IResource res = context.GetResource(l.ResourceId); if (!ResourceValidatorSet.HasValidator(res.ResourceType, res.ResourceVersion)) { //Need to trap the no registered validator message issues.AddRange(ResourceValidatorSet.Validate(context, res, true)); continue; } layer = (ILayerDefinition)res; if (recurse) { issues.AddRange(ResourceValidatorSet.Validate(context, layer, recurse)); } IVectorLayerDefinition vl = null; if (layer.SubLayer.LayerType == LayerType.Vector) { vl = (IVectorLayerDefinition)layer.SubLayer; } if (vl != null) { try { IFeatureSource fs = (IFeatureSource)context.GetResource(vl.ResourceId); if (l.Selectable) { //Test selectability requirement string[] idProps = fs.GetIdentityProperties(this.Connection, vl.FeatureName); if (idProps == null || idProps.Length == 0) { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_MapDefinition_UnselectableLayer, string.Format(Strings.MDF_UnselectableLayer, l.Name, vl.FeatureName, fs.ResourceID))); } } try { FdoSpatialContextList scList = context.GetSpatialContexts(fs.ResourceID); if (scList.SpatialContext == null || scList.SpatialContext.Count == 0) { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_MapDefinition_MissingSpatialContext, string.Format(Strings.MDF_MissingSpatialContextWarning, fs.ResourceID))); } else { if (scList.SpatialContext.Count > 1) { issues.Add(new ValidationIssue(resource, ValidationStatus.Information, ValidationStatusCode.Info_MapDefinition_MultipleSpatialContexts, string.Format(Strings.MDF_MultipleSpatialContextsInformation, fs.ResourceID))); } bool skipGeomCheck = false; //TODO: Switch to the correct version (2.1), once released if (scList.SpatialContext[0].CoordinateSystemWkt != mdef.CoordinateSystem) { if (layer.SubLayer.LayerType == LayerType.Raster && this.Connection.SiteVersion <= SiteVersions.GetVersion(OSGeo.MapGuide.MaestroAPI.KnownSiteVersions.MapGuideOS2_0_2)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_MapDefinition_RasterReprojection, string.Format(Strings.MDF_RasterReprojectionError, fs.ResourceID))); } else { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_MapDefinition_LayerReprojection, string.Format(Strings.MDF_DataReprojectionWarning, fs.ResourceID))); } skipGeomCheck = true; } if (vl.Geometry != null && !skipGeomCheck) { var env = this.Connection.FeatureService.GetSpatialExtent(fs.ResourceID, vl.FeatureName, vl.Geometry); if (!env.Intersects(mapEnv)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_MapDefinition_DataOutsideMapBounds, string.Format(Strings.MDF_DataOutsideMapWarning, fs.ResourceID))); } } } } catch (Exception ex) { var nex = ex as NullExtentException; if (nex != null) { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_MapDefinition_FeatureSourceWithNullExtent, string.Format(Strings.MDF_LayerWithNullExtent, fs.ResourceID))); } else { string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_MapDefinition_ResourceRead, string.Format(Strings.MDF_ResourceReadError, fs.ResourceID, msg))); } } } catch (Exception ex) { string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_MapDefinition_FeatureSourceRead, string.Format(Strings.MDF_FeatureSourceReadError, l.ResourceId, msg))); } } } catch (Exception ex) { string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_MapDefinition_LayerRead, string.Format(Strings.MDF_LayerReadError, l.ResourceId, msg))); } } context.MarkValidated(resource.ResourceID); return(issues.ToArray()); }
private void ValidateWidgetReferencesForMenu(IApplicationDefinition fusionApp, IMenu menu, List <ValidationIssue> issues, ResourceValidationContext context, IResource resource) { foreach (var item in menu.Items) { var subMenu = item as IMenu; var widgetRef = item as IWidgetItem; if (subMenu != null) { ValidateWidgetReferencesForMenu(fusionApp, subMenu, issues, context, resource); } else if (widgetRef != null) { var id = widgetRef.Widget; var wgt = fusionApp.FindWidget(id); var uiWgt = wgt as IUIWidget; string parentName = "<unknown>"; //NOXLATE var cnt = menu as IWidgetContainer; var fly = menu as IFlyoutItem; if (cnt != null) { parentName = cnt.Name; } else if (fly != null) { parentName = fly.Label; } if (wgt == null) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_Fusion_InvalidWidgetReference, string.Format(Strings.ADF_InvalidWidgetReferenceInContainer, id, parentName))); } else { if (uiWgt == null) { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_Fusion_NonStandardUiWidgetAttachedToContainer, string.Format(Strings.ADF_NonUiWidgetAttachedToContainer, id, parentName))); } else { if (string.IsNullOrEmpty(uiWgt.Label) && string.IsNullOrEmpty(uiWgt.ImageUrl)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_Fusion_NoLabelOnWidget, string.Format(Strings.ADF_ReferencedWidgetInMenuHasNoLabel, id, parentName))); } } } } } }
/// <summary> /// Validates the simple symbol definition. /// </summary> /// <param name="ssym">The ssym.</param> /// <param name="context">The context.</param> /// <returns></returns> protected static IEnumerable<ValidationIssue> ValidateSimpleSymbolDefinition(ISimpleSymbolDefinition ssym, ResourceValidationContext context) { //Check that one geometry usage context has been specified if (ssym.AreaUsage == null && ssym.LineUsage == null && ssym.PointUsage == null) { yield return new ValidationIssue(ssym, ValidationStatus.Error, ValidationStatusCode.Error_SymbolDefinition_NoGeometryUsageContexts, Strings.SSDF_NoGeometryUsageContext); } //Validate image graphics foreach (var graphic in ssym.Graphics) { if (graphic.Type == GraphicElementType.Image) { IImageGraphic image = (IImageGraphic)graphic; if (image.Item != null) { if (image.Item.Type == ImageType.Reference) { IImageReference imgRef = (IImageReference)image.Item; if (!context.ResourceExists(imgRef.ResourceId)) { yield return new ValidationIssue(ssym, ValidationStatus.Error, ValidationStatusCode.Error_SymbolDefinition_ImageGraphicReferenceResourceIdNotFound, Strings.SSDF_ImageGraphicReferenceResourceIdNotFound); } else { var res = context.GetResource(imgRef.ResourceId); var resData = res.EnumerateResourceData(); bool found = false; foreach (var item in resData) { if (item.Name == imgRef.LibraryItemName) found = true; } if (!found) { yield return new ValidationIssue(ssym, ValidationStatus.Error, ValidationStatusCode.Error_SymbolDefinition_ImageGraphicReferenceResourceDataNotFound, string.Format(Strings.SSDF_ImageGraphicReferenceResourceDataNotFound, imgRef.ResourceId, imgRef.LibraryItemName)); } } } else //inline { //TODO: Validate inline image content } } } } string xml = ResourceTypeRegistry.SerializeAsString(ssym); //Check non existent symbol parameters foreach (var paramDef in ssym.ParameterDefinition.Parameter) { string name = "%" + paramDef.Identifier + "%"; //NOXLATE if (!xml.Contains(name) && string.IsNullOrEmpty(paramDef.DefaultValue)) { yield return new ValidationIssue(ssym, ValidationStatus.Warning, ValidationStatusCode.Warning_SymbolDefinition_SymbolParameterNotUsed, string.Format(Strings.SSDF_SymbolParameterNotUsed, paramDef.Identifier)); } } //TODO: Do the reverse check. Placeholders not pointing to a symbol parameter }
/// <summary> /// Validates the simple symbol definition. /// </summary> /// <param name="ssym">The ssym.</param> /// <param name="context">The context.</param> /// <returns></returns> protected IEnumerable <ValidationIssue> ValidateSimpleSymbolDefinition(ISimpleSymbolDefinition ssym, ResourceValidationContext context) { //Check that one geometry usage context has been specified if (ssym.AreaUsage == null && ssym.LineUsage == null && ssym.PointUsage == null) { yield return(new ValidationIssue(ssym, ValidationStatus.Error, ValidationStatusCode.Error_SymbolDefinition_NoGeometryUsageContexts, Strings.SSDF_NoGeometryUsageContext)); } //Validate image graphics foreach (var graphic in ssym.Graphics) { if (graphic.Type == GraphicElementType.Image) { IImageGraphic image = (IImageGraphic)graphic; if (image.Item != null) { if (image.Item.Type == ImageType.Reference) { IImageReference imgRef = (IImageReference)image.Item; if (!context.ResourceExists(imgRef.ResourceId)) { yield return(new ValidationIssue(ssym, ValidationStatus.Error, ValidationStatusCode.Error_SymbolDefinition_ImageGraphicReferenceResourceIdNotFound, Strings.SSDF_ImageGraphicReferenceResourceIdNotFound)); } else { var res = context.GetResource(imgRef.ResourceId); var resData = this.Connection.ResourceService.EnumerateResourceData(res.ResourceID); bool found = false; foreach (var item in resData.ResourceData) { if (item.Name == imgRef.LibraryItemName) { found = true; } } if (!found) { yield return(new ValidationIssue(ssym, ValidationStatus.Error, ValidationStatusCode.Error_SymbolDefinition_ImageGraphicReferenceResourceDataNotFound, string.Format(Strings.SSDF_ImageGraphicReferenceResourceDataNotFound, imgRef.ResourceId, imgRef.LibraryItemName))); } } } else //inline { //TODO: Validate inline image content } } } } string xml = ObjectFactory.SerializeAsString(ssym); //Check non existent symbol parameters foreach (var paramDef in ssym.ParameterDefinition.Parameter) { string name = "%" + paramDef.Identifier + "%"; //NOXLATE if (!xml.Contains(name) && string.IsNullOrEmpty(paramDef.DefaultValue)) { yield return(new ValidationIssue(ssym, ValidationStatus.Warning, ValidationStatusCode.Warning_SymbolDefinition_SymbolParameterNotUsed, string.Format(Strings.SSDF_SymbolParameterNotUsed, paramDef.Identifier))); } } //TODO: Do the reverse check. Placeholders not pointing to a symbol parameter }
/// <summary> /// Validats the specified resources for common issues associated with this /// resource type /// </summary> /// <param name="context"></param> /// <param name="resource"></param> /// <param name="recurse"></param> /// <returns></returns> public ValidationIssue[] Validate(ResourceValidationContext context, IResource resource, bool recurse) { Check.ArgumentNotNull(context, nameof(context)); if (context.IsAlreadyValidated(resource.ResourceID)) { return(null); } if (resource.ResourceType != ResourceTypes.FeatureSource.ToString()) { return(null); } List <ValidationIssue> issues = new List <ValidationIssue>(); IFeatureSource feature = (IFeatureSource)resource; IFeatureService featSvc = this.Connection.FeatureService; //Feature Join Optimization check foreach (var ext in feature.Extension) { foreach (var rel in ext.AttributeRelate) { if (string.IsNullOrEmpty(rel.Name)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_EmptyJoinPrefix, string.Format(Strings.FS_EmptyJoinPrefix, ext.Name))); } if (rel.RelatePropertyCount > 0) { if (rel.RelatePropertyCount == 1) { var srcFs = feature; var dstFs = (IFeatureSource)context.GetResource(rel.ResourceId); var leftProvider = srcFs.Provider.ToUpper(); var rightProvider = dstFs.Provider.ToUpper(); //FDO Join optimization check if (leftProvider.Contains("OSGEO.SQLITE") && rightProvider.Contains("OSGEO.SQLITE") && srcFs.ResourceID == rel.ResourceId) //NOXLATE { continue; } //FDO Join optimization check if (leftProvider.Contains("OSGEO.SQLSERVERSPATIAL") && rightProvider.Contains("OSGEO.SQLSERVERSPATIAL") && srcFs.ResourceID == rel.ResourceId) //NOXLATE { continue; } //TODO: Fix the capabilities response. Because it's not telling us enough information! //Anyways, these are the providers known to provide sorted query results. bool bLeftSortable = leftProvider.Contains("OSGEO.SDF") || //NOXLATE leftProvider.Contains("OSGEO.SHP") || //NOXLATE leftProvider.Contains("OSGEO.SQLITE") || //NOXLATE leftProvider.Contains("OSGEO.ODBC") || //NOXLATE leftProvider.Contains("OSGEO.SQLSERVERSPATIAL") || //NOXLATE leftProvider.Contains("OSGEO.MYSQL") || //NOXLATE leftProvider.Contains("OSGEO.POSTGRESQL"); //NOXLATE bool bRightSortable = leftProvider.Contains("OSGEO.SDF") || //NOXLATE leftProvider.Contains("OSGEO.SHP") || //NOXLATE leftProvider.Contains("OSGEO.SQLITE") || //NOXLATE leftProvider.Contains("OSGEO.ODBC") || //NOXLATE leftProvider.Contains("OSGEO.SQLSERVERSPATIAL") || //NOXLATE leftProvider.Contains("OSGEO.MYSQL") || //NOXLATE leftProvider.Contains("OSGEO.POSTGRESQL"); //NOXLATE if (!bLeftSortable || !bRightSortable) { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_Potential_Bad_Join_Performance, string.Format(Strings.FS_PotentialBadJoinPerformance, ext.Name, bLeftSortable, bRightSortable))); } } else { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_Potential_Bad_Join_Performance, string.Format(Strings.FS_PotentialBadJoinPerformance2, ext.Name))); } } } } //Plaintext credential check string providerNameUpper = feature.Provider.ToUpper(); string fsXml = feature.Serialize().ToUpper(); //You'll get warnings either way if (providerNameUpper == "OSGEO.SQLSERVERSPATIAL" || //NOXLATE providerNameUpper == "OSGEO.MYSQL" || //NOXLATE providerNameUpper == "OSGEO.POSTGRESQL" || //NOXLATE providerNameUpper == "OSGEO.ODBC" || //NOXLATE providerNameUpper == "OSGEO.ARCSDE" || //NOXLATE providerNameUpper == "OSGEO.WFS" || //NOXLATE providerNameUpper == "OSGEO.WMS" || //NOXLATE providerNameUpper == "KING.ORACLE" || //NOXLATE providerNameUpper == "AUTODESK.ORACLE") //NOXLATE { //Fortunately, all the above providers are universal in the naming choice of credential connection parameters if ((fsXml.Contains("<NAME>USERNAME</NAME>") && !fsXml.Contains(StringConstants.MgUsernamePlaceholder)) || (fsXml.Contains("<NAME>PASSWORD</NAME>") && !fsXml.Contains(StringConstants.MgPasswordPlaceholder))) //NOXLATE { issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_Plaintext_Credentials, Strings.FS_PlaintextCredentials)); } else { issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_Cannot_Package_Secured_Credentials, Strings.FS_CannotPackageSecuredCredentials)); } //Has the placeholder token(s) if (fsXml.Contains(StringConstants.MgUsernamePlaceholder) || fsXml.Contains(StringConstants.MgPasswordPlaceholder)) { //Find the MG_USER_CREDENTIALS resource data item bool bFound = false; var resData = this.Connection.ResourceService.EnumerateResourceData(feature.ResourceID); foreach (var data in resData.ResourceData) { if (data.Name == StringConstants.MgUserCredentialsResourceData) { bFound = true; } } if (!bFound) { issues.Add(new ValidationIssue(feature, ValidationStatus.Error, ValidationStatusCode.Error_FeatureSource_SecuredCredentialTokensWithoutSecuredCredentialData, Strings.FS_SecuredCredentialTokensWithoutSecuredCredentialData)); } } } //Note: Must be saved! string s = featSvc.TestConnection(feature.ResourceID); if (s.Trim().ToUpper() != true.ToString().ToUpper()) { issues.Add(new ValidationIssue(feature, ValidationStatus.Error, ValidationStatusCode.Error_FeatureSource_ConnectionTestFailed, string.Format(Strings.FS_ConnectionTestFailed, s))); return(issues.ToArray()); } try { System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.InvariantCulture; FdoSpatialContextList lst = context.GetSpatialContexts(feature.ResourceID); if (lst == null || lst.SpatialContext == null || lst.SpatialContext.Count == 0) { issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_NoSpatialContext, Strings.FS_NoSpatialContextWarning)); } else { foreach (FdoSpatialContextListSpatialContext c in lst.SpatialContext) { if (c.Extent == null || c.Extent.LowerLeftCoordinate == null || c.Extent.UpperRightCoordinate == null) { issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_EmptySpatialContext, Strings.FS_EmptySpatialContextWarning)); } else if (double.Parse(c.Extent.LowerLeftCoordinate.X, ci) <= -1000000 && double.Parse(c.Extent.LowerLeftCoordinate.Y, ci) <= -1000000 && double.Parse(c.Extent.UpperRightCoordinate.X, ci) >= 1000000 && double.Parse(c.Extent.UpperRightCoordinate.Y, ci) >= 1000000) { issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_DefaultSpatialContext, Strings.FS_DefaultSpatialContextWarning)); } } } } catch (Exception ex) { string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); issues.Add(new ValidationIssue(feature, ValidationStatus.Error, ValidationStatusCode.Error_FeatureSource_SpatialContextReadError, string.Format(Strings.FS_SpatialContextReadError, msg))); } List <string> classes = new List <string>(); try { var schemaNames = featSvc.GetSchemas(feature.ResourceID); if (schemaNames.Length == 0) { issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_NoSchemasFound, Strings.FS_SchemasMissingWarning)); } } catch (Exception ex) { var wex = ex as System.Net.WebException; if (wex != null) //Most likely timeout due to really large schema { string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_Validation_Timeout, string.Format(Strings.FS_ValidationTimeout, msg))); } else { string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); issues.Add(new ValidationIssue(feature, ValidationStatus.Error, ValidationStatusCode.Error_FeatureSource_SchemaReadError, string.Format(Strings.FS_SchemaReadError, msg))); } } string configDocXml = feature.GetConfigurationContent(Connection); if (!string.IsNullOrEmpty(configDocXml)) { var doc = ConfigurationDocument.LoadXml(configDocXml); var odbcDoc = doc as OdbcConfigurationDocument; if (odbcDoc != null) { issues.AddRange(ValidateOdbcDoc(feature, odbcDoc)); } } context.MarkValidated(resource.ResourceID); return(issues.ToArray()); }
protected object BackgroundValidate(BackgroundWorker worker, DoWorkEventArgs e, params object[] args) { //Collect all documents to be validated. Some of these selected items //may be folders. var documents = new List<string>(); foreach (object a in args) { string rid = a.ToString(); if (ResourceIdentifier.Validate(rid)) { var resId = new ResourceIdentifier(rid); if (resId.IsFolder) { foreach (IRepositoryItem o in _conn.ResourceService.GetRepositoryResources((string)args[0]).Children) { if (!o.IsFolder) { documents.Add(o.ResourceId); } } } else { documents.Add(rid); } } } worker.ReportProgress(0); var context = new ResourceValidationContext(_conn.ResourceService, _conn.FeatureService); var set = new ValidationResultSet(); int i = 0; foreach (string s in documents) { worker.ReportProgress((int)((i / (double)documents.Count) * 100), s); IResource item = null; try { item = _conn.ResourceService.GetResource(s); set.AddIssues(ResourceValidatorSet.Validate(context, item, true)); } catch (Exception ex) { string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); set.AddIssue(new ValidationIssue(item, ValidationStatus.Error, ValidationStatusCode.Error_General_ValidationError, string.Format(Strings.ValidationResourceLoadFailed, msg))); } i++; worker.ReportProgress((int)((i / (double)documents.Count) * 100), s); } return set.GetAllIssues(); }
/// <summary> /// Validats the specified resources for common issues associated with this /// resource type /// </summary> /// <param name="context"></param> /// <param name="resource"></param> /// <param name="recurse"></param> /// <returns></returns> public ValidationIssue[] Validate(ResourceValidationContext context, IResource resource, bool recurse) { if (resource.ResourceType != ResourceTypes.ApplicationDefinition.ToString()) { return(null); } //TODO: Other items to check for // // - References to non-existent widgets // - MapWidget checks // - Ensure map id checks out // - Ensure context menu id checks out // - Verify containers of template are all referenced within this flexible layout // - Check required parameters of widgets are satisfied List <ValidationIssue> issues = new List <ValidationIssue>(); IApplicationDefinition fusionApp = resource as IApplicationDefinition; if (fusionApp.MapSet == null || fusionApp.MapSet.MapGroupCount == 0) { issues.Add(new ValidationIssue(fusionApp, ValidationStatus.Error, ValidationStatusCode.Error_Fusion_MissingMap, string.Format(Strings.ADF_MapMissingError))); } else { foreach (IMapGroup mapGroup in fusionApp.MapSet.MapGroups) { bool checkCmsProjection = false; List <IMapDefinition> mapDefsInGroup = new List <IMapDefinition>(); foreach (IMap map in mapGroup.Map) { if (IsCommercialOverlay(map)) { checkCmsProjection = true; } if (map.Type.ToLower() == "virtualearth") { //As of July 1, 2017 we need an API key on Bing Maps var bingMapsKey = fusionApp.GetValue("BingMapKey"); if (string.IsNullOrEmpty(bingMapsKey)) { issues.Add(new ValidationIssue(fusionApp, ValidationStatus.Error, ValidationStatusCode.Error_Fusion_BingMapsMissingApiKey, Strings.ADF_BingMapsMissingApiKey)); } //If this is still referencing the "Hybrid" base layer type, that no longer exists in the v8 API if (map.CmsMapOptions.Type == "Hybrid") { issues.Add(new ValidationIssue(fusionApp, ValidationStatus.Error, ValidationStatusCode.Error_Fusion_BingMapsHybridBaseLayerNoLongerAvailable, Strings.ADF_BingMapsHybridLayerNoLongerAvailable)); } } try { if (map.Type.ToLower() == "mapguide") //NOXLATE { var mdfId = map.GetMapDefinition(); if (string.IsNullOrEmpty(mdfId) || !this.Connection.ResourceService.ResourceExists(mdfId)) { issues.Add(new ValidationIssue(fusionApp, ValidationStatus.Error, ValidationStatusCode.Error_Fusion_InvalidMap, string.Format(Strings.ADF_MapInvalidError, mapGroup.id))); } else { IMapDefinition mdef = (IMapDefinition)context.GetResource(mdfId); mapDefsInGroup.Add(mdef); IEnvelope mapEnv = ObjectFactory.CreateEnvelope(mdef.Extents.MinX, mdef.Extents.MinY, mdef.Extents.MaxX, mdef.Extents.MaxY); if (mapGroup.InitialView != null) { if (!mapEnv.Contains(mapGroup.InitialView.CenterX, mapGroup.InitialView.CenterY)) { issues.Add(new ValidationIssue(mdef, ValidationStatus.Warning, ValidationStatusCode.Warning_Fusion_InitialViewOutsideMapExtents, string.Format(Strings.ADF_ViewOutsideMapExtents))); } } if (recurse) { issues.AddRange(ResourceValidatorSet.Validate(context, mdef, recurse)); } } } } catch (Exception ex) { string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); issues.Add(new ValidationIssue(fusionApp, ValidationStatus.Error, ValidationStatusCode.Error_Fusion_MapValidationError, string.Format(Strings.ADF_MapValidationError, mapGroup.id, msg))); } } if (checkCmsProjection) { foreach (var mdf in mapDefsInGroup) { var wkt = mdf.CoordinateSystem; var csCode = this.Connection.CoordinateSystemCatalog.ConvertWktToCoordinateSystemCode(wkt); if (csCode.ToUpper() != "WGS84.PSEUDOMERCATOR") //NOXLATE { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_Fusion_MapCoordSysIncompatibleWithCommericalLayers, string.Format(Strings.ADF_MapWithIncompatibleCommericalCs, mdf.ResourceID))); } } } } } //Check labels of referenced widgets foreach (var wset in fusionApp.WidgetSets) { foreach (var cnt in wset.Containers) { var menu = cnt as IMenu; if (menu != null) { ValidateWidgetReferencesForMenu(fusionApp, menu, issues, context, resource); } } } context.MarkValidated(resource.ResourceID); return(issues.ToArray()); }
/// <summary> /// Perform base validation logic /// </summary> /// <param name="context"></param> /// <param name="resource"></param> /// <param name="recurse"></param> /// <returns></returns> protected static ValidationIssue[] ValidateBase(ResourceValidationContext context, IResource resource, bool recurse) { Check.NotNull(context, "context"); //NOXLATE if (context.IsAlreadyValidated(resource.ResourceID)) return null; var ldef = resource as ILayerDefinition; var vldef = ldef.SubLayer as IVectorLayerDefinition; var gldef = ldef.SubLayer as IRasterLayerDefinition; var dldef = ldef.SubLayer as IDrawingLayerDefinition; List<ValidationIssue> issues = new List<ValidationIssue>(); if (ldef.SubLayer == null) issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_LayerNull, Strings.LDF_LayerNullError)); ClassDefinition cls = null; if (vldef != null || gldef != null) { //Load referenced feature source IFeatureSource fs = null; try { fs = (IFeatureSource)context.GetResource(ldef.SubLayer.ResourceId); issues.AddRange(ResourceValidatorSet.Validate(context, fs, recurse)); } catch (Exception) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_FeatureSourceLoadError, string.Format(Strings.LDF_FeatureSourceLoadError))); } if (fs != null) { //Verify specified feature class and geometry check out try { string qualClassName = vldef == null ? gldef.FeatureName : vldef.FeatureName; string geometry = vldef == null ? gldef.Geometry : vldef.Geometry; bool foundSchema = false; bool foundGeometry = false; cls = fs.GetClass(qualClassName); if (cls != null) { foundSchema = true; foreach (PropertyDefinition col in cls.Properties) { if (col.Name == geometry) { foundGeometry = true; break; } } if (vldef != null && vldef.PropertyMapping != null) { foreach (INameStringPair s in vldef.PropertyMapping) { bool found = false; foreach (PropertyDefinition col in cls.Properties) { if (col.Name == s.Name) { found = true; break; } } if (!found) issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_ClassNotFound, string.Format(Strings.LDF_SchemaMissingError, qualClassName, fs.ResourceID))); } } } if (!foundSchema) issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_ClassNotFound, string.Format(Strings.LDF_SchemaMissingError, qualClassName, fs.ResourceID))); else if (!foundGeometry) issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_GeometryNotFound, string.Format(Strings.LDF_GeometryMissingError, geometry, qualClassName, fs.ResourceID))); } catch (Exception ex) { issues.Add(new ValidationIssue(fs, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_Generic, string.Format(Strings.LDF_SchemaAndColumnReadFailedError, ex.ToString()))); } if (recurse) { issues.AddRange(ResourceValidatorSet.Validate(context, fs, recurse)); } } } if (vldef != null) { if (string.IsNullOrEmpty(vldef.FeatureName)) issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_MissingFeatureSource, Strings.LDF_MissingFeatureSourceError)); if (string.IsNullOrEmpty(vldef.Geometry)) issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_MissingGeometry, Strings.LDF_MissingGeometryError)); if (vldef.VectorScaleRange == null || !vldef.HasVectorScaleRanges()) issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_MissingScaleRanges, Strings.LDF_MissingScaleRangesError)); else { //Test for overlapping scale ranges List<KeyValuePair<double, double>> ranges = new List<KeyValuePair<double, double>>(); foreach (IVectorScaleRange vsr in vldef.VectorScaleRange) { IVectorScaleRange2 vsr2 = vsr as IVectorScaleRange2; if (vsr2 != null) { var area = vsr2.AreaStyle; var line = vsr2.LineStyle; var point = vsr2.PointStyle; if (vsr2.CompositeStyleCount > 0 && (area != null || line != null || point != null)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LayerDefinition_CompositeStyleDefinedAlongsideBasicStyle, string.Format( Strings.LDF_CompositeStyleDefinedAlongsideBasicStyle, vsr2.MinScale.HasValue ? vsr2.MinScale.Value : 0, vsr2.MaxScale.HasValue ? vsr2.MaxScale.Value.ToString() : Strings.Infinity))); } if (vsr2.CompositeStyleCount > 0) { foreach (var cs in vsr2.CompositeStyle) { foreach (var cr in cs.CompositeRule) { if (cr.CompositeSymbolization != null) { foreach (var si in cr.CompositeSymbolization.SymbolInstance) { //verify that symbol references point to valid symbol definitions if (si.Reference.Type == SymbolInstanceType.Reference) { var symRef = (ISymbolInstanceReferenceLibrary)si.Reference; if (!context.ResourceExists(symRef.ResourceId)) issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_SymbolDefintionReferenceNotFound, string.Format( Strings.LDF_SymbolDefintionReferenceNotFound, symRef.ResourceId))); if (cls != null) { //warn if the symbol definition has usage contexts that are irrelevant against the layer's feature source var prop = cls.FindProperty(vldef.Geometry) as GeometricPropertyDefinition; if (prop != null) { var gtypes = new List<FeatureGeometricType>(prop.GetIndividualGeometricTypes()); var sym = context.GetResource(symRef.ResourceId) as ISimpleSymbolDefinition; if (sym != null) { if (sym.LineUsage != null && !gtypes.Contains(FeatureGeometricType.Curve)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Information, ValidationStatusCode.Info_LayerDefinition_IrrelevantUsageContext, string.Format( Strings.LDF_IrrelevantUsageContext, symRef.ResourceId, FeatureGeometricType.Curve.ToString()))); } if (sym.AreaUsage != null && !gtypes.Contains(FeatureGeometricType.Surface)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Information, ValidationStatusCode.Info_LayerDefinition_IrrelevantUsageContext, string.Format( Strings.LDF_IrrelevantUsageContext, symRef.ResourceId, FeatureGeometricType.Surface.ToString()))); } if (sym.PointUsage != null && !gtypes.Contains(FeatureGeometricType.Point)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Information, ValidationStatusCode.Info_LayerDefinition_IrrelevantUsageContext, string.Format( Strings.LDF_IrrelevantUsageContext, symRef.ResourceId, FeatureGeometricType.Point.ToString()))); } } } } } //verify that the overrides specified are for symbol parameters that actually exist if (si.ParameterOverrides.Count > 0) { if (si.Reference.Type == SymbolInstanceType.Reference) { var symRef = (ISymbolInstanceReferenceLibrary)si.Reference; var sym = (ISymbolDefinitionBase)context.GetResource(symRef.ResourceId); var paramList = new Dictionary<string, IParameter>(); foreach (var p in sym.GetParameters()) { paramList[p.Identifier] = p; } foreach (var ov in si.ParameterOverrides.Override) { if (!paramList.ContainsKey(ov.ParameterIdentifier)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LayerDefinition_SymbolParameterOverrideToNonExistentParameter, string.Format( Strings.LDF_SymbolParameterOverrideToNonExistentParameter, symRef.ResourceId, ov.ParameterIdentifier))); } } } } } } } } } } ranges.Add(new KeyValuePair<double, double>( vsr.MaxScale.HasValue ? vsr.MaxScale.Value : double.PositiveInfinity, vsr.MinScale.HasValue ? vsr.MinScale.Value : double.NegativeInfinity)); } double min = double.PositiveInfinity; double max = double.NegativeInfinity; foreach (KeyValuePair<double, double> sr in ranges) { min = Math.Min(min, sr.Value); max = Math.Max(max, sr.Key); if (sr.Key < sr.Value) issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_MinMaxScaleSwapped, string.Format(Strings.LDF_MinAndMaxScaleSwappedError, sr.Value, sr.Key))); } ranges.Sort(CompareScales); //TODO: Detect gaps in scale ranges for (int i = 0; i < ranges.Count; i++) for (int j = i + 1; j < ranges.Count; j++) if (ranges[i].Key > ranges[j].Value || ranges[i].Value > ranges[j].Value) issues.Add(new ValidationIssue(resource, ValidationStatus.Information, ValidationStatusCode.Info_LayerDefinition_ScaleRangeOverlap, string.Format(Strings.LDF_ScaleRangesOverlapInformation, ranges[i].Value, ranges[i].Key, ranges[j].Value, ranges[j].Key))); } } else if (gldef != null) { if (gldef.GridScaleRange == null || gldef.GridScaleRangeCount == 0) issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_NoGridScaleRanges, Strings.LDF_MissingScaleRangesError)); else if (gldef.GridScaleRangeCount != 1) issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LayerDefinition_MultipleGridScaleRanges, Strings.LDF_MultipleScaleRangesWarning)); } else if (dldef != null) { IDrawingSource dws = null; try { dws = (IDrawingSource)context.GetResource(dldef.ResourceId); } catch (Exception) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_DrawingSourceError, Strings.LDF_DrawingSourceError)); } if (dws != null) { if (Array.IndexOf(ldef.CurrentConnection.Capabilities.SupportedServices, (int)ServiceType.Drawing) >= 0) { var dwSvc = (IDrawingService)ldef.CurrentConnection.GetService((int)ServiceType.Drawing); //Check if specified section exists var shtList = dwSvc.EnumerateDrawingSections(dws.ResourceID); DrawingSectionListSection sheet = null; foreach (var sht in shtList.Section) { if (sht.Name.Equals(dldef.Sheet)) { sheet = sht; break; } } if (sheet == null) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_DrawingSourceSheetNotFound, string.Format(Strings.LDF_SheetNotFound, dldef.Sheet))); } else { //null or empty filter means all layers, in that case do nothing if (!string.IsNullOrEmpty(dldef.LayerFilter)) { //Check if specified layers all exist in specified section var specifiedLayers = dldef.LayerFilter.Split(','); //NOXLATE var dwLayers = new Dictionary<string, string>(); var shtLayers = dwSvc.EnumerateDrawingLayers(dws.ResourceID, sheet.Name); foreach (var sl in shtLayers) { dwLayers.Add(sl, sl); } foreach (var sl in specifiedLayers) { if (!dwLayers.ContainsKey(sl.Trim())) issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_DrawingSourceSheetLayerNotFound, string.Format(Strings.LDF_SheetLayerNotFound, sl.Trim(), sheet.Name))); } } } } if (recurse) { issues.AddRange(ResourceValidatorSet.Validate(context, dws, recurse)); } } } else { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LayerDefinition_UnsupportedLayerType, Strings.LDF_UnsupportedLayerTypeWarning)); } context.MarkValidated(resource.ResourceID); return issues.ToArray(); }
private void ValidateWidgetReferencesForMenu(IApplicationDefinition fusionApp, IMenu menu, List<ValidationIssue> issues, ResourceValidationContext context, IResource resource) { foreach (var item in menu.Items) { var subMenu = item as IMenu; var widgetRef = item as IWidgetItem; if (subMenu != null) { ValidateWidgetReferencesForMenu(fusionApp, subMenu, issues, context, resource); } else if (widgetRef != null) { var id = widgetRef.Widget; var wgt = fusionApp.FindWidget(id); var uiWgt = wgt as IUIWidget; string parentName = "<unknown>"; //NOXLATE var cnt = menu as IWidgetContainer; var fly = menu as IFlyoutItem; if (cnt != null) parentName = cnt.Name; else if (fly != null) parentName = fly.Label; if (wgt == null) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_Fusion_InvalidWidgetReference, string.Format(Strings.ADF_InvalidWidgetReferenceInContainer, id, parentName))); } else { if (uiWgt == null) { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_Fusion_NonStandardUiWidgetAttachedToContainer, string.Format(Strings.ADF_NonUiWidgetAttachedToContainer, id, parentName))); } else { if (string.IsNullOrEmpty(uiWgt.Label) && string.IsNullOrEmpty(uiWgt.ImageUrl)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_Fusion_NoLabelOnWidget, string.Format(Strings.ADF_ReferencedWidgetInMenuHasNoLabel, id, parentName))); } } } } } }
public void TestSymbolDefinitionValidation() { var conn = CreateTestConnection(); var ssym = ObjectFactory.CreateSimpleSymbol(conn, "Test", "Test"); ssym.ResourceID = "Library://UnitTests/Test.SymbolDefinition"; var context = new ResourceValidationContext(conn.ResourceService, conn.FeatureService); var issues = ResourceValidatorSet.Validate(context, ssym, true); Assert.True(issues.Any(x => x.StatusCode == ValidationStatusCode.Error_SymbolDefinition_NoGeometryUsageContexts)); var param = ssym.CreateParameter(); param.Identifier = "TEST"; ssym.ParameterDefinition.AddParameter(param); context = new ResourceValidationContext(conn.ResourceService, conn.FeatureService); issues = ResourceValidatorSet.Validate(context, ssym, true); Assert.True(issues.Any(x => x.StatusCode == ValidationStatusCode.Warning_SymbolDefinition_SymbolParameterNotUsed)); var imgRef = ssym.CreateImageReference("Library://UnitTest/IDontExist.LayerDefinition", "Foo.png"); var img = ssym.CreateImageGraphics(); img.Item = imgRef; ssym.AddGraphics(img); context = new ResourceValidationContext(conn.ResourceService, conn.FeatureService); issues = ResourceValidatorSet.Validate(context, ssym, true); Assert.True(issues.Any(x => x.StatusCode == ValidationStatusCode.Error_SymbolDefinition_ImageGraphicReferenceResourceIdNotFound)); conn.ResourceService.SetResourceXmlData("Library://UnitTests/Layers/HydrographicPolygons.LayerDefinition", File.OpenRead("TestData/MappingService/UT_HydrographicPolygons.ldf")); imgRef = ssym.CreateImageReference("Library://UnitTests/Layers/HydrographicPolygons.LayerDefinition", "Foo.png"); img = ssym.CreateImageGraphics(); img.Item = imgRef; ssym.AddGraphics(img); context = new ResourceValidationContext(conn.ResourceService, conn.FeatureService); issues = ResourceValidatorSet.Validate(context, ssym, true); Assert.True(issues.Any(x => x.StatusCode == ValidationStatusCode.Error_SymbolDefinition_ImageGraphicReferenceResourceDataNotFound)); }
/// <summary> /// Performs base validation logic /// </summary> /// <param name="context"></param> /// <param name="resource"></param> /// <param name="recurse"></param> /// <returns></returns> protected static ValidationIssue[] ValidateBase(ResourceValidationContext context, IResource resource, bool recurse) { Check.ArgumentNotNull(context, nameof(context)); if (context.IsAlreadyValidated(resource.ResourceID)) { return(null); } if (resource.ResourceType != ResourceTypes.WebLayout.ToString()) { return(null); } List <ValidationIssue> issues = new List <ValidationIssue>(); IWebLayout layout = resource as IWebLayout; if (layout.Map == null || layout.Map.ResourceId == null) { issues.Add(new ValidationIssue(layout, ValidationStatus.Error, ValidationStatusCode.Error_WebLayout_MissingMap, string.Format(Strings.WL_MissingMapError))); } else { //Check for duplicate command names var cmdSet = layout.CommandSet; Dictionary <string, ICommand> cmds = new Dictionary <string, ICommand>(); foreach (ICommand cmd in cmdSet.Commands) { if (cmds.ContainsKey(cmd.Name)) { issues.Add(new ValidationIssue(layout, ValidationStatus.Error, ValidationStatusCode.Error_WebLayout_DuplicateCommandName, string.Format(Strings.WL_DuplicateCommandName, cmd.Name))); } else { cmds[cmd.Name] = cmd; } } //Check for duplicate property references in search commands foreach (ISearchCommand search in cmdSet.Commands.OfType <ISearchCommand>()) { Dictionary <string, string> resColProps = new Dictionary <string, string>(); foreach (IResultColumn resCol in search.ResultColumns.Column) { if (resColProps.ContainsKey(resCol.Property)) { issues.Add(new ValidationIssue(layout, ValidationStatus.Error, ValidationStatusCode.Error_WebLayout_DuplicateSearchCommandResultColumn, string.Format(Strings.WL_DuplicateSearchResultColumn, search.Name, resCol.Property))); } else { resColProps.Add(resCol.Property, resCol.Property); } } } //Check for command references to non-existent commands foreach (IUIItem item in layout.ContextMenu.Items) { if (item.Function == UIItemFunctionType.Command) { ICommandItem cmdRef = (ICommandItem)item; if (!cmds.ContainsKey(cmdRef.Command)) { issues.Add(new ValidationIssue(layout, ValidationStatus.Error, ValidationStatusCode.Error_WebLayout_NonExistentContextMenuCommandReference, string.Format(Strings.WL_NonExistentMenuCommandReference, cmdRef.Command))); } } } foreach (IUIItem item in layout.TaskPane.TaskBar.Items) { if (item.Function == UIItemFunctionType.Command) { ICommandItem cmdRef = (ICommandItem)item; if (!cmds.ContainsKey(cmdRef.Command)) { issues.Add(new ValidationIssue(layout, ValidationStatus.Error, ValidationStatusCode.Error_WebLayout_NonExistentTaskPaneCommandReference, string.Format(Strings.WL_NonExistentTaskPaneCommandReference, cmdRef.Command))); } } } foreach (IUIItem item in layout.ToolBar.Items) { if (item.Function == UIItemFunctionType.Command) { ICommandItem cmdRef = (ICommandItem)item; if (!cmds.ContainsKey(cmdRef.Command)) { issues.Add(new ValidationIssue(layout, ValidationStatus.Error, ValidationStatusCode.Error_WebLayout_NonExistentToolbarCommandReference, string.Format(Strings.WL_NonExistentToolbarCommandReference, cmdRef.Command))); } } } try { IMapDefinition mdef = (IMapDefinition)context.GetResource(layout.Map.ResourceId); if (layout.Map.InitialView != null) { var mapEnv = ObjectFactory.CreateEnvelope(mdef.Extents.MinX, mdef.Extents.MinY, mdef.Extents.MaxX, mdef.Extents.MaxY); if (!mapEnv.Contains(layout.Map.InitialView.CenterX, layout.Map.InitialView.CenterY)) { issues.Add(new ValidationIssue(mdef, ValidationStatus.Warning, ValidationStatusCode.Warning_WebLayout_InitialViewOutsideMapExtents, string.Format(Strings.WL_StartViewOutsideExtentsWarning))); } } if (recurse) { issues.AddRange(ResourceValidatorSet.Validate(context, mdef, true)); } } catch (Exception ex) { string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); issues.Add(new ValidationIssue(layout, ValidationStatus.Error, ValidationStatusCode.Error_WebLayout_Generic, string.Format(Strings.WL_MapValidationError, layout.Map.ResourceId, msg))); } } context.MarkValidated(resource.ResourceID); return(issues.ToArray()); }
/// <summary> /// Performs base validation logic /// </summary> /// <param name="context"></param> /// <param name="resource"></param> /// <param name="recurse"></param> /// <returns></returns> protected static ValidationIssue[] ValidateBase(ResourceValidationContext context, IResource resource, bool recurse) { Check.NotNull(context, "context"); //NOXLATE if (context.IsAlreadyValidated(resource.ResourceID)) return null; if (resource.ResourceType != OSGeo.MapGuide.MaestroAPI.ResourceTypes.LoadProcedure) return null; if (resource.ResourceVersion != new Version(1, 0, 0)) return null; var set = new ValidationResultSet(); var loadProc = (resource as ILoadProcedure).SubType; if (loadProc.Type == LoadType.Dwg) { set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LoadProcedure_DwgNotSupported, Strings.LPROC_DWGNotSupported)); return set.GetAllIssues(); //all she wrote } if (loadProc.Type == LoadType.Raster) { set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LoadProcedure_RasterNotSupported, Strings.LPROC_RasterNotSupported)); return set.GetAllIssues(); //all she wrote } if (loadProc.Type == LoadType.Sdf) { set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LoadProcedure_Sdf2OptionsNotSupported, Strings.LPROC_Sdf2OptionsNotSupported)); set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LoadProcedure_GeneralizationNotSupported, Strings.LPROC_GeneralizationNotSupported)); } if (loadProc.Type == LoadType.Shp) { set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LoadProcedure_ConvertToSdf3NotSupported, Strings.LPROC_ConvertToSdf3NotSupported)); set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LoadProcedure_GeneralizationNotSupported, Strings.LPROC_GeneralizationNotSupported)); } if (loadProc.Type == LoadType.Sqlite) { set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LoadProcedure_GeneralizationNotSupported, Strings.LPROC_GeneralizationNotSupported)); } var fproc = loadProc as IBaseLoadProcedure; if (fproc != null) { foreach (var fn in fproc.SourceFile) { if (!System.IO.File.Exists(fn)) { set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LoadProcedure_SourceFileNotFound, string.Format(Strings.LPROC_SourceFileNotFound, fn))); } } } context.MarkValidated(resource.ResourceID); return set.GetAllIssues(); }
/// <summary> /// Perform base validation logic /// </summary> /// <param name="context"></param> /// <param name="resource"></param> /// <param name="recurse"></param> /// <returns></returns> protected ValidationIssue[] ValidateBase(ResourceValidationContext context, IResource resource, bool recurse) { Check.ArgumentNotNull(context, nameof(context)); if (context.IsAlreadyValidated(resource.ResourceID)) { return(null); } var ldef = resource as ILayerDefinition; var vldef = ldef.SubLayer as IVectorLayerDefinition; var gldef = ldef.SubLayer as IRasterLayerDefinition; var dldef = ldef.SubLayer as IDrawingLayerDefinition; List <ValidationIssue> issues = new List <ValidationIssue>(); if (ldef.SubLayer == null) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_LayerNull, Strings.LDF_LayerNullError)); } ClassDefinition cls = null; if (vldef != null || gldef != null) { //Load referenced feature source IFeatureSource fs = null; try { fs = (IFeatureSource)context.GetResource(ldef.SubLayer.ResourceId); } catch (Exception) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_FeatureSourceLoadError, string.Format(Strings.LDF_FeatureSourceLoadError))); } if (fs != null) { //Verify specified feature class and geometry check out try { string qualClassName = vldef == null ? gldef.FeatureName : vldef.FeatureName; string geometry = vldef == null ? gldef.Geometry : vldef.Geometry; bool foundSchema = false; bool foundGeometry = false; cls = this.Connection.FeatureService.GetClassDefinition(fs.ResourceID, qualClassName); if (cls != null) { foundSchema = true; foreach (PropertyDefinition col in cls.Properties) { if (col.Name == geometry) { foundGeometry = true; break; } } if (vldef != null && vldef.PropertyMapping != null) { foreach (INameStringPair s in vldef.PropertyMapping) { bool found = false; foreach (PropertyDefinition col in cls.Properties) { if (col.Name == s.Name) { found = true; break; } } if (!found) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_InvalidPropertyMapping, string.Format(Strings.LDF_InvalidPropertyMapping, s.Name, qualClassName))); } } } } if (!foundSchema) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_ClassNotFound, string.Format(Strings.LDF_SchemaMissingError, qualClassName, fs.ResourceID))); } else if (!foundGeometry) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_GeometryNotFound, string.Format(Strings.LDF_GeometryMissingError, geometry, qualClassName, fs.ResourceID))); } } catch (Exception ex) { issues.Add(new ValidationIssue(fs, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_Generic, string.Format(Strings.LDF_SchemaAndColumnReadFailedError, ex.ToString()))); } if (recurse) { issues.AddRange(ResourceValidatorSet.Validate(context, fs, recurse)); } } } if (vldef != null) { if (string.IsNullOrEmpty(vldef.FeatureName)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_MissingFeatureName, Strings.LDF_MissingFeatureSourceError)); } if (string.IsNullOrEmpty(vldef.Geometry)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_MissingGeometry, Strings.LDF_MissingGeometryError)); } if (vldef.VectorScaleRange == null || !vldef.HasVectorScaleRanges()) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_MissingScaleRanges, Strings.LDF_MissingScaleRangesError)); } else { //Test for overlapping scale ranges List <KeyValuePair <double, double> > ranges = new List <KeyValuePair <double, double> >(); foreach (IVectorScaleRange vsr in vldef.VectorScaleRange) { IVectorScaleRange2 vsr2 = vsr as IVectorScaleRange2; if (vsr2 != null) { var area = vsr2.AreaStyle; var line = vsr2.LineStyle; var point = vsr2.PointStyle; if (vsr2.CompositeStyleCount > 0 && (area != null || line != null || point != null)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LayerDefinition_CompositeStyleDefinedAlongsideBasicStyle, string.Format( Strings.LDF_CompositeStyleDefinedAlongsideBasicStyle, vsr2.MinScale.HasValue ? vsr2.MinScale.Value : 0, vsr2.MaxScale.HasValue ? vsr2.MaxScale.Value.ToString() : Strings.Infinity))); } if (vsr2.CompositeStyleCount > 0) { foreach (var cs in vsr2.CompositeStyle) { foreach (var cr in cs.CompositeRule) { if (cr.CompositeSymbolization != null) { foreach (var si in cr.CompositeSymbolization.SymbolInstance) { //verify that symbol references point to valid symbol definitions if (si.Reference.Type == SymbolInstanceType.Reference) { var symRef = (ISymbolInstanceReferenceLibrary)si.Reference; if (!context.ResourceExists(symRef.ResourceId)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_SymbolDefintionReferenceNotFound, string.Format( Strings.LDF_SymbolDefintionReferenceNotFound, symRef.ResourceId))); } if (cls != null) { //warn if the symbol definition has usage contexts that are irrelevant against the layer's feature source var prop = cls.FindProperty(vldef.Geometry) as GeometricPropertyDefinition; if (prop != null) { var gtypes = new List <FeatureGeometricType>(prop.GetIndividualGeometricTypes()); var sym = context.GetResource(symRef.ResourceId) as ISimpleSymbolDefinition; if (sym != null) { if (sym.LineUsage != null && !gtypes.Contains(FeatureGeometricType.Curve)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Information, ValidationStatusCode.Info_LayerDefinition_IrrelevantUsageContext, string.Format( Strings.LDF_IrrelevantUsageContext, symRef.ResourceId, FeatureGeometricType.Curve.ToString()))); } if (sym.AreaUsage != null && !gtypes.Contains(FeatureGeometricType.Surface)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Information, ValidationStatusCode.Info_LayerDefinition_IrrelevantUsageContext, string.Format( Strings.LDF_IrrelevantUsageContext, symRef.ResourceId, FeatureGeometricType.Surface.ToString()))); } if (sym.PointUsage != null && !gtypes.Contains(FeatureGeometricType.Point)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Information, ValidationStatusCode.Info_LayerDefinition_IrrelevantUsageContext, string.Format( Strings.LDF_IrrelevantUsageContext, symRef.ResourceId, FeatureGeometricType.Point.ToString()))); } } } } } //verify that the overrides specified are for symbol parameters that actually exist if (si.ParameterOverrides.Count > 0) { if (si.Reference.Type == SymbolInstanceType.Reference) { var symRef = (ISymbolInstanceReferenceLibrary)si.Reference; var sym = (ISymbolDefinitionBase)context.GetResource(symRef.ResourceId); var paramList = new Dictionary <string, IParameter>(); foreach (var p in sym.GetParameters()) { paramList[p.Identifier] = p; } foreach (var ov in si.ParameterOverrides.Override) { if (!paramList.ContainsKey(ov.ParameterIdentifier)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LayerDefinition_SymbolParameterOverrideToNonExistentParameter, string.Format( Strings.LDF_SymbolParameterOverrideToNonExistentParameter, symRef.ResourceId, ov.ParameterIdentifier))); } } } } } } } } } } ranges.Add(new KeyValuePair <double, double>( vsr.MaxScale.HasValue ? vsr.MaxScale.Value : double.PositiveInfinity, vsr.MinScale.HasValue ? vsr.MinScale.Value : double.NegativeInfinity)); } double min = double.PositiveInfinity; double max = double.NegativeInfinity; foreach (KeyValuePair <double, double> sr in ranges) { min = Math.Min(min, sr.Value); max = Math.Max(max, sr.Key); if (sr.Key < sr.Value) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_MinMaxScaleSwapped, string.Format(Strings.LDF_MinAndMaxScaleSwappedError, sr.Value, sr.Key))); } } ranges.Sort(CompareScales); //TODO: Detect gaps in scale ranges for (int i = 0; i < ranges.Count; i++) { for (int j = i + 1; j < ranges.Count; j++) { if (ranges[i].Key > ranges[j].Value || ranges[i].Value > ranges[j].Value) { issues.Add(new ValidationIssue(resource, ValidationStatus.Information, ValidationStatusCode.Info_LayerDefinition_ScaleRangeOverlap, string.Format(Strings.LDF_ScaleRangesOverlapInformation, ranges[i].Value, ranges[i].Key, ranges[j].Value, ranges[j].Key))); } } } } } else if (gldef != null) { if (string.IsNullOrEmpty(gldef.FeatureName)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_MissingFeatureName, Strings.LDF_MissingFeatureSourceError)); } if (string.IsNullOrEmpty(gldef.Geometry)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_MissingGeometry, Strings.LDF_MissingGeometryError)); } if (gldef.GridScaleRange == null || gldef.GridScaleRangeCount == 0) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_NoGridScaleRanges, Strings.LDF_MissingScaleRangesError)); } else if (gldef.GridScaleRangeCount != 1) { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LayerDefinition_MultipleGridScaleRanges, Strings.LDF_MultipleScaleRangesWarning)); } } else if (dldef != null) { IDrawingSource dws = null; try { dws = (IDrawingSource)context.GetResource(dldef.ResourceId); } catch (Exception) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_DrawingSourceError, Strings.LDF_DrawingSourceError)); } if (dws != null) { if (Array.IndexOf(this.Connection.Capabilities.SupportedServices, (int)ServiceType.Drawing) >= 0) { var dwSvc = (IDrawingService)this.Connection.GetService((int)ServiceType.Drawing); //Check if specified section exists var shtList = dwSvc.EnumerateDrawingSections(dws.ResourceID); DrawingSectionListSection sheet = null; foreach (var sht in shtList.Section) { if (sht.Name.Equals(dldef.Sheet)) { sheet = sht; break; } } if (sheet == null) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_DrawingSourceSheetNotFound, string.Format(Strings.LDF_SheetNotFound, dldef.Sheet))); } else { //null or empty filter means all layers, in that case do nothing if (!string.IsNullOrEmpty(dldef.LayerFilter)) { //Check if specified layers all exist in specified section var specifiedLayers = dldef.LayerFilter.Split(','); //NOXLATE var dwLayers = new Dictionary <string, string>(); var shtLayers = dwSvc.EnumerateDrawingLayers(dws.ResourceID, sheet.Name); foreach (var sl in shtLayers) { dwLayers.Add(sl, sl); } foreach (var sl in specifiedLayers) { if (!dwLayers.ContainsKey(sl.Trim())) { issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_DrawingSourceSheetLayerNotFound, string.Format(Strings.LDF_SheetLayerNotFound, sl.Trim(), sheet.Name))); } } } } } if (recurse) { issues.AddRange(ResourceValidatorSet.Validate(context, dws, recurse)); } } } else { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_LayerDefinition_UnsupportedLayerType, Strings.LDF_UnsupportedLayerTypeWarning)); } context.MarkValidated(resource.ResourceID); return(issues.ToArray()); }
/// <summary> /// Validats the specified resources for common issues associated with this /// resource type /// </summary> /// <param name="context"></param> /// <param name="resource"></param> /// <param name="recurse"></param> /// <returns></returns> public ValidationIssue[] Validate(ResourceValidationContext context, IResource resource, bool recurse) { Check.NotNull(context, "context"); //NOXLATE if (context.IsAlreadyValidated(resource.ResourceID)) return null; if (resource.ResourceType != ResourceTypes.FeatureSource) return null; List<ValidationIssue> issues = new List<ValidationIssue>(); IFeatureSource feature = (IFeatureSource)resource; IFeatureService featSvc = feature.CurrentConnection.FeatureService; //Feature Join Optimization check foreach (var ext in feature.Extension) { foreach (var rel in ext.AttributeRelate) { if (string.IsNullOrEmpty(rel.Name)) { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_EmptyJoinPrefix, string.Format(Strings.FS_EmptyJoinPrefix, ext.Name))); } if (rel.RelatePropertyCount > 0) { if (rel.RelatePropertyCount == 1) { var srcFs = feature; var dstFs = (IFeatureSource)context.GetResource(rel.ResourceId); var leftProvider = srcFs.Provider.ToUpper(); var rightProvider = dstFs.Provider.ToUpper(); //FDO Join optimization check if (leftProvider.Contains("OSGEO.SQLITE") && rightProvider.Contains("OSGEO.SQLITE") && srcFs.ResourceID == rel.ResourceId) //NOXLATE continue; //FDO Join optimization check if (leftProvider.Contains("OSGEO.SQLSERVERSPATIAL") && rightProvider.Contains("OSGEO.SQLSERVERSPATIAL") && srcFs.ResourceID == rel.ResourceId) //NOXLATE continue; //TODO: Fix the capabilities response. Because it's not telling us enough information! //Anyways, these are the providers known to provide sorted query results. bool bLeftSortable = leftProvider.Contains("OSGEO.SDF") || //NOXLATE leftProvider.Contains("OSGEO.SHP") || //NOXLATE leftProvider.Contains("OSGEO.SQLITE") || //NOXLATE leftProvider.Contains("OSGEO.ODBC") || //NOXLATE leftProvider.Contains("OSGEO.SQLSERVERSPATIAL") || //NOXLATE leftProvider.Contains("OSGEO.MYSQL") || //NOXLATE leftProvider.Contains("OSGEO.POSTGRESQL"); //NOXLATE bool bRightSortable = leftProvider.Contains("OSGEO.SDF") || //NOXLATE leftProvider.Contains("OSGEO.SHP") || //NOXLATE leftProvider.Contains("OSGEO.SQLITE") || //NOXLATE leftProvider.Contains("OSGEO.ODBC") || //NOXLATE leftProvider.Contains("OSGEO.SQLSERVERSPATIAL") || //NOXLATE leftProvider.Contains("OSGEO.MYSQL") || //NOXLATE leftProvider.Contains("OSGEO.POSTGRESQL"); //NOXLATE if (!bLeftSortable || !bRightSortable) { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_Potential_Bad_Join_Performance, string.Format(Strings.FS_PotentialBadJoinPerformance, ext.Name, bLeftSortable, bRightSortable))); } } else { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_Potential_Bad_Join_Performance, string.Format(Strings.FS_PotentialBadJoinPerformance2, ext.Name))); } } } } //Plaintext credential check string providerNameUpper = feature.Provider.ToUpper(); string fsXml = feature.Serialize().ToUpper(); //You'll get warnings either way if (providerNameUpper == "OSGEO.SQLSERVERSPATIAL" || //NOXLATE providerNameUpper == "OSGEO.MYSQL" || //NOXLATE providerNameUpper == "OSGEO.POSTGRESQL" || //NOXLATE providerNameUpper == "OSGEO.ARCSDE" || //NOXLATE providerNameUpper == "OSGEO.WFS" || //NOXLATE providerNameUpper == "OSGEO.WMS" || //NOXLATE providerNameUpper == "KING.ORACLE" || //NOXLATE providerNameUpper == "AUTODESK.ORACLE") //NOXLATE { //Fortunately, all the above providers are universal in the naming choice of credential connection parameters if ((fsXml.Contains("<NAME>USERNAME</NAME>") && !fsXml.Contains(StringConstants.MgUsernamePlaceholder)) || (fsXml.Contains("<NAME>PASSWORD</NAME>") && !fsXml.Contains(StringConstants.MgPasswordPlaceholder))) //NOXLATE issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_Plaintext_Credentials, Strings.FS_PlaintextCredentials)); else issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_Cannot_Package_Secured_Credentials, Strings.FS_CannotPackageSecuredCredentials)); //Has the placeholder token(s) if (fsXml.Contains(StringConstants.MgUsernamePlaceholder) || fsXml.Contains(StringConstants.MgPasswordPlaceholder)) { //Find the MG_USER_CREDENTIALS resource data item bool bFound = false; var resData = feature.EnumerateResourceData(); foreach (var data in resData) { if (data.Name == StringConstants.MgUserCredentialsResourceData) { bFound = true; } } if (!bFound) { issues.Add(new ValidationIssue(feature, ValidationStatus.Error, ValidationStatusCode.Error_FeatureSource_SecuredCredentialTokensWithoutSecuredCredentialData, Strings.FS_SecuredCredentialTokensWithoutSecuredCredentialData)); } } } //Note: Must be saved! string s = featSvc.TestConnection(feature.ResourceID); if (s.Trim().ToUpper() != true.ToString().ToUpper()) { issues.Add(new ValidationIssue(feature, ValidationStatus.Error, ValidationStatusCode.Error_FeatureSource_ConnectionTestFailed, string.Format(Strings.FS_ConnectionTestFailed, s))); return issues.ToArray(); } try { System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.InvariantCulture; FdoSpatialContextList lst = context.GetSpatialContexts(feature.ResourceID); if (lst == null || lst.SpatialContext == null || lst.SpatialContext.Count == 0) issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_NoSpatialContext, Strings.FS_NoSpatialContextWarning)); else foreach (FdoSpatialContextListSpatialContext c in lst.SpatialContext) if (c.Extent == null || c.Extent.LowerLeftCoordinate == null || c.Extent.UpperRightCoordinate == null) issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_EmptySpatialContext, Strings.FS_EmptySpatialContextWarning)); else if (double.Parse(c.Extent.LowerLeftCoordinate.X, ci) <= -1000000 && double.Parse(c.Extent.LowerLeftCoordinate.Y, ci) <= -1000000 && double.Parse(c.Extent.UpperRightCoordinate.X, ci) >= 1000000 && double.Parse(c.Extent.UpperRightCoordinate.Y, ci) >= 1000000) issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_DefaultSpatialContext, Strings.FS_DefaultSpatialContextWarning)); } catch (Exception ex) { string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); issues.Add(new ValidationIssue(feature, ValidationStatus.Error, ValidationStatusCode.Error_FeatureSource_SpatialContextReadError, string.Format(Strings.FS_SpatialContextReadError, msg))); } List<string> classes = new List<string>(); try { var schemaNames = featSvc.GetSchemas(feature.ResourceID); if (schemaNames.Length == 0) issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_NoSchemasFound, Strings.FS_SchemasMissingWarning)); } catch (Exception ex) { var wex = ex as System.Net.WebException; if (wex != null) //Most likely timeout due to really large schema { string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_Validation_Timeout, string.Format(Strings.FS_ValidationTimeout, msg))); } else { string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); issues.Add(new ValidationIssue(feature, ValidationStatus.Error, ValidationStatusCode.Error_FeatureSource_SchemaReadError, string.Format(Strings.FS_SchemaReadError, msg))); } } var classNames = featSvc.GetClassNames(feature.ResourceID, null); foreach (var className in classNames) { try { string[] idProps = featSvc.GetIdentityProperties(feature.ResourceID, className); if (idProps.Length == 0) issues.Add(new ValidationIssue(feature, ValidationStatus.Information, ValidationStatusCode.Info_FeatureSource_NoPrimaryKey, string.Format(Strings.FS_PrimaryKeyMissingInformation, className))); } catch (Exception ex) { string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); //#1403 workaround if (msg.Contains("MgClassNotFound")) //NOXLATE issues.Add(new ValidationIssue(feature, ValidationStatus.Information, ValidationStatusCode.Info_FeatureSource_NoPrimaryKey, string.Format(Strings.FS_PrimaryKeyMissingInformation, className))); else issues.Add(new ValidationIssue(feature, ValidationStatus.Error, ValidationStatusCode.Error_FeatureSource_SchemaReadError, string.Format(Strings.FS_SchemaReadError, msg))); } } context.MarkValidated(resource.ResourceID); return issues.ToArray(); }
/// <summary> /// Performs base resource validation /// </summary> /// <param name="context"></param> /// <param name="resource"></param> /// <param name="recurse"></param> /// <returns></returns> protected static ValidationIssue[] ValidateBase(ResourceValidationContext context, IResource resource, bool recurse) { Check.NotNull(context, "context"); //NOXLATE if (context.IsAlreadyValidated(resource.ResourceID)) return null; if (resource.ResourceType != ResourceTypes.MapDefinition) return null; List<ValidationIssue> issues = new List<ValidationIssue>(); IMapDefinition mdef = resource as IMapDefinition; if (string.IsNullOrEmpty(mdef.CoordinateSystem)) { issues.Add(new ValidationIssue(mdef, ValidationStatus.Warning, ValidationStatusCode.Warning_MapDefinition_MissingCoordinateSystem, Strings.MDF_NoCoordinateSystem)); } foreach (IMapLayerGroup g in mdef.MapLayerGroup) { if (g.ShowInLegend && (g.LegendLabel == null || g.LegendLabel.Trim().Length == 0)) issues.Add(new ValidationIssue(mdef, ValidationStatus.Information, ValidationStatusCode.Info_MapDefinition_GroupMissingLabelInformation, string.Format(Strings.MDF_GroupMissingLabelInformation, g.Name))); else if (g.ShowInLegend && g.LegendLabel.Trim().ToLower() == "layer group") //NOXLATE issues.Add(new ValidationIssue(mdef, ValidationStatus.Information, ValidationStatusCode.Info_MapDefinition_GroupHasDefaultLabel, string.Format(Strings.MDF_GroupHasDefaultLabelInformation, g.Name))); if (!string.IsNullOrEmpty(g.Group)) { var grp = mdef.GetGroupByName(g.Group); if (grp == null) issues.Add(new ValidationIssue(mdef, ValidationStatus.Error, ValidationStatusCode.Error_MapDefinition_GroupWithNonExistentGroup, string.Format(Strings.MDF_GroupWithNonExistentGroup, g.Name, g.Group))); } } List<IBaseMapLayer> layers = new List<IBaseMapLayer>(); foreach (IBaseMapLayer l in mdef.MapLayer) layers.Add(l); if (mdef.BaseMap != null && mdef.BaseMap.HasGroups()) { if (mdef.BaseMap.ScaleCount == 0) issues.Add(new ValidationIssue(mdef, ValidationStatus.Error, ValidationStatusCode.Error_MapDefinition_NoFiniteDisplayScales, Strings.MDF_NoFiniteDisplayScalesSpecified)); foreach (IBaseMapGroup g in mdef.BaseMap.BaseMapLayerGroup) { foreach (IBaseMapLayer l in g.BaseMapLayer) layers.Add(l); } } Dictionary<string, IBaseMapLayer> nameCounter = new Dictionary<string, IBaseMapLayer>(); foreach (IBaseMapLayer l in layers) { if (nameCounter.ContainsKey(l.Name)) issues.Add(new ValidationIssue(mdef, ValidationStatus.Warning, ValidationStatusCode.Error_MapDefinition_DuplicateLayerName, string.Format(Strings.MDF_LayerNameDuplicateWarning, l.Name, l.ResourceId, nameCounter[l.Name].ResourceId))); else nameCounter.Add(l.Name, l); var ml = l as IMapLayer; if (ml != null && !string.IsNullOrEmpty(ml.Group)) { var grp = mdef.GetGroupByName(ml.Group); if (grp == null) issues.Add(new ValidationIssue(mdef, ValidationStatus.Error, ValidationStatusCode.Error_MapDefinition_LayerWithNonExistentGroup, string.Format(Strings.MDF_LayerWithNonExistentGroup, ml.Name, ml.Group))); } if (l.ShowInLegend && (string.IsNullOrEmpty(l.LegendLabel) || l.LegendLabel.Trim().Length == 0)) issues.Add(new ValidationIssue(mdef, ValidationStatus.Information, ValidationStatusCode.Warning_MapDefinition_LayerMissingLegendLabel, string.Format(Strings.MDF_LayerMissingLabelInformation, l.Name))); var mapEnv = ObjectFactory.CreateEnvelope(mdef.Extents.MinX, mdef.Extents.MinY, mdef.Extents.MaxX, mdef.Extents.MaxY); try { ILayerDefinition layer = null; IResource res = context.GetResource(l.ResourceId); if (!ResourceValidatorSet.HasValidator(res.ResourceType, res.ResourceVersion)) { //Need to trap the no registered validator message issues.AddRange(ResourceValidatorSet.Validate(context, res, true)); continue; } layer = (ILayerDefinition)res; if (recurse) { issues.AddRange(ResourceValidatorSet.Validate(context, layer, recurse)); } IVectorLayerDefinition vl = null; if (layer.SubLayer.LayerType == LayerType.Vector) vl = (IVectorLayerDefinition)layer.SubLayer; if (vl != null) { try { IFeatureSource fs = (IFeatureSource)context.GetResource(vl.ResourceId); //The layer recurses on the FeatureSource //issues.AddRange(Validation.Validate(fs, true)); try { FdoSpatialContextList scList = context.GetSpatialContexts(fs.ResourceID); if (scList.SpatialContext == null || scList.SpatialContext.Count == 0) issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_MapDefinition_MissingSpatialContext, string.Format(Strings.MDF_MissingSpatialContextWarning, fs.ResourceID))); else { if (scList.SpatialContext.Count > 1) issues.Add(new ValidationIssue(resource, ValidationStatus.Information, ValidationStatusCode.Info_MapDefinition_MultipleSpatialContexts, string.Format(Strings.MDF_MultipleSpatialContextsInformation, fs.ResourceID))); bool skipGeomCheck = false; //TODO: Switch to the correct version (2.1), once released if (scList.SpatialContext[0].CoordinateSystemWkt != mdef.CoordinateSystem) { if (layer.SubLayer.LayerType == LayerType.Raster && mdef.CurrentConnection.SiteVersion <= SiteVersions.GetVersion(OSGeo.MapGuide.MaestroAPI.KnownSiteVersions.MapGuideOS2_0_2)) issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_MapDefinition_RasterReprojection, string.Format(Strings.MDF_RasterReprojectionError, fs.ResourceID))); else issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_MapDefinition_LayerReprojection, string.Format(Strings.MDF_DataReprojectionWarning, fs.ResourceID))); skipGeomCheck = true; } if (vl.Geometry != null && !skipGeomCheck) { var env = fs.GetSpatialExtent(vl.FeatureName, vl.Geometry); if (!env.Intersects(mapEnv)) issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_MapDefinition_DataOutsideMapBounds, string.Format(Strings.MDF_DataOutsideMapWarning, fs.ResourceID))); } } } catch (Exception ex) { var nex = ex as NullExtentException; if (nex != null) { issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_MapDefinition_FeatureSourceWithNullExtent, string.Format(Strings.MDF_LayerWithNullExtent, fs.ResourceID))); } else { string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_MapDefinition_ResourceRead, string.Format(Strings.MDF_ResourceReadError, fs.ResourceID, msg))); } } } catch (Exception ex) { string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_MapDefinition_FeatureSourceRead, string.Format(Strings.MDF_FeatureSourceReadError, l.ResourceId, msg))); } } } catch (Exception ex) { string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_MapDefinition_LayerRead, string.Format(Strings.MDF_LayerReadError, l.ResourceId, msg))); } } context.MarkValidated(resource.ResourceID); return issues.ToArray(); }
/// <summary> /// Performs any pre-save validation on the currently edited resource, by default /// this returns the results of a non-cascading <see cref="ResourceValidatorSet"/> /// validation run. Override this if you have a custom method of validation. /// </summary> protected virtual ICollection<ValidationIssue> ValidateEditedResource() { var context = new ResourceValidationContext(_svc.ResourceService, _svc.FeatureService); //Don't recurse as we only want to validate the current resource var issues = ResourceValidatorSet.Validate(context, this.Resource, false); var set = new ValidationResultSet(issues); var errors = set.GetIssuesForResource(this.Resource.ResourceID, ValidationStatus.Error); return errors; }