Annotation Interface DynTab
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 -
Optional Element Summary
Optional ElementsModifier and TypeOptional ElementDescriptionString[]Roles allowed to access this tab (declarative access control).booleanWhether the user can close the tab by clicking the X button.String[]Tab parameters in "key=value" format.booleanWhether 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 nameThe 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 titleThe 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 includePagePath 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 closeableWhether 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 uniqueIdentifierUnique 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 securedResourceWhether this dynamic tab is a secured (protected) resource.When set to
true, theAbstractSecuredResourceScannerregisters this tab'suniqueIdentifier()as a secured resource at deploy time. TheAbstractAccessCheckInterceptorthen enforces access control when the tab is opened viacallAccessPointMethod().Access rights can be granted in two ways:
- Declarative (InMemory): Specify
allowedRoles()in this annotation. TheInMemorySecuredResourceScannerreads bothsecuredResourceandallowedRolesat deploy time and stores them in memory. The pairedInMemoryAccessCheckInterceptorenforces access based on these declared roles. This is the default approach — zero configuration, everything is declared in the annotation. - DB-based: The developer creates a custom
DBSecuredResourceScanner(extendingAbstractSecuredResourceScanner) that writes secured resources to a database table, ignoringallowedRoles. Access rules are managed through an Admin UI. A pairedDBAccessCheckInterceptorreads allowed roles from the database at runtime.
Default:
false(tab is not protected)- Default:
false
- Declarative (InMemory): Specify
-
securedResourceDisplayName
String securedResourceDisplayNameHuman-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()istrue.- Default:
""
-
allowedRoles
String[] allowedRolesRoles allowed to access this tab (declarative access control).Used by the
InMemorySecuredResourceScanner/InMemoryAccessCheckInterceptorpair. Only meaningful whensecuredResource()istrue.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[] parametersTab 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:
{}
-