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

Embedding a JSpinner inside a JTable cell

Main.java:

import javax.swing.table.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
  
public class JSpinnerTableExample extends JFrame {
 
  public JSpinnerTableExample(){
    super( "JSpinnerTable Example" );
    
    SpinnerNumberModel spinnerModel1 = new SpinnerNumberModel(10.0, -500.0, 500.0, .5);
    SpinnerDateModel spinnerModel2 = new SpinnerDateModel();
 
    DefaultTableModel dtm = new DefaultTableModel();
    dtm.setDataVector(new Object[][]{{ spinnerModel1, "JSpinner1" },
                                     { spinnerModel2, "JSpinner2" }},
                      new Object[]{"JSpinner","String"});
                     
    JTable table = new JTable(dtm);
    table.getColumn("JSpinner").setCellRenderer(new SpinnerRenderer());
    table.getColumn("JSpinner").setCellEditor(new SpinnerEditor());
 
    table.setRowHeight(20);
    JScrollPane scroll = new JScrollPane(table);
    getContentPane().add(scroll);
 
    setSize( 400, 100 );
    setVisible(true);
  }
 
  public static void main(String[] args) {
    JSpinnerTableExample frame = new JSpinnerTableExample();
    frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
  }
}
 
class SpinnerRenderer extends JSpinner implements TableCellRenderer {
   public SpinnerRenderer() {
      setOpaque(true);
   }
  
   public Component getTableCellRendererComponent(JTable table, Object value,
                    boolean isSelected, boolean hasFocus, int row, int column) {
      setModel((SpinnerModel) value);
  
      return this;
   }
}
  
class SpinnerEditor extends AbstractCellEditor implements TableCellEditor {
   protected JSpinner spinner;
  
   public SpinnerEditor() {
      spinner = new JSpinner();
   }
 
   public Component getTableCellEditorComponent(JTable table, Object value,
                    boolean isSelected, int row, int column) {
      spinner.setModel((SpinnerModel) value);
 
      return spinner;
   }
 
   public Object getCellEditorValue() {
      SpinnerModel sm = spinner.getModel();
      return sm;
   }
}

Adding a background image to a JTree that does not scroll

(1.3+)

Main.java:

import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import java.awt.*;
import java.net.*;
import java.awt.event.*;
 
public class Main extends JFrame
{
   public Main() {
      DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
      for (int i=0; i<100; i++) {
         DefaultMutableTreeNode child = new DefaultMutableTreeNode("Child " + (i+1));
         root.add(child);
      }
      JTree tree = new JTree(root);
 
      tree.setOpaque( false );
  
 
      DefaultTreeCellRenderer cr = new DefaultTreeCellRenderer();
      cr.setOpaque(false);
      cr.setBackground(new Color(0, 0, 0, 0));  
      cr.setBackgroundNonSelectionColor(null);
      tree.setCellRenderer(cr);
 
      ImageJScrollPane scrollpane = new ImageJScrollPane(tree);
      scrollpane.setBackgroundImage(new ImageIcon("mong.jpg"));
 
      getContentPane().add(scrollpane);
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(400, 400);
      main.setVisible(true);
   }
}
 
class ImageJScrollPane extends JScrollPane
{
   private ImageIcon image = null;
 
   public ImageJScrollPane() {
      this(null, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
   }
 
   public ImageJScrollPane(Component view) {
      this(view, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
   }
 
   public ImageJScrollPane(Component view, int vsbPolicy, int hsbPolicy) {
      super(view, vsbPolicy, hsbPolicy);
      if (view instanceof JComponent) {
         ((JComponent) view).setOpaque(false);
      }
      setOpaque(false);
      getViewport().setOpaque(false);
      getViewport().setScrollMode(JViewport.BLIT_SCROLL_MODE);
   }
 
   public ImageJScrollPane(int vsbPolicy, int hsbPolicy) {
      this(null, vsbPolicy, hsbPolicy);
   }
 
   public void setBackgroundImage(ImageIcon image) {
      this.image = image;
   }
 
   public void paint(Graphics g) {
      if (image != null) {
         Rectangle rect = getViewport().getViewRect();
         for (int x=0; x<rect.width; x+=image.getIconWidth()) {
            for (int y=0; y<rect.height; y+=image.getIconHeight()) {
               g.drawImage(image.getImage(), x, y, null, null);
            }
         }
         super.paint(g);
      }
 
   }
}

Image used:

Using Apache’s Xerces SAX parser

Download the Xerces Java parser at http://xml.apache.org/xerces2-j/index.html. Adjust your classpath and specify that you want to use the Xerces parser.

Programmatically:

import org.xml.sax.helpers.*;
import javax.xml.parsers.*;
import org.xml.sax.*;
import java.io.*;
 
public class Main 
{
   public static void main(String []args) {
      try {
         SAXParserFactory factory = new org.apache.xerces.jaxp.SAXParserFactoryImpl();    
         SAXParser parser = factory.newSAXParser();
 
         InputSource is = new InputSource(new FileReader("example.xml"));
         parser.parse(is, new DefaultHandler());
      }
      catch(ParserConfigurationException e) {
         e.printStackTrace();
      }
      catch(SAXException e) {
         e.printStackTrace();
      }
      catch(IOException e) {
         e.printStackTrace();
      }        
   }
}

Declaratively:

   java -Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl Main

Traversing a DOM tree using a TreeWalker in Java

(DOM Level 2!) TreeWalker allows you to navigate a DOM tree. You can specify the view on the tree with whatToShow flags and a NodeFilter (for an example on using a NodeFilter, check out How do I traverse a DOM tree using a NodeIterator).

Once you have a TreeWalker instance, you can navigate through the structure using various methods that speak for themselves. Check out the API docs for more information: TreeWalker, NodeFilter.

customers.xml (!!remove the space between ? and xml):

<? xml version="1.0" encoding="UTF-8"?>
<customers>
   <customer id="C12345">
      <name>Joris Van den Bogaert</name>
      <address>
         <addressline>Handelskaai 3</addressline>
         <zip>1000</zip>
         <location>Brussels</location>
         <country>BELGIUM</country>
      </address>
   </customer>
   <customer id="C23495">
      <name>John Doe</name>
      <address>
         <addressline>5, S 5th Ave.</addressline>
         <zip>59715</zip>
         <location>Bozeman, MT</location>
         <country>US</country>
      </address>
   </customer>
   <customer id="C03429">
      <name>John Babcock</name>
      <address>
         <addressline>73, Broad street</addressline>
         <zip>06418</zip>
         <location>Chester, CT</location>
         <country>US</country>
      </address>
   </customer>
   <customer id="C12345">
      <name>Dominique Bodard</name>
      <address>
         <addressline>21-23, Rue de Madrid</addressline>
         <zip>75008</zip>
         <location>Paris</location>
         <country>FRANCE</country>
      </address>
   </customer>
</customers>

Main.java:

import org.w3c.dom.*;
import org.w3c.dom.traversal.*;
  
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
 
import java.io.*;
   
public class Main
{
   public static void main(String []args) {
      Document doc;
  
      try {
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
         DocumentBuilder db = dbf.newDocumentBuilder();
         doc = db.parse(new File("customers.xml")); 
 
         if (!doc.isSupported("Traversal", "2.0")) {
            System.out.println("Traversal not supported in your parser version");
            System.exit(1);
         }
 
         DocumentTraversal dt = (DocumentTraversal) doc;
         TreeWalker walker = dt.createTreeWalker(doc, 
                                                 NodeFilter.SHOW_ALL, 
                                                 null, 
                                                 true);
  
         outputNode(walker.getCurrentNode());  // #document
         outputNode(walker.nextNode());        // customers
         outputNode(walker.nextNode());        // #text
         outputNode(walker.nextNode());        // customer
         outputNode(walker.nextNode());        // #text
         outputNode(walker.nextNode());        // name
         outputNode(walker.lastChild());       // #text [Joris Van den Bogaert]
         outputNode(walker.nextNode());        // #text
         outputNode(walker.nextNode());        // address
         outputNode(walker.previousSibling()); // #text
         outputNode(walker.nextNode());        // address
         outputNode(walker.nextNode());        // #text
         outputNode(walker.parentNode());      // address
         outputNode(walker.nextNode());        // #text
         outputNode(walker.nextSibling());     // addressline
         outputNode(walker.nextNode());        // #text [Handelskaai 3]
         outputNode(walker.previousNode());    // addressline
         outputNode(walker.parentNode());      // address
      }
      catch(Exception e) {
         e.printStackTrace();
      }
   } 
 
   public static void outputNode(Node node) {
      System.out.print(node.getNodeName());
      if (node.getNodeType() == Node.TEXT_NODE && !node.getNodeValue().trim().equals("")) {
         System.out.print(" [" + node.getNodeValue() + "]");
      }
      System.out.println();
   } 
}

outputs:

#document
customers
#text
customer
#text
name
#text [Joris Van den Bogaert]
#text
address
#text
address
#text
address
#text
addressline
#text [Handelskaai 3]
addressline
address

Update rows from a database table

Check out the MySQL syntax for UPDATE here.

Here’s an example that modifes a value in the customer table. You need to create a Statement object from a Connection and invoke executeUpdate on it, passing it the SQL UPDATE command. It returns a ResultSet containing the database rows that match your query. You can then iterate over the rows with the next method. The first call to next will position the “cursor” to the first row. You can get a particular column in that row with the getXXX methods, specifying either the column index or the column name. Make sure the database column type and the resulting variable type match, or a proper conversion is done. If types don’t match, a Bad format SQLException is thrown.

Main.java:

import java.util.*;
import java.sql.*;
  
public class Main {
   public static void main(String []args) {
      try {
         Database db = new Database("org.gjt.mm.mysql.Driver",
                                    "jdbc:mysql://192.168.0.1/esus",
                                    "joris",
                                    "mypass");
         Connection con = db.getConnection();
         CustomerDAO custDAO = new CustomerDAO(con);
 
         printCollection(custDAO.getAllRows()); 
 
         Customer cust = custDAO.getCustomer("Joris Van den Bogaert");
         if (cust != null) {
            cust.setEmail("joris_vandenbogaert1@yahoo.com");
            custDAO.updateEmail(cust);
         }
  
         System.out.println();
         printCollection(custDAO.getAllRows()); 
         db.close();
      }
      catch(DatabaseException e) {
         e.printStackTrace();
      }
   }
 
   public static void printCollection(Collection c) {
      Iterator iter = c.iterator();
      while (iter.hasNext()) {
         System.out.println(iter.next());
      }
   }
}
 
class Customer
{
   private String name;
   private String email;
 
   public Customer() { }
 
   public Customer(String name, String email) {
      setName(name);
      setEmail(email);
   }
  
   public void setName(String name) {
      this.name = name;
   }
 
   public void setEmail(String email) {
      this.email = email;
   }
 
   public String getName() {
      return name;
   }
 
   public String getEmail() {
      return email;
   }
 
   public String toString() {
      return "Customer [name=" + getName() + ", email=" + getEmail() + "]";
   }
}
 
class Database
{
   Connection connection = null;
  
   public Database(String driver, String url, String user, String pass) 
                      throws DatabaseException 
   {
      try {
         Class.forName(driver).newInstance();
 
         connection = DriverManager.getConnection(url, user, pass);
      }
      catch(Exception e) {
         throw new DatabaseException(e.getMessage());
      }
   }
 
   public Connection getConnection() {
      return connection;
   }
 
   public void close() throws DatabaseException {
      try {
         connection.close();
      }
      catch(Exception e) {
         throw new DatabaseException(e.getMessage());
      }
   } 
}   
 
class DatabaseException extends Exception {
   public DatabaseException() {
   }
 
   public DatabaseException(String message) {
      super(message);
   }
}
 
class CustomerDAO 
{
   Connection connection = null;
 
   public CustomerDAO(Connection connection) {
      this.connection = connection;
   }
 
   public void updateEmail(Customer cust) throws DatabaseException {
      try {
         Statement stmt = connection.createStatement();
 
         stmt.executeUpdate("UPDATE customers SET email = '" + cust.getEmail() + "' " +
                            "WHERE name = '" + cust.getName() + "'");
         stmt.close();      
      }
      catch(SQLException e) {
         throw new DatabaseException(e.getMessage());
      }
   }
 
   public Customer getCustomer(String name) throws DatabaseException {
      try {
         Statement stmt = connection.createStatement();
         ResultSet rs = stmt.executeQuery("SELECT * FROM customers " +
                                          "WHERE name='" + name + "'");
         if (rs.next()) {
            Customer cust = new Customer();
            cust.setName(rs.getString("name"));
            cust.setEmail(rs.getString("email"));
            return cust;
         }
      }
      catch(SQLException e) {
         throw new DatabaseException(e.getMessage());
      }
 
      return null;
   } 
 
   public Collection getAllRows() throws DatabaseException {
      try {
         ArrayList al = new ArrayList();
 
         Statement stmt = connection.createStatement();
         ResultSet rs = stmt.executeQuery("SELECT * FROM customers");
         while (rs.next()) {
            Customer cust = new Customer();
            cust.setName(""+rs.getString("name"));
            cust.setEmail(rs.getString("email"));
            al.add(cust);
         }
         
         stmt.close();
 
         return al;
      }
      catch(SQLException e) {
         throw new DatabaseException(e.getMessage());
      }
   }
}

outputs:

Customer [name=Joris Van den Bogaert, email=joris1@esus.com]
Customer [name=Alicia Kolesnikova, email=alicia1@esus.com]

Customer [name=Joris Van den Bogaert, email=joris_vandenbogaert1@yahoo.com]
Customer [name=Alicia Kolesnikova, email=alicia1@esus.com]

Returning an image stored in mysql with a servlet

To answer this, I created a table images in a test database and stored the esus logo in it.

mysql> create table images (imageuid int(10) not null auto_increment, 
name varchar(30), data blob, length int(6), primary key(imageuid));
Query OK, 0 rows affected (0.12 sec) 
mysql> desc images;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| imageuid | int(10)     |      | PRI | NULL    | auto_increment |
| name     | varchar(30) | YES  |     | NULL    |                |
| length   | int(6)      | YES  |     | NULL    |                |
| data     | blob        | YES  |     | NULL    |                |
+----------+-------------+------+-----+---------+----------------+

To save an image in this table, use the following code and specify the image at command line. Use a JPG image, as the MIME content type for the servlet we’ll write will be image/jpeg.

Main.java:

import java.util.*;
import java.text.*;
import java.sql.*;
import java.io.*;  
 
public class Main {
   public static void main(String []args) throws Exception {
      try {
         if (args.length != 1) {
            System.out.println("Usage: java Main <img>");
            System.exit(1);
         }
 
         Class.forName("org.gjt.mm.mysql.Driver").newInstance();
         Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/testdb", 
                                                       "",
                                                       "");
 
         File file = new File(args[0]);
         FileInputStream fis=new FileInputStream(file);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         byte buf[]=new byte[1024];
         int length=-1;
         while((length=fis.read(buf))!=-1) {
            baos.write(buf,0,length);
         }
 
         PreparedStatement insertStmt = conn.prepareStatement(
                                       "INSERT INTO images (name, length, data) " +
                                       "VALUES (?, ?, ?)");
         insertStmt.setString(1, file.getName());
         insertStmt.setInt(2, (int) file.length());
         insertStmt.setBytes(3, baos.toByteArray());
         insertStmt.execute();
 
         fis.close();
         baos.close();
      }
      catch(Exception e) {
         e.printStackTrace();
      }
   } 
}

The servlet that delivers the image to the browser looks just like any other one, except that the MIME content-type attribute is set to image/jpeg (use image/gif for GIF files). The rest of the code handles the reading of the image from the mysql table given its unique index.

Servlet GetImage.java:

import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.sql.*;
import java.io.*;
 
public class GetImage extends HttpServlet {
 
   public void doGet(
       HttpServletRequest request,
       HttpServletResponse response)
         throws ServletException, IOException {
 
     response.setContentType("image/jpeg");
 
     ServletOutputStream sos = response.getOutputStream();
 
     int imageuid = Integer.parseInt(getValues(request, "imageuid"));
     byte[] buf = getImageFromDB(imageuid);
 
     sos.write(buf);
 
     sos.flush();
  }
 
   public byte[] getImageFromDB(int imageuid) {
      byte[] buffer = null;
 
      try {
         Class.forName("org.gjt.mm.mysql.Driver").newInstance();
         Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/testdb", 
                                                       "",
                                                       "");
 
         Statement stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery("SELECT name, length, data FROM images " +
                                          "where imageuid = " + imageuid);
      
         if (rs.next()) {
            String name = rs.getString("name");
            int length = rs.getInt("length");
            buffer = rs.getBytes("data");
         }
      }
      catch(Exception e) {
         e.printStackTrace();
      }
 
      return buffer;
   }
 
   public String getValues(HttpServletRequest request, String name) {
      String retVal = "";
 
      String values[] = request.getParameterValues(name);
      if (values == null) {
      }
      else if (values.length == 1) {
         retVal = values[0];
      }
      else {
         for (int i=0; i<values.length; i++) {
            retVal += values[i] + ", ";
         }
      }
 
      return retVal;
   }
}

You can now use the reference to this servlet in an img src HTML tag:

<html>
<body>
<center><img src="http://localhost:8080/servlet/GetImage?imageuid=1"></center>
</body>
</html>

Creating an editable JList

Courtesy of Nobuo Tamemasa (http://www2.gol.com/users/tame/swing/examples/JTableExamples1.html)



EditableListExample.java:

import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
 
/**
 * @version 1.0 12/24/98
 */
public class EditableListExample extends JFrame {
 
  public EditableListExample() {
    super(&quot;Editable List Example&quot;);
    
    String[] data = {&quot;a&quot;,&quot;b&quot;,&quot;c&quot;,&quot;d&quot;,&quot;e&quot;,&quot;f&quot;,&quot;g&quot;};
    
    JList list = new JList( data );
    JScrollPane scrollList = new JScrollPane( list );
    scrollList.setMinimumSize(new Dimension(100,80));
    Box listBox = new Box(BoxLayout.Y_AXIS);
    listBox.add(scrollList);
    listBox.add(new JLabel(&quot;JList&quot;));
         
    DefaultTableModel dm = new DefaultTableModel();
    Vector dummyHeader = new Vector();
    dummyHeader.addElement(&quot;&quot;);
    dm.setDataVector(
      strArray2Vector(data),
      dummyHeader);
    JTable table = new JTable( dm );
    table.setShowGrid(false);
    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    JScrollPane scrollTable = new JScrollPane( table );
    scrollTable.setColumnHeader(null);
    scrollTable.setMinimumSize(new Dimension(100,80));
    Box tableBox = new Box(BoxLayout.Y_AXIS);
    tableBox.add(scrollTable);
    tableBox.add(new JLabel(&quot;JTable&quot;));
    
    Container c = getContentPane();
    c.setLayout(new BoxLayout(c, BoxLayout.X_AXIS));
    c.add(listBox);
    c.add(new JSeparator(SwingConstants.VERTICAL));
    //c.add(new JLabel(&quot;test&quot;));
    //c.add(new JSeparator(SwingConstants.HORIZONTAL));
    c.add(tableBox);
    setSize( 220, 130 );
    setVisible(true);
  } 
   
  private Vector strArray2Vector(String[] str) {
    Vector vector = new Vector();
    for (int i=0;i&lt;str.length;i++) {
      Vector v = new Vector();
      v.addElement(str[i]);
      vector.addElement(v);
    }
    return vector;
  }

  public static void main(String[] args) {
    final EditableListExample frame = new EditableListExample();
    frame.addWindowListener( new WindowAdapter() {
      public void windowClosing( WindowEvent e ) {
        System.exit(0);
      }
    });
  }
}