Monday, November 4, 2013

Chain of Responsibility, aka CoR




What it means


CoR UML Digram
Processing or handling the request in a chained fashion, where all the objects are either equally capable or capable of executing the request based on certain conditions. If one object can not process, the request is passed on to the next available handler in the chain, and so on. And, the request is finally processed by one of them.



Applications of CoR

  • Rule engine to apply n number of rules
  • A parsing engine, similar to XML Parsing
  • Assigning the responsibility to an available executor, for example, in a chat based support application

And..many more if you look around. My imagination is compilers and interpreters too are based on this design pattern.

References


How it is similar or different from other patterns?

Often, the question arises, why CoR is different from Strategy, decorator and command etc. Below are the links where we can find some useful discussion:

A pop window (row editor) example for JTable

Have been working on web application for quite sometime. But, I must say, a taste of how desktop applications are built using Swing and JavaFx is not bad either. 

Recently, one of my friend came up with a question, how to get a pop up editor for a row in JTable the way we get for a grid in web application. Honestly, I never worked on Swing based app in my career, my first hand experience on swing programming lasted only till college. So, I decided to take this opportunity to learn a bit of swing. 

After doing a bit of study on oracle's swing docs & tutorial and going thru a few similar questions on stack overflow, I found a close answer to the problem.

I thinks, couple of tricks to achieve this was:
  1. First, to instantiate JTable, use the constructor that accepts TableModel (that extends AbstractTableModel), so that, the default cell editing can be disabled, otherwise the double click event will enable the cell editing instead of popping up an editor JFrame.
  2. Second, use a JInternalFrame as a popup editor box.

And, here is the sample code:


package com.myapp.test;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.AbstractTableModel;

public class JTableFrame extends JFrame {

 private static final long serialVersionUID = 1L;
 public static final boolean DEBUG = false;

 JTableFrame() {

  MyTableModel myMyTableModel = new MyTableModel();

  JTable table = new JTable(myMyTableModel);
  
  table.addMouseListener(new MouseAdapter() {
   public void mouseClicked(MouseEvent e) {
    if (e.getClickCount() == 2) {
     JTable target = (JTable) e.getSource();
     int row = target.getSelectedRow();
     int column = target.getSelectedColumn();
     System.out.println("row=" + row + " - " + "col=" + column);
     System.out.println("value here is:"
       + target.getValueAt(row, column));
     
     // use JInternalFrame as pop up editor
     JInternalFrame editorPopup = new JInternalFrame(
       "Edit Record", true, true, true, true);

     GridLayout gridLayout = new GridLayout(0, 2);
     gridLayout.setHgap(5);
     gridLayout.setVgap(5);

     editorPopup.setLayout(gridLayout);
     
     // creating the popup form elements and setting the values
     for (int i = 0; i < target.getColumnCount(); i++) {
      System.out.print(target.getValueAt(row, i) + ":");

      editorPopup.add(new JLabel(getColumnTitle(i)));
      JTextField txtFname = new JTextField(20);
      txtFname.setText(target.getValueAt(row, i).toString());
      editorPopup.add(txtFname);

     }

     JButton okButton = new JButton("Ok");
     okButton.addMouseListener(new MouseAdapter() {
      public void mouseClicked(MouseEvent e) {

       JOptionPane.showMessageDialog(((JButton) e
         .getSource()).getParent(), "Record Saved!");
      }
     });

     editorPopup.add(okButton);
     editorPopup.add(new JButton("Cancel"));

     editorPopup.pack();

     target.add(editorPopup);
     editorPopup.setVisible(true);
    }

   }
  });

  table.setPreferredScrollableViewportSize(new Dimension(1000, 700));
  table.setFillsViewportHeight(true);

  // Create the scroll pane and add the table to it.
  JScrollPane scrollPane = new JScrollPane(table);

  add(scrollPane);
  this.setSize(1000, 600);
  // pack();
  setVisible(true);
 }

 class MyTableModel extends AbstractTableModel {

  private static final long serialVersionUID = 1L;

  private String[] columnNames = { "First Name", "Last Name", "Sport",
    "# of Years", "Vegetarian" };
  private Object[][] data = {
    { "Kathy", "Smith", "Snowboarding", new Integer(5),
      new Boolean(false) },
    { "John", "Doe", "Rowing", new Integer(3), new Boolean(true) },
    { "Sue", "Black", "Knitting", new Integer(2),
      new Boolean(false) },
    { "Jane", "White", "Speed reading", new Integer(20),
      new Boolean(true) },
    { "Joe", "Brown", "Pool", new Integer(10), new Boolean(false) } };

  public int getColumnCount() {
   return columnNames.length;
  }

  public int getRowCount() {
   return data.length;
  }

  public String getColumnName(int col) {
   return columnNames[col];
  }

  public Object getValueAt(int row, int col) {
   return data[row][col];
  }

  /*
   * JTable uses this method to determine the default renderer/ editor for
   * each cell. If we didn't implement this method, then the last column
   * would contain text ("true"/"false"), rather than a check box.
   */
  public Class getColumnClass(int c) {
   return getValueAt(0, c).getClass();
  }

  /*
   * Overriden this to disable the default editing of cell 
   */
  public boolean isCellEditable(int row, int col) {

   return false;

  }

  /*
   * Don't need to implement this method unless your table's data can
   * change.
   */
  public void setValueAt(Object value, int row, int col) {
   if (DEBUG) {
    System.out.println("Setting value at " + row + "," + col
      + " to " + value + " (an instance of "
      + value.getClass() + ")");
   }

   data[row][col] = value;
   fireTableCellUpdated(row, col);

   if (DEBUG) {
    System.out.println("New value of data:");
    printDebugData();
   }
  }

  private void printDebugData() {
   int numRows = getRowCount();
   int numCols = getColumnCount();

   for (int i = 0; i < numRows; i++) {
    System.out.print("    row " + i + ":");
    for (int j = 0; j < numCols; j++) {
     System.out.print("  " + data[i][j]);
    }
    System.out.println();
   }
   System.out.println("--------------------------");
  }

 }
 
 private String getColumnTitle(int index) {

  String title = null;

  switch (index) {
  case 0:
   title = "First Name";
   break;
  case 1:
   title = "Second Name";
   break;
  case 2:
   title = "Sport";
   break;
  case 3:
   title = "No of Year";
   break;
  case 4:
   title = "is Vegitarian?";
   break;
  case 5:
   title = "--";
   break;
  }

  return title;
 }

 public static void main(String args[]) {
  new JTableFrame();
 }
}

Maven FAQs

Maven, as a build tool replacement for ANT, has been on my Radar for last few months now. Although, we as team are little late to adopt it. However, for late adopters, there is always an added advantage of availability of resources.
 
There are plenty of resources and books available online at the cost, it uses your network bandwidth. However, for a build tool, usually we go by learning only what we need to do and mostly, "learning by doing" approach. Hence, maintaining this FAQ of a some of the interesting find outs of Maven, while trying to learn it, following the reverse engineering way. 

Please Note: Many of us, including me, would agree that Maven is not just the build tool. But, it always wise to learn walking first, rather than learning how to run, isn't it? :)

What does it mean if the maven dependency is of type war?

http://maven.apache.org/plugins/maven-war-plugin/overlays.html

What is transitive dependency?


What does different dependency scopes mean?

http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope

How to test a webapp using Jetty?

http://maven.apache.org/plugins/maven-war-plugin/examples/rapid-testing-jetty6-plugin.html

How to force maven to update local maven repository?

http://stackoverflow.com/questions/15673431/how-to-force-maven-to-update-local-repo

How to enable compilation at a particular Java version, say JDK1.5?

By default, if you run the maven build from eclipse, it takes the build JDK version set up in the Eclipse's project environment. So, to enable the build at higher or lower JDK level,  add this to your plugin list, so that the correct version is being taken for java compiler:


<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-compiler-plugin</artifactId>
 <version>2.0.2</version>
 <configuration>
  <source>1.5</source>
  <target>1.5</target>
 </configuration>
</plugin> 
 

Eclipse fails to copy resources, results in error something like below:

org.apache.maven.lifecycle.LifecycleExecutionException: Internal error in the plugin manager executing goal 'org.apache.maven.plugins:maven-resources-plugin:2.2:resources': Mojo execution failed.

We faced this issue while running maven build from eclipse, after bit of goggling and connecting some dots, we realized that the default maven-resources-plugin version used by eclipse, which is by the way defined in some pom.xml somewhere in your eclipse installation folder, was 2.1. This is a bit buggy when it is used with certain eclipse variants. So, in order to resolve this problem, point it to a higher version plugin. To do this, add the maven-resources-plugin, a plugin entry in your <plugins> list of pom.xml, precisely, like this:


<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-resources-plugin</artifactId>
 <version>2.5</version>
</plugin>
 
In my case, pointing it to 2.5 resolved this issue.
 

Using Maven, compiling and Running a Java File, with main() method?

 
mvn compile exec:java -Dexec.mainClass="com.myapp.App"  

 
  

Prototype

Prototype is another creation pattern. Intent:  - Intent is to create objects by cloning existing instance  - Specify the kinds of obj...