myfaces-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Christian Beikov <christian.bei...@gmail.com>
Subject Re: Unwrap CC ValueExpression?
Date Mon, 13 May 2013 12:25:04 GMT
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 <andraschko.thomas@gmail.com>

> 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 <kito.mann@virtua.com>
>
> > 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 <
> > andraschko.thomas@gmail.com> 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/>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message