Product SiteDocumentation Site

6.3. Ad-hoc attributes

The best way to understand ad-hoc attributes is look how they're defined. The example below uses three attributes to define some security questions for an user.
User user = new User("john");

  user.setAttribute(new Attribute<Integer>("QuestionTotal", 2);

  // attribute for question #1
  user.setAttribute(new Attribute<String>("Question1", "What is favorite toy?"));
  user.setAttribute(new Attribute<String>("Question1Answer", "Gum"));

  // attribute for question #2
  user.setAttribute(new Attribute<String>("Question2", "What is favorite word?"));
  user.setAttribute(new Attribute<String>("Question2Answer", "Hi"));

Ad-hoc attributes are not strong-typed as formal attributes, they are just a key/value pair. Where the key is the attribute's name and the latter its value. The key point here is that they offer great flexibility to your identity model as you can define any attribute you want without changing any type.


Note that ad-hoc attributes are not typed. You should use them wisely, otherwise they may become unmanageable.
In theory, all PicketLink types such as IdentityType, Relationship and Partition support ad-hoc attributes. The reason is that all those types are a subtypes of AttributedType. But in practice, even if a type support ad-hoc attributes the underlying store may not. Which means you can not use those attributes. The LDAP Identity Store, for example, does not support ad-hoc attributes at all if used alone. Take a look at Chapter 9, Identity Management - Working with LDAP for more details about how to support ad-hoc attributes when using the LDAP store.
Those attributes are also queriable. The example below shows how you can use the Query API to search for types using ad-hoc attributes:
  IdentityQueryBuilder queryBuilder = identityManager.getQueryBuilder();
  IdentityQuery<User> query = identityManager.<User> createIdentityQuery(User.class);

  query.where(queryBuilder.equal(IdentityType.QUERY_ATTRIBUTE.byName("SomeAttribute"), "SomeAttributeValue"));

  List<User> result = query.getResultList();

  for (User user : result) {
    // do something