Skip to content

Using Bindable Property Placeholders

thofrey edited this page Apr 1, 2014 · 6 revisions

Table of Contents

  1. Introduction
  2. The Problem
  3. The Solution
  4. Additional Considerations

Introduction

This article is a tutorial of how to implement BindablePropertyPlaceholders. Before I begin the tutorial, I will give an overview of my problem and how I used bindable property placeholders to solve it. I had a case where I needed multiple versions of an application to run with one mach-ii.xml Maybe I could of used application.cfc, but I'm not familiar with it so I chose the approach to start an application (module) using 'index.cfm?module=app1'.

The default event of the controller xml is an event that evaluates the module argument and executes the appropriate event in the module. When a user wants to access the secured section of the application (administrator section), the loginPlugin is executed which displays a popup with the login text argument and the user enters their userID and password. When the authentication is successful, the nextEvent specified in the loginPlugin arguments is executed which executes an event in the controller xml that evaluates the module name and executes the appropriate secured event in the module. When a user logs in, a userFacade object is created for the user. At the beginning of each authenticated event is a requiredRoles filter that checks the role permissions in the userFacade against the list of supplied roles that have permission to execute the event.

The Problem

When the userFacade doesn't exist, the user's session has timed out. The requiredRoles filter automatically informs the user that their session has timed out and redirects to the loginPlugin to display the login popup. There are two key pieces of information that are needed for this multiple module logic approach: (1) Module name and (2) login text. The loginPlugin doesn't know the login text to display because it couldn't be supplied as a loginPlugin argument because there are multiple applications involved. The events of the controller xml always needs the module name to know how to redirect the event.

The Solution

I used bindable property placeholders to tell the requiredRoles filter the moduleName and applicationText. These arguments are passed as parameters to the filter in the filters section of the module's xml. The whole premise of bindable variables is that existing properties can be passed as parameters to Mach-II modules such as plugins, filters, and listeners. Since this is the case, the properties that are to be referenced must first be declared in the properties section of the module's xml.

    <properties>
        <!-- application settings -->
        <property name="applicationTitle" value="Transportation Parking" />
        <property name="moduleName" value="Parking" />
    </properties>

    <event-filters>
        <event-filter name="RequiredRoles" type="RequiredRolesFilter">
            <!--
            for module driven applications, the applicationText and module parameters
            must also be supplied
            -->
            <parameters>
                <parameter name="application" value="${applicationTitle}" />
                <parameter name="module" value="${moduleName}" />
            </parameters>
        </event-filter>
    </event-filters>

Notice the syntax of the bindable variables, dollar sign '$' followed by left curly bracket {, followed by the name of the parameter, followed by right curly bracket }.

The code for the filter to load these arguments can be something like this:

    <!---
    INITIALIZATION / CONFIGURATION
    --->
    <cffunction name="configure" access="public" returntype="void" output="false" hint="Sets up the filter">

        <!--- Set up the userfacade property --->
        <cfset variables.UserFacade = getProperty("UserFacade") />

        <!--- assign application with multiple modules parameters (if supplied) --->
        <cfset variables.application = getParameter( "application" ) />
        <cfset variables.module = getParameter( "module" ) />
    </cffunction>

Additional Considerations

Also, you can only use bindable property placeholders for configure time parameters (parameters used when defining a filter, plugin, etc.) and cannot be used as runtime parameters (paramArgs in filters). For example, Mach-II will not bind a property for placeholders for runtime parameters in filters:

    <event-handler event="someEvent" access="public">
        <filter name="runSomeFilter">
            <parameter name="elementProperty" value="${somePropertyName}"/>
        </filter>
        ... additional commands ...
    </event-handler>

The value of elementProperty will be ${somePropertyName}. It would be better to set a "smart default" as a configure time parameter when defining the filter and use the runtime parameter to optionally override elementProperty if the smart default is not the required.

Clone this wiki locally