Desktop sharing using ssh tunnel

Share desktop of A to B with C as the hop. You’ll need access to your own server (C).

Execute on A: (assuming 192.168.1.100 is the ip of machine A)

% ssh -R 3390:192.168.1.100:3389 -l username myserver.com
log in and execute
ping 8.8.8.8 -i 5
to prevent the connection from timing out

Execute on B

% ssh -l username myserver.com -L 3391:localhost:3390

This means that you will be able to connect at localhost:3391 from your home computer and everything will be forwarded to myserver.com:3390.

Point your remote desktop connection to localhost:3391

cropped-DSC_0066-1024x477

Hibernate 4 Integrator pattern and Spring’s DI

Enabling @Autowired in Hibernate entities.

Create an EventListener that kicks in after a Hibernate LOAD event.  Using AutowireCapableBeanFactory to wire @Autowire’d dependencies.

package be.esus.core.infrastructure.hibernate;

import be.core.architecture.common.locator.SpringLocator;
import org.hibernate.event.spi.PostLoadEvent;
import org.hibernate.event.spi.PostLoadEventListener;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;

// https://jira.spring.io/browse/SPR-9187
public class MyPostLoadEventListener implements PostLoadEventListener {
   @Override
   public void onPostLoad(PostLoadEvent postLoadEvent) {
      Object entity = postLoadEvent.getEntity();

      AutowireCapableBeanFactory spring = SpringLocator.getApplicationContext().getAutowireCapableBeanFactory();
      spring.autowireBean(entity);
   }
}

(SpringLocator is a simple custom class that is ApplicationContextAware in order to have static access to the ApplicationContext)

Register your new listener in Hibernate’s EventListenerRegistry.

package be.esus.core.infrastructure.hibernate;

import org.hibernate.cfg.Configuration;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventType;
import org.hibernate.integrator.spi.Integrator;
import org.hibernate.metamodel.source.MetadataImplementor;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
import org.springframework.stereotype.Component;

@Component
public class MyEventListenerIntegrator implements Integrator {

   @Override
   public void integrate(Configuration configuration, SessionFactoryImplementor sessionFactory,
                         SessionFactoryServiceRegistry serviceRegistry) {
      EventListenerRegistry eventListenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );

      eventListenerRegistry.appendListeners(EventType.POST_LOAD, new MyPostLoadEventListener());
   }

   @Override
   public void integrate(MetadataImplementor metadataImplementor,
                         SessionFactoryImplementor sessionFactoryImplementor,
                         SessionFactoryServiceRegistry sessionFactoryServiceRegistry) {

   }

   @Override
   public void disintegrate(SessionFactoryImplementor sessionFactoryImplementor,
                            SessionFactoryServiceRegistry sessionFactoryServiceRegistry) {

   }
}

To register your SPI (see service loader), create
a (text) file called org.hibernate.integrator.spi.Integrator in META-INF/services/ and put the FQCN of your integrator in it:

be.esus.core.infrastructure.hibernate.MyEventListenerIntegrator

Drawing a textured rectangle in Swing

Main.java:

import java.awt.image.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame {
   private BufferedImage image; 
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      image = toBufferedImage(new javax.swing.ImageIcon("c:\djkrush.jpg").getImage());
   }
 
   public void paint(Graphics g) {
      Graphics2D g2d = (Graphics2D) g;
 
      Rectangle2D tr = new Rectangle2D.Double(0, 0, image.getWidth(), image.getHeight());
      TexturePaint tp = new TexturePaint(image, tr);
 
      // draw texture filled ellipse, but with antialiasing
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                           RenderingHints.VALUE_ANTIALIAS_ON);
      BasicStroke bs = new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,
                           10, null, 0);
      g2d.setStroke(bs);
      g2d.setPaint(tp);
      g2d.drawRect(10, 40, 150, 150);
   }
 
   public BufferedImage toBufferedImage(Image image) {
      BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), 
                                           BufferedImage.TYPE_INT_RGB); 
 
      // copy the original image
      Graphics g = bi.createGraphics();
    
      g.drawImage(image, 0, 0, null);
      g.dispose();
 
      return bi;
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(170, 210);
      main.setVisible(true);
   }
}

Image used:

Create an InputStream that returns a filtered version of the original InputStream

Create a class that extends from FilterInputStream and override the method read in which you convert the original value to a new value.

Following example introduces the ChangeCaseInputStream which will convert any character to uppercase or lowercase depending on how you instantiated the class.

Main.java:

import java.io.*;
 
public class Main {
   public static void main(String args[]) {
      if (args.length != 1) {
         System.out.println("Usage: java Main <filename.txt>");
         System.exit(1);
      }
 
      try {
         FileInputStream fis = new FileInputStream(args[0]);
         ChangeCaseInputStream ccis = new ChangeCaseInputStream(
                                        ChangeCaseInputStream.UPPERCASE, fis);
         int b;
         while ((b = ccis.read()) > 0) {
            System.out.print((char) b);
         }
         ccis.close();
      }
      catch(FileNotFoundException e) {
         System.out.println(e);
      }
      catch(IOException e) {
         System.out.println(e);
      }
   }
}
 
class ChangeCaseInputStream extends FilterInputStream {
   public static final int LOWERCASE = 1;
   public static final int UPPERCASE = 2;
 
   private int conversionType;
 
   public ChangeCaseInputStream(int conversionType, InputStream in) {
      super(in);
 
      this.conversionType = conversionType;
   }
 
   public int read() throws IOException {
      int b = in.read();
 
      // first check for EOF
      if (b < 0) {
         return b;
      }
 
      if (conversionType == LOWERCASE) {
         b = (int) Character.toLowerCase((char) b);
      }
      else if (conversionType == UPPERCASE) {
         b = (int) Character.toUpperCase((char) b);
      }
 
      return b;     
   }
}

Using a PushbackReader

The class PushbackReader is useful if you want to look ahead at the incoming stream of data. It allows you to unread the data that you have read. The amount of data that can be unread can be specified.

Here’s a simple Parser example that puts it into practice. The main method creates an instance and passes as an argument a reader that points to the Character stream to be processed, in this case a FileReader. Then it repeatedly reads tokens until EOF. The Parser’s getNextToken method reads in one character to determine what method it should call and unreads that character back onto the stream.

Main.java:

import java.util.*;
import java.io.*;
  
public class Main {   
   public static void main(String[] args) throws Exception {
      if (args.length != 1) { 
         System.out.println("Usage: java Main <file>");
         System.exit(1);
      }
 
      BufferedReader br = new BufferedReader(new FileReader(args[0]));
      Parser parser = new Parser(br);
      String token;
      while ((token = parser.getNextToken()) != null) {
         System.out.println("Found: " + parser.getType() + "t[" + token + "]");
      }
   }
}
 
class Parser
{
   private final static int NOTOKEN  = 0;
   private final static int VARIABLE = 1;
   private final static int ASSIGN   = 2;
   private final static int SEMICOL  = 3;
 
   PushbackReader pr;
   String token = null;
   int type = NOTOKEN;
 
   public Parser(Reader r) {
      pr = new PushbackReader(r);
   }
 
   public String getType() {
      if (type == VARIABLE) return "VARIABLE";
      else if (type == ASSIGN) return "ASSIGN";
      else if (type == SEMICOL) return "SEMICOL";
  
      return "NOTOKEN";
   }
   
   public String getNextToken() throws IOException {
      token = null;
      type = NOTOKEN;
 
      skipWhitespace();
      int k = pr.read();
      if (k != -1) {
         char c = (char) k;
         pr.unread(k);
         if (Character.isLetter(c)) {
            parseVariable();
         }
         else if (c == ':') {
            parseAssign();
         }
         else if (c == ';') {
            parseSemicol();
         }
         else {
            parseError("Unrecognized character: " + c);
         }
      }
  
      return token;
   }
 
   public void skipWhitespace() throws IOException {
      int k;
      while ((k = pr.read()) > -1) {
         if (!Character.isWhitespace((char) k)) {
            pr.unread(k);
            break;
         }
      }   
   }
  
   private void parseVariable() throws IOException {
      StringBuffer buffer = new StringBuffer();
      int k;
      type = VARIABLE;
      while ((k = pr.read()) > -1) {
         if (Character.isLetter((char) k) || Character.isDigit((char) k)) {
            buffer.append((char) k);
         }
         else {
            break;
         }
      }
 
      token = buffer.toString();
   }
 
   private void parseAssign() throws IOException {
      pr.read();   // read ':'  which we already know
      int k = pr.read();
      if (k > -1 && ((char) k) == '=') {
         type = ASSIGN;
         token = ":=";
      }
      else {
         parseError("Expected character '=', found character '" + (char) k + "'");
      }
   }
 
   private void parseSemicol() throws IOException {
      pr.read();   // read ';'  which we already know
      type = SEMICOL;
      token = ";";
   }
 
   private void parseError(String error) {
      System.err.println("ParseError: " + error);
   }
}

Using it on the file test.pas:

a := b;
var1 := var2;

results in:

Found: VARIABLE	[a]
Found: ASSIGN	[:=]
Found: VARIABLE	[b]
Found: SEMICOL	[;]
Found: VARIABLE	[var1]
Found: ASSIGN	[:=]
Found: VARIABLE	[var2]
Found: SEMICOL	[;]

Using it on the file test2.pas:

a12345 := b0003
var1 = var2;

outputs:

Found: VARIABLE [a12345]
Found: ASSIGN   [:=]
Found: VARIABLE [b0003]
Found: VARIABLE [var1]
ParseError: Unrecognized character: =

Renaming and deleting a file in Java

Rename:

Use the method renameTo in the File class. If the destination folder is different from the source folder, it will move the file to the destination folder. Eg.

import java.io.*;
 
public class FileRename 
{
   public static void main(String []args) {
      File file = new File("c:\test.txt");
 
      file.renameTo(new File("c:\test2.txt"));
 
      System.out.println(file.getName());
   }

}

Notice that, after renaming, getName returns the old filename. Bug? Anyone?

Delete:

Use the method delete in the File class. Eg.

import java.io.*;
 
public class FileDelete
{
   public static void main(String []args) {
      File file = new File("c:\test.txt");
 
      file.delete();
   }
}

Changing the mouse cursor when moving over a component

Add a mouse listeners to the component and set another cursor when the mouse
enters it. Set it to the default cursor when the mouse moves out of it.

Here’s an example that creates a JFrame with a number of buttons, each with
a different mouse cursor. Our method createCursor will associate a cursor
to a component.

import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
 
public class Main extends JFrame
{
   private Vector buttons = new Vector();
     
   public static void main(String []args) {
      Main main = new Main();
      main.show();
   }
 
   public Main() {
      buttons.addElement(CreateCursor(new JButton("DEFAULT_CURSOR"), Cursor.DEFAULT_CURSOR));
      buttons.addElement(CreateCursor(new JButton("CROSSHAIR_CURSOR"), Cursor.CROSSHAIR_CURSOR));
      buttons.addElement(CreateCursor(new JButton("TEXT_CURSOR"), Cursor.TEXT_CURSOR));
      buttons.addElement(CreateCursor(new JButton("WAIT_CURSOR"), Cursor.WAIT_CURSOR));
      buttons.addElement(CreateCursor(new JButton("SW_RESIZE_CURSOR"), Cursor.SW_RESIZE_CURSOR));
      buttons.addElement(CreateCursor(new JButton("SE_RESIZE_CURSOR"), Cursor.SE_RESIZE_CURSOR));
      buttons.addElement(CreateCursor(new JButton("NW_RESIZE_CURSOR"), Cursor.NW_RESIZE_CURSOR));
      buttons.addElement(CreateCursor(new JButton("NE_RESIZE_CURSOR"), Cursor.NE_RESIZE_CURSOR));
      buttons.addElement(CreateCursor(new JButton("N_RESIZE_CURSOR"), Cursor.N_RESIZE_CURSOR));
      buttons.addElement(CreateCursor(new JButton("S_RESIZE_CURSOR"), Cursor.S_RESIZE_CURSOR));
      buttons.addElement(CreateCursor(new JButton("W_RESIZE_CURSOR"), Cursor.W_RESIZE_CURSOR));
      buttons.addElement(CreateCursor(new JButton("E_RESIZE_CURSOR"), Cursor.E_RESIZE_CURSOR));
      buttons.addElement(CreateCursor(new JButton("HAND_CURSOR"), Cursor.HAND_CURSOR));
      buttons.addElement(CreateCursor(new JButton("MOVE_CURSOR"), Cursor.MOVE_CURSOR));
 
	getContentPane().setLayout(new GridLayout(buttons.size(), 1));
 
      for (int i=0; i<buttons.size(); i++) {
         getContentPane().add((JButton) buttons.elementAt(i));
      }
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
            System.exit(0);
         }
      });
 
      pack();
   }
 
   private JComponent CreateCursor(final JComponent component, final int cursor) {
	component.addMouseListener(new MouseAdapter() {
	   public void mouseEntered(MouseEvent e) {
		component.setCursor(Cursor.getPredefinedCursor(cursor));
	   }
	   public void mouseExited(MouseEvent e) {
		component.setCursor(Cursor.getDefaultCursor());
	   }
 	});
 
      return component;
   }  
}

Determining the OS at runtime

Use the following code to get information about the operating system:

   System.out.println("OS Name: " + System.getProperty("os.name"));
   System.out.println("OS Architecture: " + System.getProperty("os.arch"));
   System.out.println("OS Version: " + System.getProperty("os.version"));

Output will be something like:

   OS Name: Windows NT
   OS Architecture: x86
   OS Version: 4.0

Converting a hexadecimal value to a byte

The Byte class has a static method decode that can decode decimal, hexadecimal and octal values.

Main.java:

public class Main {
   public static void main(String args[]) throws Exception {
      byte b = Byte.decode("0x0a").byteValue();
  
      System.out.println(b);
   }
}

outputs

10

Performing a fast array copy

The System class contains a method called arraycopy that copies an array or part of an array to another one. You specify a source array (the elements that are being copied) and a destination array (where the elements should go). You should have allocated enough memory for the destination array to hold the new values. Also, you can specify the source offset that indicates from what index the copying should start and an destination offset that indicates what index the values should be copied to. The types of the source array and destination array should match (eg. you can’t copy elements from an object array into an integer array) or an ArrayStoreException will be thrown.

This example copies 5 elements from arr starting from index 3 into arr2 starting from index 0.

Main.java:

import java.util.*;
import java.io.*;
 
public class Main
{
   public static void main(String []args) {
      int arr[] = { 10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9 };
      int arr2[] = new int[5];
      System.arraycopy(arr, 3, arr2, 0, 5);
 
      System.out.print("arr:nt");
      printArray(arr);
      System.out.print("arr2:nt");
      printArray(arr2);
   }      
 
   public static void printArray(int []arr) {
      for (int i=0; i<arr.length; i++) {
         System.out.print(arr[i] + " ");
      }
      System.out.println();
   }
}