I believe it would be possible to solve it with -> 1) check if current component (media etc.) is inside a CC 2) get the CC 3) check if expressionString contains ".attrs." and extract the attribute name 4) get the expression via the CC#getAttributes(attributeName)
But don't know if it works in all cases. Maybe there exists a better and cleaner solution? 2013/5/13 Thomas Andraschko <[email protected]> > 3.5.4 but thats indepenent :) > > > > 2013/5/13 Christian Beikov <[email protected]> > >> What PF version are you using? >> >> >> 2013/5/13 Thomas Andraschko <[email protected]> >> >> > It's really view independent and my Controller is RequestScoped. >> > The only problem is that currently graphicImage/media/filedownload are >> > unusable in a CC, if you need to pass the EL into the CC. >> > >> > >> > 2013/5/13 Christian Beikov <[email protected]> >> > >> > > The difference is that it can handle the view based scopes where the >> > > primefaces impl can't. But as I just realize this won't help you at >> all. >> > > Sorry but for now I can't think of a reliable general purpose way to >> > > retrieve the contents without rebuilding the view, I have to think >> about >> > > it. >> > > Do you need any context information like iteration status or so to >> > evaluate >> > > the expression to a meaningful value or is it completely independent >> of >> > the >> > > view? >> > > What scope has the myController? >> > > >> > > >> > > 2013/5/13 Thomas Andraschko <[email protected]> >> > > >> > > > Hi Christian, >> > > > >> > > > i don't understand your solution exactly. >> > > > Whats the difference? >> > > > It would still store the #{cc.attrs.xxx} expression and #{cc} cant >> be >> > > > evaluated without #pushComponentToEL(cc). >> > > > Also #createView should be avoided for such a request IMO because of >> > > > performance. >> > > > >> > > > Regards, >> > > > Thomas >> > > > >> > > > >> > > > >> > > > >> > > > 2013/5/13 Christian Beikov <[email protected]> >> > > > >> > > > > I'd rather say this should be fixed by restoring the view before >> > > > accessing >> > > > > the expression. I have done something like that for >> > > > > DynamicContentResourceHandler which probably is used in this case >> > here >> > > > too. >> > > > > Basically you need to save the viewId and the expression together >> in >> > > the >> > > > > session so you are able to restore the adequate expression in the >> > > > resource >> > > > > handler. I did the following for GraphicImageRenderer: >> > > > > >> > > > > >> > > > > @Override >> > > > > protected String getImageSrc(FacesContext context, >> GraphicImage >> > > > image) >> > > > > { >> > > > > String src = null; >> > > > > String name = image.getName(); >> > > > > >> > > > > if(name != null) { >> > > > > String libName = image.getLibrary(); >> > > > > ResourceHandler handler = >> > > > > context.getApplication().getResourceHandler(); >> > > > > Resource res = handler.createResource(name, libName); >> > > > > >> > > > > if(res == null) { >> > > > > return "RES_NOT_FOUND"; >> > > > > } else { >> > > > > return >> > > > > >> context.getExternalContext().encodeResourceURL(res.getRequestPath()); >> > > > > } >> > > > > } else { >> > > > > Object value = image.getValue(); >> > > > > >> > > > > if (value == null) { >> > > > > return ""; >> > > > > } else if(value instanceof String) { >> > > > > src = getResourceURL(context, (String) value); >> > > > > } else if (value instanceof StreamedContent) { >> > > > > ViewHandler viewHandler = >> > > > > context.getApplication().getViewHandler(); >> > > > > StreamedContent streamedContent = >> (StreamedContent) >> > > > value; >> > > > > Resource resource = >> > > > > >> > > > > >> > > > >> > > >> > >> context.getApplication().getResourceHandler().createResource("dynamiccontent", >> > > > > "primefaces", streamedContent.getContentType()); >> > > > > String resourcePath = resource.getRequestPath(); >> > > > > >> > > > > // servlet path/prefix is added already in >> > > > > ViewHandler.getActionURL so remove it here >> > > > > resourcePath = >> > > > > >> > resourcePath.substring(resourcePath.indexOf("/javax.faces.resource/")); >> > > > > resourcePath = viewHandler.getActionURL(context, >> > > > > resourcePath); >> > > > > >> > > > > String rid = createUniqueContentId(context); >> > > > > StringBuilder builder = new >> > > StringBuilder(resourcePath); >> > > > > >> > > > > if(resourcePath.contains("?")) >> > > > > builder.append("&"); >> > > > > else >> > > > > builder.append("?"); >> > > > > >> > > > > >> > > > > >> > > > > >> > > > >> > > >> > >> builder.append(DynamicContentResourceHandler.DYNAMIC_CONTENT_PARAM).append("=").append(rid); >> > > > > builder.append("&").append("ln=primefaces"); >> > > > > >> > > > > for (UIComponent kid : image.getChildren()) { >> > > > > if (kid instanceof UIParameter) { >> > > > > UIParameter param = (UIParameter) kid; >> > > > > >> > > > > >> > > > > >> > > > > >> > > > >> > > >> > >> builder.append("&").append(param.getName()).append("=").append(param.getValue()); >> > > > > } >> > > > > } >> > > > > >> > > > > src = builder.toString(); >> > > > > Map<String, String> dynamicContentMap = new >> > > > HashMap<String, >> > > > > String>(); >> > > > > >> > > > > >> > > > > >> > > > >> > > >> > >> dynamicContentMap.put(DynamicContentResourceHandler.DYNAMIC_CONTENT_VALUE_EXPRESSION_KEY, >> > > > > image.getValueExpression("value").getExpressionString()); >> > > > > >> > > > > >> > > > > >> > > > >> > > >> > >> dynamicContentMap.put(DynamicContentResourceHandler.DYNAMIC_CONTENT_VIEW_ID_KEY, >> > > > > context.getViewRoot().getViewId()); >> > > > > >> > > > > >> context.getExternalContext().getSessionMap().put(rid, >> > > > > dynamicContentMap); >> > > > > } >> > > > > >> > > > > // Add caching if needed >> > > > > if (!image.isCache()) { >> > > > > src += src.contains("?") ? "&" : "?"; >> > > > > src = src + "primefaces_image=" + >> > > > > UUID.randomUUID().toString(); >> > > > > } >> > > > > >> > > > > } >> > > > > >> > > > > return src; >> > > > > } >> > > > > >> > > > > >> > > > > And then I have the DynamicContentResourceHandler: >> > > > > >> > > > > public class DynamicContentResourceHandler extends >> > > PrimeResourceHandler{ >> > > > > >> > > > > private final static Logger logger = >> > > > > Logger.getLogger(DynamicContentResourceHandler.class.getName()); >> > > > > >> > > > > public static final String DYNAMIC_CONTENT_VIEW_ID_KEY = >> > "viewId"; >> > > > > public static final String >> DYNAMIC_CONTENT_VALUE_EXPRESSION_KEY = >> > > > > "valueExpression"; >> > > > > public static final String DYNAMIC_CONTENT_PARAM = "pfdrid"; >> > > > > >> > > > > public DynamicContentResourceHandler(ResourceHandler wrapped) >> { >> > > > > super(wrapped); >> > > > > } >> > > > > >> > > > > @Override >> > > > > public void handleResourceRequest(FacesContext context) throws >> > > > > IOException { >> > > > > Map<String,String> params = >> > > > > context.getExternalContext().getRequestParameterMap(); >> > > > > String library = params.get("ln"); >> > > > > String dynamicContentId = >> params.get(DYNAMIC_CONTENT_PARAM); >> > > > > >> > > > > if(dynamicContentId != null && library != null && >> > > > > library.equals("primefaces")) { >> > > > > Map<String,Object> session = >> > > > > context.getExternalContext().getSessionMap(); >> > > > > StreamedContent content = null; >> > > > > >> > > > > try { >> > > > > @SuppressWarnings("unchecked") >> > > > > Map<String, String> dynamicContentMap = >> (Map<String, >> > > > > String>) session.get(dynamicContentId); >> > > > > >> > > > > if(dynamicContentMap != null){ >> > > > > String viewId = >> > > > > dynamicContentMap.get(DYNAMIC_CONTENT_VIEW_ID_KEY); >> > > > > String dynamicContentEL = >> > > > > dynamicContentMap.get(DYNAMIC_CONTENT_VALUE_EXPRESSION_KEY); >> > > > > >> > > > > // Workaround for view based scopes >> > > > > >> > > > > >> > > > > >> > > > >> > > >> > >> context.setViewRoot(context.getApplication().getViewHandler().createView(context, >> > > > > viewId)); >> > > > > >> > > > > ELContext eLContext = context.getELContext(); >> > > > > ValueExpression ve = >> > > > > >> > > > > >> > > > >> > > >> > >> context.getApplication().getExpressionFactory().createValueExpression(context.getELContext(), >> > > > > dynamicContentEL, StreamedContent.class); >> > > > > content = (StreamedContent) >> > ve.getValue(eLContext); >> > > > > >> > > > > ExternalContext externalContext = >> > > > > context.getExternalContext(); >> > > > > >> > > > > externalContext.setResponseStatus(HttpServletResponse.SC_OK); >> > > > > >> > > > > externalContext.setResponseContentType(content.getContentType()); >> > > > > >> > > > > byte[] buffer = new byte[2048]; >> > > > > >> > > > > int length; >> > > > > InputStream inputStream = content.getStream(); >> > > > > >> > > > > while ((length = (inputStream.read(buffer))) >> >= >> > 0) >> > > { >> > > > > >> > > > > externalContext.getResponseOutputStream().write(buffer, 0, >> length); >> > > > > } >> > > > > >> > > > > >> > externalContext.getResponseOutputStream().flush(); >> > > > > context.responseComplete(); >> > > > > } else { >> > > > > ExternalContext externalContext = >> > > > > context.getExternalContext(); >> > > > > >> > > > > >> externalContext.setResponseStatus(HttpServletResponse.SC_NOT_FOUND); >> > > > > >> > externalContext.getResponseOutputStream().flush(); >> > > > > context.responseComplete(); >> > > > > } >> > > > > } catch(Exception e) { >> > > > > logger.log(Level.SEVERE, "Error in streaming >> dynamic >> > > > > resource.", e); >> > > > > } finally { >> > > > > session.remove(dynamicContentId); >> > > > > >> > > > > if(content != null) { >> > > > > content.getStream().close(); >> > > > > } >> > > > > } >> > > > > } >> > > > > else { >> > > > > super.handleResourceRequest(context); >> > > > > } >> > > > > } >> > > > > >> > > > > } >> > > > > >> > > > > This at least works for me, hope it can help you too. >> > > > > >> > > > > >> > > > > 2013/5/13 Thomas Andraschko <[email protected]> >> > > > > >> > > > > > Hi Kito, >> > > > > > >> > > > > > CC: >> > > > > > >> > > > > > >> > > > > >> > > > >> > > >> > >> ---------------------------------------------------------------------------------------------------------------- >> > > > > > <composite:interface> >> > > > > > <composite:attribute name="pdfStream" >> > > > > > type="org.primefaces.model.StreamedContent" required="true" /> >> > > > > > </composite:interface> >> > > > > > >> > > > > > <composite:implementation> >> > > > > > <p:media value="#{cc.attrs.pdfStream}" width="100%" >> > > > > height="600px" >> > > > > > player="pdf"/> >> > > > > > </composite:implementation> >> > > > > > >> > > > > > >> > > > > >> > > > >> > > >> > >> ---------------------------------------------------------------------------------------------------------------- >> > > > > > >> > > > > > View: >> > > > > > >> > > > > > >> > > > > >> > > > >> > > >> > >> ---------------------------------------------------------------------------------------------------------------- >> > > > > > <cc:myCC pdfStream="#{reportController.report} /> >> > > > > > >> > > > > > >> > > > > >> > > > >> > > >> > >> ---------------------------------------------------------------------------------------------------------------- >> > > > > > >> > > > > > PF receives the Expression String via: >> > > > > > >> > > > > > >> > > > > >> > > > >> > > >> > >> ---------------------------------------------------------------------------------------------------------------- >> > > > > > media.getValueExpression("value").getExpressionString(); >> > > > > > >> > > > > > >> > > > > >> > > > >> > > >> > >> ---------------------------------------------------------------------------------------------------------------- >> > > > > > >> > > > > > If it should work inside a CC, we must receive >> > > "#{cc.attrs.pdfStream}" >> > > > > > instead of "#{cc.attrs.pdfStream}". >> > > > > > >> > > > > > How can get the real expression here? >> > > > > > >> > > > > > Thanks, >> > > > > > Thomas >> > > > > > >> > > > > > >> > > > > > 2013/5/13 Kito Mann <[email protected]> >> > > > > > >> > > > > > > Hello Thomas, >> > > > > > > >> > > > > > > I think this is doable. Can you send us your composite >> component >> > > > code? >> > > > > > > >> > > > > > > ___ >> > > > > > > >> > > > > > > Kito D. Mann | @kito99 | Author, JSF in Action >> > > > > > > Virtua, Inc. | http://www.virtua.com | JSF/Java EE training >> and >> > > > > > consulting >> > > > > > > http://www.JSFCentral.com - JavaServer Faces FAQ, news, and >> > info | >> > > > > > > @jsfcentral >> > > > > > > +1 203-998-0403 >> > > > > > > >> > > > > > > * JSF2 in Action Course - 6/17 - London: >> > > > > > > http://skillsmatter.com/course/home/jsf-and-ajax/ng-6708 >> > > > > > > * Listen to the Enterprise Java Newscast: * >> > > > > > > http://blogs.jsfcentral.com/JSFNewscast/ >> > > > > > > * >> > > > > > > * JSFCentral Interviews Podcast: >> > > > > > > http://www.jsfcentral.com/resources/jsfcentralpodcasts/ >> > > > > > > * Sign up for the JSFCentral Newsletter: >> > > > > > > http://oi.vresp.com/?fid=ac048d0e17 >> > > > > > > >> > > > > > > >> > > > > > > On Mon, May 13, 2013 at 7:17 AM, Thomas Andraschko < >> > > > > > > [email protected]> wrote: >> > > > > > > >> > > > > > > > Hi, >> > > > > > > > >> > > > > > > > is it possible unwrap a CC ValueExpresion? >> > > > > > > > i found a bug with PrimeFaces p:media inside a composite >> > > component >> > > > > and >> > > > > > i >> > > > > > > > would like to fix it. >> > > > > > > > >> > > > > > > > If you pass the EL via a CC attr (e.g. >> #{myController.content}) >> > > and >> > > > > > > attach >> > > > > > > > it to p:media (e.g. #{cc.attrs.content}), >> > > > > > > > p:media gets the ValueExpression and saves them in the >> session, >> > > to >> > > > > > later >> > > > > > > > stream the content in a resource request. >> > > > > > > > Later the ResourceHandler evaluates it and tries to get the >> > value >> > > > of >> > > > > > > > #{cc.attrs.content}, which can't work ofc. >> > > > > > > > >> > > > > > > > So is it possible to extract the "real" EL before store it >> in >> > the >> > > > > > > session? >> > > > > > > > Is there a solution which also works in mojarra? >> > > > > > > > >> > > > > > > > >> > > > > > > > Regards, >> > > > > > > > Thomas >> > > > > > > > >> > > > > > > >> > > > > > >> > > > > >> > > > > >> > > > > >> > > > > -- >> > > > > <br/> >> > > > > <br/> >> > > > > Mit freundlichen Grüßen,<br/> >> > > > > <hr/> >> > > > > <b>Christian Beikov</b><br/> >> > > > > Blazebit Design & Developing<br/> >> > > > > <a href="http://www.blazebit.com">http://www.blazebit.com >> </a><br/> >> > > > > >> > > > >> > > >> > > >> > > >> > > -- >> > > <br/> >> > > <br/> >> > > Mit freundlichen Grüßen,<br/> >> > > <hr/> >> > > <b>Christian Beikov</b><br/> >> > > Blazebit Design & Developing<br/> >> > > <a href="http://www.blazebit.com">http://www.blazebit.com</a><br/> >> > > >> > >> >> >> >> -- >> <br/> >> <br/> >> Mit freundlichen Grüßen,<br/> >> <hr/> >> <b>Christian Beikov</b><br/> >> Blazebit Design & Developing<br/> >> <a href="http://www.blazebit.com">http://www.blazebit.com</a><br/> >> > >

