如何在运行时检测可用的MyFace实现版本

时间:2014-05-26 09:29:45

标签: java jsf-2 myfaces

主题标题真的说明了一切:

我想在运行时检测MyFaces的版本。这可能吗?

很久以前似乎有一个discussion about this kind of feature,但如果它被实现并且其中的链接被破坏,我找不到任何东西。

MyFaces 2.0及以上版本。 Websphere 8.0.x

1 个答案:

答案 0 :(得分:2)

我终于found a solution了。每个类都有一个包对象,该对象具有获取规范版本,实现名称和实现版本的属性。当然,这些属性中的数据质量取决于实现,但它对我到目前为止使用的实现(规范版本是错误的并且是实现版本的副本,但我可以接受它)已经足够了。

/**
 * This method provides a convenient means of determining the JSF
 * Specification version.
 *
 * @return JSF Specification version, e.g. 2.1
 * @since 1.5
 */
public static String getSpecificationVersion() {
    return FacesContext.getCurrentInstance().getClass().getPackage().getSpecificationVersion();
}

/**
 * This method provides a convenient means of determining the JSF
 * Implementation version.
 *
 * @return JSF Implementation version, e.g. 2.1.26
 * @since 1.5
 */
public static String getImplementationVersion() {
    return FacesContext.getCurrentInstance().getClass().getPackage().getImplementationVersion();
}

/**
 * This method provides a convenient means of determining the JSF
 * Implementation Title.
 *
 * @return JSF implementation title, e.g. Mojarra.
 * @since 1.5
 */
public static String getImplementationTitle() {
    return FacesContext.getCurrentInstance().getClass().getPackage().getImplementationTitle();
}

由于我需要在普通servlet中使用此信息,因此我还必须确保存在FacesContext。幸运@BalusC has described how to do this。您只需使用此类,如果不存在,则创建新的JSF LifeCycle。

public class FacesUtil {

    // Getters -----------------------------------------------------------------------------------

    public static FacesContext getFacesContext(
        HttpServletRequest request, HttpServletResponse response)
    {
        // Get current FacesContext.
        FacesContext facesContext = FacesContext.getCurrentInstance();

        // Check current FacesContext.
        if (facesContext == null) {

            // Create new Lifecycle.
            LifecycleFactory lifecycleFactory = (LifecycleFactory)
                FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY); 
            Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);

            // Create new FacesContext.
            FacesContextFactory contextFactory  = (FacesContextFactory)
                FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
            facesContext = contextFactory.getFacesContext(
                request.getSession().getServletContext(), request, response, lifecycle);

            // Create new View.
            UIViewRoot view = facesContext.getApplication().getViewHandler().createView(
                facesContext, "");
            facesContext.setViewRoot(view);                

            // Set current FacesContext.
            FacesContextWrapper.setCurrentInstance(facesContext);
        }

        return facesContext;
    }

    // Helpers -----------------------------------------------------------------------------------

    // Wrap the protected FacesContext.setCurrentInstance() in a inner class.
    private static abstract class FacesContextWrapper extends FacesContext {
        protected static void setCurrentInstance(FacesContext facesContext) {
            FacesContext.setCurrentInstance(facesContext);
        }
    }     

}

最后,由于我们使用的是Primefaces,我们得到一个包裹的Faces Context,它反过来生成Primefaces的版本信息而不是Myfaces / Mojarra的版本信息。因此,我们必须检查它是否是PrimeFacesContext,而不是FacesContet.getCurrentInstance,如果这样解开它:

private static Object facesContext() {
    FacesContext context = FacesContext.getCurrentInstance();
    if (context == null)
        return "No Jsf Context";
    if (context instanceof PrimeFacesContext)
        return ((PrimeFacesContext) context).getWrapped();
    return context;
}