Wednesday, December 25, 2013

ADF - Showing UCM Images in carousel

I had an interesting requirement where we are showing all the available properties in a list view(new feature in 11.1.1.7). Each row of a list view has a carousel. Carousel will show images of the concerned property. The images are residing in UCM. Whenever a new image is uploaded in UCM automatically the carousel will include the new image as well.




Now i will explain how we have implemented the same.


Page :
-----------

Put a carousel component in list item or table column:
 <af:carousel id="c1"  var="row1" 
                                     value="#{backingBeanScope.PropertySearchBean.propertyImages}"
                                     varStatus="vs" auxiliaryPopOut="hover"
                                     displayItems="circular"
                                     emptyText="No Images to Display"
                                     controlArea="small"
                                     contentDelivery="immediate">
                        
                          <f:facet name="nodeStamp">
                            <af:carouselItem id="ci1"
                                             inlineStyle="background-color:transparent;">
                              <af:image source="/showimageservlet?index=#{vs.index}&amp;id=#{row1.pk1}"  
                                          inlineStyle="width:180px; height:145px;"/>
                              </af:panelGroupLayout>
                            </af:carouselItem>
                          </f:facet>
</af:carousel>

 The value of carousel is pointing to propertyImages(List<ImageInfo>) attribute in backing bean.
ImageInfo is a bean which has been built to contain properties of the images like 
    private BlobDomain imageData;
    private String imageTitle;
    private String pk1;
    private String pk2;
    private String dID;

Backing Bean method:
----------------------------
    public List<ImageInfo> getPropertyImages()
    {
//pk1 of property
       String propertyCode = (String)resolveExpressionasObject("#{row.FacilityCode}").toString();
  // if already we have retrieved once from UCM, no need to retrieve again. We keep it in session, // // //pageFlowScope depending on number of images, etc
        propertyImages = getPropertyImageListFromPageFlowScope(propertyCode);
        if(propertyImages != null)
            return propertyImages; 
      // Get images from UCM, create ImageInfo objects and return a list containg ImageInfo
        propertyImages = getImages(propertyCode);
        putImagesMapInPageFlowScope(propertyImages, propertyCode);
        return propertyImages;
    }

The source of the image is coming from a servlet and I am passing two parameters to the servlet : pk1 (primary key of the list ie, property id in my case), vs.index(index of image in carousel so that if you click to enlarge it, the same will be opened)

Servlet:
-------------
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response) throws ServletException,
                                                           IOException {
        int index = Integer.parseInt(request.getParameter("index"));
        String propertyCode = request.getParameter("id");
        
        HashMap hmap = (HashMap)request.getSession().getAttribute("ImagesMap");
        List<ImageInfo> list = (List<ImageInfo>)hmap.get(propertyCode);
        ImageInfo imageInfo = list.get(index);
        BlobDomain bd = imageInfo.getImageData();
        OutputStream os = response.getOutputStream();
         BufferedInputStream in =
            new BufferedInputStream(new ByteArrayInputStream(bd.toByteArray()));
         
        int b;
        byte[] buffer = new byte[10240];
        while ((b = in.read(buffer, 0, 10240)) != -1) {
            os.write(buffer, 0, b);
        }
        os.close();
    }

Please provide your comments if it looks useful.
Let me know if this can be improved or for any queries on the same.

-----Deepak

1 comment:

  1. i need to use carousel to display images from folder

    ReplyDelete