Platform Request Listener

From LongJump Support Wiki

Notepad.png

Note: This experimental feature is currently disabled.

ISVs can use PlatformRequestListener interface to modify selected multipart requests before they get to the server. Any class defined in the platform that implements that interface can then intercept requests coming to the server, and manipulate them before sending them on the server for processing.

The interceptor is called only for multipart REST requests, for these URIs:

URI Method Content Type
/rest/record/{object id} POST Multipart/form-data
/rest/record/{object id}/{record id} PUT Multipart/form-data
/rest/document/record/{object id} POST Multipart/form-data

PlatformRequestListener Interface

Here is the PlatformRequestListener interface:

package com.platform.api;

import java.util.Map;
import com.platform.api.MultipartData;

public interface PlatformRequestListener
{
  public void processRequest(Map<String, MultipartData> parts, Map params);
}

The arguments delivered to the processRequest method are:

parts
Maps part names to the corresponding parts in the multipart data object.
params
Map the key/value pairs in the XML request that was sent along with all the file parts.

Notepad.png

Note: A multipart REST request always contains an XML part that specifies the request, and a file part that constitutes the payload. The params argument contains the request settings extracted from the XML. The parts argument carries the payload.

Learn more: See the PlatformRequestListener interface.

MultipartData Class

When the listener gets the multipart data object, it can manipulate the contents of that object in any manner it desires, using the MultipartData APIs shown here:

package demo.common;

import com.platform.api.*;


public class MultipartData {
    private String file_name;
    private String encoding_type;
    private File file;
    private String file_parameter_name;

    public MultipartData(String file_name, String encoding_type, 
                         File file, String file_parameter_name)
    {
      this.file_name = file_name;
      this.encoding_type = encoding_type;
      this.file = file;
      this.file_parameter_name = file_parameter_name;
    }

    public String getFileParameterName() {
      return file_parameter_name;
    }

    public String getFileName() {
      return this.file_name;
    }

    public File getFile() {
      return this.file;
    }

    public String getContentType() {
      return this.encoding_type;
    }

    public void setFileName(String fileName) {
      file_name = fileName;
    }

    public void setContentType(String encodingType) {
      encoding_type = encodingType;
    }

    public void setFile(File file) {
      this.file = file;
    }

    public void setFileParameterName(String fileParameterName) {
      this.file_parameter_name = fileParameterName;
    } 
}
Learn more: MultipartData class

Sample Implementation

This implementation crops images that are sent to the platform over one of the interceptable REST APIs.

import com.platform.api.MultipartData;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Hashtable;
import java.util.List;
import java.util.Map.Entry;

import javax.imageio.ImageIO;

public class SampleRequestListener 
    implements com.platform.api.PlatformRequestListener
{
    public void processRequest(Map<String, MultipartData> parts, Map params)
    {
      Functions.debug("processRequest from Impl");
      Functions.debug("parts.size() is " + parts.size());        
      for(Map.Entry<String, MultipartData> e: parts.entrySet())
      {
        if(e.getKey().equals("pic"))
        {
          MultipartData mp = e.getValue();               
          File f = mp.getFile();                
          try
          {
            f = resizeAndCrop(f, 200, 200, 0, 400, 0, 100);
          }
          catch(Throwable t)
          {
            Functions.debug(t);
          }            
          mp.setFile(f);
        }
      }
      Functions.debug("parts.size() is " + parts.size());
    }
    
    private File resizeAndCrop(File f, int width, int height, int top,
            int cropHeight, int left, int cropWidth) 
    throws IOException 
    {
      BufferedImage image = ImageIO.read(f);
      BufferedImage resized = new BufferedImage(width, height,
                                                BufferedImage.TYPE_INT_ARGB);
      Graphics2D g = resized.createGraphics();
      g.setComposite(AlphaComposite.Src);
      g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                         RenderingHints.VALUE_INTERPOLATION_BILINEAR);
      g.setRenderingHint(RenderingHints.KEY_RENDERING,
                         RenderingHints.VALUE_RENDER_QUALITY);
      g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                         RenderingHints.VALUE_ANTIALIAS_ON);

      g.drawImage(image, 0, 0, width, height, null);
      g.dispose();

      FilteredImageSource filteredImageSource = new FilteredImageSource(
              resized.getSource(), 
              new CropImageFilter(left, top, cropWidth, cropHeight));
      Image croppedImage = 
              Toolkit.getDefaultToolkit().createImage(filteredImageSource);

      BufferedImage cropped = new BufferedImage(cropWidth, cropHeight,
                                                BufferedImage.TYPE_INT_ARGB);
      Graphics2D bufImageGraphics = cropped.createGraphics();
      bufImageGraphics.drawImage(croppedImage, 0, 0, null);

      ImageIO.write(cropped, "png", f);
      return f;
    }

}