Save This Page
Home » hibernate-search-src-20081106 » example » [javadoc | source]
    1   package example;
    2   
    3   import java.awt;
    4   import java.awt.event;
    5   import java.io;
    6   import java.sql;
    7   import org.postgresql.largeobject;
    8   
    9   /**
   10    * This example is a small application that stores and displays images
   11    * held on a postgresql database.
   12    *
   13    * Before running this application, you need to create a database, and
   14    * on the first time you run it, select "Initialise" in the "PostgreSQL"
   15    * menu.
   16    *
   17    * Important note: You will notice we import the org.postgresql.largeobject
   18    * package, but don't import the org.postgresql package. The reason for this is
   19    * that importing postgresql can confuse javac (we have conflicting class names
   20    * in org.postgresql.* and java.sql.*). This doesn't cause any problems, as
   21    * long as no code imports org.postgresql.
   22    *
   23    * Under normal circumstances, code using any jdbc driver only needs to import
   24    * java.sql, so this isn't a problem.
   25    *
   26    * It's only if you use the non jdbc facilities, do you have to take this into
   27    * account.
   28    *
   29    * Note: For PostgreSQL 6.4, the driver is now Thread safe, so this example
   30    * application has been updated to use multiple threads, especially in the
   31    * image storing and retrieving methods.
   32    */
   33   
   34   public class ImageViewer implements ItemListener
   35   {
   36     Connection db;
   37     Statement stat;
   38     LargeObjectManager lom;
   39     Frame frame;
   40     Label label;		// Label used to display the current name
   41     List list;		// The list of available images
   42     imageCanvas canvas;	// Canvas used to display the image
   43     String currentImage;	// The current images name
   44     
   45     // This is a simple component to display our image
   46     public class imageCanvas extends Canvas
   47     {
   48       // holds the image
   49       private Image image;
   50       
   51       // holds the background buffer
   52       private Image bkg;
   53       
   54       // the size of the buffer
   55       private Dimension size;
   56       
   57       public imageCanvas()
   58       {
   59         image=null;
   60       }
   61       
   62       public void setImage(Image img)
   63       {
   64         image=img;
   65         repaint();
   66       }
   67       
   68       // This defines our minimum size
   69       public Dimension getMinimumSize()
   70       {
   71         return new Dimension(400,400);
   72       }
   73       
   74       public Dimension getPreferedSize()
   75       {
   76         return getMinimumSize();
   77       }
   78       
   79       public void update(Graphics g)
   80       {
   81         paint(g);
   82       }
   83       
   84       /**
   85        * Paints the image, using double buffering to prevent screen flicker
   86        */
   87       public void paint(Graphics gr)
   88       {
   89         Dimension s = getSize();
   90         
   91         if(size==null || bkg==null || !s.equals(size)) {
   92   	size = s;
   93   	bkg = createImage(size.width,size.height);
   94         }
   95         
   96         // now set the background
   97         Graphics g = bkg.getGraphics();
   98         g.setColor(Color.gray);
   99         g.fillRect(0,0,s.width,s.height);
  100         
  101         // now paint the image over the background
  102         if(image!=null)
  103   	g.drawImage(image,0,0,this);
  104         
  105         // dispose the graphics instance
  106         g.dispose();
  107         
  108         // paint the image onto the component
  109         gr.drawImage(bkg,0,0,this);
  110         
  111       }
  112       
  113     }
  114     
  115     public ImageViewer(Frame f,String url,String user,String password) throws ClassNotFoundException, FileNotFoundException, IOException, SQLException
  116     {
  117       frame = f;
  118       
  119       MenuBar mb = new MenuBar();
  120       Menu m;
  121       MenuItem i;
  122       
  123       f.setMenuBar(mb);
  124       mb.add(m = new Menu("PostgreSQL"));
  125       m.add(i= new MenuItem("Initialise"));
  126       i.addActionListener(new ActionListener() {
  127         public void actionPerformed(ActionEvent e) {
  128   	ImageViewer.this.init();
  129         }
  130       });
  131       
  132       m.add(i= new MenuItem("Exit"));
  133       ActionListener exitListener = new ActionListener() {
  134         public void actionPerformed(ActionEvent e) {
  135   	ImageViewer.this.close();
  136         }
  137       };
  138       m.addActionListener(exitListener);
  139       
  140       mb.add(m = new Menu("Image"));
  141       m.add(i= new MenuItem("Import"));
  142       ActionListener importListener = new ActionListener() {
  143         public void actionPerformed(ActionEvent e) {
  144   	ImageViewer.this.importImage();
  145         }
  146       };
  147       i.addActionListener(importListener);
  148       
  149       m.add(i= new MenuItem("Remove"));
  150       ActionListener removeListener = new ActionListener() {
  151         public void actionPerformed(ActionEvent e) {
  152   	ImageViewer.this.removeImage();
  153         }
  154       };
  155       i.addActionListener(removeListener);
  156       
  157       // To the north is a label used to display the current images name
  158       f.add("North",label = new Label());
  159       
  160       // We have a panel to the south of the frame containing the controls
  161       Panel p = new Panel();
  162       p.setLayout(new FlowLayout());
  163       Button b;
  164       p.add(b=new Button("Refresh List"));
  165       b.addActionListener(new ActionListener() {
  166         public void actionPerformed(ActionEvent e) {
  167   	ImageViewer.this.refreshList();
  168         }
  169       });
  170       p.add(b=new Button("Import new image"));
  171       b.addActionListener(importListener);
  172       p.add(b=new Button("Remove image"));
  173       b.addActionListener(removeListener);
  174       p.add(b=new Button("Quit"));
  175       b.addActionListener(exitListener);
  176       f.add("South",p);
  177       
  178       // And a panel to the west containing the list of available images
  179       f.add("West",list=new List());
  180       list.addItemListener(this);
  181       
  182       // Finally the centre contains our image
  183       f.add("Center",canvas = new imageCanvas());
  184       
  185       // Load the driver
  186       Class.forName("org.postgresql.Driver");
  187       
  188       // Connect to database
  189       db = DriverManager.getConnection(url, user, password);
  190       
  191       // Create a statement
  192       stat = db.createStatement();
  193       
  194       // Also, get the LargeObjectManager for this connection
  195       lom = ((org.postgresql.Connection)db).getLargeObjectAPI();
  196       
  197       // Now refresh the image selection list
  198       refreshList();
  199     }
  200     
  201     
  202     /**
  203      * This method initialises the database by creating a table that contains
  204      * the image names, and Large Object OID's
  205      */
  206     public void init()
  207     {
  208       try {
  209         //db.setAutoCommit(true);
  210         stat.executeUpdate("create table images (imgname name,imgoid oid)");
  211         label.setText("Initialised database");
  212         db.commit();
  213       } catch(SQLException ex) {
  214         label.setText(ex.toString());
  215       }
  216       
  217       // This must run outside the previous try{} catch{} segment
  218       //try {
  219       //db.setAutoCommit(true);
  220       //} catch(SQLException ex) {
  221       //label.setText(ex.toString());
  222       //}
  223     }
  224     
  225     /**
  226      * This closes the connection, and ends the application
  227      */
  228     public void close()
  229     {
  230       try {
  231         db.close();
  232       } catch(SQLException ex) {
  233         System.err.println(ex.toString());
  234       }
  235       System.exit(0);
  236     }
  237     
  238     /**
  239      * This imports an image into the database, using a Thread to do this in the
  240      * background.
  241      */
  242     public void importImage()
  243     {
  244       FileDialog d = new FileDialog(frame,"Import Image",FileDialog.LOAD);
  245       d.setVisible(true);
  246       String name = d.getFile();
  247       String dir = d.getDirectory();
  248       d.dispose();
  249       
  250       // now start the true importer
  251       Thread t = new importer(db,name,dir);
  252       //t.setPriority(Thread.MAX_PRIORITY);
  253       t.start();
  254     }
  255     
  256     /**
  257      * This is an example of using a thread to import a file into a Large Object.
  258      * It uses the Large Object extension, to write blocks of the file to the
  259      * database.
  260      */
  261     class importer extends Thread
  262     {
  263       String name,dir;
  264       Connection db;
  265       
  266       public importer(Connection db,String name,String dir) {
  267         this.db = db;
  268         this.name = name;
  269         this.dir = dir;
  270       }
  271       
  272       public void run() {
  273         
  274         // Now the real import stuff
  275         if(name!=null && dir!=null) {
  276   	Statement stat = null;
  277   	
  278   	try {
  279   	  // fetch the large object manager
  280   	  LargeObjectManager lom = ((org.postgresql.Connection)db).getLargeObjectAPI();
  281   	  
  282   	  db.setAutoCommit(false);
  283   	  
  284   	  // A temporary buffer - this can be as large as you like
  285   	  byte buf[] = new byte[2048];
  286   	  
  287   	  // Open the file
  288   	  FileInputStream fis = new FileInputStream(new File(dir,name));
  289   	  
  290   	  // Now create the large object
  291   	  int oid = lom.create();
  292   	  LargeObject blob = lom.open(oid);
  293   	  
  294   	  // Now copy the file into the object.
  295   	  //
  296   	  // Note: we dont use write(buf), as the last block is rarely the same
  297   	  // size as our buffer, so we have to use the amount read.
  298   	  int s,t=0;
  299   	  while((s=fis.read(buf,0,buf.length))>0) {
  300   	    t+=s;
  301   	    blob.write(buf,0,s);
  302   	  }
  303   	  
  304   	  // Close the object
  305   	  blob.close();
  306   	  
  307   	  // Now store the entry into the table
  308   	  
  309   	  // As we are a different thread to the other window, we must use
  310   	  // our own thread
  311   	  stat = db.createStatement();
  312   	  stat.executeUpdate("insert into images values ('"+name+"',"+oid+")");
  313   	  db.commit();
  314   	  db.setAutoCommit(false);
  315   	  
  316   	  // Finally refresh the names list, and display the current image
  317   	  ImageViewer.this.refreshList();
  318   	  ImageViewer.this.displayImage(name);
  319   	} catch(Exception ex) {
  320   	  label.setText(ex.toString());
  321   	} finally {
  322   	  // ensure the statement is closed after us
  323   	  try {
  324   	    if(stat != null)
  325   	      stat.close();
  326   	  } catch(SQLException se) {
  327   	    System.err.println("closing of Statement failed");
  328   	  }
  329   	}
  330         }
  331       }
  332     }
  333     
  334     /**
  335      * This refreshes the list of available images
  336      */
  337     public void refreshList()
  338     {
  339       try {
  340         // First, we'll run a query, retrieving all of the image names
  341         ResultSet rs = stat.executeQuery("select imgname from images order by imgname");
  342         if(rs!=null) {
  343   	list.removeAll();
  344   	while(rs.next())
  345   	  list.addItem(rs.getString(1));
  346   	rs.close();
  347         }
  348       } catch(SQLException ex) {
  349         label.setText(ex.toString()+" Have you initialised the database?");
  350       }
  351     }
  352     
  353     /**
  354      * This removes an image from the database
  355      *
  356      * Note: With postgresql, this is the only way of deleting a large object
  357      * using Java.
  358      */
  359     public void removeImage()
  360     {
  361       try {
  362         //
  363         // Delete any large objects for the current name
  364         //
  365         // Note: We don't need to worry about being in a transaction
  366         // here, because we are not opening any blobs, only deleting
  367         // them
  368         //
  369         ResultSet rs = stat.executeQuery("select imgoid from images where imgname='"+currentImage+"'");
  370         if(rs!=null) {
  371   	// Even though there should only be one image, we still have to
  372   	// cycle through the ResultSet
  373   	while(rs.next()) {
  374   	  lom.delete(rs.getInt(1));
  375   	}
  376         }
  377         rs.close();
  378         
  379         // Finally delete any entries for that name
  380         stat.executeUpdate("delete from images where imgname='"+currentImage+"'");
  381         
  382         label.setText(currentImage+" deleted");
  383         currentImage=null;
  384         refreshList();
  385       } catch(SQLException ex) {
  386         label.setText(ex.toString());
  387       }
  388     }
  389     
  390     /**
  391      * This displays an image from the database.
  392      *
  393      * For images, this is the easiest method.
  394      */
  395     public void displayImage(String name)
  396     {
  397       try {
  398         //
  399         // Now as we are opening and reading a large object we must
  400         // turn on Transactions. This includes the ResultSet.getBytes()
  401         // method when it's used on a field of type oid!
  402         //
  403         db.setAutoCommit(false);
  404         
  405         ResultSet rs = stat.executeQuery("select imgoid from images where imgname='"+name+"'");
  406         if(rs!=null) {
  407   	// Even though there should only be one image, we still have to
  408   	// cycle through the ResultSet
  409   	while(rs.next()) {
  410   	  canvas.setImage(canvas.getToolkit().createImage(rs.getBytes(1)));
  411   	  label.setText(currentImage = name);
  412   	}
  413         }
  414         rs.close();
  415       } catch(SQLException ex) {
  416         label.setText(ex.toString());
  417       } finally {
  418   	try {
  419   	  db.setAutoCommit(true);
  420   	} catch(SQLException ex2) {
  421   	}
  422       }
  423     }
  424     
  425     public void itemStateChanged(ItemEvent e) {
  426       displayImage(list.getItem(((Integer)e.getItem()).intValue()));
  427     }
  428     
  429     /**
  430      * This is the command line instructions
  431      */
  432     public static void instructions()
  433     {
  434       System.err.println("java example.ImageViewer jdbc-url user password");
  435       System.err.println("\nExamples:\n");
  436       System.err.println("java -Djdbc.driver=org.postgresql.Driver example.ImageViewer jdbc:postgresql:test postgres password\n");
  437       
  438       System.err.println("This example tests the binary large object api of the driver.\nBasically, it will allow you to store and view images held in the database.");
  439       System.err.println("Note: If you are running this for the first time on a particular database,\nyou have to select \"Initialise\" in the \"PostgreSQL\" menu.\nThis will create a table used to store image names.");
  440     }
  441     
  442     /**
  443      * This is the application entry point
  444      */
  445     public static void main(String args[])
  446     {
  447       if(args.length!=3) {
  448         instructions();
  449         System.exit(1);
  450       }
  451       
  452       try {
  453         Frame frame = new Frame("PostgreSQL ImageViewer v7.0 rev 1");
  454         frame.setLayout(new BorderLayout());
  455         ImageViewer viewer = new ImageViewer(frame,args[0],args[1],args[2]);
  456         frame.pack();
  457         frame.setLocation(0,50);
  458         frame.setVisible(true);
  459       } catch(Exception ex) {
  460         System.err.println("Exception caught.\n"+ex);
  461         ex.printStackTrace();
  462       }
  463     }
  464   }

Save This Page
Home » hibernate-search-src-20081106 » example » [javadoc | source]