-
Available since OmniFaces 1.0
The <o:importConstants>
taghandler allows the developer to have a mapping of all constant field values of the given fully qualified name of a type in the request scope. The constant field values are those public static final fields. This works for classes, interfaces and enums.
Usage
For example:
public class Foo {
public static final String FOO1 = "foo1";
public static final String FOO2 = "foo2";
}
public interface Bar {
public String BAR1 = "bar1";
public String BAR2 = "bar2";
}
public enum Baz {
BAZ1, BAZ2;
}
public enum Faz implements Bar {
FAZ1, FAZ2;
}
The constant field values of the above types can be mapped into the request scope as follows:
<o:importConstants type="com.example.Foo" />
<o:importConstants type="com.example.Bar" />
<o:importConstants type="com.example.Baz" var="Bazzz" />
<o:importConstants type="com.example.Faz" />
...
#{Foo.FOO1}, #{Foo.FOO2}, #{Bar.BAR1}, #{Bar.BAR2}, #{Bazzz.BAZ1}, #{Bazzz.BAZ2}, #{Faz.FAZ1}, #{Faz.BAR2}
...
<h:selectOneMenu>
<f:selectItems value="#{Faz.values()}" /> <!-- FAZ1, FAZ2, BAR1, BAR2 -->
</h:selectOneMenu>
The map is by default stored in the request scope by the simple name of the type as variable name. You can override this by explicitly specifying the var
attribute, as demonstrated for com.example.Baz
in the above example.
The resolved constants are by reference stored in the cache to improve retrieving performance. There is also a runtime (no, not compiletime as that's just not possible in EL) check during retrieving the constant value. If a constant value doesn't exist, then an IllegalArgumentException
will be thrown.
Since version 4.3, you can use the loader
attribute to specify an object whose class loader will be used to load the class specified in the type
attribute. The class loader of the given object is resolved as specified in Utils.getClassLoader(Object)
. In the end this should allow you to use a more specific class when there are duplicate instances in the runtime classpath, e.g. via multiple (plugin) libraries.
Since version 4.6, when the class specified in the type
attribute is an enum
, such as Baz
or Faz
in the above example, then you can use #{Faz.members()}
to exclusively access enum members rather than all constant field values.
<h:selectOneMenu>
<f:selectItems value="#{Faz.members()}" /> <!-- FAZ1, FAZ2 -->
</h:selectOneMenu>
JSF 2.3
JSF 2.3 also offers a <f:importConstants>
, however it requires being placed in <f:metadata>
which may not be appropriate when you intend to import constants only from a include, tagfile or a composite component.
All constants of ConstantsBean
- Constant one
- Constant two
All values of ExampleEnum
- ONE
- TWO
- THREE
Providing enum values as dropdown items
Providing enum values as dropdown items by var
Try to access an invalid constant
This should throw an IllegalArgumentException as ExampleEnum.FOUR
doesn't exist.
<o:importConstants type="org.omnifaces.showcase.taghandlers.ConstantsBean" />
<o:importConstants type="org.omnifaces.showcase.model.ExampleEnum" />
<h3>All constants of <code>ConstantsBean</code></h3>
<ul>
<li>#{ConstantsBean.CONSTANT1}</li>
<li>#{ConstantsBean.CONSTANT2}</li>
</ul>
<hr />
<h3>All values of <code>ExampleEnum</code></h3>
<ul>
<li>#{ExampleEnum.ONE}</li>
<li>#{ExampleEnum.TWO}</li>
<li>#{ExampleEnum.THREE}</li>
</ul>
<hr />
<h3>Providing enum values as dropdown items</h3>
<h:form>
<h:selectOneMenu value="#{constantsBean.exampleEnum}">
<f:selectItem itemLabel="Please select one" noSelectionOption="true" />
<f:selectItems value="#{ExampleEnum}" />
<f:ajax render="@form" />
</h:selectOneMenu>
<p>Selected: #{constantsBean.exampleEnum}</p>
<p>Is it <code>TWO</code>? #{constantsBean.exampleEnum == ExampleEnum.TWO}</p>
<!-- Note that you can also just do #{constantsBean.exampleEnum == 'TWO'} -->
</h:form>
<hr />
<h3>Providing enum values as dropdown items by var</h3>
<h:form>
<h:selectOneMenu value="#{constantsBean.exampleEnum}">
<f:selectItem itemLabel="Please select one" noSelectionOption="true" />
<f:selectItems value="#{ExampleEnum.values()}" var="exampleEnum"
itemValue="#{exampleEnum}" itemLabel="#{exampleEnum.friendlyName}" />
<f:ajax render="@form" />
</h:selectOneMenu>
<p>Selected: #{constantsBean.exampleEnum.friendlyName}</p>
<p>Is it <code>Two</code>? #{constantsBean.exampleEnum == ExampleEnum.TWO}</p>
<!-- Note that you can also just do #{constantsBean.exampleEnum == 'TWO'} -->
</h:form>
<hr />
<h3>Try to access an invalid constant</h3>
<p>This should throw an IllegalArgumentException as <code>ExampleEnum.FOUR</code> doesn't exist.</p>
<h:form>
<h:commandButton value="Try to access ExampleEnum.FOUR" action="#{constantsBean.setExampleEnum(ExampleEnum.FOUR)}" />
</h:form>
package org.omnifaces.showcase.taghandlers;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Named;
import org.omnifaces.showcase.model.ExampleEnum;
@Named
@RequestScoped
public class ConstantsBean {
public static final String CONSTANT1 = "Constant one";
public static final String CONSTANT2 = "Constant two";
private ExampleEnum exampleEnum;
public ExampleEnum getExampleEnum() {
return exampleEnum;
}
public void setExampleEnum(ExampleEnum exampleEnum) {
this.exampleEnum = exampleEnum;
}
}
package org.omnifaces.showcase.model;
public enum ExampleEnum {
ONE, TWO, THREE;
public String getFriendlyName() {
return name().charAt(0) + name().substring(1).toLowerCase();
}
}