New Posts New Posts RSS Feed: Cross-Type Verifiers
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

Cross-Type Verifiers

 Post Reply Post Reply
Author
jbelci View Drop Down
Newbie
Newbie
Avatar

Joined: 09-Oct-2011
Location: Perth
Posts: 5
Post Options Post Options   Quote jbelci Quote  Post ReplyReply Direct Link To This Post Topic: Cross-Type Verifiers
    Posted: 10-Oct-2011 at 7:44pm
Hi Guys

I have been trying to implement cross type verifiers, followng the examples from http://drc.ideablade.com/xwiki/bin/view/Documentation/validation%2Dcreate%2Dcustom%2Dverifier.  My first try worked fine, but i am now having some issues with a second object structure i am trying to implement it on.

I have 2 object types in my graph, these are Person and PersonPosition. The person position is a collection of positions the person held while employed by a company, each of these has a start and end date.

i,e,
Person
      PersonPositions (enumerable list of person position)
           StartDate (propery of person position)
           EndDate (propery of person position)

The business rule i am trying to implement is that none of the person positions' dates can overlap with other positions. I can do this in the person position object and it works reasonably well (shows that the position i just edited has an error), however when one of the dates is chaged, i want all the person positions to run validation to check against the other positions. This is so i can show the user all positions that have overlapping dates.

I tried to implement this at the person object level using the code below. it compiles and runs fine, but cant seem to get the triggers to fire. I am hoping its something small i am doing wrong.

///<summary>Get the PersonPosition Verifier.</summary>
            private static Verifier GetPersonPositionVerifier()
            {
                string description =
                  "Position dates must not overlap";
                DelegateVerifier<Person> v = new DelegateVerifier<Person>(description, PersonPositionValidCondition);

                v.VerifierOptions.ExecutionModes =VerifierExecutionModes.InstanceAndOnAfterSetTriggers;

                TriggerItem startDateTriggerItem = new TriggerItem(typeof(PersonPosition), PersonPosition.PathFor(e => e.StartDate));
                TriggerLink startDateTriggerLink = new TriggerLink(startDateTriggerItem, GetPositionsAssociatedWithPerson, true);
                v.AddTrigger(startDateTriggerLink);

                TriggerItem endDateTriggerItem = new TriggerItem(typeof(PersonPosition), PersonPosition.PathFor(e => e.EndDate));
                TriggerLink endDateTriggerLink = new TriggerLink(endDateTriggerItem, GetPositionsAssociatedWithPerson, true);

                v.AddTrigger(endDateTriggerLink);

                return v;
            }

            public static IEnumerable<PersonPosition> GetPositionsAssociatedWithPerson(Object person)
            {
                var aPerson = (Person)person;
                return aPerson.PersonPositions;
            }

private static VerifierResult PersonPositionValidCondition(
              Person pTarget, TriggerContext pTriggerContext,
              VerifierContext pVerifierContext)
            {

               //Do validation stuff here
            }


Any help would be greatly appriciated

regards
Jason
         
Back to Top
DenisK View Drop Down
IdeaBlade
IdeaBlade


Joined: 25-Aug-2010
Posts: 715
Post Options Post Options   Quote DenisK Quote  Post ReplyReply Direct Link To This Post Posted: 12-Oct-2011 at 1:04pm
Hi Jason;

I want to make sure I understand your business rule.

You have a Person and it has PersonPosition collections. Each PersonPosition has a StartDate and EndDate. You want to make sure that the dates do not overlap with the other PersonPosition, in other words, a Person should only hold at most 1 position (PersonPosition) at any given time within a company.

This means that you're only comparing between a Person.PersonPositions collection. This is not exactly cross type verifiers as you're only verifying one type of object, the PersonPosition type.

One suggestion is to implement something similar to this.

private static Verifier GetPersonPositionVerifier()
{
     string description = "Position dates must not overlap";
     DelegateVerifier<PersonPosition> v = 
             new DelegateVerifier<PersonPosition>(description, PersonPositionValidCondition);

     v.VerifierOptions.ExecutionModes =VerifierExecutionModes.InstanceAndOnAfterSetTriggers;
     v.AddTrigger(PersonPosition.PathFor(p => p.StartDate));
     v.AddTrigger(PersonPosition.PathFor(p => p.EndDate));                

     return v;
}

private static VerifierResult PersonPositionValidCondition
    (PersonPosition pTarget, TriggerContext pTriggerContext, VerifierContext pVerifierContext)
{

   var allPositions = pTarget.Person.PersonPositions;
   bool isOk = true;
   foreach(var aPosition in allPositions)
   {
        //insert logic to check against all other positions here
   }
   
   return VerifierResult(isOk);
}

I hope I'm on the right track here. Please do let me know if I'm not.

Back to Top
jbelci View Drop Down
Newbie
Newbie
Avatar

Joined: 09-Oct-2011
Location: Perth
Posts: 5
Post Options Post Options   Quote jbelci Quote  Post ReplyReply Direct Link To This Post Posted: 12-Oct-2011 at 5:47pm
That is exactly correct, and I have written that code above (close enough anyway) and it works fine.

The issue is that I want all overlapping PersonPosition objects to raise verification alerts when this happens, not just the one that was just edited.

Cheers
Jason

Back to Top
DenisK View Drop Down
IdeaBlade
IdeaBlade


Joined: 25-Aug-2010
Posts: 715
Post Options Post Options   Quote DenisK Quote  Post ReplyReply Direct Link To This Post Posted: 13-Oct-2011 at 11:53am
Ah I see. Then let's see if the following works. I've tested this on my machine (with Employee.Orders in NorthwindIB model) so it should.

You're actually quite close with a few changes.

 private static Verifier GetPersonPositionVerifier()
            {
                string description =
                  "Position dates must not overlap";
                DelegateVerifier<PersonPosition> v = new DelegateVerifier<
PersonPosition>(description, PersonPositionValidCondition);

                v.VerifierOptions.ExecutionModes =VerifierExecutionModes.InstanceAndOnAfterSetTriggers;

                TriggerItem startDateTriggerItem = new TriggerItem(typeof(PersonPosition), PersonPosition.PathFor(e => e.StartDate));
                TriggerLink startDateTriggerLink = new TriggerLink(startDateTriggerItem, GetPositionsAssociatedWithPerson, true);
                v.AddTrigger(startDateTriggerLink);

                TriggerItem endDateTriggerItem = new TriggerItem(typeof(PersonPosition), PersonPosition.PathFor(e => e.EndDate));
                TriggerLink endDateTriggerLink = new TriggerLink(endDateTriggerItem, GetPositionsAssociatedWithPerson, true);

                v.AddTrigger(endDateTriggerLink);

                return v;
            }

            public static IEnumerable<PersonPosition> GetPositionsAssociatedWithPerson(Object personPos)
            {
                var aPerson = ((PersonPosition)personPos).Person;
                return aPerson.PersonPositions;
            }
Back to Top
jbelci View Drop Down
Newbie
Newbie
Avatar

Joined: 09-Oct-2011
Location: Perth
Posts: 5
Post Options Post Options   Quote jbelci Quote  Post ReplyReply Direct Link To This Post Posted: 13-Oct-2011 at 7:49pm
Thank you, That worked a treat.

I was sure i tried something like that. I must have just stuffed up something somewhere.

Once again, thanks for the help and the quick responses

Jason
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down