<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7506930953173811591</id><updated>2011-11-22T23:25:23.133-06:00</updated><category term='C++'/><category term='Json'/><category term='Grails'/><category term='trac'/><category term='iText'/><category term='Java'/><category term='Javascript'/><category term='Ajax'/><category term='Gridsphere'/><category term='Web Services'/><category term='Dynamic Script Tag'/><title type='text'>Xiaoyun Tang's Blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://xytang.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://xytang.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Xiaoyun Tang</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>20</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7506930953173811591.post-601712458153881867</id><published>2008-06-03T10:30:00.005-06:00</published><updated>2008-06-03T11:29:35.543-06:00</updated><title type='text'>Update Spreadsheet Using JDBC-ODBC Bridge</title><content type='html'>Sun JDBC-ODBC bridge driver provides a convenient way to interact a Spreadsheet as a relational database. We can manipulate a Spreadsheet like we do to a database.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;1. Code snippet to update a spreadsheet:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;a. Update&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt; String updateSql = "update [qas test$] set URL='http://www.mytest.com/possible' where Title Like '%A multiline button is possible%' ";&lt;br /&gt;&lt;br /&gt;int updateSuccess = stmnt.executeUpdate(updateSql);&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;b. Insertion&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt; String insertSql = "Insert into [qas test$] (Title, URL, Month, Year) values ('Test More Is Better', 'http://www.mytest.com/testMore', 'June', 2008 )";&lt;br /&gt;&lt;br /&gt;int insertSuccess = stmnt.executeUpdate(insertSql);&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;2. Don't forget to set 'readOnly=false' when creating connection to a Spreadsheet:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt; c = DriverManager.getConnection( "jdbc:odbc:Driver={Microsoft Excel Driver (*.xls)};DBQ=C:/Documents and Settings/tangk1.FIC/Desktop/qa.xls; readOnly= false");  &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I run into the following exception fist time I wrote the code:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt; [Microsoft][ODBC Excel Driver] Operation must use an updateable query.     at sun.jdbc.odbc.JdbcOdbc.createSQLException(JdbcOdbc.java:6998)     at sun.jdbc.odbc.JdbcOdbc.standardError(JdbcOdbc.java:7155)     at sun.jdbc.odbc.JdbcOdbc.SQLExecDirect(JdbcOdbc.java:3143)     at sun.jdbc.odbc.JdbcOdbcStatement.execute2(JdbcOdbcStatement.java:440)     at sun.jdbc.odbc.JdbcOdbcStatement.executeUpdate(JdbcOdbcStatement.java:321)     at nwag.eFileProject.ExcelReader.main(ExcelReader.java:53)&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Then I figured out the connection is read only by default if we do not set "readOnly=true", because the 'readOnly' property specifies if transactions in this connection are ready only. To update a Spreadsheet, we have to explicitly set 'readOnly=true'.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;3. A complete sample code to update a spreadsheet:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt; import java.sql.Connection; import java.sql.SQLException;&lt;br /&gt;import java.sql.Statement; import java.sql.ResultSet;&lt;br /&gt;import java.sql.DriverManager;&lt;br /&gt;&lt;br /&gt;public class ExcelReader  {  &lt;br /&gt;public static void main( String [] args ) throws ClassNotFoundException, SQLException     {&lt;br /&gt;&lt;br /&gt;Connection c = null;     &lt;br /&gt;Statement stmnt = null;     &lt;br /&gt;ResultSet rs = null;              &lt;br /&gt;&lt;br /&gt;try {&lt;br /&gt;  Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" );                  &lt;br /&gt;  c = DriverManager.getConnection( "jdbc:odbc:Driver={Microsoft Excel Driver         (*.xls)};DBQ=C:/Documents and   Settings/tangk1.FIC/Desktop/qa.xls; readOnly= false");&lt;br /&gt;  stmnt = c.createStatement();                      &lt;br /&gt;&lt;br /&gt;  String updateSql = "update [qas test$] set URL='http://www.mytest.com/possible' where         Title Like '%A multiline button is   possible%' ";         &lt;br /&gt;  String insertSql = "Insert into [qas test$] (Title, URL, Month, Year) values ('Test More Is     Better',   'http://www.mytest.com/testMore', 'June', 2008 )";&lt;br /&gt;  String query = "select * from [qas test$] where Year=2008 ";&lt;br /&gt;&lt;br /&gt;  int updateSuccess = stmnt.executeUpdate(updateSql);&lt;br /&gt;  int insertSuccess = stmnt.executeUpdate(insertSql);         &lt;br /&gt;  rs = stmnt.executeQuery( query );&lt;br /&gt;&lt;br /&gt;  while( rs.next()) {&lt;br /&gt;&lt;br /&gt;      String title  = rs.getString("Title");&lt;br /&gt;      String url = rs.getString( "URL" );             &lt;br /&gt;      String month = rs.getString("Month");             &lt;br /&gt;      String year = rs.getString("Year");             &lt;br /&gt;      System.out.println( title + " URL : " + url + ", Year " + year + ", Month " + month );&lt;br /&gt;  }                    &lt;br /&gt;  } catch( Exception e )         {          &lt;br /&gt;      e.printStackTrace();     &lt;br /&gt;  }         finally{         &lt;br /&gt;      if (rs != null)             &lt;br /&gt;          rs.close();&lt;br /&gt;      if (stmnt != null)             &lt;br /&gt;          stmnt.close();&lt;br /&gt;      if (c != null)&lt;br /&gt;          c.close();&lt;br /&gt;  }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;The Spreadsheet used in this example can be found from &lt;a title="here" href="http://spreadsheets.google.com/pub?key=p8e5n98h0Vcvq-Ru0fI0iTQ" id="e99j"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7506930953173811591-601712458153881867?l=xytang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xytang.blogspot.com/feeds/601712458153881867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7506930953173811591&amp;postID=601712458153881867' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/601712458153881867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/601712458153881867'/><link rel='alternate' type='text/html' href='http://xytang.blogspot.com/2008/06/sun-jdbc-odbc-driver-privates.html' title='Update Spreadsheet Using JDBC-ODBC Bridge'/><author><name>Xiaoyun Tang</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7506930953173811591.post-3558046043062779620</id><published>2008-02-08T14:53:00.000-06:00</published><updated>2008-02-08T15:03:07.437-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>How to Connect to an Excel Spreadsheet Using JDBC-ODBC Bridge Driver?</title><content type='html'>&lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;JDBC-ODBC can be used to access MS Excel spreadsheets as if they were databases, and thus we could utilize the power of SQL.&lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;There are two ways to connect to a spreadsheet file using jdbc-odbc: Using DSN connection and Using DSN-less connection. The main difference is the construction of JDBC URL.&lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p style="font-weight: bold;" class="MsoNormal"&gt;1. Using DSN connection&lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;To use DSN connection, we firstly need to set up the Excel Spreadsheet as an ODBC source by using Windows Administrative Tools. The details of creating a User DSN can be found from &lt;a href="http://www.devx.com/Java/Article/17848"&gt;here&lt;/a&gt;. Once the DSN is defined, we can interact the target spreadsheet file using jdbc-odbc. The db connection string is (please refer the complete sample for details ):&lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;java.sql.Connection c = java.sql.DriverManager.getConnection( "jdbc:odbc:qa", "", "" );&lt;br /&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;“qa” is the name of DSN which points at a &lt;a href="http://spreadsheets.google.com/pub?key=p8e5n98h0Vcvq-Ru0fI0iTQ"&gt;spreadsheet file&lt;/a&gt; which is going to be processed. &lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p style="font-weight: bold;" class="MsoNormal"&gt;2. Using DSN-less connection&lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;It is also possible to connect to a spreadsheet without using DSN, which provides a more flexible way within code to point JDBC at an Excel file of interest without the accesses to a client registry to define the required DSN. Without DSN, the db connection is created as following, please not the difference of constructed JDBC URL:&lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;java.sql.DriverManager.getConnection( "jdbc:odbc:Driver={Microsoft Excel Driver (*.xls)};DBQ=C:/Documents and Settings/myPath/Desktop/qa.xls");&lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;Here DBQ defines the path to the target spreadsheet file (qa.xls). Both backslash and forward slash work well.&lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;With using DSN, we need easy access to a client registry to define the required DSN, while jdbc-odbc driver provide a more flexible method to connect to spreadsheet files without DSN.&lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p style="font-weight: bold;" class="MsoNormal"&gt;3. A complete example of connecting to a spreadsheet using JDBC-ODBC&lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;Here is a complete sample of connecting to a Spreadsheet file using JDBC&lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;import java.sql.Connection;&lt;br /&gt;import java.sql.Statement;&lt;br /&gt;import java.sql.ResultSet;&lt;br /&gt;import java.sql.DriverManager;&lt;br /&gt;&lt;br /&gt;public class ExcelReader&lt;br /&gt;{&lt;br /&gt; public static void main( String [] args )&lt;br /&gt; {&lt;br /&gt;     Connection c = null;&lt;br /&gt;     Statement stmnt = null;&lt;/p&gt;&lt;p class="MsoNormal"&gt;       try&lt;br /&gt;     {&lt;br /&gt;         Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" );&lt;/p&gt;    &lt;p class="MsoNormal"&gt;//&lt;span style="color: rgb(204, 0, 0);"&gt;using DSN connection. Here qa is the name of DSN&lt;/span&gt;&lt;br /&gt;//c = DriverManager.getConnection( "jdbc:odbc:qa", "", "" );&lt;br /&gt;&lt;br /&gt;//&lt;span style="color: rgb(204, 0, 0);"&gt;using DSN-less connection&lt;/span&gt;&lt;br /&gt;         c = DriverManager.getConnection( "jdbc:odbc:Driver={Microsoft Excel Driver (*.xls)};DBQ=C:/Documents and Settings/tangk1.FIC/Desktop/qa.xls");&lt;br /&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;br /&gt;         stmnt = c.createStatement();&lt;br /&gt;         String query = "select * from [qas test$] where Month='March' and Year=2001;";&lt;br /&gt;         ResultSet rs = stmnt.executeQuery( query );&lt;br /&gt;     &lt;br /&gt;         System.out.println( "Found the following URLs:" );&lt;br /&gt;         while( rs.next() )&lt;br /&gt;         {&lt;br /&gt;             System.out.println( rs.getString( "URL" ) + " " + rs.getInt("Year"));&lt;br /&gt;         }&lt;br /&gt;     }&lt;br /&gt;     catch( Exception e )&lt;br /&gt;     {&lt;br /&gt;         System.err.println( e );&lt;br /&gt;     }&lt;br /&gt;     finally&lt;br /&gt;     {&lt;br /&gt;         try&lt;br /&gt;         {&lt;br /&gt;             stmnt.close();&lt;br /&gt;             c.close();&lt;br /&gt;         }&lt;br /&gt;         catch( Exception e )&lt;br /&gt;         {&lt;br /&gt;             System.err.println( e );&lt;br /&gt;         }&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;}&lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;Reference:&lt;/p&gt;  &lt;p class="MsoNormal"&gt;JDBC-ODBC Bridge Driver Enables Spreadsheet-as-database Interaction ( http://www.devx.com/Java/Article/17848)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7506930953173811591-3558046043062779620?l=xytang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xytang.blogspot.com/feeds/3558046043062779620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7506930953173811591&amp;postID=3558046043062779620' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/3558046043062779620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/3558046043062779620'/><link rel='alternate' type='text/html' href='http://xytang.blogspot.com/2008/02/how-to-connect-to-excel-spreadsheet.html' title='How to Connect to an Excel Spreadsheet Using JDBC-ODBC Bridge Driver?'/><author><name>Xiaoyun Tang</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7506930953173811591.post-4416567154904571303</id><published>2007-10-14T20:18:00.000-06:00</published><updated>2007-11-14T11:47:57.865-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Rename/Move Files Using java.io.File API</title><content type='html'>&lt;p&gt; &lt;/p&gt;  &lt;p style="font-weight: bold;" class="MsoNormal"&gt;1. Rename a File in Place&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-left: 0.25in;"&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Rename a file in the original place is trivial by using &lt;span style="font-style: italic;"&gt;renameTo()&lt;/span&gt; method in &lt;span style="font-style: italic;"&gt;java.io.File&lt;/span&gt; class. The following code snapshot will change a file name from “&lt;span style="font-style: italic;"&gt;oldName.pdf&lt;/span&gt;” to “&lt;span style="font-style: italic;"&gt;newName.pdf&lt;/span&gt;”:&lt;br /&gt;&lt;/p&gt;  &lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;p&gt; &lt;/p&gt;String oldName = “oldName.pdf”;&lt;br /&gt;String newName = “newName.pdf”;&lt;br /&gt;&lt;br /&gt;File f = new File(oldName);&lt;br /&gt;f.renameTo(newName);&lt;br /&gt;&lt;br /&gt;&lt;p class="MsoNormal" style="margin-left: 0.25in;"&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;span style="font-weight: bold;"&gt;2. Rename/Move a File to an Existing Directory&lt;/span&gt;  &lt;p class="MsoNormal"&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;It is also easy to rename a file, and move the file to an existing directory. The following code will change the file name from “&lt;span style="font-style: italic;"&gt;oldName.pdf&lt;/span&gt;” to “&lt;span style="font-style: italic;"&gt;newName.pdf&lt;/span&gt;”, and also move the file from “&lt;span style="font-style: italic;"&gt;C:\oldDir&lt;/span&gt;” to “&lt;span style="font-style: italic;"&gt;C:\newDirsubDir&lt;/span&gt;” provide “&lt;span style="font-style: italic;"&gt;C:\newDir\subDir&lt;/span&gt;” exists:&lt;br /&gt;&lt;/p&gt; &lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;p&gt; &lt;/p&gt;    &lt;p class="MsoNormal"&gt;String oldDir = “C:\\oldDir\\”;&lt;br /&gt;String oldName = “oldName.pdf”;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;    &lt;p class="MsoNormal"&gt;String newDir = “C:\\oldDir\subDir\\”;&lt;br /&gt;String newName = “newName.pdf”;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;File f = new File (oldDir, oldName);&lt;/p&gt;  &lt;p class="MsoNormal"&gt;f.renameTo(newDir + newName);&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;/p&gt;  &lt;/div&gt;The last line of code will rename and also move the file to newDir , &lt;span style="font-style: italic;"&gt;C:\newDir\subDir&lt;/span&gt;.&lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;/p&gt;  &lt;p style="font-weight: bold;" class="MsoNormal"&gt;3. Rename/Move a File to an Directory that does not exist&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;The piece of code above won’t work if &lt;span style="font-style: italic;"&gt;C:\newDir\subDir\&lt;/span&gt; does not exist. However, we still can achieve our goal by a little more work. Here is how we do:&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt; &lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;p class="MsoNormal"&gt;String oldDir = “C:\\oldDir\\”;&lt;br /&gt;String oldName = “oldName.pdf”;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;/p&gt;      &lt;p class="MsoNormal"&gt;String newDir = “C:\\oldDir\\subDir\\”;&lt;br /&gt;File pDir = new File(newDir);&lt;br /&gt;pDir.mkroots();&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;String newName = “newName.pdf”;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;/p&gt;    &lt;p style="color: rgb(204, 0, 0);" class="MsoNormal"&gt;File f = new File (oldDir, oldName);&lt;br /&gt;f.renameTo(newDir + newName);&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;/p&gt; &lt;/div&gt;The last two lines of code in red will create all directories along the path if they do not exist, and then rename and move the file to the new directory.  &lt;p class="MsoNormal"&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7506930953173811591-4416567154904571303?l=xytang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xytang.blogspot.com/feeds/4416567154904571303/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7506930953173811591&amp;postID=4416567154904571303' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/4416567154904571303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/4416567154904571303'/><link rel='alternate' type='text/html' href='http://xytang.blogspot.com/2007/10/renamemove-files-using-java.html' title='Rename/Move Files Using java.io.File API'/><author><name>Xiaoyun Tang</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7506930953173811591.post-1209794095715622219</id><published>2007-08-22T20:32:00.000-06:00</published><updated>2007-08-22T21:16:05.026-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='trac'/><title type='text'>Having Fun with Trac: Tracd + Digest Authentication</title><content type='html'>&lt;span style="font-style: italic;"&gt;&lt;br /&gt;Tracd&lt;/span&gt; is a lightweight standalone &lt;span style="font-style: italic;"&gt;Trac&lt;/span&gt; web server, which was added to &lt;span style="font-style: italic;"&gt;Trac&lt;/span&gt; framework since version 0.7. Running  &lt;span style="font-style: italic;"&gt;Trac&lt;/span&gt; on &lt;span style="font-style: italic;"&gt;Tracd&lt;/span&gt; is very simple, while needs a bit more work with authentication. &lt;span style="font-style: italic;"&gt;Tracd&lt;/span&gt; supports both &lt;span style="font-style: italic;"&gt;Basic&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;Digest&lt;/span&gt; authentication. The default is to use &lt;span style="font-style: italic;"&gt;Digest &lt;/span&gt;authentication. In certain situations, I found out that &lt;span style="font-style: italic;"&gt;Digest&lt;/span&gt; authentication is an easy and quick way to provide access controls to &lt;span style="font-style: italic;"&gt;Trac&lt;/span&gt; web application. Here are the steps to create &lt;span style="font-style: italic;"&gt;Digest&lt;/span&gt; authentication for tracd web server:&lt;br /&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;/p&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;   1. Creating a Password File&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;We used the &lt;span style="font-style: italic;"&gt;htdigest&lt;/span&gt; tool which Apache provides to create a digest password file. The following command creates a digest password file &lt;span style="font-style: italic;"&gt;users.mytest&lt;/span&gt; with realm name &lt;span style="font-style: italic;"&gt;mytest&lt;/span&gt; and also adds user &lt;span style="font-style: italic;"&gt;tom&lt;/span&gt; to the file:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;htdigest -c tractest/users.mytest mytest tom&lt;br /&gt;&lt;/div&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;br /&gt;If file &lt;span style="font-style: italic;"&gt;users.mytest&lt;/span&gt; exits, then we should remove option &lt;span style="font-style: italic;"&gt;–c&lt;/span&gt; in the command above. We will be promoted for a password to enter for each user that we create.&lt;br /&gt;&lt;/p&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;/p&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;2. Creating Trac Permissions&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;We also need to add &lt;span style="font-style: italic;"&gt;Trac&lt;/span&gt; permissions for each user created in step 1. Permission privileges are managed using the &lt;span style="font-style: italic;"&gt;trac-admin&lt;/span&gt; tool. For example, the following command will grant all privileges to user &lt;span style="font-style: italic;"&gt;tom&lt;/span&gt; to project &lt;span style="font-style: italic;"&gt;tractest&lt;/span&gt;:&lt;/p&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt; &lt;/p&gt; &lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;trac-admin tractest/ permission add tom TRAC_ADMIN&lt;br /&gt;&lt;/p&gt; &lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;span style="font-weight: bold;"&gt;3. Using &lt;/span&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;Digest&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; Authentication&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;The following command will force &lt;span style="font-style: italic;"&gt;Tracd&lt;/span&gt; to trace users' activities with project &lt;span style="font-style: italic;"&gt;tractest&lt;/span&gt; using Digest authentication:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;tracd -p 1234 -a tractest, tractest/users.mytest, mytest tractest&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;When launching &lt;span style="font-style: italic;"&gt;Trac&lt;/span&gt; from &lt;span style="color: rgb(0, 0, 255);"&gt;&lt;u&gt;&lt;a href="http://localhost:1234/tractest/login"&gt;http://localhost:1234/tractest/login&lt;/a&gt;&lt;/u&gt;&lt;/span&gt;, a log-in form pops up and asks for user's name and password. &lt;span style="font-style: italic;"&gt;Tracd&lt;/span&gt; also allows sharing a password file among multiple projects on one instance of &lt;span style="font-style: italic;"&gt;Trac&lt;/span&gt;.&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;Reference:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Tracd :&lt;b&gt; &lt;/b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;u&gt;&lt;a href="http://trac.edgewall.org/wiki/TracStandalone"&gt;http://trac.edgewall.org/wiki/TracStandalone&lt;/a&gt;&lt;/u&gt;&lt;/span&gt;&lt;br /&gt;Trac Permission: &lt;span style="color: rgb(0, 0, 255);"&gt;&lt;u&gt;&lt;a href="http://trac.edgewall.org/wiki/TracPermissions"&gt;http://trac.edgewall.org/wiki/TracPermissions&lt;/a&gt;&lt;/u&gt;&lt;/span&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt; &lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7506930953173811591-1209794095715622219?l=xytang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xytang.blogspot.com/feeds/1209794095715622219/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7506930953173811591&amp;postID=1209794095715622219' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/1209794095715622219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/1209794095715622219'/><link rel='alternate' type='text/html' href='http://xytang.blogspot.com/2007/08/tracd-is-lightweight-standalone-trac.html' title='Having Fun with Trac: Tracd + Digest Authentication'/><author><name>Xiaoyun Tang</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7506930953173811591.post-4765314804504890622</id><published>2007-08-07T21:49:00.000-06:00</published><updated>2007-08-07T22:06:47.959-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Comparison of C++ and Java (VIII): Vtable vs. Method Invocation Table and Binary Compatibility (1)</title><content type='html'>&lt;p class="MsoNormal"&gt;&lt;span style="font-weight: normal;"&gt;Both Java and C++ have mechanisms to support   dynamic polymorphism via run-time method binding, C++ uses &lt;span style="font-style: italic;"&gt;vtable&lt;/span&gt; to achieve   this goal while Java is by method invocation table. The difference of these   two mechanisms leads to the different behaviours regarding to binary   compatibility. &lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="font-weight: bold;"&gt;   A vtable exmple&lt;br /&gt;&lt;/p&gt; in C++, a &lt;span style="font-style: italic;"&gt;vtable&lt;/span&gt; contains the addresses of the object's dynamically bound methods. Method calls are performed by fetching the method's address from the object's &lt;span style="font-style: italic;"&gt;vtable&lt;/span&gt;. The &lt;span style="font-style: italic;"&gt;vtable &lt;/span&gt;is the same for all objects belonging to the same class, and is therefore typically shared between them.&lt;br /&gt;&lt;br /&gt;Considering the following example. &lt;span style="font-style: italic;"&gt;Class A&lt;/span&gt; defines one virtual function &lt;span style="font-style: italic;"&gt;methodA&lt;/span&gt; which just prints out a silly message:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;span style="font-style: italic;"&gt;A.h&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;class A{&lt;br /&gt;&lt;br /&gt;public:&lt;br /&gt;A(){}&lt;br /&gt;virtual void   methodB();&lt;br /&gt;};      &lt;p class="MsoNormal"&gt;   &lt;span style="font-style: italic;"&gt;A.cc&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;void A::methodA(){&lt;br /&gt;cout&amp;lt;&amp;lt;"print from method A "&amp;lt;&amp;lt;endl;&lt;br /&gt;};&lt;br /&gt;&lt;/p&gt;  &lt;/div&gt;   The vtable of A looks like:&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-style: italic;"&gt;   vtable layout of class A:&lt;/span&gt; &lt;/p&gt;    &lt;p class="MsoNormal"&gt;   A::_ZTV1A: 3u entries&lt;br /&gt;0&lt;span style=""&gt;     &lt;/span&gt;0u&lt;br /&gt;8&lt;span style=""&gt;     &lt;/span&gt;(int (*)(...))(&amp;_ZTI1A)&lt;br /&gt;16&lt;span style=""&gt;    &lt;/span&gt;A::methodA&lt;/p&gt; &lt;/div&gt;   The offset of A::methodA is 16.&lt;br /&gt;&lt;br /&gt;Here is a test class to reference class A:&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-style: italic;"&gt;   test.cc&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;   int main (int argc, char *argv[]){&lt;br /&gt;A* a = new   A();&lt;br /&gt;a-&amp;gt;methodA();&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt; &lt;/div&gt;&lt;br /&gt;We compile and link program by the following three steps:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-style: italic;"&gt;&gt;&gt;g++ -c A.cc&lt;/div&gt;&lt;div style="font-style: italic;"&gt;&gt;&gt;g++ -c test.cc&lt;/div&gt;&gt;&gt;g++ A.o test.o –o test&lt;br /&gt;&lt;br /&gt;and run test program&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&gt;&gt;./test &lt;/span&gt;&lt;br /&gt;&lt;p class="MsoNormal"&gt;   and get output:&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;&gt;&gt;Print from method A&lt;/span&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;   In the example above, method call&lt;span style="font-style: italic;"&gt; a-&amp;gt;methodA&lt;/span&gt; fetches &lt;span style="font-style: italic;"&gt;methodA&lt;/span&gt; from a address   with offset 16. &lt;/p&gt; &lt;span style="font-weight: bold;"&gt;Adding a virtual method breaks binary compatibility in C++&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To show this, we add a virtual function &lt;span style="font-style: italic;"&gt;methodB&lt;/span&gt; to &lt;span style="font-style: italic;"&gt;class&lt;/span&gt; &lt;span style="font-style: italic;"&gt;A &lt;/span&gt;right BEFORE &lt;span style="font-style: italic;"&gt;methodA&lt;/span&gt; :&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-style: italic;"&gt;   A.h&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;class A{&lt;br /&gt;public:&lt;br /&gt;A(){}&lt;br /&gt;&lt;span style=""&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;virtual void methodB(); // a new added function&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;virtual void   methodA();&lt;br /&gt;}; &lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;   &lt;span style="font-style: italic;"&gt;A.cc&lt;/span&gt; &lt;/p&gt;   &lt;p class="MsoNormal"&gt;   void A::methodA(){&lt;br /&gt;cout&amp;lt;&amp;lt;"print from method A "&amp;lt;&amp;lt;endl;&lt;br /&gt;} &lt;/p&gt; &lt;p class="MsoNormal"&gt; &lt;/p&gt;   &lt;p class="MsoNormal"&gt;   &lt;span style="color: rgb(255, 0, 0);"&gt; void A::methodB(){&lt;br /&gt;cout&amp;lt;&amp;lt;"print from method B "&amp;lt;&amp;lt;endl;&lt;br /&gt;}&lt;/span&gt; &lt;/p&gt;  &lt;/div&gt;  Then we recompile &lt;span style="font-style: italic;"&gt;class A&lt;/span&gt; BUT NOT &lt;span style="font-style: italic;"&gt;class test&lt;/span&gt;, and link them again:&lt;br /&gt;&lt;p class="MsoNormal"&gt;&lt;/p&gt;&lt;div style="font-style: italic;"&gt;&gt;&gt;g++ -c A.cc&lt;/div&gt;&lt;div style="font-style: italic;"&gt;&gt;&gt;g++ A.o test.o –o test&lt;/div&gt; &lt;p&gt;&lt;/p&gt; Then we run test program:&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&gt;&gt;./test&lt;/span&gt;   &lt;p class="MsoNormal"&gt;   and get out put:&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;&gt;&gt;Print from method B&lt;/span&gt; &lt;/p&gt;Why not "&lt;span style="color: rgb(255, 0, 0);"&gt; Print from method A&lt;/span&gt;" as I would expect? Let's take a look at the &lt;span style="font-style: italic;"&gt;vtable&lt;/span&gt; of the revised class A:&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-style: italic;"&gt;   vtable of revised class A&lt;/span&gt; &lt;/p&gt;     &lt;p class="MsoNormal"&gt;   A::_ZTV1A: 4u entries&lt;br /&gt;0&lt;span style=""&gt;     &lt;/span&gt;0u&lt;br /&gt;8&lt;span style=""&gt;     &lt;/span&gt;(int (*)(...))(&amp;_ZTI1A)&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;16&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;    &lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;A::methodB&lt;/span&gt;&lt;br /&gt;24&lt;span style=""&gt;    &lt;/span&gt;A::methodA&lt;/p&gt;  &lt;/div&gt;  Note the address of &lt;span style="font-style: italic;"&gt;methodA&lt;/span&gt; is now with offset 24, while the address of 16 is occupied by &lt;span style="font-style: italic;"&gt;methodB&lt;/span&gt;. If we execute test program without recompilation, the address with offset 16 is still referenced and thus &lt;span style="font-style: italic;"&gt;methodB&lt;/span&gt; gets called.&lt;br /&gt;&lt;br /&gt;This problem shown above is known as "constant recompilation problem" and is usually considered as a side effect of C++: because C++ compiler references methods or variables by numeric offset at compilation time, sometimes we add a new method or a new instance variable to a class, any and all classes that reference that class will require a recompilation, or they break.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;   &lt;a href="http://www.awprofessional.com/articles/article.asp?p=99697&amp;seqNum=2&amp;amp;rl=1"&gt;&lt;br /&gt; &lt;/a&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt; &lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7506930953173811591-4765314804504890622?l=xytang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xytang.blogspot.com/feeds/4765314804504890622/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7506930953173811591&amp;postID=4765314804504890622' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/4765314804504890622'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/4765314804504890622'/><link rel='alternate' type='text/html' href='http://xytang.blogspot.com/2007/08/comparison-of-c-and-java-vtable-vs.html' title='Comparison of C++ and Java (VIII): Vtable vs. Method Invocation Table and Binary Compatibility (1)'/><author><name>Xiaoyun Tang</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7506930953173811591.post-4195295075378837562</id><published>2007-07-30T18:51:00.000-06:00</published><updated>2007-07-30T19:22:05.111-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Comparisons of C++ and Java (VII): An Example of Desirable Data Hiding</title><content type='html'>In many of my readings, data hidings are said undesirable and are not encouraged. However, I at some circumstance, data hidings can make things simpler. For example, in my work, I need to implement an application with classes relationship looks like:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;     A&lt;br /&gt;      /   \&lt;br /&gt;   C     B&lt;br /&gt;        / |  \&lt;br /&gt;     B1 B2 B3&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Class A is the base class, class B and C are subclasses of A, and class B1, B2 and B3 are subclasses of B. Base class A is defined as:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;span style="font-style: italic;"&gt; A.h&lt;br /&gt;&lt;br /&gt;&lt;/span&gt; class A{&lt;br /&gt;  public:&lt;br /&gt;    A(){}&lt;br /&gt;    static int id;&lt;br /&gt;    virtual void doSomething();&lt;br /&gt;    virtual int getId(){return ++id;}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt; A.cc&lt;/span&gt;&lt;br /&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;   int A::id=0;&lt;br /&gt;void A::doSomething(){&lt;br /&gt;for (int k = 0; k&amp;lt;10; k++)&lt;br /&gt; cout&amp;lt;&amp;lt;"id is : "&amp;lt;&amp;lt;getId()&amp;lt;&amp;lt;endl;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Here method &lt;span style="font-style: italic;"&gt;doSomething&lt;/span&gt; simply print out ids. We want class B and C have their own id sequences, and all class B's share the same id sequences. That is both B and C classes' ids should start from 1. Class B1, B2, and B3 will share the same id sequence. To achieve this, We can design class C and B as following:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;span style="font-style: italic;"&gt; B.h&lt;br /&gt;&lt;br /&gt;&lt;/span&gt; class B:public A{&lt;br /&gt;  public:&lt;br /&gt;    B(){}&lt;br /&gt;    static int id;&lt;br /&gt;    virtual int getId()&lt;br /&gt;     {&lt;br /&gt;       return ++id;&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt; B.cc&lt;/span&gt;&lt;br /&gt;int B::id=0;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Since data member id is defined again in both class C and B, A/id is hidden and inaccessible from both classes. Each class holds their own data id which starts from 0;&lt;br /&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;   For class B's subclasses, we want them to share the same id sequence, so we DO   NOT want to hide the id from class B. class B1, B2 and B3 are defined as   following:&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt; &lt;/p&gt;  &lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;span style="font-style: italic;"&gt;B1.h&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;class B1:public B{&lt;br /&gt;    public:&lt;br /&gt;    B1(){}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;B2.h&lt;br /&gt;&lt;br /&gt;&lt;/span&gt; class B2:public B{&lt;br /&gt;  public:&lt;br /&gt;    B2(){}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;B3.h&lt;/span&gt;&lt;br /&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt; &lt;/p&gt; class B3:public B{&lt;br /&gt;  public:&lt;br /&gt;     B3(){}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;And the following test code generate some results that is what we expect:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt; C* c = new C();&lt;br /&gt;      B1* b1 = new B1();&lt;br /&gt;      B2* b2 = new B2();&lt;br /&gt;      B3* b3 = new B3();&lt;br /&gt;&lt;br /&gt;      cout&amp;lt;&amp;lt;"In class C, ids are:   "&amp;lt;&amp;lt;endl;&lt;br /&gt;      c-&amp;gt;doSomething();&lt;br /&gt;      cout&amp;lt;&amp;lt;"In class B1, ids   are:"&amp;lt;&amp;lt;endl;&lt;br /&gt;      b1-&amp;gt;doSomething();&lt;br /&gt;      cout&amp;lt;&amp;lt;"In class B2, ids are:   "&amp;lt;&amp;lt;endl;&lt;br /&gt;      b2-&amp;gt;doSomething();&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;The result looks like:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;In class C, ids are:&lt;br /&gt;id is : 1&lt;br /&gt;id is : 2&lt;br /&gt;id is : 3&lt;br /&gt;id is : 4&lt;br /&gt;id is : 5&lt;br /&gt;id is : 6&lt;br /&gt;id is : 7&lt;br /&gt;id is : 8&lt;br /&gt;id is : 9&lt;br /&gt;id is : 10&lt;br /&gt;In class B1, ids are:&lt;br /&gt;id is : 1&lt;br /&gt;id is : 2&lt;br /&gt;id is : 3&lt;br /&gt;id is : 4&lt;br /&gt;id is : 5&lt;br /&gt;id is : 6&lt;br /&gt;id is : 7&lt;br /&gt;id is : 8&lt;br /&gt;id is : 9&lt;br /&gt;id is : 10&lt;br /&gt;In class B2, ids are:&lt;br /&gt;id is : 11&lt;br /&gt;id is : 12&lt;br /&gt;id is : 13&lt;br /&gt;id is : 14&lt;br /&gt;id is : 15&lt;br /&gt;id is : 16&lt;br /&gt;id is : 17&lt;br /&gt;id is : 18&lt;br /&gt;id is : 19&lt;br /&gt;id is : 20&lt;br /&gt;In class B3, ids are:&lt;br /&gt;id is : 21&lt;br /&gt;id is : 22&lt;br /&gt;id is : 23&lt;br /&gt;id is : 24&lt;br /&gt;id is : 25&lt;br /&gt;id is : 26&lt;br /&gt;id is : 27&lt;br /&gt;id is : 28&lt;br /&gt;id is : 29&lt;br /&gt;id is : 30&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;There may be many other ways to achieve the same goal, but I found this solution is so simple and easy to understand and implement.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In Java, we can do the exactly same thing except a little change in the   syntax. I am not going to bother to write the code.&lt;br /&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;br /&gt;In both Java and C++, the mechanism of data hiding from inheritance is called   implicitly data hiding. In C#, it is said we can do explicitly data hiding by using "new"   modifier. I think it is a cool feature in the language because I can tell the   compiler I am doing data hiding on purpose.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7506930953173811591-4195295075378837562?l=xytang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xytang.blogspot.com/feeds/4195295075378837562/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7506930953173811591&amp;postID=4195295075378837562' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/4195295075378837562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/4195295075378837562'/><link rel='alternate' type='text/html' href='http://xytang.blogspot.com/2007/07/comparisons-of-c-and-java-example-of.html' title='Comparisons of C++ and Java (VII): An Example of Desirable Data Hiding'/><author><name>Xiaoyun Tang</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7506930953173811591.post-2068043360120267796</id><published>2007-07-07T10:54:00.000-06:00</published><updated>2007-07-07T11:24:43.171-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Comparisons of C++ and Java (VI): Constant Modifier</title><content type='html'>&lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;Constant&lt;span style=""&gt; modifier is &lt;/span&gt;&lt;span style="font-style: italic;"&gt;const&lt;/span&gt; in C++ and &lt;span style="font-style: italic;"&gt;final&lt;/span&gt; in Java.   However, &lt;span style="font-style: italic;"&gt;const&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;final&lt;/span&gt; are not equivalent at any situations (In C++, we can   also define a constant by using the &lt;tt style="font-style: italic;"&gt;#define&lt;/tt&gt; preprocessor directive, but I am not   going to discuss it here)&lt;br /&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;   &lt;span&gt;&lt;span&gt;&lt;br /&gt;1. For primitive data type, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="font-style: italic;"&gt;const&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;final&lt;/span&gt; have the same meaning&lt;/span&gt;, that is the   variable can only be assigned once and its value cannot be changed. For   instance:&lt;/p&gt; &lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;const int i = 10;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;  &lt;p class="MsoNormal"&gt;   in C++ is equivalent to&lt;br /&gt;&lt;/p&gt;  &lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;final int i = 10;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;  &lt;p class="MsoNormal"&gt;   in Java. It illegal to modify the variable after its initialization in both   cases.&lt;br /&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;   &lt;span style=""&gt;&lt;/span&gt;  &lt;/p&gt; &lt;p class="MsoNormal"&gt;   &lt;span&gt;&lt;br /&gt;2. However,&lt;/span&gt; &lt;span&gt;for non-primitive data type (reference data type in Java,   structured data types and address types in C++), &lt;/span&gt;&lt;span style="font-style: italic;"&gt;const&lt;/span&gt;&lt;span&gt; and &lt;/span&gt;&lt;span style="font-style: italic;"&gt;final&lt;/span&gt;&lt;span&gt; are   different&lt;/span&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;Let take a look at some examples.  In Java, this piece of code is perfectly legal: &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;final int[] ary = {1, 2, 3, 4, 5};&lt;br /&gt;ary[4] = 6; //legal&lt;br /&gt;&lt;br /&gt;&lt;/div&gt; &lt;p class="MsoNormal"&gt;However in C++, this piece of code:&lt;br /&gt;&lt;/p&gt; &lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;const int ary[] = {1, 2, 3, 4, 5};&lt;br /&gt;ary[4] = 6; // illegal. compilation-time error&lt;br /&gt;&lt;br /&gt; &lt;p class="MsoNormal"&gt;         &lt;/p&gt; &lt;/div&gt;  &lt;p class="MsoNormal"&gt;   will generate compilation-time error:&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;Error: assignment of read-only location.&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;span&gt;3. Why &lt;/span&gt;&lt;span style="font-style: italic;"&gt;const&lt;/span&gt;&lt;span&gt; and &lt;/span&gt;&lt;span style="font-style: italic;"&gt;final&lt;/span&gt;&lt;span&gt; are different regarding to non-primitive datatype?&lt;/span&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;   For mathematics, a constant is a value that never changes, thereby remaining a   fixed value. So in C++, a constant is a REAL constant. &lt;code style="font-style: italic;"&gt;const&lt;/code&gt; is infectious. A &lt;span style="font-style: italic;"&gt;const&lt;/span&gt; modifier    ensures that the object is immutable (It is called   &lt;span style="font-style: italic;"&gt;Const Correctness in C++&lt;/span&gt;). When &lt;tt style="font-style: italic;"&gt;const&lt;/tt&gt; keyword is involved when used with   pointers or references, we can't modify what the pointer points to or the   reference refers to.&lt;br /&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;   While, there is no such const correctness in Java. A &lt;span style="font-style: italic;"&gt;final&lt;/span&gt; modifier just   tells the compiler that the reference to the object cannot be re-assigned, but   nothing about its content.  A &lt;span style="font-style: italic;"&gt;final&lt;/span&gt; modifier can never change the immutability of an   object. A constant in Java is NOT a real constant. &lt;span style="font-style: italic;"&gt;cons&lt;/span&gt;t is a   reserved keyword in Java. We may expect the implementation of &lt;span style="font-style: italic;"&gt;Const Correctness&lt;/span&gt; in Java in the future.&lt;br /&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt; &lt;code&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7506930953173811591-2068043360120267796?l=xytang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xytang.blogspot.com/feeds/2068043360120267796/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7506930953173811591&amp;postID=2068043360120267796' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/2068043360120267796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/2068043360120267796'/><link rel='alternate' type='text/html' href='http://xytang.blogspot.com/2007/07/constants-modifier-constant-modifier-is.html' title='Comparisons of C++ and Java (VI): Constant Modifier'/><author><name>Xiaoyun Tang</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7506930953173811591.post-1017020453599369530</id><published>2007-06-27T12:06:00.000-06:00</published><updated>2007-07-07T11:19:42.524-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Comparisons of C++ and Java (V): Immutability of Strings</title><content type='html'>&lt;p class="MsoNormal"&gt;     &lt;/p&gt;Strings are not the same in C++ and Java regarding to immutability. In Java,   String objects are immutable, where C++ string type is mutable.  &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;   Let’s take a look at some examples: &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;   &lt;span style="font-weight: bold;"&gt; A C++ Example&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;  &lt;div class="MsoNormal" style="background-color: rgb(232, 232, 232);"&gt;&lt;span style="font-family:Verdana;"&gt;   &lt;span style="font-family:courier new;"&gt;string str1=”It is     Friday, ”;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  string str2=”I am completely released”;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  str1.append(str2);   &lt;/span&gt;   &lt;p style="font-family: courier new;" class="MsoNormal"&gt;               cout&amp;lt;&amp;lt;str1&amp;lt;&amp;lt;endl;&lt;/p&gt;      &lt;p class="MsoNormal"&gt;   &lt;/p&gt; &lt;/div&gt;   &lt;p class="MsoNormal"&gt;   The program will print: &lt;span style="color: rgb(255, 0, 0);"&gt;It is Friday, I am completely   released&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;   &lt;span style="font-weight: bold;"&gt; A Java Example&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;div class="MsoNormal" style="background-color: rgb(232, 232, 232);"&gt;            &lt;p class="MsoNormal"  style="font-family:Verdana;"&gt;       &lt;span style="font-family:courier new;"&gt;String str1 = “It is Friday,”;    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    String str2 = “I am completely released!”;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    str1.concat(str2);   &lt;/span&gt;&lt;/p&gt;   &lt;p style="font-family: courier new;" class="MsoNormal"&gt;    System.out.println(str1);&lt;/p&gt;    &lt;/div&gt;  &lt;p class="MsoNormal"&gt;   The program will print: &lt;span style="color: rgb(255, 0, 0);"&gt;It is Friday,&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;   &lt;span style="font-weight: bold;"&gt; Immutability of strings in C++ and Java&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;   In C++, a string type is mutable.&lt;span style=""&gt;  &lt;/span&gt;As shown in   example 1, &lt;span style="font-style: italic;"&gt;str1.append(str2)&lt;/span&gt; appends   &lt;span style="font-style: italic;"&gt;str2&lt;/span&gt; to the end of   &lt;span style="font-style: italic;"&gt;str1,&lt;/span&gt; and   &lt;span style="font-style: italic;"&gt;str1&lt;/span&gt; becomes   “&lt;span style="font-style: italic;"&gt;It is Friday, I am completely   released&lt;/span&gt;”. In addition to   &lt;span style="font-style: italic;"&gt;append()&lt;/span&gt;, similar functions like   &lt;span style="font-style: italic;"&gt;substr() &lt;/span&gt;and   &lt;span style="font-style: italic;"&gt;assign()&lt;/span&gt; etc. in std::string class DO   alter a C++ string. &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;   By co&lt;span style="font-size:85%;"&gt;ntrast, in Ja&lt;/span&gt;va,   &lt;span style="font-style: italic;"&gt;String&lt;/span&gt; objects designed as immutable.   &lt;span style=""&gt; &lt;/span&gt;As shown in example 2,   &lt;span style="font-style: italic;"&gt;str1.concat()&lt;/span&gt; creates a new   &lt;span style="font-style: italic;"&gt;String&lt;/span&gt; object, the old string   &lt;span style="font-style: italic;"&gt;str1&lt;/span&gt; remains unchanged. It is also true   for some other methods such as   &lt;span style="font-style: italic;"&gt;substring()&lt;/span&gt;,   &lt;span style="font-style: italic;"&gt;toLowerCase()&lt;/span&gt; and   &lt;span style="font-style: italic;"&gt;toUpperCase()&lt;/span&gt;. In other words,   &lt;span style=";font-family:Arial;font-size:85%;"  &gt;a&lt;span style=";font-family:lucida grande;font-size:100%;"  &gt;ny operation performed on one   &lt;/span&gt;&lt;span style="font-style: italic;font-family:lucida grande;font-size:100%;"  &gt;String&lt;/span&gt;&lt;span style=";font-family:lucida grande;font-size:100%;"  &gt; reference will never have any   effect on the content of the String object.&lt;/span&gt;&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;   &lt;span style=""&gt; &lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;   &lt;span style="font-weight: bold;"&gt; Reduce Object Creation in Java&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;   Because of its mutability and the object-creation overhead of a String object,   performance could be a problem. In fact, Java provides several mechanisms to   reduce String objects creation: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;span style="font-style: italic;"&gt;String literal Pool&lt;/span&gt;: Java compiler     optimizes handling of &lt;span style="font-style: italic;"&gt;String&lt;/span&gt;     literals. Only one &lt;span style="font-style: italic;"&gt;String&lt;/span&gt; object is     shared be all strings that have same character sequence. Such strings are     said to be &lt;i style=""&gt;interned&lt;/i&gt;, meaning that they share a unique     &lt;span style="font-style: italic;"&gt;String&lt;/span&gt; object. The     &lt;span style="font-style: italic;"&gt;String&lt;/span&gt; class maintains a private pool     called &lt;i style=""&gt;String intern pool&lt;/i&gt;, where such strings are interned.     &lt;span style="font-style: italic;"&gt;Java automatically interns     &lt;span style="font-style: italic;"&gt;String literals&lt;/span&gt;.&lt;/span&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;span style="font-style: italic;"&gt;Interning of Strings&lt;/span&gt;: we can also     explicitly make a String object interned. Intern() method from String class     can help achieve interning of a String . &lt;span style="color: rgb(51, 51, 51);"&gt;When     the &lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;code style="font-style: italic;"&gt;&lt;span style="color: rgb(51, 51, 51);"&gt;intern()&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;span style="color: rgb(51, 51, 51);"&gt; method is invoked on a     &lt;span style="font-style: italic;"&gt;String&lt;/span&gt;, JVM first checks the     &lt;span style="font-style: italic;"&gt;String&lt;/span&gt; literal pool. If a     &lt;span style="font-style: italic;"&gt;String&lt;/span&gt; with the same content is     already in the pool, a reference to the     &lt;span style="font-style: italic;"&gt;String&lt;/span&gt; in the pool is returned.     Otherwise, the &lt;span style="font-style: italic;"&gt;String&lt;/span&gt; is added to the     pool and a reference to it is returned. The result is that after interning,     all Strings with the same content will point to the same object&lt;/span&gt;.   &lt;/li&gt; &lt;/ul&gt;   &lt;div style="text-align: left;"&gt;          Can we intern all   &lt;span style="font-style: italic;"&gt;Strings&lt;/span&gt;? The answer is may not. As the   intern string pool grows                           large,                               the cost to find a String in the pool could   become             more expensive   than                                   creating a new                                       object.&lt;br /&gt;&lt;ul&gt;     &lt;li&gt;       &lt;span style="font-style: italic;"&gt;StringBuffer and StringBuilder serves as       mutable strings&lt;/span&gt;: as a sort of complementary, Java provides       &lt;span style="font-style: italic;"&gt;StringBuffer &lt;/span&gt;as a sort of mutable       string.  Content of a       &lt;span style="font-style: italic;"&gt;StringBuffer&lt;/span&gt; object can be       modified. It is more efficient to use a       &lt;span style="font-style: italic;"&gt;StringBuffer&lt;/span&gt; instead of operations       that result in the creation of many intermediate String object. Introduced       in J2SE 5.0, &lt;span style="font-style: italic;"&gt;Stringbuilder&lt;/span&gt; class       provides an API compatible with StringBuilder but is unsynchronized.     &lt;/li&gt;   &lt;/ul&gt;&lt;br /&gt;&lt;/div&gt; &lt;div style="text-align: left;"&gt; &lt;/div&gt; &lt;ol start="3" style="margin-top: 0in; text-align: left;" type="a"&gt; &lt;/ol&gt; &lt;div style="text-align: left;"&gt; &lt;/div&gt; &lt;p class="MsoNormal" style="text-align: left;"&gt;     &lt;/p&gt;  &lt;p class="MsoNormal"&gt;   &lt;span style=""&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7506930953173811591-1017020453599369530?l=xytang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xytang.blogspot.com/feeds/1017020453599369530/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7506930953173811591&amp;postID=1017020453599369530' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/1017020453599369530'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/1017020453599369530'/><link rel='alternate' type='text/html' href='http://xytang.blogspot.com/2007/06/comparisons-of-c-and-java-v.html' title='Comparisons of C++ and Java (V): Immutability of Strings'/><author><name>Xiaoyun Tang</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7506930953173811591.post-8407513862995358109</id><published>2007-05-30T22:51:00.000-06:00</published><updated>2007-05-30T23:20:40.476-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Comparisons of C++ and Java (IV): Accessibility of Indirect Base Classes</title><content type='html'>&lt;p class="MsoNormal"&gt;     &lt;/p&gt;  &lt;p class="MsoNormal"&gt;   Firstly, let’s take a look at two examples in C++ and Java respectively:&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-weight: bold;"&gt;Example 1 (In Java):&lt;/span&gt; &lt;/p&gt;  &lt;div style="background-color: rgb(232, 232, 232);"&gt;                     &lt;p class="MsoNormal"&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;     A.java&lt;/span&gt;&lt;br /&gt;public class A {&lt;br /&gt;A (){}&lt;br /&gt;void     &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;printMsg&lt;/span&gt;(){&lt;br /&gt;     System.out.println("print     from class A");&lt;br /&gt;}&lt;br /&gt;}   &lt;/p&gt;   &lt;p class="MsoNormal"&gt;         &lt;/p&gt;                     &lt;p class="MsoNormal"&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;     B.java&lt;/span&gt;&lt;br /&gt;public class B extends A {&lt;br /&gt;B (){}&lt;br /&gt;void     &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;printMsg&lt;/span&gt;(){&lt;br /&gt;System.out.println("print from class B ");&lt;br /&gt;}&lt;br /&gt;}   &lt;/p&gt;   &lt;p class="MsoNormal"&gt;         &lt;/p&gt;                              &lt;p class="MsoNormal"&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;     C.java&lt;/span&gt;&lt;br /&gt;public class C extends B {&lt;br /&gt;C (){}&lt;br /&gt;void     &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;printMsg&lt;/span&gt;(){&lt;br /&gt;// &lt;span style="color: rgb(204, 0, 0);"&gt;direct base class B is accessible but now indirect base class A&lt;/span&gt;&lt;br /&gt;super.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;printMsg&lt;/span&gt;();&lt;br /&gt;System.out.println("print from class C");&lt;br /&gt;}&lt;br /&gt;}   &lt;/p&gt;   &lt;p class="MsoNormal"&gt;         &lt;/p&gt;   &lt;p style="font-weight: bold;" class="MsoNormal"&gt;&lt;span style="font-style: italic;"&gt;     Test code snippet&lt;/span&gt;   &lt;/p&gt;   &lt;p class="MsoNormal"&gt;         &lt;/p&gt;      &lt;p class="MsoNormal"&gt;     C c = new C();&lt;br /&gt;c.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;printMsg&lt;/span&gt;();&lt;/p&gt;   &lt;p class="MsoNormal"&gt;         &lt;/p&gt;&lt;p class="MsoNormal"&gt;         &lt;/p&gt; &lt;/div&gt; &lt;p class="MsoNormal"&gt;   The inheritance path looks like:&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;    A (indirect base)&lt;br /&gt;  |&lt;br /&gt;  B  (direct base)&lt;br /&gt;  |&lt;br /&gt;  C&lt;/p&gt;&lt;p class="MsoNormal"&gt;  &lt;/p&gt;      &lt;p class="MsoNormal"&gt;The test Results are:&lt;br /&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;print from class B&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;print from class C&lt;/span&gt;   &lt;/p&gt;  &lt;p class="MsoNormal"&gt;In &lt;span style="font-style: italic;"&gt;class C&lt;/span&gt;, method "&lt;span style="font-style: italic;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;printMsg&lt;/span&gt;()&lt;/span&gt;" in direct base &lt;span style="font-style: italic;"&gt;class B&lt;/span&gt; is accessible by calling:&lt;/p&gt;&lt;p style="color: rgb(204, 0, 0);" class="MsoNormal"&gt;super.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;printMsg&lt;/span&gt;()&lt;/p&gt;However, the method "&lt;span style="font-style: italic;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;printMsg&lt;/span&gt;()&lt;/span&gt;" in &lt;span style="font-weight: bold; font-style: italic;"&gt;indirect&lt;/span&gt; base &lt;span style="font-style: italic;"&gt;class A &lt;/span&gt;is not accessible.&lt;span style=""&gt; &lt;/span&gt;What about in   C++? Let’s take a look at an exactly same example but in C++.&lt;br /&gt;&lt;br /&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-weight: bold;"&gt;   Example 2 (In C++): same as Example 1 but written in C++&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;  &lt;div style="background-color: rgb(232, 232, 232);"&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;class A:&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;                  &lt;p class="MsoNormal"&gt;     class A{&lt;br /&gt;public:&lt;br /&gt;A(){}&lt;br /&gt;void &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;printMsg&lt;/span&gt;( ){&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;cout&lt;/span&gt;&amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;lt&lt;/span&gt;;&amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;lt&lt;/span&gt;;" print from class A "&amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;lt&lt;/span&gt;;&amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;lt&lt;/span&gt;;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;endl&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;};   &lt;/p&gt;   &lt;p class="MsoNormal"&gt;      &lt;span style="font-weight: bold; font-style: italic;"&gt;class B&lt;/span&gt;:&lt;br /&gt;&lt;/p&gt;                     &lt;p class="MsoNormal"&gt;     class B : public A{&lt;br /&gt;public:&lt;br /&gt;B(){}&lt;br /&gt;void &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;printMsg&lt;/span&gt;(){&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;cout&lt;/span&gt;&amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;lt&lt;/span&gt;;&amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;lt&lt;/span&gt;;" print from class B "&amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;lt&lt;/span&gt;;&amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;lt&lt;/span&gt;;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;endl&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;};&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;class C:&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;         &lt;/p&gt;               &lt;p class="MsoNormal"&gt;     &lt;span style=""&gt;                            &lt;/span&gt;   &lt;/p&gt;               &lt;p class="MsoNormal"&gt;     class C:public B{&lt;br /&gt;public:&lt;br /&gt;C(){}&lt;br /&gt;void &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;printMsg&lt;/span&gt;(){&lt;br /&gt;A::printMsg();//&lt;span style="color: rgb(204, 0, 0);"&gt;indirect base is accessible too&lt;/span&gt;&lt;br /&gt;B::&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;printMsg&lt;/span&gt;();&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;cout&lt;/span&gt;&amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;lt&lt;/span&gt;;&amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;lt&lt;/span&gt;;" print from class C "&amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;lt&lt;/span&gt;;&amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;lt&lt;/span&gt;;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_29"&gt;endl&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;};   &lt;/p&gt;   &lt;p class="MsoNormal"&gt;         &lt;/p&gt;   &lt;p style="font-style: italic;" class="MsoNormal"&gt;&lt;span style="font-weight: bold;"&gt;     Test code snippet:&lt;/span&gt;   &lt;/p&gt;      &lt;p class="MsoNormal"&gt;         C* c = new Polygon::C();&lt;br /&gt;c-&amp;gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_30"&gt;printMsg&lt;/span&gt;();   &lt;/p&gt;   &lt;p class="MsoNormal"&gt;         &lt;/p&gt; &lt;/div&gt;    &lt;p class="MsoNormal"&gt;     &lt;span style=""&gt;&lt;/span&gt;The test code will print:&lt;br /&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;   print from class A&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;print from class B&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(204, 0, 0);"&gt;print from class C&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;   As we have noticed, the indirect base &lt;span style="font-style: italic;"&gt;class A &lt;/span&gt;is accessible in &lt;span style="font-style: italic;"&gt;class C&lt;/span&gt; which is different than in Java as shown in Example 1.&lt;br /&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-weight: bold;"&gt;Why C++ and Java are different at this point?&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;As my understanding it is because in C++, multiple-inheritance is allowed. A derived class may inherit methods   with same finger print from different base classes as shown below: &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;class A&lt;/span&gt;&lt;br /&gt;class A {&lt;br /&gt;public A();&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;pulbic&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_32"&gt;printMsg&lt;/span&gt;();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;class B1&lt;br /&gt;&lt;/span&gt;class B1 {&lt;br /&gt;public B1()&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_33"&gt;pulbic&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_34"&gt;printMsg&lt;/span&gt;();&lt;br /&gt;}&lt;br /&gt;&lt;p class="MsoNormal"&gt; &lt;/p&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;class B2&lt;/span&gt;&lt;br /&gt;class B2 {&lt;br /&gt;public B2();&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_35"&gt;pulbic&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_36"&gt;printMsg&lt;/span&gt;();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;class C&lt;/span&gt;&lt;br /&gt;class C : public B1,B2{&lt;br /&gt;public C();&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_37"&gt;pulbic&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_38"&gt;printMsg&lt;/span&gt;();&lt;br /&gt;}  &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The inheritance path is shown as:&lt;br /&gt;                 A (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_39"&gt;indirect&lt;/span&gt; base)&lt;br /&gt;               /  \&lt;br /&gt;             B1  B2 (direct base)&lt;br /&gt;              \   /&lt;br /&gt;                C   &lt;p class="MsoNormal"&gt;   &lt;span style="font-style: italic;"&gt; Class C&lt;/span&gt; has two direct base &lt;span style="font-style: italic;"&gt;classes B1&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;B2&lt;/span&gt;. This arises the ambiguity   because both have a method called “&lt;span style="font-style: italic;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_40"&gt;printMsg&lt;/span&gt;()&lt;/span&gt;”.   &lt;span style=""&gt; &lt;/span&gt;Image what if the &lt;span style="font-style: italic;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_41"&gt;printMsg&lt;/span&gt;()&lt;/span&gt; in class C would   &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_42"&gt;like&lt;/span&gt; to inherit both "&lt;span style="font-style: italic;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_43"&gt;printMsg&lt;/span&gt;()&lt;/span&gt;" from &lt;span style="font-style: italic;"&gt;class B1&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;class B2&lt;/span&gt;?   &lt;span style=""&gt; &lt;/span&gt;Fortunately, C++ provides techniques to &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_44"&gt;eliminates&lt;/span&gt;   the ambiguities by &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_45"&gt;explict&lt;/span&gt; qualification: &lt;span style="font-style: italic; font-weight: bold;"&gt;B1::&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_46"&gt;printMsg&lt;/span&gt;()&lt;/span&gt; or &lt;span style="font-style: italic; font-weight: bold;"&gt;B2::&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_47"&gt;printMsg&lt;/span&gt;()&lt;/span&gt;   explicitly tells compiler which version of "&lt;span style="font-style: italic;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_48"&gt;printMsg&lt;/span&gt;()&lt;/span&gt;" is been used. However,   the solution also leads the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_49"&gt;de&lt;/span&gt;-encapsulation of indirect base &lt;span style="font-style: italic;"&gt;classes A&lt;/span&gt; in the   inheritance tree. &lt;/p&gt; &lt;p class="MsoNormal"&gt;   &lt;span style=""&gt; &lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;   Unlike C++, in Java, strict inheritance is enforced and all classes are   single-rooted by the &lt;span style="font-style: italic;"&gt;class&lt;/span&gt; &lt;span style="font-style: italic;"&gt;Object&lt;/span&gt;. Multiple implementation inheritance is not   allowed, thus the confusion in the examples above does not exist. Everything   in the super class is inherited by the subclass. Thus, there is no need to   access the indirect base class upward in the inheritance tree. &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7506930953173811591-8407513862995358109?l=xytang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xytang.blogspot.com/feeds/8407513862995358109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7506930953173811591&amp;postID=8407513862995358109' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/8407513862995358109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/8407513862995358109'/><link rel='alternate' type='text/html' href='http://xytang.blogspot.com/2007/05/comparisons-of-c-and-java-iv.html' title='Comparisons of C++ and Java (IV): Accessibility of Indirect Base Classes'/><author><name>Xiaoyun Tang</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7506930953173811591.post-956814902772287850</id><published>2007-05-21T21:52:00.000-06:00</published><updated>2007-05-21T21:59:33.266-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Comparisons of C++ and Java (III): Method Overriding</title><content type='html'>&lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;   Method overriding is not quite the same in C++ as in Java. Here are some   examples show the differences: &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-weight: bold;"&gt;   Method overriding in Java&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;div style="background-color: rgb(232, 232, 232);"&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-style: italic;"&gt;     base.java&lt;/span&gt;   &lt;/p&gt;                  &lt;p class="MsoNormal"&gt;     public class base {&lt;br /&gt;base (){}&lt;br /&gt;void     &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;printMsg&lt;/span&gt;(){&lt;br /&gt;System.out.println("print from base class");&lt;br /&gt;}&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;}&lt;/span&gt;   &lt;/p&gt;   &lt;p class="MsoNormal"&gt;         &lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-style: italic;"&gt;     Derived.java&lt;/span&gt;   &lt;/p&gt;                  &lt;p class="MsoNormal"&gt;     public class derived extends base {&lt;br /&gt;derived     (){}&lt;br /&gt;void     &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;printMsg&lt;/span&gt;(){&lt;br /&gt;System.out.println("print from derived class");&lt;br /&gt;}&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;}&lt;/span&gt;   &lt;/p&gt;   &lt;p class="MsoNormal"&gt;         &lt;/p&gt;                  &lt;p class="MsoNormal"&gt;&lt;span style="font-style: italic;"&gt;     test code snippet:&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;public static void main(String &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;args&lt;/span&gt;[]){&lt;br /&gt;base b = new derived();&lt;br /&gt;b.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;printMsg&lt;/span&gt;();&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;}&lt;/span&gt;   &lt;/p&gt;   &lt;p class="MsoNormal"&gt;         &lt;/p&gt; &lt;/div&gt; &lt;p class="MsoNormal"&gt;   What do we get: &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;&amp;gt;&amp;gt; print from derived class&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p style="font-weight: bold;" class="MsoNormal"&gt;   Non-virtual method overriding in C++&lt;/p&gt;   &lt;div style="background-color: rgb(232, 232, 232);"&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-style: italic;"&gt;   base.h&lt;/span&gt; &lt;/p&gt;      &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;   class base{&lt;br /&gt;public:&lt;br /&gt;base(){}&lt;br /&gt;void &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;printMsg&lt;/span&gt;();&lt;br /&gt;&lt;span style="font-style: italic;"&gt;};&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;     &lt;/p&gt;    &lt;p style="font-family: Courier New;" class="MsoNormal"&gt;&lt;span style="font-style: italic;"&gt;base.cc&lt;/span&gt;&lt;br /&gt;void base::&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;printMsg&lt;/span&gt;(){&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;cout&lt;/span&gt;&amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;lt&lt;/span&gt;;&amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;lt&lt;/span&gt;;" print from base"&amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;lt&lt;/span&gt;;&amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;lt&lt;/span&gt;;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;endl&lt;/span&gt;;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-style: italic;"&gt;derived.h&lt;/span&gt;&lt;br /&gt;class derived : public base {&lt;br /&gt;public:&lt;br /&gt;derived(){};&lt;br /&gt;void &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;printMsg&lt;/span&gt;();&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;};&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-style: italic;"&gt;derived.cc&lt;/span&gt; &lt;/p&gt;   &lt;p class="MsoNormal"&gt;   void derived::&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;printMsg&lt;/span&gt;(){&lt;span style=""&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;cout&lt;/span&gt;&amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;lt&lt;/span&gt;;&amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;lt&lt;/span&gt;;" print from derived class"&amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;lt&lt;/span&gt;;&amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;lt&lt;/span&gt;;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;endl&lt;/span&gt;;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;}&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-style: italic;"&gt;   test code snippet:&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt;  &lt;p class="MsoNormal"&gt;   base* d = new derived();&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;d-&amp;gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;printMsg&lt;/span&gt;();&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;  &lt;/p&gt;&lt;/div&gt;  &lt;p class="MsoNormal"&gt;And what do I get:&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;gt;&amp;gt;&lt;span style="color: rgb(204, 0, 0);"&gt;print from base class&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt;  &lt;p class="MsoNormal"&gt;which is not what I expect? But how does it happen? The reason is still because of the binding   mechanisms in C++ and Java.&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;As we know there are two binding   mechanisms in C++: static binding and dynamic binding. Dynamic binding is   implemented through virtual functions; the actual code for the functions is   not attached or bound until execution time.&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;On the other hand, static binding   occurs when the functions code is “bound” at compile time. This means that   when a non-virtual function is called, the compiler determines at compile time   which version of the function to call. When overriding a non-virtual method   in a derived class, if we call the method via base class reference or   pointer type, the method in the base class is called. In our example above, the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;printMsg&lt;/span&gt;() in the base class is called and print out "print from base class".&lt;br /&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;   &lt;span style=""&gt;  &lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;As we have discussed before, in Java all method are treated as virtual, so   dynamic binding applied all the time. And when we override a method in a   derived class, we are able to call the method via a base class reference. &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-weight: bold;"&gt;   So what is the solution in C++ if I want to call the overridden methods in a derived   class via a base class reference?&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;   The answer is to make the method in base class virtual, as shown below:&lt;/p&gt;  &lt;div style="background-color: rgb(232, 232, 232);"&gt; &lt;p class="MsoNormal"&gt;   base.h &lt;/p&gt;     &lt;p class="MsoNormal"&gt;   class base{&lt;br /&gt;public:&lt;br /&gt;base(){}&lt;br /&gt;virtual void &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;printMsg&lt;/span&gt;();&lt;br /&gt;}; &lt;/p&gt; &lt;/div&gt;  &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;Because the function &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;printMsg&lt;/span&gt;() is virtual, dynamic binding applies. When we call the derived method via a base class   reference, we get what we want: &lt;/p&gt;   &lt;p class="MsoNormal"&gt;     &amp;gt;&amp;gt; &lt;span style="color: rgb(204, 0, 0);"&gt;print from derived class&lt;/span&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7506930953173811591-956814902772287850?l=xytang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xytang.blogspot.com/feeds/956814902772287850/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7506930953173811591&amp;postID=956814902772287850' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/956814902772287850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/956814902772287850'/><link rel='alternate' type='text/html' href='http://xytang.blogspot.com/2007/05/comparisons-of-c-and-java-iii-method.html' title='Comparisons of C++ and Java (III): Method Overriding'/><author><name>Xiaoyun Tang</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7506930953173811591.post-1390229479945631266</id><published>2007-05-20T23:50:00.000-06:00</published><updated>2007-05-21T12:04:16.456-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Comparisons of C++ and Java (II): Static Variables</title><content type='html'>&lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;   I used a lot of static variables in Java programming and I don't feel any   tricks except you have to know why you make a variable static. I thought it   would be the same to use static variable in C++. However, it is not true. &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;   &lt;b style=""&gt;In C++, static data member must be defined outside class   definition&lt;/b&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;   &lt;b style=""&gt; &lt;/b&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;   In Java, we declare a static variable in class scope and can access it   anywhere inside the class. In C++, I thought it must be the same way.   Actually it is not. Here is the example. I declare a variable static in head   file  (test.h) and try to use it in the program file (test.cc) as shown   in the sample code: &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt;  &lt;div style="background-color: rgb(232, 232, 232);"&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-style: italic;"&gt;   test.h&lt;/span&gt;&lt;/p&gt;      &lt;p class="MsoNormal"&gt;   class test {&lt;br /&gt; private:&lt;br /&gt;        &lt;span style=""&gt;        &lt;/span&gt;static int i;&lt;br /&gt; public:&lt;br /&gt;      test();&lt;span style="font-family:Courier New;"&gt;&lt;br /&gt;}&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt;     &lt;p class="MsoNormal"&gt;&lt;span style="font-style: italic;"&gt;   test.cc&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;test::test(){&lt;/span&gt;&lt;br /&gt; i = 0;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;}&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;   &lt;b style=""&gt; &lt;/b&gt; &lt;/p&gt; &lt;/div&gt;   &lt;p class="MsoNormal"&gt;   At compilation, I get an error says &lt;b style=""&gt;“undefined reference to   `test::i”.  &lt;/b&gt;After I looked up some books and also did some &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;Google&lt;/span&gt;   search, I finally figured   out that a static variable must be defined in the program file. So test.cc   should look like:&lt;br /&gt;&lt;/p&gt;     &lt;div style="background-color: rgb(232, 232, 232);"&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-style: italic;"&gt;     test.cc&lt;/span&gt;   &lt;/p&gt;   &lt;p class="MsoNormal"&gt;         &lt;/p&gt;               &lt;p class="MsoNormal"&gt;&lt;span style="font-weight: bold;"&gt;     int test::i;&lt;/span&gt; //We can also initialize i here, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;eg&lt;/span&gt;. int test::i = 0.&lt;br /&gt;test::test(){&lt;br /&gt; i = 0;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;}&lt;/span&gt;   &lt;/p&gt; &lt;/div&gt; &lt;p class="MsoNormal"&gt;    Now compiler is happy. But why? The reason is that C++ keeps two files for a   class: class declaration (header file) and class definition (program) file.   The header file contains the class declaration and does not necessary reserve   storage space associated with the identifier, while the program file contains   method definitions and reserve storage space for each given identifier.&lt;/p&gt;&lt;p class="MsoNormal"&gt; So   when we declare a static data member within a class definition, it is NOT   defined. In other words, we are not allocate storage for it. Instead, we must   provide a global definition for it elsewhere outside class definition because   it does not belong to any specific instance of the class.&lt;br /&gt;&lt;/p&gt; What about in Java? Java has a simplified matter by   only have class and variable definitions. There are no sole declarations in   Java, so class definition and variable definitions are also   class declarations and variable declarations. In other words, in Java, all   classes, data members and variables within methods are defined, therefore &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;storage&lt;/span&gt; spaces are reserved for primitive data types.    &lt;p class="MsoNormal"&gt;   &lt;b style=""&gt; &lt;/b&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;   &lt;b style=""&gt; &lt;/b&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;   &lt;b style=""&gt;In C++, a local variable can be static&lt;/b&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;   &lt;b style=""&gt; &lt;/b&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;   In C++, a local variable can be static. For example: &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt;   &lt;div style="background-color: rgb(232, 232, 232);"&gt; &lt;p class="MsoNormal"  style="font-family:Courier New;"&gt;   test::test(){ &lt;/p&gt; &lt;p class="MsoNormal"  style="font-family:Courier New;"&gt;   &lt;span style=""&gt;   &lt;/span&gt;i = 0; &lt;/p&gt; &lt;p class="MsoNormal" face="Courier New"&gt;   &lt;span style=""&gt;   &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;static int count = 0;&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-family:Courier New;"&gt;   }&lt;/span&gt; &lt;/p&gt; &lt;/div&gt;    &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;   is perfectly legal in C++. A local static variable has the same life time as a   global static variable, but its scope is local to the function in which it is   declared. It sounds a good idea to me.&lt;br /&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;   In Java, a static variable can only be declared inside a class scope. Compiler   will complain if a local variable is declared as static inside a method   scope,  Even inner classed cannot have static declarations. &lt;/p&gt;&lt;br /&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7506930953173811591-1390229479945631266?l=xytang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xytang.blogspot.com/feeds/1390229479945631266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7506930953173811591&amp;postID=1390229479945631266' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/1390229479945631266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/1390229479945631266'/><link rel='alternate' type='text/html' href='http://xytang.blogspot.com/2007/05/comparisons-of-c-and-java-ii-static.html' title='Comparisons of C++ and Java (II): Static Variables'/><author><name>Xiaoyun Tang</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7506930953173811591.post-5888972972850051015</id><published>2007-05-17T20:44:00.000-06:00</published><updated>2007-05-20T10:00:58.948-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Comparisons of C++ and Java (I): Static Binding and Dynamic Binding in C++</title><content type='html'>&lt;p class="MsoNormal"&gt;After years of Java programming, I have to pick up C++ for my work. Sometimes, it is hard to switch from Java thinking. Here is one of the example: Static binding and Dynamic binding in C++. &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;   Let me start with 3 examples.&lt;br /&gt;&lt;/p&gt; &lt;p style="font-weight: bold;" class="MsoNormal"&gt;Example 1 (In Java):&lt;/p&gt;  &lt;p style="background-color: rgb(204, 204, 255);" class="MsoNormal"&gt;     &lt;/p&gt; &lt;div style="background-color: rgb(204, 204, 255);" class="MsoNormal"&gt;&lt;span style="font-weight: bold;"&gt;base class:&lt;/span&gt;&lt;br /&gt;  &lt;p  style="background-color: rgb(204, 204, 255);font-family:Courier New;" class="MsoNormal"&gt;&lt;span style="font-family:Courier New;"&gt;public class base{&lt;/span&gt;&lt;br /&gt;public base(){}&lt;br /&gt;public void printMsg(){&lt;br /&gt; System.out.println("I am printMsg() from base class");&lt;br /&gt;} &lt;/p&gt;  &lt;p style="background-color: rgb(204, 204, 255); font-weight: bold;" class="MsoNormal"&gt;derived class&lt;br /&gt;&lt;/p&gt; &lt;p style="background-color: rgb(204, 204, 255);" class="MsoNormal"&gt;&lt;span style="font-weight: bold;"&gt;    &lt;/span&gt; &lt;/p&gt;       &lt;p  style="background-color: rgb(204, 204, 255);font-family:Courier New;" class="MsoNormal"&gt;  public class derived extends base{&lt;br /&gt;public derived(){}&lt;br /&gt;public void printMsg(){&lt;br /&gt;&lt;span style=""&gt;          &lt;/span&gt;System.out.println("I am printMsg() from derived class")&lt;br /&gt;}&lt;br /&gt;)&lt;br /&gt;&lt;/p&gt;  &lt;p style="background-color: rgb(204, 204, 255);" class="MsoNormal"&gt;&lt;span style="font-weight: bold;"&gt;A test class&lt;/span&gt;&lt;span style="font-style: italic;"&gt;:&lt;/span&gt; &lt;/p&gt; &lt;p style="background-color: rgb(204, 204, 255);" class="MsoNormal"&gt;     &lt;/p&gt;       &lt;p class="MsoNormal" face="Courier New" style="background-color: rgb(204, 204, 255);"&gt;    public class test {&lt;br /&gt;public static void main(String[] args){&lt;br /&gt;base myClass = new derived();&lt;br /&gt;myClass.printMsg();&lt;br /&gt;}&lt;br /&gt;}&lt;/p&gt;&lt;/div&gt;What do get? Here we go:  &lt;p class="MsoNormal" style=""&gt;     &lt;/p&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(204, 0, 0); font-weight: bold;"&gt;I am printMsg() from derived class&lt;/span&gt;  &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-weight: bold;"&gt;    &lt;/span&gt; &lt;/p&gt; It is so obvious to a Java programmer. OK, let’s look at C++ version of the example above.&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-weight: bold;"&gt;Example 2 (in C++):&lt;/span&gt; &lt;span style="font-weight: normal;"&gt;this example&lt;/span&gt; &lt;span style="font-weight: normal;"&gt;&lt;span style="font-style: italic;"&gt;looks&lt;/span&gt; exactly same as example 1 but in C++&lt;/span&gt;.  &lt;br /&gt;&lt;/p&gt;     &lt;p class="MsoNormal" style="background-color: rgb(204, 204, 255);"&gt;     &lt;/p&gt;       &lt;p class="MsoNormal" style="background-color: rgb(204, 204, 255);"&gt;     &lt;/p&gt;    &lt;p style="background-color: rgb(204, 204, 255);" class="MsoNormal"&gt;&lt;span style="font-weight: bold;"&gt;base class:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;class base{&lt;br /&gt;public:&lt;br /&gt;base(){};&lt;br /&gt;void printMsg( cout&amp;lt;&amp;lt;”hi, printMsg() from base”&amp;lt;&amp;lt;endl;);&lt;br /&gt;};&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;...&lt;br /&gt;&lt;br /&gt;derived class:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;class derived : public base {&lt;br /&gt;public:&lt;br /&gt;derived();&lt;br /&gt;void printMsg(cout&amp;lt;&amp;lt;”hi, printMsg() from derived class”&amp;lt;&amp;lt;endl);&lt;br /&gt;};&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;...&lt;br /&gt;test class snippet&lt;/span&gt;&lt;br /&gt;....&lt;br /&gt;&lt;span style="background-color: rgb(204, 204, 255);"&gt;base* myClass = new Polygon::derived();&lt;/span&gt;&lt;br /&gt;myClass-&amp;gt;printMsg();&lt;br /&gt;...&lt;br /&gt;&lt;/p&gt;&lt;p style="background-color: rgb(204, 204, 255);" class="MsoNormal"&gt;&lt;/p&gt;What do we get? There we go:         &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p style="font-weight: bold;" class="MsoNormal"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;&amp;gt;&amp;gt;hi, printMsg() from base&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;   and not “&lt;span style="font-style: italic;"&gt;hi, printMsg() from derived class&lt;/span&gt;” as I expected. &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;How can I access derived class version of printMsg() in C++? There is a way out: by using pure virtual methods. In &lt;span style="font-style: italic;"&gt;base.cc&lt;/span&gt; we change declaration of void printMsg() as: &lt;/p&gt;&lt;span style="font-weight: bold;"&gt;Example 3 (in C++)&lt;/span&gt;: This example is same as example 2 except in the base class. The method printMsg() is made &lt;span style="font-style: italic;"&gt;pure virtual&lt;/span&gt;:&lt;br /&gt;&lt;p class="MsoNormal" style="background-color: rgb(204, 204, 255); font-family: Courier New;"&gt;&lt;br /&gt;class base{&lt;br /&gt;public:&lt;br /&gt;base(){};&lt;br /&gt;&lt;span style="text-decoration: line-through;"&gt;void printMsg( cout&amp;lt;&amp;lt;”hi, printMsg() from base”&amp;lt;&amp;lt;endl;);&lt;/span&gt;&lt;br /&gt;virtual void printMsg() = 0;&lt;br /&gt;}; &lt;/p&gt;&lt;p style="font-family: Courier New; background-color: rgb(204, 204, 255);" class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;Then compile and run, I get what I want:&lt;br /&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p style="font-weight: bold;" class="MsoNormal"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;&amp;gt;&amp;gt;hi, printMsg() from derived class&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;   The derived class version of printMsg() get called. &lt;/p&gt;   &lt;p style="font-weight: bold;" class="MsoNormal"&gt; What is going on here?&lt;/p&gt;&lt;p class="MsoNormal"&gt;It is because Java and C++ provide different binding mechanisms to achieve run-time polymorphism.&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;In C++ there are two kinds of data binding: &lt;span style="font-style: italic;"&gt;static binding&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;dynamic binding&lt;/span&gt;. &lt;span style="font-style: italic;"&gt;Static binding&lt;/span&gt; is by means of nonpuer virtual functions while &lt;span style="font-style: italic;"&gt;dynamic binding&lt;/span&gt; is by virtual functions.&lt;br /&gt;At run time, the implementation is chosen differently.&lt;span style=""&gt; &lt;/span&gt;In static binding, decision is made by the &lt;span style="font-style: italic;"&gt;static type of pointer or reference&lt;/span&gt;, while in dynamic binding, decision is made by the actual type of object being pointed to.&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;This can explain the results from example 2 and 3. In example 2, base class contains no virtual printMsg() function, so it is static binding. In example 3, method printMsg() is a virtual function, so dynamic binding applies, therefore the derived class version of printMsg() is picked up.&lt;/p&gt;&lt;p class="MsoNormal"&gt;What happens in Java? In Java, every method is treated as pure virtual method and dynamic binding applies always. &lt;/p&gt;  &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-style: italic;"&gt;   Extra note on pure virtual method in C++:&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;     &lt;/p&gt; &lt;ol start="1" style="margin-top: 0in;" type="1"&gt;   &lt;li class="MsoNormal" style=""&gt;     When using pure virtual methods in C++, never try to call a pure virtual method from a constructor or destructor. Compiler will complain “error: abstract virtual `virtual method' called from constructor” at compilation time.   &lt;/li&gt;   &lt;li class="MsoNormal" style=""&gt;     Making destructor virtual is a best practice since it would make sure the destructor in derived class get called too as desired.   &lt;/li&gt; &lt;/ol&gt; &lt;p class="MsoNormal" style="margin-left: 0.25in;"&gt;     &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7506930953173811591-5888972972850051015?l=xytang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xytang.blogspot.com/feeds/5888972972850051015/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7506930953173811591&amp;postID=5888972972850051015' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/5888972972850051015'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/5888972972850051015'/><link rel='alternate' type='text/html' href='http://xytang.blogspot.com/2007/05/comparison-of-c-and-java-i-static.html' title='Comparisons of C++ and Java (I): Static Binding and Dynamic Binding in C++'/><author><name>Xiaoyun Tang</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7506930953173811591.post-90349707559045294</id><published>2007-03-20T15:59:00.000-06:00</published><updated>2007-07-30T19:02:43.665-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Gridsphere'/><title type='text'>Pack Input Jar Files Dynamically</title><content type='html'>When host a web site which allows users to download reusable Java class files which are compressed into different jar files, to reduce the download time for the client and the band with usage for the server, it would be nice to provide users an option to be able to download highly compressed packed files. As shown in the snippet of a sample download page, users will select any jar files and choose download them in a highly dense format - pack200.&lt;br /&gt;&lt;br /&gt;&lt;table&gt;   &lt;tbody&gt;   &lt;tr&gt;     &lt;td&gt;       &lt;select name="fileList" size="5"&gt;&lt;option value="file_1.jar"&gt;file_1.jar&lt;/option&gt;&lt;option value="file_2.jar"&gt;file_2.jar&lt;/option&gt;&lt;option value="file_3.jar"&gt;file_3.jar&lt;/option&gt;&lt;option value="file_4.jar"&gt;file_4.jar&lt;/option&gt;&lt;option value="file_5.jar"&gt;file_5.jar&lt;/option&gt;&lt;option value="file_6.jar"&gt;file_6.jar&lt;/option&gt;&lt;option value="file_7.jar"&gt;file_7.jar&lt;/option&gt;&lt;option value="file_8.jar"&gt;file_8.jar&lt;/option&gt;&lt;option value="file_9.jar"&gt;file_9.jar&lt;/option&gt;&lt;option value="file_10.jar"&gt;file_10.jar&lt;/option&gt;&lt;/select&gt;     &lt;/td&gt;     &lt;td valign="bottom"&gt;       &lt;input value="Compress/Download" type="submit"&gt;     &lt;/td&gt;   &lt;/tr&gt;   &lt;/tbody&gt; &lt;/table&gt; &lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;Pack Compressing Classes&lt;br /&gt;&lt;br /&gt;&lt;/span&gt; The JSR 200 (Network Transfer Format for Java&lt;sup&gt;&lt;span style=""&gt;TM&lt;/span&gt;&lt;/sup&gt; Archives) specifies a "dense download" format to compress input jar files in pack format. JSR 200 is supported with Java 5. The run-time API to pack and unpack the data and files is abstract class: java.util.jar.pack200.&lt;br /&gt;&lt;br /&gt;Pack200 is a abstract class and has one private constructor so it cannot be initialized directly. It provide two static methods to obtain new instance of the Packer engine:&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;span style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);font-family:monospace;" &gt;&lt;br /&gt;&lt;/span&gt; &lt;div style="background-color: rgb(232, 232, 232);"&gt; &lt;br /&gt;     Packer packer = Pack200.newPacker();&lt;br /&gt;&lt;br /&gt;&lt;/div&gt; &lt;code&gt;&lt;br /&gt;and &lt;/code&gt;an instance of the Unpacker engine&lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/jar/Pack200.html#newUnpacker%28%29" style="font-family: Courier New;"&gt;&lt;code&gt;&lt;/code&gt;&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;  Unpacker unpacker = Pack200.newUnpacker();&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Pack Jar Files at Runtime&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The following example shows how to convert jar files into a pack format  at run-time step by step:&lt;br /&gt;&lt;br /&gt;1. Obtain an instance of Packer engine:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;  Packer packer = Pack200.newPacker();&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;2. Set up output file stream for output packed stream:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;  FileOutputStream fos = new FileOutputStream("/tmp/test.pack");&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;3. Read the input jar into a Jar File input stream:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;  JarFile jarFile = new JarFile("/path/to/myfile.jar");&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;4. Call the packer to archive jar file:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;  packer.pack(jarFile, fos);&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;5. Close input file streams:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;  jarFile.close();&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;If there are more than one input jar files, repeat step 3, 4 and 5.&lt;br /&gt;&lt;br /&gt;6. Close output stream:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;   fos.close();&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;7. Set content type as &lt;span style="font-family:Verdana;"&gt;"&lt;span style="font-style: italic;"&gt;pack200-gzip&lt;/span&gt;". &lt;/span&gt;&lt;span style="font-family:Verdana;"&gt;This indicates to the server that the client application desires a version of the file encoded with Pack200 and further compressed with gzip:&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Unpack Paked Stream&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The unpacker engine is used by deployment applications to transform the byte-stream back to JAR format.&lt;br /&gt;&lt;br /&gt;The follow steps show how to unpack a packed files:&lt;br /&gt;&lt;br /&gt;1. Create an instance of Unpacker engine:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;Unpacker unpacker = Pack200.newUnpacker();&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;2. Read in input packed file and set up output file:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;  File infile = new File("/tmp/test.pack");&lt;br /&gt;&lt;br /&gt;  FileOutputStream fostream = new FileOutputStream("/tmp/test.jar");&lt;br /&gt;  JarOutputStream jostream = new JarOutputStream(fostream);&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;3. Call unpacker&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;  unpacker.unpack(infile, jostream);&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;4. Close file stream:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;  jostream.close();&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt; References:&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;h1&gt;   &lt;span style="font-size:85%;"&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/index.html" style="font-weight: normal;" target="blank_" title="JDKTM 5.0 Documentation"&gt;JDKTM 5.0 Documentation&lt;/a&gt;&lt;/span&gt;&lt;span style="font-weight: normal;font-size:85%;" &gt;&lt;span style="font-family:Verdana;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;&lt;/li&gt;&lt;li&gt;&lt;h1&gt;&lt;span style="font-weight: normal;font-size:85%;" &gt;&lt;a href="http://jcp.org/aboutJava/communityprocess/review/jsr200/index.html" title="Network Transfer Format JSR 200 Specification"&gt;Network Transfer Format JSR 200 Specification&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;/h1&gt;&lt;/li&gt;&lt;/ol&gt; &lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7506930953173811591-90349707559045294?l=xytang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xytang.blogspot.com/feeds/90349707559045294/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7506930953173811591&amp;postID=90349707559045294' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/90349707559045294'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/90349707559045294'/><link rel='alternate' type='text/html' href='http://xytang.blogspot.com/2007/03/when-host-web-site-which-allows-users.html' title='Pack Input Jar Files Dynamically'/><author><name>Xiaoyun Tang</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7506930953173811591.post-2878238895279607137</id><published>2007-03-20T15:55:00.000-06:00</published><updated>2007-07-30T19:04:44.885-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Generate Documents With Gridsphere Portlet -- A Bug in build.xml</title><content type='html'>&lt;div style="text-align: left;"&gt;I wanted to create document for my portlet called&lt;span style="font-style: italic;"&gt;testportlet&lt;/span&gt; created in GridsphereframeworkWhen I run&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;   &lt;span style="font-family:Courier New;"&gt;&lt;br /&gt;ant docs&lt;br /&gt;&lt;br /&gt;&lt;/span&gt; &lt;/div&gt; &lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;/span&gt;I got errors:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;   &lt;span style="font-family:Courier New;"&gt;&lt;br /&gt;BUILDFAILED&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;/path/to/gridsphere-2.1.5/projects/testportlet/build.xml:256:   No sou rce filesand no packages have been specified.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt; &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;In the &lt;span style="font-style: italic;"&gt;build.xml&lt;/span&gt; file the"&lt;span style="font-style: italic;"&gt;ant docs&lt;/span&gt;" is defined as:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;....&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt; &amp;lt;target name="docs"   depends="javadocs"description="Create   projectdocumentation"/&amp;gt;&lt;/span&gt;        &lt;span style="font-family:Courier New;"&gt;       &amp;lt;!--===================================================================--&amp;gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;     &amp;lt;!-- Creates   allthe   APIdocumentation                                  --&amp;gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;       &amp;lt;!--===================================================================--&amp;gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;       &amp;lt;targetname="javadocs" depends="setenv"   description="CreateJavadocs"&amp;gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;          &amp;lt;echo&amp;gt;CreatingJavadocs&amp;lt;/echo&amp;gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;          &amp;lt;delete   quiet="true"dir="${build.javadoc}"/&amp;gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;          &amp;lt;mkdirdir="${build.javadoc}"/&amp;gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;          &amp;lt;javadoc&lt;/span&gt;&lt;span style="font-weight: bold;font-family:Courier New;" &gt;sourcepath="src"&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;           classpathref="classpath"&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;           destdir="${build.javadoc}"&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;           author="true"&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;           version="true"&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;           splitindex="true"&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;           use="true"&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;           maxmemory="180m"&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;           windowtitle="${project.title}"&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;           doctitle="${project.api}"&amp;gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;              &amp;lt;!--bottom="Copyright &amp;amp;#169; 2002,2003 GridLab Project. All   RightsReserved."&amp;gt; --&amp;gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;       &amp;lt;/javadoc&amp;gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;      &amp;lt;/target&amp;gt;&lt;/span&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;I am using Java 1.5 and Apach Ant 1.6. Look like it is the issue of Java 1.5,the &lt;span style="font-style: italic;"&gt;sourcepath&lt;/span&gt; is ignored even though Irun "&lt;span style="font-style: italic;"&gt;javadoc&lt;/span&gt;" command from a separatepackage independent of Gridsphere framework. I modified a little bit of the&lt;span style="font-style: italic;"&gt;build.xml&lt;/span&gt; file and now it is workingwell:&lt;br /&gt;&lt;br /&gt;1. First remove attribute sourcepath="src"&lt;br /&gt;2. Add "&amp;lt;fileset dir="src" /&amp;gt;" to &amp;lt;javadoc&amp;gt; element.&lt;br /&gt;&lt;br /&gt;The modified file should look like:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;span style="font-family:Courier New;"&gt;....&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt; &amp;lt;target name="docs"   depends="javadocs"description="Create   projectdocumentation"/&amp;gt;&lt;/span&gt;        &lt;span style="font-family:Courier New;"&gt;       &amp;lt;!--===================================================================--&amp;gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;     &amp;lt;!-- Creates   allthe API   documentation   --&amp;gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;       &amp;lt;!--===================================================================--&amp;gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;       &amp;lt;targetname="javadocs" depends="setenv"   description="CreateJavadocs"&amp;gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;          &amp;lt;echo&amp;gt;CreatingJavadocs&amp;lt;/echo&amp;gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;          &amp;lt;delete   quiet="true"dir="${build.javadoc}"/&amp;gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;          &amp;lt;mkdirdir="${build.javadoc}"/&amp;gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;          &amp;lt;javadoc&lt;/span&gt;&lt;span style="text-decoration: line-through;font-family:Courier New;" &gt;sourcepath="src"&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;           classpathref="classpath"&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;           destdir="${build.javadoc}"&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;           author="true"&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;           version="true"&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;           splitindex="true"&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;           use="true"&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;           maxmemory="180m"&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;           windowtitle="${project.title}"&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;           doctitle="${project.api}"&amp;gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;               &lt;/span&gt;&lt;span style="font-weight: bold;font-family:Courier New;" &gt;&amp;lt;filesetdir="src"   /&amp;gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;              &amp;lt;!--bottom="Copyright &amp;amp;#169; 2002,2003 GridLab Project. All   RightsReserved."&amp;gt;   --&amp;gt;         &lt;/span&gt;&lt;span style="font-weight: bold;font-family:Courier New;" &gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;       &amp;lt;/javadoc&amp;gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt;      &amp;lt;/target&amp;gt;&lt;/span&gt;    &lt;span style="font-family:Courier New;"&gt; ...&lt;br /&gt;&lt;br /&gt;&lt;/span&gt; &lt;/div&gt;&lt;br /&gt;Save file and run "&lt;span style="font-style: italic;"&gt;ant docs&lt;/span&gt;" or"&lt;span style="font-style: italic;"&gt;ant javadocs&lt;/span&gt;", the document files aregenerated in/path/to/&lt;span style="font-family:Courier New;"&gt;gridsphere-2.1.5/projects/test&lt;/span&gt;portlet/build/docs/javadocs/.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Commentary:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Some one had mentioned that the combination of ant 1.6 and Java 1.5 wouldigmore attribute "&lt;span style="font-style: italic;"&gt;sourcepath&lt;/span&gt;" in thebuild file, but I think it is the problem of Java 1.5.  Do Gridspherepeople notice that? Anyway, it is still very nice to be able to generatedocuments for portlets from within Gridsphere framework environment if we do alittle bit extra work.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7506930953173811591-2878238895279607137?l=xytang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xytang.blogspot.com/feeds/2878238895279607137/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7506930953173811591&amp;postID=2878238895279607137' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/2878238895279607137'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/2878238895279607137'/><link rel='alternate' type='text/html' href='http://xytang.blogspot.com/2007/03/i-wanted-to-create-document-for-my.html' title='Generate Documents With Gridsphere Portlet -- A Bug in build.xml'/><author><name>Xiaoyun Tang</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7506930953173811591.post-6112897079426645909</id><published>2007-03-08T20:01:00.000-06:00</published><updated>2007-03-09T10:17:33.868-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='iText'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>A Web Form Based PDFs Merger</title><content type='html'> &lt;p class="MsoNormal"&gt;   &lt;font size="4"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;span style="font-style: italic;"&gt;Task&lt;/span&gt;:   Provide a web-based application allows users to merger multiple files.   Application is running in Grails framework.&lt;br&gt; &lt;/p&gt; &lt;br&gt; &lt;span style="font-style: italic;"&gt;Analysis&lt;/span&gt;: This problem can be split into three sub-tasks and be solved in three steps: upload multiple pdf files, retrieve submitted files and merger multiple pdfs.&lt;br&gt; &lt;br&gt; &lt;p class="MsoNormal"&gt;   &lt;span style="font-weight: bold;"&gt;Step1: Upload Multiple PDFs Files&lt;/span&gt;&lt;br&gt; &lt;/p&gt; &lt;br&gt; Upload and process multiple files from a Web Form is not a trivial task because file input element allows uploading only one file at a time. Inspired by &lt;a href="http://the-stickman.com/web-development/javascript/upload-multiple-files-with-a-single-file-element/" title="StickBlog"&gt;StickBlog&lt;/a&gt;'s excellent &lt;a href="http://the-stickman.com/web-development/javascript/upload-multiple-files-with-a-single-file-element/" title="post"&gt;post&lt;/a&gt;: &lt;span style="font-style: italic;"&gt;Upload multiple files with a single file element. &lt;/span&gt;I decided to use Javascript instead of Applet to achieve this goal. I modified StickBlog's code to accommodate my needs. The user interface &lt;a href="http://docs.google.com/View?docid=ddctjbfp_17dkqbpr" target="blank_" title="pdfmerger.gsp"&gt;pdfmerger.gsp&lt;/a&gt; has the following element:&lt;br&gt; &lt;br&gt; &lt;div class="MsoNormal" style="background-color: rgb(232, 232, 232);"&gt;   &lt;span style="font-family: Courier New;"&gt;   &lt;br&gt;       &amp;lt;g:form    &lt;span style="font-weight: bold;"&gt;action="merge"&lt;/span&gt; method="post"    enctype="multipart/form-data"&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;     &amp;lt;input   &lt;span style="font-weight: bold;"&gt;id='myfile'&lt;/span&gt; type='file' name=''   &lt;span style="font-weight: bold;"&gt;onChange="addElement()"&lt;/span&gt;&amp;gt;&amp;lt;/input&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;     &amp;lt;input   type="submit" value="Submit"&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;     &amp;lt;br&amp;gt;Files list   (Please note maximun number of uploaded files is   5):&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;     &amp;lt;!-- This is   where the output will appear   --&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;       &lt;span style="font-weight: bold;"&gt;&amp;lt;div   id="filesList"&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;       &amp;lt;/g:form&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;    &lt;/span&gt; &lt;/div&gt; &lt;p class="MsoNormal"&gt;   &lt;span style="font-family: Courier New;"&gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt; &lt;/p&gt; The event onChange of file input is captured.  Each time a file is selected, the Javascript function &lt;span style="font-style: italic;"&gt;addElement&lt;/span&gt; in &lt;a href="http://docs.google.com/View?docid=ddctjbfp_16f5fxhj" title="script.js"&gt;script.js&lt;/a&gt; is invoked&lt;br&gt; &lt;br&gt; &lt;div style="background-color: rgb(232, 232, 232);"&gt;       &lt;br&gt;       var new_row = document.createElement('div' );&lt;br&gt;   &lt;br&gt; &lt;/div&gt; &lt;br&gt; and a new &amp;lt;div&amp;gt; element is created and three elements: a text input box, a button and a file input box are appended to it. The text input box is just for display the file name. You can use other element for this purpose too:&lt;br&gt; &lt;br&gt; &lt;div style="background-color: rgb(232, 232, 232);"&gt;      &lt;br&gt;       var new_row_input =document.createElement( 'input' );&lt;br&gt;       new_row_input.type = 'text';&lt;br&gt;       new_row_input.name = "ins_" + (childs.length + 1)&lt;br&gt;       new_row_input.value = element.value;&lt;br&gt;&lt;br&gt; &lt;/div&gt; &lt;br&gt; The button is used to delete a corresponding uploaded file if it is clicked on:&lt;br&gt; &lt;br&gt; &lt;div style="background-color: rgb(232, 232, 232);"&gt;    &lt;span style="font-family: Courier New;"&gt;  &lt;br&gt;       var new_row_button =document.createElement( 'input'   );&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;     new_row_button.type   = 'button';&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;       new_row_button.onclick = function   (){&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;       ...&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;       ...&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;   }&lt;br&gt;   &lt;br&gt;   &lt;/span&gt; &lt;/div&gt; &lt;br&gt; The file input box stored the uploaded files and will be submitted to server, and we like to make it invisible:&lt;br&gt; &lt;br&gt; &lt;div style="background-color: rgb(232, 232, 232);"&gt;    &lt;br&gt;       &lt;span style="font-family: Courier New;"&gt;var   new_row_file_input =document.createElement( 'input'   );&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;       new_row_file_input.setAttribute ('name','file_' +   count);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;       new_row_file_input.setAttribute ('id','file_' +   count);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;       new_row_file_input.value =   element.value;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;       new_row_file_input.style.opacity = 0;&lt;br&gt;   &lt;br&gt;   &lt;/span&gt; &lt;/div&gt; &lt;br&gt; Finally, the newly created &amp;lt;div&amp;gt; element is appended to &amp;lt;div&amp;gt;with id"file_list " in pdfmerger.gsp: &lt;br&gt; &lt;br&gt; &lt;div class="MsoNormal" style="background-color: rgb(232, 232, 232);"&gt;    &lt;br&gt;        &lt;span style="font-family: Courier New;"&gt;new_row.appendChild(new_row_input);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;    new_row.appendChild(   new_row_button );&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;      new_row.appendChild(new_row_file_input);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;        &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;      &lt;span style="font-family: Courier New;"&gt;target_list.appendChild   (new_row);&lt;/span&gt;&lt;br&gt;   &lt;br&gt; &lt;/div&gt; &lt;p class="MsoNormal"&gt;   &lt;br&gt; &lt;/p&gt; &lt;p class="MsoNormal"&gt;   The complete Javascript can be found   &lt;a href="http://docs.google.com/View?docid=ddctjbfp_16f5fxhj" target="blank_" title="here"&gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p class="MsoNormal"&gt;   &lt;br&gt; &lt;/p&gt; &lt;span style="font-weight: bold;"&gt;Step 2: Retrieve Submitted Files&lt;br&gt; &lt;br style="font-weight: bold;"&gt; &lt;/span&gt;Submitted files are retrieved and processed on server side in acontroller called &lt;a href="http://docs.google.com/View?docid=ddctjbfp_18ggf2pz" target="blank_" title="here"&gt;PdfmergerController.java&lt;/a&gt;.In Grails, retrieving files is very easy by using build in Spring file system.We want to retrieve all submitted files and stored into an ArrayList for furtherprocessing.&lt;br&gt; &lt;br&gt; &lt;div style="background-color: rgb(232, 232, 232);"&gt;    &lt;br&gt;     &lt;span style="font-family: Courier New;"&gt; for (i in 0..   max_num-1){&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;           def file_name = "file_" + i;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;           def f = request.getFile(file_name);      &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;           if(f!=null &amp;amp;&amp;amp;   !(f.isEmpty())){&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;                //println "file content type " +   f.getContentType()&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;               FileInputStream ins =   f.getInputStream()&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;               pdfs.add(ins);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;          }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;   }&lt;br&gt;    &lt;br&gt;   &lt;/span&gt; &lt;/div&gt; &lt;br&gt; &lt;span style="font-weight: bold;"&gt;Step 3: Merger Multiple PDFs&lt;br&gt; &lt;br&gt; &lt;/span&gt;Once we have all submitted files in the list pdfs, we are ready to mergerthe PDFs. I just adopted the source code of method "concatPDFs" from&lt;a href="http://java-x.blogspot.com/2006/11/merge-pdf-files-with-itext.html" target="blank_" title="Abhi's"&gt; Abhi'spost&lt;/a&gt;. It works so well with my system. The source code ofPdfmergerController.java can be found &lt;a href="http://docs.google.com/View?docid=ddctjbfp_18ggf2pz" title="here"&gt;here&lt;/a&gt;.We added a &lt;span style="font-style: italic;"&gt;beforeInterceptor&lt;/span&gt; to validatefiles content type before request is processed further.&lt;br&gt; &lt;br&gt; &lt;span style="font-weight: bold;"&gt;Commentary&lt;br&gt; &lt;br&gt; &lt;/span&gt;&lt;span style="font-family: Verdana;"&gt;1. If server side processing is done ina J2ee environment, a third party library is needed since Java Servlet and Jspdo not have building mechanism to handle web form based file uploading. I had&lt;/span&gt;&lt;span class="mainText" style="font-family: Verdana;"&gt;Apache Jakarta CommonsFileUpload package. It is an open source and can be downloaded from &lt;a href="http://jakarta.apache.org/commons/fileupload/"&gt;Apache Jakarta CommonsFileUpload project&lt;/a&gt;. Another package &lt;a href="http://jakarta.apache.org/commons/io/"&gt;Apache Jakarta Commons IOproject&lt;/a&gt; is also needed internally by FileUpload package.&lt;br&gt; &lt;br style="font-family: Verdana;"&gt; &lt;/span&gt;&lt;span style="font-family: Verdana;"&gt;2. In step 3, we do file content typecheck on server side. However, it is also a good idea to validate content typeat client side when file is uploaded.&lt;br&gt; &lt;br style="font-family: Verdana;"&gt; &lt;/span&gt;&lt;span style="font-family: Verdana;"&gt;3. I just test the sample applicationwith IE and Firefox and no other else.&lt;/span&gt;&lt;br style="font-family: Verdana;"&gt; &lt;span style="font-weight: bold;"&gt;&lt;br&gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;References&lt;br&gt; &lt;br&gt; &lt;/span&gt;1. &lt;a href="http://the-stickman.com/web-development/javascript/upload-multiple-files-with-a-single-file-element/" title="StickBlog: Upload multiple files with a single file element"&gt;Uploadmultiple files with a single file element(&lt;/a&gt;&lt;a href="http://the-stickman.com/web-development/javascript/upload-multiple-files-with-a-single-file-element/" title="StickBlog: Upload multiple files with a single file element"&gt;StickBlog&lt;/a&gt;&lt;a href="http://the-stickman.com/web-development/javascript/upload-multiple-files-with-a-single-file-element/" title="StickBlog: Upload multiple files with a single file element"&gt;)&lt;/a&gt;&lt;br&gt; 2. &lt;a href="http://java-x.blogspot.com/2006/11/merge-pdf-files-with-itext.html"&gt;MergePDF files with iText (Abhi on Java)&lt;/a&gt;&lt;br&gt; 3. &lt;a href="http://grails.codehaus.org/Tutorials"&gt;Grails onlinetutorial&lt;/a&gt;&lt;br&gt; 4. &lt;a href="http://itextdocs.lowagie.com/tutorial/"&gt;Tutorial: iText ByExample&lt;/a&gt;&lt;br&gt; 5. &lt;span class="mainText"&gt;&lt;a href="http://jakarta.apache.org/commons/fileupload/"&gt;ApacheJakarta Commons FileUpload project&lt;/a&gt;&lt;br&gt; 6. &lt;/span&gt;&lt;span class="mainText"&gt;&lt;a href="http://jakarta.apache.org/commons/io/"&gt;Apache Jakarta Commons IOproject&lt;/a&gt;&lt;/span&gt;&lt;br&gt; &lt;br&gt; &lt;br&gt; &lt;br&gt; &lt;br&gt; &lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7506930953173811591-6112897079426645909?l=xytang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xytang.blogspot.com/feeds/6112897079426645909/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7506930953173811591&amp;postID=6112897079426645909' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/6112897079426645909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/6112897079426645909'/><link rel='alternate' type='text/html' href='http://xytang.blogspot.com/2007/03/web-form-based-pdfs-merger-task-provide.html' title='A Web Form Based PDFs Merger'/><author><name>Xiaoyun Tang</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7506930953173811591.post-5241140827525595164</id><published>2007-02-18T12:01:00.000-06:00</published><updated>2007-03-09T09:55:33.868-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dynamic Script Tag'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Services'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='Json'/><title type='text'></title><content type='html'> &lt;div style="text-align: center;"&gt;   &lt;span style="font-weight: bold;"&gt; Ajax Sandbox (1): Calling Remote Web Services&lt;br&gt;   Play with Json and Java Json API&lt;/span&gt;&lt;br&gt; &lt;/div&gt; &lt;br&gt; Json (JavaScript Oject Notation)i s a very interesting format for exchangingdata across domains. Comparing with XML,Jsont is easy to parse with JavaScript,and thus helps to establish a easy way to call remote web services from a Ajaxapplication.&lt;br&gt; &lt;br&gt; Here is an example of providing web services in Json format by utilizing JavaJson API. There are three core components in this example: a POJO class (&lt;a href="http://docs.google.com/View?docid=ddctjbfp_13f5vpq7" target="blank_" title="Book.java"&gt;Book.java&lt;/a&gt;) which stores the data model; a Java servlet&lt;span style="font-style: italic;"&gt; (&lt;/span&gt;&lt;a title="bookWS.java" target="blank_" href="http://docs.google.com/View?docid=ddctjbfp_9fhmmg6"&gt;bookWS.java&lt;/a&gt; &lt;a href="http://docs.google.com/View?docid=ddctjbfp_9fhmmg6" target="blank_" title="bookWS.java"&gt;&lt;/a&gt;) which provides web services in Json presentation; A html page (&lt;a href="http://docs.google.com/View?docid=ddctjbfp_12c8sv5x" target="blank_" title="bookWSTest.html"&gt;bookWSTest.html&lt;/a&gt;) which shows how to call a remote web services in JavaScript using. The working environment is Netbeans 5.5 RC2 as IDE, glassfish v2 as application server.&lt;br&gt; &lt;br&gt; &lt;span style="font-weight: bold;"&gt;Data Source&lt;br&gt; &lt;/span&gt;&lt;br&gt; The data source is a POJO class (&lt;a href="http://docs.google.com/View?docid=ddctjbfp_13f5vpq7" target="blank_" title="Book.java"&gt;Book.java&lt;/a&gt;),which represents a data table "book" in the database:&lt;br&gt; &lt;br&gt; &lt;div align="left"&gt;   &lt;table style="width: 465px; height: 96px;" border="1" cellpadding="3" cellspacing="0"&gt;     &lt;tbody&gt;     &lt;tr align="center"&gt;       &lt;td width="25%"&gt;         &lt;span style="font-weight: bold;"&gt; id*&lt;/span&gt;&lt;br&gt;       &lt;/td&gt;       &lt;td width="25%"&gt;         &lt;span style="font-weight: bold;"&gt; title&lt;/span&gt;&lt;br&gt;       &lt;/td&gt;       &lt;td width="25%"&gt;         &lt;span style="font-weight: bold;"&gt; author&lt;/span&gt;&lt;br&gt;       &lt;/td&gt;       &lt;td width="25%"&gt;         &lt;span style="font-weight: bold;"&gt; price&lt;/span&gt;&lt;br&gt;       &lt;/td&gt;     &lt;/tr&gt;     &lt;tr align="center"&gt;       &lt;td width="25%"&gt;         1&lt;br&gt;       &lt;/td&gt;       &lt;td width="25%"&gt;         Java EE 5 Tutorial&lt;br&gt;       &lt;/td&gt;       &lt;td width="25%"&gt;         John Smith&lt;br&gt;       &lt;/td&gt;       &lt;td width="25%"&gt;         45.6&lt;br&gt;       &lt;/td&gt;     &lt;/tr&gt;     &lt;tr align="center"&gt;       &lt;td width="25%"&gt;         2&lt;br&gt;       &lt;/td&gt;       &lt;td width="25%"&gt;         Ajax For Java Developer&lt;br&gt;       &lt;/td&gt;       &lt;td width="25%"&gt;         Rayn Todd&lt;br&gt;       &lt;/td&gt;       &lt;td width="25%"&gt;         29.0&lt;br&gt;       &lt;/td&gt;     &lt;/tr&gt;     &lt;/tbody&gt;   &lt;/table&gt; &lt;/div&gt; &lt;br&gt; &lt;span style="font-weight: bold;"&gt;Create a Web Services&lt;br&gt; &lt;br&gt; &lt;/span&gt;The second component is a servlet (&lt;a href="http://docs.google.com/View?docid=ddctjbfp_9fhmmg6" target="blank_" title="bookWS.java"&gt;bookWS.java&lt;/a&gt;) which returns a list of books stored in the database. The result is in Jsonformat and is ready for a client to consume.&lt;br&gt; &lt;br&gt; Before we go to further, let us take a look at the desired Json format in thisexample:&lt;br&gt; &lt;br&gt; The following example shows the JSON representation of a object that describe onbook:&lt;br&gt; &lt;br&gt; &lt;div style="background-color: rgb(232, 232, 232);"&gt;   &lt;span style="font-style: italic;"&gt;&lt;br&gt;List A&lt;/span&gt;:&lt;br&gt;   &lt;pre style="margin-bottom: 0.2in;"&gt;{"title":"Java EE 5 Tutorial","price":45.6,"author":"John Smith","id":1}&lt;br&gt;&lt;br&gt;&lt;/pre&gt; &lt;/div&gt; And the returned list of books look like:&lt;br&gt; &lt;br&gt; &lt;div style="background-color: rgb(232, 232, 232);"&gt;   &lt;span style="font-style: italic;"&gt;&lt;br&gt;List B&lt;/span&gt;:&lt;br&gt;   &lt;pre style="margin-bottom: 0.2in;"&gt;{"ResultSet":&lt;br&gt;{"books":&lt;br&gt;[{"title":"Java EE 5 Tutorial","price":45.6,"author":"John Smith","id":1},&lt;br&gt;{"title":"Ajax For Java Developer","price":29,"author":"Rayn Todd","id":2}]&lt;br&gt;}&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;/pre&gt; &lt;/div&gt; Now let's look at how we can utilize Java Json API to create web service in Json format. &lt;br&gt; &lt;br&gt; The entity class in accessible via resource injection. A JPQL select query isused to select data from database:&lt;br&gt; &lt;br&gt; &lt;div style="background-color: rgb(232, 232, 232);"&gt;   &lt;span style="font-family: Courier New;"&gt;  &lt;br&gt;  String sql ="select object(o)   fromBook as o";  //select all book   indb&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;  Query q   =em.createQuery(sql);      //executequery&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;  ArrayList bookList =   newArrayList(q.getResultList()); //store all books in   alist&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;  resultSet   =getResults(bookList);&lt;br&gt;&lt;br&gt;&lt;/span&gt; &lt;/div&gt; &lt;br&gt; A private method is created to convert the list of books into a Json object by utilizing Java Json API:&lt;br&gt; &lt;br&gt; &lt;div style="background-color: rgb(232, 232, 232);"&gt;   &lt;font style="font-family: Courier New; color: rgb(0, 0, 0);" size="2"&gt;&lt;br&gt;privateJSONObject getResults(ArrayList bookList){&lt;br&gt;&lt;br&gt;        JSONArray items = new JSONArray();&lt;br&gt;           JSONObject resultSet =   newJSONObject();&lt;br&gt;          &lt;br&gt;           JSONObject books = new   JSONObject();&lt;br&gt;          &lt;br&gt;       try {&lt;br&gt;           for (int i = 0; i   &amp;lt;bookList.size(); i++){&lt;br&gt;               Book o   =(Book)bookList.get(i);&lt;br&gt;              &lt;br&gt;                 JSONObjectbook_obj = new JSONObject();&lt;br&gt;                       &lt;br&gt;               book_obj.put("id",   o.getId());&lt;br&gt;               book_obj.put("title",   o.getTitle());&lt;br&gt;               book_obj.put("author",   o.getAuthor());&lt;br&gt;               book_obj.put("price",   o.getPrice());&lt;br&gt;               items.put(book_obj);         &lt;br&gt;           }&lt;br&gt;&lt;br&gt;           books.put("books", items);&lt;br&gt;           resultSet.put("ResultSet", books);&lt;br&gt;          &lt;br&gt;         }catch (JSONException e){&lt;br&gt;               System.out.println("Error:   Could not create Book JSONObject");&lt;br&gt;         }&lt;br&gt;           return resultSet;&lt;br&gt;     }&lt;br&gt;&lt;br style="color: rgb(153, 153, 153); font-style: italic;"&gt;&lt;/font&gt; &lt;/div&gt; &lt;br&gt; The resulting Json object is then serialized and returned to client:&lt;br&gt; &lt;br&gt; &lt;div style="background-color: rgb(232, 232, 232);"&gt;   &lt;span style="font-family: Courier New;"&gt;&lt;br&gt;    out.println(callback + "("   +resultSEt.toString() + ")");    &lt;br&gt;&lt;br&gt;&lt;/span&gt; &lt;/div&gt; &lt;br&gt; "callback" is the name of callback function that can be defined by users' inputand retrieved by:&lt;br&gt; &lt;br&gt; &lt;div style="background-color: rgb(232, 232, 232);"&gt;   &lt;span style="font-family: Courier New;"&gt;    &lt;br&gt;    String callback   =request.getParameter("callback");&lt;br&gt;&lt;br&gt;&lt;/span&gt; &lt;/div&gt; &lt;br&gt; Don't forget to set up response content type as:&lt;br&gt; &lt;br&gt; &lt;div style="background-color: rgb(232, 232, 232);"&gt;   &lt;span style="font-family: Courier New;"&gt;    &lt;br&gt;    response.setContentType("text/javascript;charset=UTF-8");&lt;br&gt;&lt;br&gt;&lt;/span&gt; &lt;/div&gt; &lt;br&gt; We have done all the work in Java servlet. When the servelt receives a request like:&lt;span style="font-family: Times New Roman;"&gt; http://www.myServer.com/beanTest/bookWS?callback=&lt;span style="font-weight: bold;"&gt;resultHandler&lt;/span&gt;&lt;/span&gt;&lt;br style="font-family: Times New Roman;"&gt; &lt;br&gt; The returned results should look like:&lt;br&gt; &lt;br&gt; &lt;div style="background-color: rgb(232, 232, 232);"&gt;    &lt;span style="font-family: Courier New;"&gt;&lt;span style="font-weight: bold;"&gt;resultHandler&lt;/span&gt;(&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;pre style="margin-bottom: 0.2in; font-family: Courier New;"&gt;	{&lt;br&gt;	"ResultSet":&lt;br&gt;	{&lt;br&gt;	"books":&lt;br&gt;	[&lt;br&gt;	{"title":"Java EE 5 Tutorial","price":45.6,"author":"John Smith","id":1},&lt;br&gt;	{"title":"Ajax For Java Developer","price":29,"author":"Rayn Todd","id":2}&lt;br&gt;	]&lt;br&gt;	}&lt;br&gt;	}&lt;br&gt;)&lt;br&gt;&lt;br&gt;&lt;/pre&gt; &lt;/div&gt; Let us go to next section to see how the results is accessible in JavaScript.&lt;br&gt; &lt;br&gt; &lt;span style="font-weight: bold;"&gt;Consume Web Services&lt;br&gt;&lt;br&gt;&lt;/span&gt; We use dynamic scripting tag to make a remote web service call. The returned Json object is accessible in the call back function. Here is a sample html page (&lt;a href="http://docs.google.com/View?docid=ddctjbfp_12c8sv5x" target="blank_" title="bookWSTest.html"&gt;bookWSTest.html&lt;/a&gt;):&lt;br&gt; &lt;font size="2"&gt;&lt;br&gt; &lt;/font&gt;&lt;div style="background-color: rgb(232, 232, 232);"&gt;&lt;font size="2"&gt;   &lt;span style="font-family: Courier New;"&gt;&lt;br&gt;&amp;lt;html&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;    &amp;lt;head&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;       &amp;lt;title&amp;gt;AjaxRemote Web Services   CallTest&amp;lt;/title&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;       &amp;lt;/head&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;    &amp;lt;script&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;    functionloadPage(){&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;       var url   ="http://www.myServer.com/beanTest/booksWS?callback=resultsHandler";&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;         varheadTag   =document.getElementsByTagName("head").item(0);       &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;         varscriptTag   =document.createElement("script");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;        scriptTag.src =   url;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;        headTag.appendChild( scriptTag   );&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;  function resultsHandler(   resultsObj){&lt;/span&gt;&lt;span style="font-family: Courier New;"&gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;      var result   =document.getElementById("result");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;        result.innerHTML= " total number of books is :   "+resultsObj.ResultSet.books.length;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt;     &amp;lt;bodyonload="loadPage()"&amp;gt;&lt;/span&gt;&lt;span style="font-family: Courier New;"&gt; &lt;br&gt;         &amp;lt;divid="result"&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span style="font-family: Courier New;"&gt;&lt;br&gt;   &amp;lt;/body&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;   &lt;span style="font-family: Courier New;"&gt; &amp;lt;/html&amp;gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/font&gt; &lt;/div&gt; &lt;br&gt; When page loads, function loadPage() gets executed and write a script tag forthe web services. Inside callback function &lt;span style="font-style: italic;"&gt;resultsHandler&lt;/span&gt;, the returned Json object  is accessible. In this example, the total number of books in db is printed out.&lt;br&gt; &lt;br&gt; &lt;img src="http://docs.google.com/File?id=ddctjbfp_8dj4hvq" style="height: 183px; width: 412px;" title="total number of books"&gt;&lt;br&gt; &lt;br&gt; &lt;span style="font-weight: bold;"&gt; References:&lt;br&gt; &lt;br&gt; &lt;/span&gt; &lt;ol&gt;   &lt;li&gt;     &lt;a href="http://www.json.org" target="blank_" title="Introducing Json"&gt;Introducing     Json&lt;/a&gt;&lt;br&gt;   &lt;/li&gt;   &lt;li&gt;     &lt;a href="http://en.wikipedia.org/wiki/JSON" target="blank_" title="Json"&gt;Json&lt;/a&gt;&lt;br&gt;   &lt;/li&gt;   &lt;li&gt;     &lt;a href="http://www.xml.com/pub/a/2005/12/21/json-dynamic-script-tag.html" target="blank_" title="JSON and the Dynamic Script Tag: Easy, XML-less Web Services for JavaScript"&gt;JSON     and the Dynamic Script Tag: Easy, XML-less Web Services for JavaScript&lt;/a&gt;   &lt;/li&gt;   &lt;li&gt;     &lt;a href="http://www-128.ibm.com/developerworks/library/j-ajax2/" target="blank_" title="Ajax for Java developers: Java object serialization for Ajax"&gt;Ajax     for Java developers: Java object serialization for Ajax&lt;/a&gt;&lt;br&gt;   &lt;/li&gt;   &lt;li&gt;     &lt;a href="http://www.json.org/java/index.html" target="blank_" title="JSON in Java"&gt;JSON     in Java&lt;/a&gt;&lt;br&gt;   &lt;/li&gt; &lt;/ol&gt; &lt;br&gt; &lt;br&gt; &lt;br&gt; &lt;br&gt; &lt;br&gt; &lt;br&gt; &lt;br&gt; &lt;br&gt; &lt;br&gt; &lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7506930953173811591-5241140827525595164?l=xytang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xytang.blogspot.com/feeds/5241140827525595164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7506930953173811591&amp;postID=5241140827525595164' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/5241140827525595164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/5241140827525595164'/><link rel='alternate' type='text/html' href='http://xytang.blogspot.com/2007/02/ajax-sandbox-1-calling-remote-web.html' title=''/><author><name>Xiaoyun Tang</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7506930953173811591.post-8774179717808150875</id><published>2007-02-09T16:07:00.000-06:00</published><updated>2007-02-13T12:10:04.254-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Grails -- Using Embedded Derby Database</title><content type='html'>Apache Derby is a relational database implemented in Java. It is light-weighted and can be  easily embed it in any Java-based solution. Here is a summary of using Derby Embedded JDBC  driver within Grails framework. I used grails-0.3.1 for the time being.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:times new roman;font-size:130%;"  &gt;Section 1: Install Software:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;1.Install Apache Derby (v10.1.3.1)&lt;br /&gt;&lt;br /&gt;Follow the tutorial from http://db.apache.org/derby/papers/DerbyTut/index.html to download and install software. (Note: ij tool is great to run SQL query from command line).&lt;br /&gt;&lt;br /&gt;2.Install Grails (v 3.0.1)&lt;br /&gt;&lt;br /&gt;The installation instruction can be found &lt;a href="http://www2.blogger.com/img/gl.link.gif"&gt;here&lt;/a&gt;. Set up environmental variables as described in the tutorial.&lt;br /&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-family:times new roman;font-size:130%;"  &gt;Section 2: Configure Grails for Using Embedded Derby Database&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Inside $GRAILS_HOME, create sample application.&lt;br /&gt;&lt;br /&gt;1. Create new Grails application by run command &lt;span style="font-style: italic; color: rgb(0, 51, 0);"&gt;grails create-app&lt;/span&gt;, set up corresponding application name as &lt;span style="font-style: italic;"&gt;myTest&lt;/span&gt;. Run command “grails create-domain-class”, set up domain name as “Book”.&lt;br /&gt;&lt;br /&gt;2. Copy derby.jar and derbytools.jar from $DERBY_INSTALL to &lt;span style="font-style: italic;"&gt;myTest/lib&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;3. Configure data sources. In &lt;span style="font-style: italic;"&gt;myTest/grails-app/conf&lt;/span&gt;, there are three data source files:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt; DevelopmentDataSource.groovy&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;ProductionDataSource.groovy&lt;/span&gt; &lt;/li&gt;&lt;li&gt;T&lt;span&gt;estDataSource.groovy&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;We need change the settings to let application talk to Derby instead of default Hypersonic database. A sample setting in  &lt;span style="font-style: italic;"&gt;ProductionDataSource.groovy&lt;/span&gt; would look like:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-style: italic; background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;class ProductionDataSource {&lt;br /&gt;boolean pooling = true&lt;br /&gt;String dbCreate = "update" // one of 'create', 'create-drop','update'&lt;br /&gt;&lt;br /&gt;##note: this setting point to a embedded db in /opt/db-derby-10.2.1.6-bin.&lt;br /&gt;##The file could be anywhere that the application can reach&lt;br /&gt;String url = "jdbc:derby:/opt/db-derby-10.2.1.6-bin/derbyDB"&lt;br /&gt;&lt;br /&gt;String  driverClassName = "org.apache.derby.jdbc.EmbeddedDriver”&lt;br /&gt;&lt;br /&gt;String username = ""&lt;br /&gt;String password = ""&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;4. We need another file in myTest/grails-app/hibernate/ called hibernate-dialects.properties which looks like:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-style: italic; background-color: rgb(232, 232, 233);"&gt;&lt;br /&gt;DerbyDialect=Apache Derby&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;This file is required especially for Derby DB but not for Postgresql as I know.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Section 3: Run Application:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;1. Then we are ready to run the application, execute the command:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic; color: rgb(0, 51, 51);"&gt;grails run-app.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;If everything goes right, we should be able to launch the application from http://localhost:8080/myTest.&lt;br /&gt;&lt;br /&gt;2. To test the application by create some new records.&lt;br /&gt;&lt;br /&gt;3. To verify whether the records are in Embedded Derby database, user Derby ij tool to run SQL query against our database prodDB. Please note, Derby won't allowed access from multiple applications for embedded model, so we have to shut down our application in order to run ij tool.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;References&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:100%;"&gt;&lt;a href="http://db.apache.org/derby/papers/DerbyTut/index.html"&gt;Apache Derby Tutorial&lt;/a&gt; (http://db.apache.org/derby/papers/DerbyTut/index.html)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:100%;"&gt;&lt;a href="http://db.apache.org/derby/derby_downloads.html"&gt;Apache Derby Downloads&lt;/a&gt;&lt;/span&gt;&lt;/span&gt; (&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:100%;"&gt;http://db.apache.org/derby/derby_downloads.html)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:100%;"&gt;&lt;a href="http://grails.codehaus.org/Installation"&gt;Grails Installation Instructions&lt;/a&gt;  http://grails.codehaus.org/Installation&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7506930953173811591-8774179717808150875?l=xytang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xytang.blogspot.com/feeds/8774179717808150875/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7506930953173811591&amp;postID=8774179717808150875' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/8774179717808150875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/8774179717808150875'/><link rel='alternate' type='text/html' href='http://xytang.blogspot.com/2007/02/grails-using-embedded-derby-database.html' title='Grails -- Using Embedded Derby Database'/><author><name>Xiaoyun Tang</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7506930953173811591.post-8529335365723856270</id><published>2007-02-05T15:46:00.000-06:00</published><updated>2007-02-13T21:48:59.466-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Grails -- Interceptors in Grails</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Introduction&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;An Interceptor is one of the key components in Aspect-Oriented Programming (AOP). It is defined to intercept method invocations, constructor invocation and field access. In grails, there are only two types of interceptor: &lt;span style="font-style: italic;"&gt;beforeInterceptor&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;afterInterceptor&lt;/span&gt;. They both are action interceptors used inside controllers.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Examples&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-style: italic;"&gt;befoerIntercetor&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This simple interceptor intercepts an user's request and checks uploaded file content-type. If it is not a PDF file, then it redirects the user to a previous view and presents an error message and returns false to caller. The innovation of the method is terminated; If yes, it continues the method call and trigger an action. It is very easy to use, no any configuration is needed.&lt;br /&gt;&lt;br /&gt;&lt;div style="font-style: italic; background-color: rgb(232, 232, 232);"&gt;class myController {&lt;br /&gt;def update = {/** do something here **/}&lt;br /&gt;def save = {/** do something here **/}&lt;br /&gt;&lt;br /&gt;//This line defines which actions is going to be intercepted.&lt;br /&gt;def beforeInterceptor = [action:this.&amp;validateFileType,only:['update', 'save']]&lt;br /&gt;&lt;br /&gt;def validateFileType = {&lt;br /&gt;def myFile= request.getFile("myFile") //get uploaded file&lt;br /&gt;if (myFile!=null &amp;amp;&amp; !(myFile.isEmpty()))&lt;br /&gt;{&lt;br /&gt;def contentType = f.getContentType()&lt;br /&gt;if (contentType!="application/pdf"){&lt;br /&gt;flash.message = "File must be a valid PDF file"&lt;br /&gt;redirect(action:create) //if fails, redirect to previous page.&lt;br /&gt;return false //This will terminate method call&lt;br /&gt;}&lt;br /&gt;else {&lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;return true&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;else {&lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;return true&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;In the line&lt;br /&gt;&lt;div style="font-style: italic; background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;def beforeInterceptor = [action:this.&amp;validateFileType,only:['update', 'save']]&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;"&lt;span style="font-style: italic;"&gt;only&lt;/span&gt;" is called “condition”. The condition of an interceptor can be either &lt;span style="font-style: italic;"&gt;"only"&lt;/span&gt; or "&lt;span style="font-style: italic;"&gt;except"&lt;/span&gt;. If the condition is not defined, then all actions in the controller will be intercepted.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-style: italic;"&gt;afterInceptor&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The second interceptor is afterInterceptor. Unlike beforeInterceptor, afterInterceptor gets invoked after an action has executed and before response gets back to client. We can process response object inside afterInterceptor before it gets back to clients, for example, writing logs, compressing files, sending emails, etc.&lt;br /&gt;&lt;br /&gt;The usage of afterInterceptor is very similar to that of beforeInterceptor. In my previous posting  &lt;a href="http://xytang.blogspot.com/2007/01/grails-how-to-send-out-email-after-some.html"&gt;Grail -- How to Send Out Email After Some Actions Have Been Finished&lt;/a&gt;, I have posted an afterInterceptor example. I would like to save some space here.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Commentary&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In grails, it is quite easy to use action interceptors to intercepts process based on either request or response. And it is also quite flexible to define which actions would trigger interceptors. No any XML configuration needed, which is the promise of coding by convention.&lt;br /&gt;&lt;br /&gt;However, there are still some limitations here. As I know for the time being, an interceptor can only intercepts actions from the same controller instead of multiple controllers. In other words, no interceptor chain is supported in Grails current releases.  Despite of this, I still want to say: the interceptors are so cool!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;References&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href="http://www2.blogger.com/img/gl.link.gif"&gt;Grails Tutorial#Controllers&lt;/a&gt; (http://grails.codehaus.org/Controllers)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7506930953173811591-8529335365723856270?l=xytang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xytang.blogspot.com/feeds/8529335365723856270/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7506930953173811591&amp;postID=8529335365723856270' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/8529335365723856270'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/8529335365723856270'/><link rel='alternate' type='text/html' href='http://xytang.blogspot.com/2007/02/grails-interceptors-in-grails.html' title='Grails -- Interceptors in Grails'/><author><name>Xiaoyun Tang</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7506930953173811591.post-5616541816664033656</id><published>2007-01-30T16:40:00.000-06:00</published><updated>2007-02-13T12:09:50.325-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iText'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Grails  -- How to Add Binary PDFs Into a PdfDocument Using iText</title><content type='html'>We created an application using Grails framework. This application would allow registered users to submit application forms in PDF format. For some special reasons, we have to  store all the PDFs into a relational database.  Then we need to create a controller, such that the admin user is able to generate a PDF report which includes all the application forms that users had submitted.&lt;br /&gt;&lt;br /&gt;The key issue for this task is to retrieve PDF files from the relational database and merge them  into a single PDF file. Inspired by the &lt;a href="http://java-x.blogspot.com/2006/11/merge-pdf-files-with-itext.html"&gt;post&lt;/a&gt; by Abni, we solved the problem by using iText in the following steps:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 1&lt;/span&gt;:  Create a PdfDocument and PdfWriter:&lt;br /&gt;&lt;div style="font-style: italic; background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;Document document = new Document(PageSize.A4, 50, 50, 50, 50);&lt;br /&gt;PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream())&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 2:&lt;/span&gt;  Retrieve a binary pdf file from database and write into a byte array:&lt;br /&gt;&lt;br /&gt;Suppose I have a domain class like this:&lt;br /&gt;&lt;div style="font-style: italic; background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;class Application {&lt;br /&gt;Long id&lt;br /&gt;ong version&lt;br /&gt;&lt;br /&gt;String username //Primary key&lt;br /&gt;byte[] application&lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;In grails, it is easy to retrieve a pdf file out of database and write into a byte array , eg:&lt;br /&gt;&lt;div style="font-style: italic; background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;def app = Application.findByUsername(userName)  //here userName is the primary key&lt;br /&gt;if (app != null &amp;&amp;amp; app.application.size() &gt; 0){&lt;br /&gt;&lt;br /&gt;def byte[] app_letter = app.application&lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 3:&lt;/span&gt;  Create a PdfReader from a byte array which represents a PDF file:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-style: italic; background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;PdfReader  pdfReader= new PdfReader(app_letter)&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Please note that the byte array must represent a valid PDF file, otherwise, an exception is thrown.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 4&lt;/span&gt;: Create a page from PdfReader and add the page to PdfDocument:&lt;br /&gt;&lt;div style="font-style: italic; background-color: rgb(232, 232, 232);"&gt;&lt;br /&gt;PdfImportedPage applicationPage&lt;br /&gt;PdfContentByte&lt;br /&gt;&lt;br /&gt;//the pdf file may contain more than one pages&lt;br /&gt;for (pageNumber in 0..pdfReader.getNumberOfPages()-1){&lt;br /&gt;pageNumber++&lt;br /&gt;&lt;br /&gt;applicationPage = writer.getImportedPage(pdfReader, pageNumber) //Create page from PdfReader&lt;br /&gt;&lt;br /&gt;cb.addTemplate(applicationPage, 0, 0) // add page to PdfDocument&lt;br /&gt;....&lt;br /&gt;....&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;The snippets above just show how to retrieve one PDF file from database and add it into a PdfDocument. For multiple PDF files, we can do the same thing for each of them and update page number correspondingly.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Discussion:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;1. In step 3, the byte array used to create PdfReader must represent a valid PDF file, otherwise, an exception throws. The program should handle the exception.&lt;br /&gt;&lt;br /&gt;2. PDF files are all hold in memory. If file number is huge, then we need to consider memory issues.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Reference:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;1. &lt;a href="http://java-x.blogspot.com/2006/11/merge-pdf-files-with-itext.html"&gt;Merge PDF files with iText (Abhi on Java)&lt;/a&gt;&lt;br /&gt;2. &lt;a href="http://grails.codehaus.org/Tutorials"&gt;Grails online tutorial&lt;/a&gt;&lt;br /&gt;3. &lt;a href="http://itextdocs.lowagie.com/tutorial/"&gt;Tutorial: iText By Example&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7506930953173811591-5616541816664033656?l=xytang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xytang.blogspot.com/feeds/5616541816664033656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7506930953173811591&amp;postID=5616541816664033656' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/5616541816664033656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/5616541816664033656'/><link rel='alternate' type='text/html' href='http://xytang.blogspot.com/2007/01/grails-how-to-add-binary-pdfs-into.html' title='Grails  -- How to Add Binary PDFs Into a PdfDocument Using iText'/><author><name>Xiaoyun Tang</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7506930953173811591.post-1848314941902084381</id><published>2007-01-28T20:59:00.000-06:00</published><updated>2007-02-13T11:31:56.630-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Grails -- How to send out an email after some actions have been done?</title><content type='html'>In my work, I need to send out a notice to the administrators each time a user submit an application. There are several ways to do this. The example here just demonstrates how easy it can be done by using "afterInterceptor" just in couple of steps:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Step 1:&lt;/span&gt;  Follow the tutorial posted &lt;a href="http://grails.codehaus.org/A+simple+EmailerService"&gt;here&lt;/a&gt; to configure a couple of beans which will be used for sending email.&lt;br /&gt;&lt;br /&gt;In spring/resources.xml, add the following configurations:&lt;br /&gt;&lt;div style="background-color:#E8E8E8; font-style: italic;"&gt;&lt;br /&gt;&amp;lt;beanid="mailSender"class="org.springframework.mail.javamail.JavaMailSenderImpl" &amp;gt; &lt;br /&gt;&amp;lt;property name="host"&amp;gt;&lt;br /&gt;&amp;lt;value&amp;gt;mailServer.abc.com&amp;lt;/value&amp;gt;&lt;br /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Step 2&lt;/span&gt;: Copy three jar files into the application' local &lt;span style="font-style: italic;"&gt;lib&lt;/span&gt;: &lt;/span&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;activations.jar, mail.jar and javaee.jar&lt;/span&gt;.  These jar files are needed by&lt;span class="code-tag"&gt;&lt;span style="font-style: italic;"&gt; org.springframework.mail.javamail.JavaMailSenderImpl. &lt;/span&gt;&lt;/span&gt;&lt;span class="code-tag"&gt;&lt;span class="code-quote"&gt;which is registered in the above spring/resources.xml file.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="code-tag"&gt;&lt;span class="code-quote"&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Step 3&lt;/span&gt;: Add the following code into the controller that I want to intercept. Because I want to attach a PDF file, so I used &lt;span style="font-style: italic;"&gt;MimeMessageHelper&lt;/span&gt; .&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color:#E8E8E8; font-style: italic;"&gt;&lt;br /&gt;class ApplictionController {&lt;br /&gt;&lt;br /&gt;/** the mailSender properties is defined in the spring/resources.xml and  are automatically injected by Grails**/&lt;br /&gt;MailSender mailSender&lt;br /&gt;&lt;br /&gt;def afterInterceptor = [action:this.&amp;sendMail,only:['save']]&lt;br /&gt;&lt;br /&gt;def  sendMail= {&lt;br /&gt;   MimeMessage message = mailSender.createMimeMessage();&lt;br /&gt;   MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");&lt;br /&gt;&lt;br /&gt;   //recipient of email could be a list of email addresses&lt;br /&gt;   String [] to = new String[2]&lt;br /&gt;   to[0] = "address1@gmail.com"&lt;br /&gt;   to[1]= "address2@gmail.com"&lt;br /&gt;&lt;br /&gt;   helper.setTo(to)&lt;br /&gt;   helper.setSubject("It is a test")&lt;br /&gt;   helper.setText("check out this PDF file")&lt;br /&gt;&lt;br /&gt;   //attach a file&lt;br /&gt;   FileSystemResource file = new FileSystemResource(new File("/path/to/myApplication.pdf"));&lt;br /&gt;   helper.addAttachment("myApplication.pdf",  file);&lt;br /&gt;&lt;br /&gt;   //send mail&lt;br /&gt;   mailSender.send(message)&lt;br /&gt;}&lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Commentary:&lt;/span&gt;&lt;br /&gt;1. &lt;span class="code-tag"&gt;&lt;span class="code-quote"&gt;One interceptor can be used to intercept more than one actions, for example:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color:#E8E8E8; font-style: italic;"&gt;&lt;br /&gt;def afterInterceptor = [action:this.&amp;sendMail,only:['save', 'update']]&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The Interceptor will execute each time after "save" or "update" are finished&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-tag"&gt;&lt;span class="code-quote"&gt;&lt;span style="font-style: italic;"&gt;     &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-tag"&gt;&lt;span class="code-quote"&gt;    2. The attachment could be binary data from the database. In this case, read data into a byte array and then create a &lt;span style="font-style: italic;"&gt;ByteArrayResource&lt;/span&gt; from the byte array. The B&lt;span style="font-style: italic;"&gt;yteArrayResource&lt;/span&gt; can be attached too.&lt;br /&gt;&lt;br /&gt;3. We can intercept before some actions get executed basically the same way but using "&lt;span style="font-style: italic;"&gt;beforeInterceptor&lt;/span&gt;" instead.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Issues&lt;/span&gt;: It turns out a very simple solution once I figured out how to do it. However, the solution above just intercepts actions based on a instance of one controller. What if I want to intercept multiple controller using only one interceptor? Can we do this in Grails?&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7506930953173811591-1848314941902084381?l=xytang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xytang.blogspot.com/feeds/1848314941902084381/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7506930953173811591&amp;postID=1848314941902084381' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/1848314941902084381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7506930953173811591/posts/default/1848314941902084381'/><link rel='alternate' type='text/html' href='http://xytang.blogspot.com/2007/01/grails-how-to-send-out-email-after-some.html' title='Grails -- How to send out an email after some actions have been done?'/><author><name>Xiaoyun Tang</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
