org.omnifaces.util.JNDI Maven / Gradle / Ivy
Show all versions of omnifaces Show documentation
/*
* Copyright OmniFaces
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.omnifaces.util;
import static org.omnifaces.util.Exceptions.is;
import java.util.regex.Pattern;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import jakarta.annotation.Resource;
import jakarta.faces.application.ProjectStage;
/**
*
* Utility class for simplifying some web related tasks that use JNDI under the hood, such as getting the
* <env-entry>
from web.xml
.
*
* Note that the JSF spec defines one parameter that can optionally be defined via an env entry instead of the typical
* context/init parameter; {@link ProjectStage#PROJECT_STAGE_JNDI_NAME}. Mojarra defines an additional proprietary one:
* "java:comp/env/ClientStateSavingPassword".
*
* @author Arjan Tijms
* @since 1.6
*/
public final class JNDI {
/**
* JNDI namespace prefix, including the colon: java:
* @since 3.9
*/
public static final String JNDI_NAMESPACE_PREFIX = "java:";
/**
* JNDI namespace to lookup components: java:comp
* @since 3.9
*/
public static final String JNDI_NAMESPACE_COMPONENT = JNDI_NAMESPACE_PREFIX + "comp";
/**
* JNDI namespace to lookup all enterprise beans: java:global
* @since 3.9
*/
public static final String JNDI_NAMESPACE_GLOBAL = JNDI_NAMESPACE_PREFIX + "global";
/**
* JNDI namespace to lookup local enterprise beans within the same module: java:module
* @since 3.9
*/
public static final String JNDI_NAMESPACE_MODULE = JNDI_NAMESPACE_PREFIX + "module";
/**
* JNDI namespace to lookup local enterprise beans within the same application: java:app
* @since 3.9
*/
public static final String JNDI_NAMESPACE_APPLICATION = JNDI_NAMESPACE_PREFIX + "app";
/**
* JNDI name prefix for environment entries: java:comp/env
* @since 3.9
*/
public static final String JNDI_NAME_PREFIX_ENV_ENTRY = JNDI_NAMESPACE_COMPONENT + "/env";
/**
* Pattern for local or remote suffix in EJB interface name.
*/
public static final Pattern PATTERN_EJB_INTERFACE_SUFFIX = Pattern.compile("(LOCAL|REMOTE)$", Pattern.CASE_INSENSITIVE);
private JNDI() {
// Hide constructor.
}
/**
* Returns the named environment entry for the deployment component from where this is called. From within the web
* module this returns the <env-entry-value>
of a <env-entry>
in
* web.xml
associated with the given <env-entry-name>
.
*
* Note that the name used here is relative to "java:comp/env", which is exactly as it appears in web.xml
.
*
* Example:
*
* web.xml
*
* <env-entry>
* <cont>org.omnifaces.TEST_INTEGER</env-entry-name>
* <env-entry-type>java.lang.Integer</env-entry-type>
* <env-entry-value>10</env-entry-value>
* </env-entry>
*
*
* Lookup in Java using relative name
*
* Integer test = JNDI.getEnvEntry("org.omnifaces.TEST_INTEGER");
*
*
* Lookup in Java using full JNDI name
*
* Integer test = JNDI.lookup("java:comp/env/org.omnifaces.TEST_INTEGER");
*
*
*
* Note that even the "full JNDI name" is relative to the "deployment component" from which the lookup is done.
* To use a true global JNDI name an additional <lookup-name>
should be specified in web.xml
.
*
*
* Environment entries can also be injected using {@link Resource}.
*
* @param The expected return type.
* @param name the environment entry name relative to "java:comp/env".
* @return The environment entry value associated with the given name, or null
if
* there is none.
* @throws ClassCastException When T
is of wrong type.
* @see InitialContext#lookup(String)
* @since 1.6
*/
public static T getEnvEntry(String name) {
return lookup(JNDI_NAME_PREFIX_ENV_ENTRY + "/" + name);
}
/**
* Returns the named object from the default JNDI instance.
* @param The expected return type.
* @param name the name of the object to be retrieved
* @return the named object, or null
if there is none.
* @throws ClassCastException When T
is of wrong type.
* @see InitialContext#lookup(String)
* @since 1.6
*/
@SuppressWarnings("unchecked")
public static T lookup(String name) {
InitialContext context = null;
try {
context = new InitialContext();
return (T) context.lookup(name);
} catch (NamingException e) {
if (is(e, NameNotFoundException.class)) {
return null;
} else {
throw new IllegalStateException(e);
}
} finally {
close(context);
}
}
private static void close(InitialContext context) {
try {
if (context != null) {
context.close();
}
} catch (NamingException e) {
throw new IllegalStateException(e);
}
}
/**
* Guess JNDI name of given bean class, which can be a local or remote EJB.
* @param beanClass The bean class to guess JNDI name for.
* @return The guessed JNDI name of the given bean class.
* @since 3.9
*/
public static String guessJNDIName(Class beanClass) {
return guessJNDIName(beanClass.getName());
}
/**
* Guess JNDI name of given fully-qualified class name.
* @param className The fully-qualified class name to guess JNDI name for.
* @return The guessed JNDI name of the given fully-qualified class name.
* @since 3.9
*/
public static String guessJNDIName(String className) {
String lookupname = className.substring(className.lastIndexOf(".") + 1);
// Support naming convention that strips Local/Remote from the
// end of an interface class to try to determine the actual bean name,
// to avoid @EJB(beanName="myBeanName"), and just use plain old @EJB.
return PATTERN_EJB_INTERFACE_SUFFIX.matcher(lookupname).replaceFirst("") + "!" + className;
}
}