17

Given the following enum.

public enum Constants
{
    PAGE_LINKS(10);
    //Other constants as and when required.

    private final int value;

    private Constants(int value){
        this.value = value;
    }

    public int getValue(){
        value;
    }    
}

This enum is placed under an application scoped bean like so,

@ManagedBean
@ApplicationScoped
public final class ConstantsBean
{
    private Constants constants;

    public ConstantsBean() {}

    public Constants getConstants() {
        return constants;
    }
}

How to access the value of PAGE_LINKS in EL?

<p:dataGrid pageLinks="#{}".../>

What should be written in #{}? Is it possible?


EDIT:

Modifying the bean in the following way,

@ManagedBean
@ApplicationScoped
public final class ConstantsBean
{
    public ConstantsBean() {}

    public int getValue(Constants constants) {
        return constants.getValue();
    }
}

and then accessing in EL like so,

<p:dataGrid pageLinks="#{constantsBean.getValue('PAGE_LINKS')}".../>

somehow works but I don't believe in this ugly way.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Tiny
  • 27,221
  • 105
  • 339
  • 599

2 Answers2

20

This, as commented by Sazzadur,

#{constantsBean.constants.value}

should work. Your enum has a proper public getter for its value property. However, you should also make sure that you set the constants property of the managed bean to the desired enum value. You namely didn't do that in the code snippet posted so far and thus it remains null. EL does by design not print anything when a (base) property is null.

Here's how you could set it:

@ManagedBean
@ApplicationScoped
public final class ConstantsBean {
    private Constants constants = Constants.PAGE_LINKS;

    public Constants getConstants() {
        return constants;
    }
}

I'd however rename the property (and getter) to pageLinks for better self-documentability.

#{constantsBean.pageLinks.value}

An alternative is to use OmniFaces <o:importConstants>, based on your question history you're already familiar with OmniFaces and probably also already using it in your current project.

<o:importConstants type="com.example.Constants" />
...
#{Constants.PAGE_LINKS.value}

This way you don't need to wrap the thing in an application scoped bean.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • `` cannot find a given type. I followed [this](http://stackoverflow.com/a/17214709/1391249) answer and moved the `Constants` class (`enum` actually) **to** `/WEB-INF/classes/util/Constants.java` **from** `/src/java/util/Constants.java`. The IDE says, "*Incorrect package*". This tag (inside ``), `` throws `java.lang.IllegalArgumentException: Cannot find type 'util.Constants' in classpath.` What obvious am I missing? – Tiny Apr 25 '14 at 20:08
  • What IDE are you using? It should automatically compile the `.java` file from `/src` and put the created `.class` file in `/WEB-INF/classes`. You should not ever have the need to manually fiddle around in `/WEB-INF/classes`. Perhaps you accidently turned off automatic building? – BalusC Apr 26 '14 at 06:03
  • It is NetBeans IDE 8.0. What I did was : undeployed the application from the server (GlassFish 4.0), restarted the server, did *clean and build* and then deployed the application from all over again the scratch but the same exception then after remained. All Java packages are stored under `/src/java`. The `Constants` class is also there in `/src/java/util/Constants.java` and it is available in the build folder - `/build/web/WEB-INF/classes/util/Constants.class`. It should automatically be available to the deployed `WAR` then. – Tiny Apr 26 '14 at 08:43
  • This is the full path of the `Constants.class` (an `enum`) after the application is deployed - `E:\Project\JavaEE\Project\Project-war\build\web\WEB-INF\classes\util\Constants.class` – Tiny Apr 26 '14 at 08:54
  • To exclude the one and other, did the actual answer work for you? – BalusC Apr 27 '14 at 12:42
  • Yes one with the `@applicationScoped` works. I forgot to assign `Constants.PAGE_LINKS` to `private Constants constants` in the managed bean but I liked the OmniFaces way. I don't know why it cannot get the `enum` – Tiny Apr 27 '14 at 12:47
  • As a test, can you in a backing bean class (e.g. post construct or action method) execute the following lines without exceptions? `Class.forName("util.Constants");` and `Class.forName("util.Constants", true, Thread.currentThread().getContextClassLoader());`. – BalusC Apr 27 '14 at 12:49
  • Yes both of them are successful in a method annotated by `@PostConstruct` in a managed bean. (On the contrary, I have tried giving a non-existent class to `Class.forName()` like `Class.forName("aaa.bbb")` and they failed with `java.lang.ClassNotFoundException` as obvious). – Tiny Apr 27 '14 at 12:59
  • Okay, where is the OmniFaces JAR placed? It must be in `/WEB-INF/lib` of the deployment, not elsewhere in the classpath. – BalusC Apr 27 '14 at 13:00
  • The OmniFaces jar is placed under `/WEB-INF/lib` as other libraries. It does other functions somewhere else in the application. – Tiny Apr 27 '14 at 13:02
  • Sorry, this got me baffled. It should just work. Only thing which I haven't tried is Netbeans, but that should hardly be the cause. Are you absolutely positive that you didn't make a typo in `type` attribute? I have the impression that you're actually not using the same FQN as you've posted here as `util.Constants`, as you started to mention `aaa.bbb`. – BalusC Apr 27 '14 at 13:13
  • I looked into the qualified name very carefully. There is no typo in the `type` attribute. (Yes the `enum` name was changed after this post. It is actually `util.IntegerConstants`. I used this name everywhere including `Class.forName()` as a test case in the previous comments.) The class complies correctly. So, it should not be related to the NetBeans IDE. – Tiny Apr 27 '14 at 14:58
  • I have just upgraded OmniFaces from **1.6.3** to **1.7** and the problem vanished into thin air without any other modifications. Thank you! – Tiny Apr 27 '14 at 23:23
  • That's great, but I can't explain that. The only 1.6.3 -> 1.7 change which was made in `` is that the constants are stored in an ordered map instead of an unordered map, but that step is beyond finding the type in the classpath which has not changed. – BalusC Apr 28 '14 at 05:19
10

Since Primefaces 6.0 you can also use PrimeFaces importEnum (Before that import was in "Primefaces Extensions").

https://www.primefaces.org/showcase/ui/misc/importEnum.xhtml

tandraschko
  • 2,291
  • 13
  • 13
  • since it is not mentioned in the example above: `xmlns:pe="http://primefaces.org/ui/extensions"` is the proper namespace to include – Andreas Covidiot Jan 15 '16 at 10:23
  • and you need to add the extension to the classpath: http://stackoverflow.com/a/16017210/1915920 and https://github.com/primefaces-extensions/primefaces-extensions.github.com/wiki/Getting-Started#other-users – Andreas Covidiot Jan 21 '16 at 07:56
  • unfortunately code completion in Eclipse Kepler with JBoss Tools does not work and I found no Eclipse plugin that would support it. But nothing is perfect :-) and it's still better than writing `@Name enum Foo { xxx, bar ; public static String getXxx() { return xxx.name(); } ... }` getters and exposing the enum to the client (using it ala `#{foo.xxx}`) for me. – Andreas Covidiot Jan 21 '16 at 08:00
  • The link is dead since importEnum has been incorporated into PF as of 6.1 – Jeremy Rea Jun 07 '17 at 14:32