Annotation Interface DynTab


Annotation for automatic registration of a CDI bean as a dynamic tab.

Placed on a class that implements DyntabBeanInterface. The DynTabs library automatically scans all beans with this annotation and registers them in DynTabRegistry.

This eliminates the need for manual registration in a DynTabConfig subclass!

The annotation is @Repeatable - it can be placed multiple times on the same class. This allows a single CDI bean to serve as the basis for multiple different tabs, each with its own name, title, and parameters. Typical example: same XHTML page and same bean, but with different parameters controlling behavior.

Single tab example:

 
 @Named
 @TabScoped
 @DynTab(name = "UsersDynTab",
         uniqueIdentifier="Users",
         title = "The Users",
         includePage = "/WEB-INF/include/users/users.xhtml")
 public class UsersBean implements DyntabBeanInterface {
     // just business logic, no manual registration needed
 }
 
 

Two tabs on the same bean (one secured with declarative roles):

 
 @Named
 @TabScoped
 @DynTab(name = "DocumentsDynTab",
         uniqueIdentifier="Documents",
         title = "The Documents",
         includePage = "/WEB-INF/include/docs/docs.xhtml",
         parameters = {"listAll=false"})
 @DynTab(name = "AllDocsDynTab",
         uniqueIdentifier="AllDocs",
         title = "All Documents",
         closeable = true,
         securedResource = true,
         allowedRoles = {"ADMIN", "MANAGER"},
         includePage = "/WEB-INF/include/docs/docs.xhtml",
         parameters = {"listAll=true"})
 public class DocsBean implements DyntabBeanInterface {
     // "Documents" tab is open to everyone
     // "AllDocs" tab requires ADMIN or MANAGER role
 }
 
 

Menu items can then simply use:

 
 <p:menuitem value="Users" action="uishell:Users" />
 <p:menuitem value="Documents" action="uishell:Documents" />
 <p:menuitem value="All Documents" action="uishell:AllDocs" />
 
 
so, the pattern for action atribute value is: "uishell:_dynTab_uniqueIdentifier"

NOTE: The bean MUST implement DyntabBeanInterface. Using @TabScoped instead of @ViewScoped is recommended for isolation between tabs.

Author:
DynTabs
See Also:
  • Required Element Summary

    Required Elements
    Modifier and Type
    Required Element
    Description
    Path to the XHTML page included in the tab.
    The tab name for registration (e.g.
    The tab title displayed to the user in the tab header.
  • Optional Element Summary

    Optional Elements
    Modifier and Type
    Optional Element
    Description
    Roles allowed to access this tab (declarative access control).
    boolean
    Whether the user can close the tab by clicking the X button.
    Tab parameters in "key=value" format.
    boolean
    Whether this dynamic tab is a secured (protected) resource.
    Human-readable display name for this secured resource.
    Unique identifier for the tab.
  • Element Details

    • name

      String name
      The tab name for registration (e.g. "UsersDynTab").

      This name is used in action outcomes on XHTML pages: action="uishell:Users" will look for a tab registered as "UsersDynTab". Convention: bean name + "DynTab" suffix.

    • title

      String title
      The tab title displayed to the user in the tab header.

      Can be:

      • Plain text: "Users"
      • EL expression: "#{msg['users.title']}"
      • EL expression with a bean: "#{usersBean.tabTitle}"
    • includePage

      String includePage
      Path to the XHTML page included in the tab.

      Example: "/WEB-INF/include/users/users.xhtml"

      This page will be rendered inside the tab and has access to the dynTab object via the #{dynTab} parameter.

    • closeable

      boolean closeable
      Whether the user can close the tab by clicking the X button.

      Default: true

      For "Home" or "Dashboard" tabs that should always remain open, set this to false.

      Default:
      true
    • uniqueIdentifier

      String uniqueIdentifier
      Unique identifier for the tab.

      Used to check if a tab already exists (to prevent opening duplicates).

      If not specified, it is automatically derived from the name() attribute by removing the "DynTab" suffix (e.g. "UsersDynTab" -> "Users").

      Default:
      ""
    • securedResource

      boolean securedResource
      Whether this dynamic tab is a secured (protected) resource.

      When set to true, the AbstractSecuredResourceScanner registers this tab's uniqueIdentifier() as a secured resource at deploy time. The AbstractAccessCheckInterceptor then enforces access control when the tab is opened via callAccessPointMethod().

      Access rights can be granted in two ways:

      1. Declarative (InMemory): Specify allowedRoles() in this annotation. The InMemorySecuredResourceScanner reads both securedResource and allowedRoles at deploy time and stores them in memory. The paired InMemoryAccessCheckInterceptor enforces access based on these declared roles. This is the default approach — zero configuration, everything is declared in the annotation.
      2. DB-based: The developer creates a custom DBSecuredResourceScanner (extending AbstractSecuredResourceScanner) that writes secured resources to a database table, ignoring allowedRoles. Access rules are managed through an Admin UI. A paired DBAccessCheckInterceptor reads allowed roles from the database at runtime.

      Default: false (tab is not protected)

      Default:
      false
    • securedResourceDisplayName

      String securedResourceDisplayName
      Human-readable display name for this secured resource.

      Used in admin UIs for security management. Can be a literal string or a resource bundle key for i18n. Only meaningful when securedResource() is true.

      Default:
      ""
    • allowedRoles

      String[] allowedRoles
      Roles allowed to access this tab (declarative access control).

      Used by the InMemorySecuredResourceScanner / InMemoryAccessCheckInterceptor pair. Only meaningful when securedResource() is true.

      Example:

      
       @DynTab(name = "AllDocsDynTab",
               uniqueIdentifier = "AllDocs",
               title = "All Documents",
               securedResource = true,
               allowedRoles = {"ADMIN", "MANAGER"},
               includePage = "/WEB-INF/include/docs/docs.xhtml")
       

      Ignored by DB-based implementations, where access rules are managed through an Admin UI and stored in the database.

      Default:
      {}
    • parameters

      String[] parameters
      Tab parameters in "key=value" format.

      Examples:

      • {"listAll=false", "mode=edit"}
      • {"maxResults=50"}
      • For EL expressions: {"dynamicParam=#{someBean.value}"}

      Parameters are accessible in the bean via:

      • getParameters().get("key")
      • getDynTab().getParameters().get("key")
      Default:
      {}