Wednesday, September 2, 2009

ModelArtifactState Xaf Power to the people

Yesterday i was speaking with my friend John Pouliezos and he asked me how to the implement the following  scenario. John has managed to provide a xaf application as a SharePoint feature. Cool eh? What he wanted is the following: for specific User roles to be able to filter a specific web listview by parsing the current browser url.

Step1 : for specific User roles to be able to filter a specific web listivew

Aha sounds like ModelArtifactState’s job a lot. Cause that module is able to enable or disable behaviours /controllers (doing something) using permissions or the model. We are going to use permissions for this one

So no code is needed for step1 ModelAsrtifactState module is going to help us.

Step 2: John explain to me the urls are going to be like
http://domainName/something/stringtofilterupon/something
or
http://domainName/stringtofilterupon/something or
http://domainName/something/something/stringtofilterupon

So how can we model using permissions that?

Easy :)

We create a permission that inherits eXpand.ExpressApp.ModelArtifactState.Security.Permissions.ControllerStateRulePermission and add one property to define the regex after which we can match the filter that we are interested in and one property to tell to which propertypath to apply that filter.

[NonPersistent]
public class SharePointFilteringPermission:ControllerStateRulePermission
{
    public SharePointFilteringPermission(){
        ControllerType = typeof (SharePointFilterViewController).FullName;
        NormalCriteria = "1=1";
        EmptyCriteria = "1=1";
        ViewType=ViewType.ListView;
    }

    public override IPermission Copy(){
        return new SharePointFilteringPermission();
    }

    public string Regex { get; set; }

    public string PropertyPath { get; set; }
}

Step 3: As you saw in the previous step i have already setup my criteria properties in the constructor and by doing that I told ModelArtifactState module to enable the controller . Then using the model layout editor remove State, Module, ControllerType, NormalCriteria, EmtyCriteria ,ViewType, Nesting properties so hopefully you could end like

image

and next time we assign a permission to a role our permission detail view will be more SharePoint focused

image image

I have also assumed that the regex http://[^/]*/[^/]*/([^/]*) will match the 1st capturing group found (that is the one inside the parenthesis)

Step 4: So up to now we have manage to enable a disabled controller for a role,viewid,objecttype combination what is left is to write that controller .

public partial class SharePointFilterViewController : ViewController
{
    public SharePointFilterViewController()
    {
        InitializeComponent();
        RegisterActions(components);
    }
    protected override void OnFrameAssigned()
    {
        base.OnFrameAssigned();
        Frame.GetController<ArtifactStateCustomizationViewController>().ArtifactStateCustomized+=OnArtifactStateCustomized;
        Active[ArtifactStateCustomizationViewController.ActiveObjectTypeHasRules] = false;
    }

    private void OnArtifactStateCustomized(object sender, ArtifactStateInfoCustomizedEventArgs args){
        if (args.ArtifactStateInfo.Active){
            var sharePointFilteringPermission = ((SharePointFilteringPermission) args.ArtifactStateInfo.Rule.ArtifactRule);
            ((ListView) args.ArtifactStateInfo.View).CollectionSource.Criteria["SharePointCriteria"] =
                CriteriaOperator.Parse(sharePointFilteringPermission.PropertyPath + "=?",
                                       getValueFromQueryString(sharePointFilteringPermission.Regex));
        }
    }

    private object getValueFromQueryString(string regex){
        var input = new Uri(@"http://domainName/something/stringtofilterupon/something").ToString(); //this is for testing purposes
        // use HttpContext.Current.Request.Url instead line above
        return new Regex(regex).Match(input).Groups[0].Value;
    }
}

You see what I have done here? First I disable the controller in the same context as ArtifactStateModule operates then I attach to ArtifactStateCustomized event and only when that is fired for activating the controller I use the info provided to me by the event arguments to filtler my collection

ModelArtifactState module can be found as part of eXpand at http://code.google.com/p/expandframework/

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

0 comments:

Post a Comment