Voters are used in Magnolia whenever configuration values are not assigned at startup but instead depend on rules. The rules are user-defined using voter classes which evaluate established criteria by determining true or false of each rule.

Voters are currently used for:

  • Filter configuration: uses voters to determine whether a filter should be executed or bypassed.
  • Cache configuration: uses voters to determine whether a file should be cached or not.
  • Personalization: uses voters to determine whether a user should be served a targeted content. 

The rules to determine values should be configurable and discrete.

Voting mechanism

For example, the Cache module has to determine if a requested resource may be cached or not. There may be a series of voters that feel responsible for casting a vote on that decision. The winner of a "voting round" is based on the concept of highest according to absolute value. 

Basic concept

Voters are classes which calculate an int vote value, where positive (1, 2, 3, ...) results are treated as "yes" or "true" and (0, -1, -2, ...) results are treated as "no" or "false". If you have a set of voters, then the result of a voting is the largest absolute result. If there are two voters with the same absolute result, then the one with the higher positive value will be taken.

Examples of voting decisions:

SetVoteOutcome Description
-3, 0, 2-3The result of this voting round is a strong negative vote. Since the absolute value of 3 is greater than 2, then the negative, or false vote, is casted. 
-3, 0, 33In this case, the absolute value for the negative side and positive side have the same weight so the end result is to cast a positive, or true, vote. The default is to lean positive in the case of a tie vote.
-3, 0, 44The result of this voting round is a strong positive vote. A vote of true is casted.

Configuration

The way voters are configured can vary based on the use case. One common use case for voters is as part of a filter configuration. Since filters can be costly to execute you can save precious execution time by configuring a bypass to be checked prior to running the filter. Any filter which extends AbstractMgnlFilter can have a set of Voter bypasses configured. Each bypass is checked in the same order in which they are defined, top-down. 

In the above example we see three bypasses configured on the registration filter. In this case the filter uses the URIPatternVoter for each bypass. We want the system to allow these resource requests to bypass this filter as it does not apply for the registration process. The resources are for the registration form itself. 

Voters package

Most of Magnolia's voter classes can be found in the core module in the package info.magnolia.voting.votes. Using one or more of these voters you can create simple or complex configurations which change the behavior of the product.

Voting arrays can also be nested creating complex decision trees

Interfaces

All voter classes should implement the Voter interface. The Voting interface provides a bases for working with multiple voters.  Some classes extend from abstract base classes which provide default configuration for other voter classes.

Voter

interfaceinfo.magnolia.voting.voters.Voter

All voter classes by implement the Voter interface. 

The individual votes can then be operated on using Boolean logic. The Voter interface requires that you implement a vote() method which takes in the object T and return int. These boolean voters return "1" for a "true" and "0" for a "false" result. 

Voting

interfaceinfo.magnolia.voting.Voting

The Voting interface is for dealing with sets of voters. Options are AND, OR, HIGHEST_LEVEL voting.

Abstract classes

Some voter classes extend from abstract base classes which provide default configurations.

BaseVoterImpl 

abstract classinfo.magnolia.voting.voters.BaseVoterImpl implements Voter

BaseVoterImpl is the abstract voter that all other voters should extend from. It provides common properties for most other voters.

Properties:

name

optional

Either the node name itself or the value of this property.

enabled

optional

Enable or disable the any property which extends this class.

AbstractBoolVoter

abstract classinfo.magnolia.voting.voters.AbstractBoolVoter extends BaseVoterImpl

AbstractBoolVoter is used to create boolean voters which can't return integer values. You can steer the returned values by setting the trueValue and falseValue. Classes extending this class should override the boolVote() method. 

Properties:

falseValue

optional ,  defaults to 0

What is the value that should be returned for a false vote.

trueValue

optional ,  defaults to 1

What is the value that should be returned for a false vote.

not

optional

Negate the final result of the vote() method.

if (not) outcome = -outcome;
level

optional

The weight of the vote in terms of int.

BasePatternVoter

abstract classinfo.magnolia.voting.voters.BasePatterVoter extends AbstractBoolVoter

BasePatternVoter uses URLs to match against the pattern. The returned vote is the length of the pattern. This allows oversteering less precise votes (like allow /something/* but deny /somthing/otherthing/*). You can use the inverse property which will then return the negative value on a match. This is not the same thing as using the not property which will then vote if the pattern does not match at all.

BasePatternVoter implementations are typed to <Object> because they can work with String value, but will otherwise use the ThreadLocal context and its AggregationState. Finally, it will use a given HttpServletRequest value.

Properties:

pattern

required

The pattern to be matched with the current URI.

inverse

optional

Returns the negative value of the length of the pattern

AbstractRequestHeaderPatternVoter

abstract classinfo.magnolia.voting.voters.AbstractRequestHeaderPatternVoter extends AbstractBoolVoter

AbstractRequestHeaderPatternVoter is used to match the request headers against a pattern.

Properties:

headerName

required

The name of the header to be matched.

Definition classes

These classes are provided in the core module and can be used out of the box. Most voters extend from BaseVoterImpl either directly or indirectly. When dealing with a set of voters then it's typical to implement the Voting interface. 

AndVoting

classinfo.magnolia.voting.voters.AndVoting implements Voting

AndVoting returns the maximum vote, but only if all voters voted positive. 

AuthenticatedVoter

classinfo.magnolia.voting.voters.AuthenticatedVoter extends AbstractBoolVoter

AuthenticatedVoter checks if the current user is authenticated. Does not vote on the passed object.

BoolVoterSet

classinfo.magnolia.voting.voters.BoolVoterSet extends AbstractBoolVoter

BoolVoterSet combines a set of other voters based on a given logical operation. It's backed by VoterSet, but boolean-aware. In particular, this means that the "not" flag is handled correctly.

DefaultVoting

classinfo.magnolia.voting.DefaultVoting implements Voting

This voter has DEBUG capabilities. Use the Log Tools app to turn on debugging.

DefaultVoting returns the highest vote in the set of voters. The voting can return 0 if no voter casts a meaningful vote.

DomainNameRegexVoter

classinfo.magnolia.voting.voters.DomainNameRegexVoter extends AbstractBoolVoter

DomainNameRegexVoter determines if the request has domain that matches configured regex. Typed to Object, as it can vote on both a passed HttpServletRequest, or the current context (i.e. WebContext) if any.

Properties:

domain

required

regular expression to match the requested domain against. 

ExtensionVoter

classinfo.magnolia.voting.voters.ExtensionVoter extends AbstractBoolVoter

Typed to Object, as it can vote on a passed String. If a String is not passed then it votes on the extension found in the AggregationState.

ExtensionVoter returns:

  • false if the extension is not a valid mimetype (as configured in config:/server/MIMEMapping).
  • false  if the allow list exists, but the extension is not  in the allow list.
  • false  if the deny list exists and the extension is in the deny list.
  • true  otherwise

Properties:

allow

optional

A comma separated lists of allowed extensions.

deny

optional

A comma separated lists of denied extensions.

FalseVoter

classinfo.magnolia.voting.voters.FalseVoter extends AbstractBoolVoter

FalseVoter simply returns false.

ForwardVoter

classinfo.magnolia.voting.voters.ForwardVoter extends AbstractBoolVoter

ForwardVoter returns true if the request has been forwarded. It works by checking to see if the FORWARD_REQUEST_URI attribute is not null.

IfVoter

classinfo.magnolia.voting.voters.IfVoter

This voter has DEBUG capabilities. Use the Log Tools app to turn on debugging.

Conditional voter. If the "condition" voter is positive, returns the "then" voter's value, otherwise returns the "otherwise" voter's value.

Properties:

condition

required

The Voter configuration to base the initial decision path.

then

required

The Voter configuration to be used if condition is true.

otherwise

required

The Voter configuration to be used if condition is false.

InverseVoter

classinfo.magnolia.voting.voters.InverseVoter

InverseVoter is a voter wrapper. It calls the vote() method of the wrapped voter and multiplies the value by -1 (i.e. 5 * -1 --> -5)

Properties:

voter

required

The Voter configuration to be inverted.

NotVoter

classinfo.magnolia.voting.voters.NotVoter extends AbstractBoolVoter

NotVoter inverts the boolean outcome of a voter. This is not the same thing as inverting the value InverseVoter.

Properties:

voter

required

The Voter configuration to be notted.

NullVoter

classinfo.magnolia.voting.voters.NullVoter implements Voter

NullVoter always returns 0 and is disabled by default. Useful for default values.

Properties:

enabled

optional ,  defaults to false

Enable or disable the any property which extends this class.

OnAdminVoter

classinfo.magnolia.voting.voters.OnAdminVoter extends AbstractBoolVoter

OnAdminVoter checks if the admin property of the server configuration is true or false.

OrVoting

classinfo.magnolia.voting.voters.OrVoting implements Voting

OrVoting returns the first positive vote. Negative votes are ignored.

PropertyVoter

classinfo.magnolia.voting.voters.PropertyVoter extends AbstractBoolVoter

PropertyVoter checks if the named Magnolia property has the expected value.

Properties:

property

required

Configuration property set in the magnolia properties file.

value

required

Expected value to return a "1" or "true" vote.

RequestExtensionVoter

classinfo.magnolia.voting.voters.RequestExtensionVoter extends AbstractBoolVoter

RequestExtensionVoter checks the extension set in the AggregationState object against a list of allowed and/or rejected extensions.

This voter is very similar to the ExtensionVoter with two exceptions. They are configured differently and RequestExtensionVoter can only vote against the AggregationState object. Meaning, that you cannot pass any objects to RequestExtensionVoter.

Properties:

allowed

optional

A List object of allowed extensions.

rejected

optional

A List object of rejected extensions.

RequestHasParametersVoter

classinfo.magnolia.voting.voters.RequestHasParametersVoter extends AbstractBoolVoter

RequestHasParametersVoter checks if the request used the "POST" method or if there are request parameters. Typed to Object, as it can vote on both a passed HttpServletRequest, or the current context (i.e. WebContext) if any.

RequestHeaderPatternRegexVoter

classinfo.magnolia.voting.voters.RequestHeaderRegexVoter extends AbstractRequestHeaderPatternVoter

RequestHeaderPatternRegexVoter takes a plain regex pattern which is matched against the specified request (configured in the headerName property).

Properties:

pattern

required

regular expression to match the header against. 

RequestHeaderPatternSimpleVoter

classinfo.magnolia.voting.voters.RequestHeaderPatternSimpleVoter extends AbstractRequestHeaderPatternVoter

RequestHeaderPatternSimpleVoter checks if the specified request header matches a simple url pattern (SimpleUrlPattern).

RequestParameterVoter

classinfo.magnolia.voting.voters.RequestParameterVoter extends AbstractBoolVoter

RequestHeaderPatternSimpleVoter checks for a specific GET and POST parameter and an optional value. If no value is specified the voter just checks for the existence of the parameter no matter what value is set.

Properties:

parameterName

required

The name of the parameter to be checked. 

parameterValue

optional

The expected value of the parameter for a true vote.

RoleBaseVoter

classinfo.magnolia.voting.voters.RoleBaseVoter extends AbstractBoolVoter

RoleBaseVoter checks if the current user has access permissions by comparing user roles and configured roles. The configured roles can be allowed or denied.

roles

required

A list or roles to compare against. 

SystemOrAdminUserVoter

classinfo.magnolia.voting.voters.SystemOrAdminUserVoter extends AbstractBoolVoter

SystemOrAdminUserVoter checks if the current user is a system or admin user by checking the user's Realm.

TrueVoter

classinfo.magnolia.voting.voters.TrueVoter extends AbstractBoolVoter

TrueVoter extends AbstractBoolVoter which simply returns true.

URIPatternVoter

classinfo.magnolia.voting.voters.URIPatternVoter extends BasePatternVoter

URIPatternVoter checks if URI matches the pattern.

URIRegexVoter

classinfo.magnolia.voting.voters.URIRegexVoter extends BasePatternVoter

URIRegexVoter extends BasePatternVoter and uses the pattern to match against the current URI in the AggregationState.

URIStartsWithVoter

classinfo.magnolia.voting.voters.URIStartsWithVoter extends BasePatternVoter

URIStartsWithVoter extends BasePatternVoter and checks if the URI starts with the given pattern.

UserAgentVoter

classinfo.magnolia.voting.voters.UserAgentVoter extends AbstractBoolVoter

UserAgentVoter extends AbstractBoolVoter and checks the user agent header in request object against a list of allowed and/or rejected user agents. Typed to Object, as it can vote on both a passed HttpServletRequest, or the current context, if any. Checks if the URI starts with the given pattern.

Properties:

allowed

optional

A sub-configuration which holds a list of String properties for whitelisting user agents. The names of the child properties is arbitrary.

rejected

optional

A sub-configuration which holds a list of String properties for blacklisting user agents. The names of the child properties is arbitrary.

VoterSet

classinfo.magnolia.voting.voters.VoterSet  extends BaseVoterImpl

VoterSet implements the Voting interface and takes a set of voters. The voting can be set as well as the returned level. If the level is not set (0) the votings result is returned.

Properties:

level

optional

The level corresponds to the "weight" or "importance" of the vote. Some votes might carry more weight in the voting process. 

op

optional

Operation to be performed. Options are AND, OR, HIGHEST_LEVEL voting.

not

optional

Negate the final result of the vote() method. See here.

if (not) outcome = -outcome;
#trackbackRdf ($trackbackUtils.getContentIdentifier($page) $page.title $trackbackUtils.getPingUrl($page))