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/>
>