Re: Tag component instantiation and EL strict or alwaysRecompile modes
On 05/06/2014 07:27, Leonardo Uribe wrote: Hi Use the standard vdl.createComponent(...) included since JSF 2.2. It has the necessary code to do the trick properly. Please note in Myfaces this method has been extend to support facelet tags too. It should work with the view pool. Thank you Leonardo. I updated my code to use this method and it perfectly works. I could remove those naughty introspections, and that is always a long term bless. Best regards, Ludovic | | AVANT D'IMPRIMER, PENSEZ A L'ENVIRONNEMENT. |
Re: Tag component instantiation and EL strict or alwaysRecompile modes
Hi Ludovic Good to know that. In my understanding, that code is the best option so far, and a lot of effort has been done to make it work. It was really hard to get it done. It has some good junit tests in place. Anyway we need to convince to the EG that myfaces behavior is the way to go. I think there is an issue already created on the spec, but I can't remember which number is. Regards Leonardo On Jun 10, 2014 10:55 AM, l.pe...@senat.fr l.pe...@senat.fr wrote: On 05/06/2014 07:27, Leonardo Uribe wrote: Hi Use the standard vdl.createComponent(...) included since JSF 2.2. It has the necessary code to do the trick properly. Please note in Myfaces this method has been extend to support facelet tags too. It should work with the view pool. Thank you Leonardo. I updated my code to use this method and it perfectly works. I could remove those naughty introspections, and that is always a long term bless. Best regards, Ludovic | | AVANT D'IMPRIMER, PENSEZ A L'ENVIRONNEMENT. |
Tag component instantiation and EL strict or alwaysRecompile modes
Dear all, I am doing something dirty in my code. I dynamically instantiate and add tag components to my component tree, according to some information that I have at runtime. My instantiation method looks like : public static UIComponent instantiateTagComponent(Location loc, String namespace, String localPrefix, String componentName, TagComponentParam params[]) { final String ERROR_MESSAGE = Erreur lors de l'instanciation d'un tag component; FacesContext ctx = FacesContext.getCurrentInstance(); AbstractFaceletContext fctx = (AbstractFaceletContext) ctx.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY); fctx.pushPageContext(new PageContextImpl()); FaceletViewDeclarationLanguage vdl = new FaceletViewDeclarationLanguage(ctx); UIPanel panel = (UIPanel) ctx.getApplication().createComponent( UIPanel.COMPONENT_TYPE ); try { Method createCompiler = FaceletViewDeclarationLanguage.class.getDeclaredMethod(createCompiler,FacesContext.class); Method createFaceletFactory = FaceletViewDeclarationLanguage.class.getDeclaredMethod(createFaceletFactory,FacesContext.class,org.apache.myfaces.view.facelets.compiler.Compiler.class); createCompiler.setAccessible(true); createFaceletFactory.setAccessible(true); org.apache.myfaces.view.facelets.compiler.Compiler compiler = (org.apache.myfaces.view.facelets.compiler.Compiler) createCompiler.invoke(vdl, ctx); FaceletFactory ff = (FaceletFactory) createFaceletFactory.invoke(vdl, ctx, compiler); TagLibrary tl = compiler.createTagLibrary(); TagConfig tc = new JSFUtilsTagUnit(tl, namespace, localPrefix, componentName,params,loc); TagHandler th = tl.createTagHandler(namespace, componentName, tc); Field declaredField = FaceletCompositionContext.class.getDeclaredField(FACELET_COMPOSITION_CONTEXT_KEY); declaredField.setAccessible(true); FaceletCompositionContextImpl faceletCompositionContextImpl = new FaceletCompositionContextImpl(ff,ctx); Class? dfcClass = Class.forName(org.apache.myfaces.view.facelets.impl.DefaultFaceletContext); Field fMCTX = dfcClass.getDeclaredField(_mctx); fMCTX.setAccessible(true); fMCTX.set(fctx, faceletCompositionContextImpl); FacesContext.getCurrentInstance().getAttributes().put((String)declaredField.get(null),faceletCompositionContextImpl); FaceletCompositionContext mctx = (FaceletCompositionContext) FaceletCompositionContext.getCurrentInstance(fctx); mctx.startComponentUniqueIdSection(); th.apply( fctx, panel ); } catch (IOException ex) { log.error(ERROR_MESSAGE, ex); } catch (InvocationTargetException ex) { log.error(ERROR_MESSAGE, ex); } catch (NoSuchMethodException ex) { log.error(ERROR_MESSAGE, ex); } catch (NoSuchFieldException ex) { log.error(ERROR_MESSAGE, ex); } catch (SecurityException ex) { log.error(ERROR_MESSAGE, ex); } catch (ClassNotFoundException ex) { log.error(ERROR_MESSAGE, ex); } catch (IllegalArgumentException ex) { log.error(ERROR_MESSAGE, ex); } catch (IllegalAccessException ex) { log.error(ERROR_MESSAGE, ex); } finally { fctx.popPageContext(); } return panel; } This is dirty, but this perfectly works for quite some time now, at least until I stick to context-param param-nameorg.apache.myfaces.CACHE_EL_EXPRESSIONS/param-name param-valuestrict/param-value /context-param if I change it to alwaysRecompile, the state is not properly restored and I end with and NPE like : 04/06/2014 12:29:41 ERROR [http-bio-8443-exec-56] - Exception occur! java.lang.NullPointerException at org.apache.myfaces.view.facelets.el.FaceletStateValueExpression.getValue(FaceletStateValueExpression.java:107) at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:68) at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:185) at org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression.getValue(ContextAwareTagValueExpression.java:96) at javax.faces.component._DeltaStateHelper.eval(_DeltaStateHelper.java:360) at javax.faces.component.UIParameter.getValue(UIParameter.java:85) at org.apache.myfaces.shared.renderkit.html.HtmlLinkRendererBase.addChildParametersToHref(HtmlLinkRendererBase.java:762) at org.apache.myfaces.shared.renderkit.html.HtmlLinkRendererBase.renderOutputLinkStart(HtmlLinkRendererBase.java:861) at org.apache.myfaces.shared.renderkit.html.HtmlLinkRendererBase.encodeBegin(HtmlLinkRendererBase.java:144) at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:596) at
Re: Tag component instantiation and EL strict or alwaysRecompile modes
Hi Use the standard vdl.createComponent(...) included since JSF 2.2. It has the necessary code to do the trick properly. Please note in Myfaces this method has been extend to support facelet tags too. It should work with the view pool. regards Leonardo Uribe On Jun 4, 2014 12:37 PM, l.pe...@senat.fr l.pe...@senat.fr wrote: Dear all, I am doing something dirty in my code. I dynamically instantiate and add tag components to my component tree, according to some information that I have at runtime. My instantiation method looks like : public static UIComponent instantiateTagComponent(Location loc, String namespace, String localPrefix, String componentName, TagComponentParam params[]) { final String ERROR_MESSAGE = Erreur lors de l'instanciation d'un tag component; FacesContext ctx = FacesContext.getCurrentInstance(); AbstractFaceletContext fctx = (AbstractFaceletContext) ctx.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY); fctx.pushPageContext(new PageContextImpl()); FaceletViewDeclarationLanguage vdl = new FaceletViewDeclarationLanguage(ctx); UIPanel panel = (UIPanel) ctx.getApplication().createComponent( UIPanel.COMPONENT_TYPE ); try { Method createCompiler = FaceletViewDeclarationLanguage .class.getDeclaredMethod(createCompiler,FacesContext.class); Method createFaceletFactory = FaceletViewDeclarationLanguage .class.getDeclaredMethod(createFaceletFactory, FacesContext.class,org.apache.myfaces.view.facelets. compiler.Compiler.class); createCompiler.setAccessible(true); createFaceletFactory.setAccessible(true); org.apache.myfaces.view.facelets.compiler.Compiler compiler = (org.apache.myfaces.view.facelets.compiler.Compiler) createCompiler.invoke(vdl, ctx); FaceletFactory ff = (FaceletFactory) createFaceletFactory.invoke(vdl, ctx, compiler); TagLibrary tl = compiler.createTagLibrary(); TagConfig tc = new JSFUtilsTagUnit(tl, namespace, localPrefix, componentName,params,loc); TagHandler th = tl.createTagHandler(namespace, componentName, tc); Field declaredField = FaceletCompositionContext. class.getDeclaredField(FACELET_COMPOSITION_CONTEXT_KEY); declaredField.setAccessible(true); FaceletCompositionContextImpl faceletCompositionContextImpl = new FaceletCompositionContextImpl(ff,ctx); Class? dfcClass = Class.forName(org.apache. myfaces.view.facelets.impl.DefaultFaceletContext); Field fMCTX = dfcClass.getDeclaredField(_mctx); fMCTX.setAccessible(true); fMCTX.set(fctx, faceletCompositionContextImpl); FacesContext.getCurrentInstance().getAttributes().put((String) declaredField.get(null),faceletCompositionContextImpl); FaceletCompositionContext mctx = (FaceletCompositionContext) FaceletCompositionContext.getCurrentInstance(fctx); mctx.startComponentUniqueIdSection(); th.apply( fctx, panel ); } catch (IOException ex) { log.error(ERROR_MESSAGE, ex); } catch (InvocationTargetException ex) { log.error(ERROR_MESSAGE, ex); } catch (NoSuchMethodException ex) { log.error(ERROR_MESSAGE, ex); } catch (NoSuchFieldException ex) { log.error(ERROR_MESSAGE, ex); } catch (SecurityException ex) { log.error(ERROR_MESSAGE, ex); } catch (ClassNotFoundException ex) { log.error(ERROR_MESSAGE, ex); } catch (IllegalArgumentException ex) { log.error(ERROR_MESSAGE, ex); } catch (IllegalAccessException ex) { log.error(ERROR_MESSAGE, ex); } finally { fctx.popPageContext(); } return panel; } This is dirty, but this perfectly works for quite some time now, at least until I stick to context-param param-nameorg.apache.myfaces.CACHE_EL_EXPRESSIONS/param-name param-valuestrict/param-value /context-param if I change it to alwaysRecompile, the state is not properly restored and I end with and NPE like : 04/06/2014 12:29:41 ERROR [http-bio-8443-exec-56] - Exception occur! java.lang.NullPointerException at org.apache.myfaces.view.facelets.el.FaceletStateValueExpression. getValue(FaceletStateValueExpression.java:107) at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:68) at org.apache.el.ValueExpressionImpl.getValue( ValueExpressionImpl.java:185) at org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression .getValue(ContextAwareTagValueExpression.java:96) at javax.faces.component._DeltaStateHelper.eval(_ DeltaStateHelper.java:360) at javax.faces.component.UIParameter.getValue(UIParameter.java:85) at org.apache.myfaces.shared.renderkit.html.HtmlLinkRendererBase.