Esempio n. 1
0
        /// <returns>true if it has failures</returns>
        private bool ValidateZones(Facility requirement, Facility submitted, Facility retFacility)
        {
            if (requirement.Zones == null)
            {
                return(false);
            }
            var ret = false;
            // hack: create a fake modelFacility candidates from spaces.
            var fakeSubmittedFacility = new Facility();

            fakeSubmittedFacility.Floors = fakeSubmittedFacility.Clone(submitted.Floors as IEnumerable <Floor>).ToList();
            fakeSubmittedFacility.Zones  = new List <Zone>();
            var lSpaces = submitted.Get <Space>().ToList();

            foreach (var zoneRequirement in requirement.Zones)
            {
                var v = new CobieObjectValidator <Zone, Space>(zoneRequirement)
                {
                    TerminationMode = TerminationMode
                };
                if (!v.HasRequirements)
                {
                    continue;
                }

                // hack: now create a fake Zone based on candidates from spaces.
                var fakeZone = fakeSubmittedFacility.Create <Zone>();
                fakeZone.Categories     = zoneRequirement.Categories.Clone().ToList();
                fakeZone.Name           = zoneRequirement.Name;
                fakeZone.ExternalEntity = zoneRequirement.ExternalEntity;
                fakeZone.ExternalSystem = zoneRequirement.ExternalSystem;
                fakeZone.ExternalId     = zoneRequirement.ExternalId;
                fakeZone.Spaces         = new List <SpaceKey>();

                var candidateSpaces = v.GetCandidates(lSpaces).ToList();

                if (candidateSpaces.Any())
                {
                    foreach (var spaceMatch in candidateSpaces)
                    {
                        var mSpace = spaceMatch.MatchedObject as Space;
                        if (mSpace == null)
                        {
                            continue;
                        }
                        var sk = new SpaceKey {
                            Name = mSpace.Name
                        };
                        fakeZone.Spaces.Add(sk);
                    }
                    if (retFacility.Zones == null)
                    {
                        retFacility.Zones = new List <Zone>();
                    }
                    var validatedZone = v.Validate(fakeZone, retFacility);
                    retFacility.Zones.Add(validatedZone);
                    var tmpFloor = retFacility.Get <Floor>(fl => fl.Name == TemporaryFloorName).FirstOrDefault();
                    if (tmpFloor == null)
                    {
                        continue;
                    }
                    // ensure that the floor and spaces are avalialale in the report facility
                    foreach (var spaceKey in validatedZone.Spaces)
                    {
                        // 1) on the floor
                        var submissionOwningFloor =
                            submitted.Get <Floor>(f => f.Spaces != null && f.Spaces.Any(sp => sp.Name == spaceKey.Name)).FirstOrDefault();
                        if (submissionOwningFloor == null)
                        {
                            continue;
                        }
                        var destFloor = retFacility.Get <Floor>(f => f.Name == submissionOwningFloor.Name).FirstOrDefault();
                        if (destFloor == null)
                        {
                            destFloor                = retFacility.Create <Floor>();
                            destFloor.Name           = submissionOwningFloor.Name;
                            destFloor.ExternalEntity = submissionOwningFloor.ExternalEntity;
                            destFloor.ExternalId     = submissionOwningFloor.ExternalId;
                            destFloor.ExternalSystem = submissionOwningFloor.ExternalSystem;
                            destFloor.Elevation      = submissionOwningFloor.Elevation;
                            destFloor.Spaces         = new List <Space>();
                            retFacility.Floors.Add(destFloor); // finally add it in the facility tree
                        }
                        // 2) now on the space.

                        var sourceSpace = tmpFloor.Spaces.FirstOrDefault(sp => sp.Name == spaceKey.Name);
                        if (sourceSpace != null)
                        {
                            destFloor.Spaces.Add(sourceSpace);
                        }
                    }
                    retFacility.Floors.Remove(tmpFloor);
                }
                else
                {
                    if (retFacility.Zones == null)
                    {
                        retFacility.Zones = new List <Zone>();
                    }
                    retFacility.Zones.Add(v.Validate((Zone)null, retFacility));
                }
                ret |= v.HasFailures;
            }
            return(ret);
        }
        /// <param name="candidateParent">If null provides a missing match report</param>
        /// <param name="targetFacility">The target facility is required to ensure that the facility tree is properly referenced</param>
        /// <returns></returns>
        internal T Validate(T candidateParent, Facility targetFacility)
        {
            var         iSubmitted        = 0;
            var         iPassed           = 0;
            List <TSub> candidateChildren = null;
            var         returnChildren    = new List <TSub>();

            // initialisation
            var retType = targetFacility.Create <T>();

            retType.Categories = new List <Category>();
            retType.SetRequirementExternalSystem(_requirementObject.ExternalSystem);
            retType.SetRequirementExternalId(_requirementObject.ExternalId);
            retType.SetRequirementName(_requirementObject.Name);
            retType.SetRequirementCategories(_requirementObject.Categories);

            // improve returning Parent
            if (candidateParent == null) // the following properties depend on the nullity of candidate
            {
                retType.Name = _requirementObject.Name;
            }
            else
            {
                retType.Name           = candidateParent.Name;
                retType.ExternalId     = candidateParent.ExternalId;
                retType.ExternalSystem = candidateParent.ExternalSystem;
                retType.Categories     = candidateParent.Categories.Clone().ToList();
                candidateChildren      = candidateParent.GetChildObjects <TSub>();
                if (candidateChildren != null)
                {
                    iSubmitted = candidateChildren.Count;
                }
            }

            var returnWithoutFurtherTests = false;

            if (!RequirementDetails.Any())
            {
                retType.Description = "Classification has no requirements.\r\n";
                retType.Categories.Add(FacilityValidator.PassedCat);
                iPassed = iSubmitted;
                returnWithoutFurtherTests = true;
            }

            // if candidate is null then consider there's no match
            if (candidateParent == null)
            {
                // it's only a failure if the requirement was itself required (not only it had atteributes required)
                if (_requirementObject.Categories != null &&
                    _requirementObject.Categories.Any(c => c.Classification == "DPoW" && c.Code == "required")
                    )
                {
                    retType.Categories.Add(FacilityValidator.FailedCat);
                }
                else
                {
                    retType.Categories.Add(FacilityValidator.PassedCat);
                }
                retType.Description = "No candidates in submission match the required classification.\r\n";
                retType.Attributes.AddRange(RequirementAttributes());
                returnWithoutFurtherTests = true;
            }
            if (returnWithoutFurtherTests)
            {
                retType.SetSubmittedChildrenCount(iSubmitted);
                retType.SetValidChildrenCount(iPassed);
                return(retType);
            }

            // ==================== begin testing at parent level

            CachedPropertiesAndAttributesValidator <T> parentCachedValidator;

            try
            {
                parentCachedValidator = new CachedPropertiesAndAttributesValidator <T>(candidateParent);
            }
            catch (ValidationException ex)
            {
                retType.Categories.Add(FacilityValidator.FailedCat);
                retType.Description += ex.Message;
                return(retType);
            }

            if (retType.Attributes == null)
            {
                retType.Attributes = new List <Attribute>();
            }

            // produce parent level description
            var outstandingRequirementsCount = 0;



            foreach (var req in RequirementDetails)
            {
                object satValue;
                var    pass = parentCachedValidator.CanSatisfy(req, out satValue);
                var    a    = targetFacility.Clone(req.Attribute);

                // todo: determine the correct theoretical behaviour; it should probably be null, but needs changes in the reporting mechanism.
                // ReSharper disable once ConvertIfStatementToNullCoalescingExpression
                if (satValue != null)
                {
                    a.Value = AttributeValue.CreateFromObject(satValue);
                }
                else
                {
                    a.Value = AttributeValue.CreateFromObject("");
                }

                //// it was previously:
                //if (satValue is AttributeValue)
                //    a.Value = satValue as AttributeValue;
                //else
                //    a.Value = null;

                if (pass)
                {
                    a.Categories = new List <Category> {
                        FacilityValidator.PassedCat
                    };
                }
                else
                {
                    a.Categories = new List <Category> {
                        FacilityValidator.FailedCat
                    };
                    outstandingRequirementsCount++;
                }

                retType.Attributes.Add(a);
            }

            retType.Description = string.Format("{0} of {1} requirement addressed.", RequirementDetails.Count - outstandingRequirementsCount, RequirementDetails.Count);
            var anyChildFails = false;

            // ==================== begin testing at child level
            //
            if (candidateChildren != null)
            {
                foreach (var modelChild in candidateChildren)
                {
                    var iChildRequirementsMatched = 0;
                    var reportChild = targetFacility.Create <TSub>();
                    reportChild.Name       = modelChild.Name;
                    reportChild.ExternalId = modelChild.ExternalId;
                    reportChild.Categories = new List <Category>();
                    reportChild.Attributes = new List <Attribute>();

                    // child classification can be copied from model
                    //
                    if (modelChild.Categories != null)
                    {
                        reportChild.Categories.AddRange(modelChild.Categories);
                    }

                    var childCachedValidator = new CachedPropertiesAndAttributesValidator <TSub>(modelChild);
                    foreach (var req in RequirementDetails)
                    {
                        object satValue;
                        if (childCachedValidator.CanSatisfy(req, out satValue))
                        {
                            // passes locally
                            if (!parentCachedValidator.AlreadySatisfies(req))
                            {
                                iChildRequirementsMatched++;
                            }
                            var a = targetFacility.Clone(req.Attribute);
                            a.Value      = AttributeValue.CreateFromObject(satValue);
                            a.Categories = new List <Category> {
                                FacilityValidator.PassedCat
                            };
                            reportChild.Attributes.Add(a);
                        }
                        else if (!parentCachedValidator.AlreadySatisfies(req)) // fails locally, and is not passed at higher level, then add to explicit report fail
                        {
                            var a = targetFacility.Clone(req.Attribute);

                            // todo: determine the correct theoretical behaviour; it should probably be null, but needs changes in the reporting mechanism.

                            // ReSharper disable once ConvertIfStatementToNullCoalescingExpression
                            if (satValue != null)
                            {
                                a.Value = AttributeValue.CreateFromObject(satValue);
                            }
                            else
                            {
                                a.Value = AttributeValue.CreateFromObject("");
                            }


                            a.Categories = new List <Category> {
                                FacilityValidator.FailedCat
                            };
                            reportChild.Attributes.Add(a);
                        }
                    }

                    var sb = new StringBuilder();
                    sb.AppendFormat("{0} of {1} outstanding requirements addressed.", iChildRequirementsMatched, outstandingRequirementsCount);

                    var pass = (outstandingRequirementsCount == iChildRequirementsMatched);
                    if (!pass)
                    {
                        anyChildFails = true;
                        reportChild.Categories.Add(FacilityValidator.FailedCat);
                    }
                    else
                    {
                        iPassed++;
                        reportChild.Categories.Add(FacilityValidator.PassedCat);
                    }
                    reportChild.Description = sb.ToString();
                    returnChildren.Add(reportChild);
                }
            }
            retType.SetChildObjects(returnChildren);
            retType.Categories.Add(
                anyChildFails ? FacilityValidator.FailedCat : FacilityValidator.PassedCat
                );

            retType.SetSubmittedChildrenCount(iSubmitted);
            retType.SetValidChildrenCount(iPassed);
            return(retType);
        }