Wednesday, 12 June 2013

First example: ValidatingRequestBodyMethodArgumentResolver

 One problem found when implementing a REST server, is that of input validation. Especially for objects, it is common to want to use the JSR-303 @Valid annotation to ensure your input is valid. Spring currently has an open bug, SPR-6709, which states that the @Valid annotation on an @RequestBody parameter does not work. Recent activity indicates it will not be with us much longer, but it is a good example to extend existing functionality.
Below is a class we have implemented to solve this problem. It delegates the translation of the request body to the original class, RequestResponseBodyMethodProcessor, and then validates the result if needed:


In this class, the delegation is clearly visible. The injected dependency to RequestMappingHandlerAdapter seems unfortunate, but it handles the underlying HttpMessageConverter implementations much better than we could do. Finally, the exception class ValidationException translates the JSR-303 constraint violations into a form we want.
Lastly, we need to configure Spring MVC to use our class. We use an XML configuration, which looks like this:



The end result is that @Valid and @RequestBody play nice together. 

Leveraging the Spring MVC 3.1 HandlerMethodArgumentResolver interface

 A familiar problem when implementing a REST server, is that your framework limits what you can do. Sometimes, this problem can be mitigated (not solved) by reformulating (i.e. changing) your business needs. For example, you can reformulate save multiple changes to an invoice and its invoice lines with one click on a save button to save each of multiple changes to an invoice and its invoice lines as separate UI actions. Unfortunately, this change increases your audit trail and thus technology trumps business needs.

Another limit is that conversions have no context. This makes the conversions easier, but also makes functionality like partial updates impossible. That is, it is not possible to that a request body can contain any subset of the changeable properties of a resource, and that all properties that are left out are left at their current values. The default Spring implementation, for example, treats undefined properties as set to their default value. Our goal was to change that to keep the current value in the database.

In this in-depth technical article, I will show you how the new Spring 3.1 interface HandlerMethodArgumentResolver can be used to remove such framework limits. The result is that your business needs are again in control, not the technology.

Background

Spring MVC 3.0 supports REST using the annotation @RequestMapping. This annotation is also used to map normal web application requests to a method of an @Controller bean. With @RequestMapping you can specify the URL being mapped and the HTTP method that a controller method understands. You can also use the annotations @PathVariable and @RequestParam to extract URL templates and request parameters from requests, respectively. The pièce de résistance for REST are the annotations @RequestBody and @ResponseBody, which map Java classes from the request body, respectively to the response body.

If you look at the code, you will see that the translation from the request to the invocation of the controller method is done using a big if/else statement in the class HandlerMethodInvoker (used in AnnotationMethodHandlerAdapter). Not the prettiest solution, and nearly impossible to extend. You can augment some functionality by using AOP, but nothing more.

Spring 3.1

Spring 3.1 will improve this by using a new class, RequestMappingHandlerAdapter, which implements a strategy pattern using the interface HandlerMethodArgumentResolver. The old/current implementation, AnnotationMethodHandlerAdapter, will remain for backward compatibility.

The core of the new implementation (at least for developers) is the interface HandlerMethodArgumentResolver. This interface has two methods: supportsParameter(MethodParameter) to check if a method parameter is supported, and resolveArgument(MethodParameter, ModelAndViewContainer, NativeWebRequest, WebDataBinderFactory) to actually resolve the method parameter from the request. Default implementations exist for all supported parameters of @RequestMapping annotated methods.

The class RequestMappingHandlerAdapter checks all method parameters against its lists of custom and default HandlerMethodArgumentResolver instances, and the first one that says it supports the method parameter will be used to resolve it.

This new interface gives us some very nice opportunities. I will explain some of them by demonstrating how easy it is to implement your own HandlerMethodArgumentResolver. The examples will show how to extend the REST framework provided by Spring, including adjusting the behavior of the existing Spring implementations.

The Spring version we are using is the latest and greatest, so first we need to add the Spring snapshot repository to our pom.xml:

And finally, we will need to adjust the Spring version of our dependencies to: 3.1.0.BUILD-SNAPSHOT


Monday, 10 June 2013

Custom JComboBox Popup in Swing

Call It in your class....

jComboBox=new JComboBox(vector);

BoundsPopupMenuListener listener =
   new BoundsPopupMenuListener(true, true);

jComboBox.addPopupMenuListener( listener );

jComboBox.setPrototypeDisplayValue("ItemWWW");


-------------------------------------------------------------------------------------------------------------------------------
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.basic.*;

/**
 *  This class will change the bounds of the JComboBox popup menu to support
 *  different functionality. It will support the following features:
 *  -  a horizontal scrollbar can be displayed when necessary
 *  -  the popup can be wider than the combo box
 *  -  the popup can be displayed above the combo box
 *
 *  Class will only work for a JComboBox that uses a BasicComboPop.
 */
public class BoundsPopupMenuListener implements PopupMenuListener
{
private boolean scrollBarRequired = true;
private boolean popupWider;
private int maximumWidth = -1;
private boolean popupAbove;
private JScrollPane scrollPane;

/**
*  Convenience constructore to allow the display of a horizontal scrollbar
*  when required.
*/
public BoundsPopupMenuListener()
{
this(true, false, -1, false);
}

/**
*  Convenience constructor that allows you to display the popup
*  wider and/or above the combo box.
*
*  @param popupWider when true, popup width is based on the popup
*                    preferred width
*  @param popupAbove when true, popup is displayed above the combobox
*/
public BoundsPopupMenuListener(boolean popupWider, boolean popupAbove)
{
this(false, popupWider, -1, popupAbove);
}

/**
*  Convenience constructor that allows you to display the popup
*  wider than the combo box and to specify the maximum width
*
*  @param maximumWidth the maximum width of the popup. The
*                      popupAbove value is set to "true".
*/
public BoundsPopupMenuListener(int maximumWidth)
{
this(true, true, maximumWidth, false);
}

/**
*  General purpose constructor to set all popup properties at once.
*
*  @param scrollBarRequired display a horizontal scrollbar when the
*         preferred width of popup is greater than width of scrollPane.
*  @param popupWider display the popup at its preferred with
*  @param maximumWidth limit the popup width to the value specified
*         (minimum size will be the width of the combo box)
*  @param popupAbove display the popup above the combo box
*
*/
public BoundsPopupMenuListener(
boolean  scrollBarRequired, boolean popupWider, int maximumWidth, boolean popupAbove)
{
setScrollBarRequired( scrollBarRequired );
setPopupWider( popupWider );
setMaximumWidth( maximumWidth );
setPopupAbove( popupAbove );
}

/**
*  Return the maximum width of the popup.
*
*  @return the maximumWidth value
*/
public int getMaximumWidth()
{
return maximumWidth;
}

/**
*  Set the maximum width for the popup. This value is only used when
*  setPopupWider( true ) has been specified. A value of -1 indicates
*  that there is no maximum.
*
*  @param maximumWidth  the maximum width of the popup
*/
public void setMaximumWidth(int maximumWidth)
{
this.maximumWidth = maximumWidth;
}

/**
*  Determine if the popup should be displayed above the combo box.
*
*  @return the popupAbove value
*/
public boolean isPopupAbove()
{
return popupAbove;
}

/**
*  Change the location of the popup relative to the combo box.
*
*  @param popupAbove  true display popup above the combo box,
*                     false display popup below the combo box.
*/
public void setPopupAbove(boolean popupAbove)
{
this.popupAbove = popupAbove;
}

/**
*  Determine if the popup might be displayed wider than the combo box
*
*  @return the popupWider value
*/
public boolean isPopupWider()
{
return popupWider;
}

/**
*  Change the width of the popup to be the greater of the width of the
*  combo box or the preferred width of the popup. Normally the popup width
*  is always the same size as the combo box width.
*
*  @param popupWider  true adjust the width as required.
*/
public void setPopupWider(boolean popupWider)
{
this.popupWider = popupWider;
}

/**
*  Determine if the horizontal scroll bar might be required for the popup
*
*  @return the scrollBarRequired value
*/
public boolean isScrollBarRequired()
{
return scrollBarRequired;
}

/**
*  For some reason the default implementation of the popup removes the
*  horizontal scrollBar from the popup scroll pane which can result in
*  the truncation of the rendered items in the popop. Adding a scrollBar
*  back to the scrollPane will allow horizontal scrolling if necessary.
*
*  @param scrollBarRequired  true add horizontal scrollBar to scrollPane
*                            false remove the horizontal scrollBar
*/
public void setScrollBarRequired(boolean scrollBarRequired)
{
this.scrollBarRequired = scrollBarRequired;
}

/**
*  Alter the bounds of the popup just before it is made visible.
*/
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e)
{
JComboBox comboBox = (JComboBox)e.getSource();

if (comboBox.getItemCount() == 0) return;

final Object child = comboBox.getAccessibleContext().getAccessibleChild(0);

if (child instanceof BasicComboPopup)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
customizePopup((BasicComboPopup)child);
}
});
}
}

protected void customizePopup(BasicComboPopup popup)
{
scrollPane = getScrollPane(popup);

if (popupWider)
popupWider( popup );

checkHorizontalScrollBar( popup );

//  For some reason in JDK7 the popup will not display at its preferred
//  width unless its location has been changed from its default
//  (ie. for normal "pop down" shift the popup and reset)

Component comboBox = popup.getInvoker();
Point location = comboBox.getLocationOnScreen();

if (popupAbove)
{
int height = popup.getPreferredSize().height;
popup.setLocation(location.x, location.y - height);
}
else
{
int height = comboBox.getPreferredSize().height;
popup.setLocation(location.x, location.y + height - 1);
popup.setLocation(location.x, location.y + height);
}
}

/*
*  Adjust the width of the scrollpane used by the popup
*/
protected void popupWider(BasicComboPopup popup)
{
JList list = popup.getList();

//  Determine the maximimum width to use:
//  a) determine the popup preferred width
//  b) limit width to the maximum if specified
//  c) ensure width is not less than the scroll pane width

int popupWidth = list.getPreferredSize().width
  + 5  // make sure horizontal scrollbar doesn't appear
  + getScrollBarWidth(popup, scrollPane);

if (maximumWidth != -1)
{
popupWidth = Math.min(popupWidth, maximumWidth);
}

Dimension scrollPaneSize = scrollPane.getPreferredSize();
popupWidth = Math.max(popupWidth, scrollPaneSize.width);

//  Adjust the width

scrollPaneSize.width = popupWidth;
scrollPane.setPreferredSize(scrollPaneSize);
scrollPane.setMaximumSize(scrollPaneSize);
}

/*
*  This method is called every time:
*  - to make sure the viewport is returned to its default position
*  - to remove the horizontal scrollbar when it is not wanted
*/
private void checkHorizontalScrollBar(BasicComboPopup popup)
{
//  Reset the viewport to the left

JViewport viewport = scrollPane.getViewport();
Point p = viewport.getViewPosition();
p.x = 0;
viewport.setViewPosition( p );

//  Remove the scrollbar so it is never painted

if (! scrollBarRequired)
{
scrollPane.setHorizontalScrollBar( null );
return;
}

// Make sure a horizontal scrollbar exists in the scrollpane

JScrollBar horizontal = scrollPane.getHorizontalScrollBar();

if (horizontal == null)
{
horizontal = new JScrollBar(JScrollBar.HORIZONTAL);
scrollPane.setHorizontalScrollBar( horizontal );
scrollPane.setHorizontalScrollBarPolicy( JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED );
}

// Potentially increase height of scroll pane to display the scrollbar

if (horizontalScrollBarWillBeVisible(popup, scrollPane))
{
Dimension scrollPaneSize = scrollPane.getPreferredSize();
scrollPaneSize.height += horizontal.getPreferredSize().height;
scrollPane.setPreferredSize(scrollPaneSize);
scrollPane.setMaximumSize(scrollPaneSize);
scrollPane.revalidate();
}
}

/*
*  Get the scroll pane used by the popup so its bounds can be adjusted
*/
protected JScrollPane getScrollPane(BasicComboPopup popup)
{
JList list = popup.getList();
Container c = SwingUtilities.getAncestorOfClass(JScrollPane.class, list);

return (JScrollPane)c;
}

/*
*  I can't find any property on the scrollBar to determine if it will be
*  displayed or not so use brute force to determine this.
*/
protected int getScrollBarWidth(BasicComboPopup popup, JScrollPane scrollPane)
{
int scrollBarWidth = 0;
JComboBox comboBox = (JComboBox)popup.getInvoker();

if (comboBox.getItemCount() > comboBox.getMaximumRowCount())
{
JScrollBar vertical = scrollPane.getVerticalScrollBar();
scrollBarWidth = vertical.getPreferredSize().width;
}

return scrollBarWidth;
}

/*
*  I can't find any property on the scrollBar to determine if it will be
*  displayed or not so use brute force to determine this.
*/
protected boolean horizontalScrollBarWillBeVisible(BasicComboPopup popup, JScrollPane scrollPane)
{
JList list = popup.getList();
int scrollBarWidth = getScrollBarWidth(popup, scrollPane);
int popupWidth = list.getPreferredSize().width + scrollBarWidth;

return popupWidth > scrollPane.getPreferredSize().width;
}

@Override
public void popupMenuCanceled(PopupMenuEvent e) {}

@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e)
{
//  In its normal state the scrollpane does not have a scrollbar

if (scrollPane != null)
{
scrollPane.setHorizontalScrollBar( null );
}
}
public static void main(String[] args) {
new BoundsPopupMenuListener();
}
}

Saturday, 8 June 2013

Capture the Screen with Java’s Robot Class

While surfing through internet, I came to this amazing piece of code in Java that takes the screen shot of your desktop and save it in a PNG file.
This example uses java.awt.Robot class to capture the screen pixels and returns a BufferedImage. Java.awt.Robot class is used to take the control of mouse and keyboard. Once you get the control, you can do any type of operation related to mouse and keyboard through your java code. This class is used generally for test automation.
Copy and paste following code in your Java class and invoke the method captureScreen() with file name as argument. The screen shot will be stored in the file that you specified in argument.

import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class SimpleScreenCapture {
public static void main(String[] args) throws Exception {
Rectangle rectangle = new Rectangle(Toolkit.getDefaultToolkit()
.getScreenSize());

JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Robot robot = new Robot();
BufferedImage img = robot.createScreenCapture(rectangle);
frame.add(new JLabel(new ImageIcon(img)));
frame.pack();
frame.setVisible(true);
File file = new File("screenshot.gif");

ImageIO.write(img, "gif", file);
}
}

Wednesday, 29 May 2013

Callable vs Runnable

Callable interface
public interface Callable<V>, where V is the return type of the method call. This interface has a single method ‘call’, which needs to be defined by all the classes which implement this interface. This method takes no arguments and returns a result of type V. This method can throw checked exceptions as well.
Runnable interface
public interface Runnable - this interface is implemented by those classes whose instances are supposed to be executed in a different thread. This interface has only one method ‘run’, which takes no arguments and obviously all the classes implementing this interface need to define this method.
This interface is implemented by the Thread class as well and it’s a common protocol for all the objects who wish to execute in a different thread. It’s one of the ways of creating threads in Java. The other way to create a thread is by sub-classing theThread class. A class implementing Runnable interface can simply pass itself to create a Thread instance and can run thereafter. This eliminates the need of sub-classing the Thread class for the purpose of executing the code in a separate thread.
As long as we don’t wish to override other methods of the Thread class, it may be a better idea to implement the Runnable interface to enable multithreading capabilities to a class than enabling the same by extending the Thread class.
Callable vs Runnable
Though both the interfaces are implemented by the classes who wish to execute in a different thread of execution, but there are few differences between the two interface which are:-
  • A Callable<V> instance returns a result of type V, whereas a Runnableinstance doesn’t
  • A Callable<V> instance may throw checked exceptions, whereas aRunnable instance can’t
The designers of Java felt a need of extending the capabilities of the Runnableinterface, but they didn’t want to affect the uses of the Runnable interface and probably that was the reason why they went for having a separate interface namedCallable in Java 1.5 than changing the already existing Runnable interface which has been a part of Java since Java 1.0.

ASCII Art Java Example

package com.jay;
 
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
 
import javax.imageio.ImageIO;
 
public class ASCIIArt {
 
  public static void main(String[] args) throws IOException {
 
 int width = 100;
 int height = 30;
 
        //BufferedImage image = ImageIO.read(new File("your path/logo.jpg"));
 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
 Graphics g = image.getGraphics();
 g.setFont(new Font("SansSerif", Font.BOLD, 24));
 
 Graphics2D graphics = (Graphics2D) g;
 graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
    RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
 graphics.drawString("JAVA", 10, 20);
 
 //save this image
 //ImageIO.write(image, "png", new File("your path/ascii-art.png"));
 
 for (int y = 0; y < height; y++) {
  StringBuilder sb = new StringBuilder();
  for (int x = 0; x < width; x++) {
 
   sb.append(image.getRGB(x, y) == -16777216 ? " " : "$");
 
  }
 
  if (sb.toString().trim().isEmpty()) {
   continue;
  }
 
  System.out.println(sb);
 }
 
  }
 
}

Tuesday, 7 May 2013

What does “event bubbling” mean? [In context of CSS]

“Delegation” and “bubbling” are terms that gets thrown round a lot in JavaScript; but what exactly do these terms mean?

Event Bubbling

In JavaScript, events bubble. This means that an event propagates through the ancestors of the element the event fired on. Lets show what this means using the HTML markup below;
<div>
    <h1>
        <a href="#">
            <span>Hello</span>
        </a>
    </h1>
</div>
Lets assume we click the span, which causes a click event to be fired on the span; nothing revolutionary so far. However, the event then propagates (or bubbles) to the parent of the span (the <a>), and a click event is fired on that. This process repeats for the next parent (or ancestor) up to the document element.
You can see this in action here. Click “Hello” and see the events as they get fired.
That’s all event bubbling is; an event fired on an element bubbles through its ancestor chain (i.e. the event is also fired on those elements). It’s important to note that this isn’t a jQuery feature, nor is it something that a developer must turn on; it’s a fundamental part of JavaScript that has always existed.
Ok, that’s a little bit of a lie… sort of.
By default, not all events bubble. For instance submit does not normally bubble, nor does change. However, jQuery masks this in the event handling code using all sorts of voodoo, so it will seem that they do bubble when using jQuery.