Pastebin launched a little side project called HostCabi.net, check it out ;-)Don't like ads? PRO users don't see any ads ;-)
Guest

how to speed this up

By: a guest on May 19th, 2009  |  syntax: Java  |  size: 10.06 KB  |  hits: 47  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1.     import java.sql.ResultSet;
  2.     import java.util.List;
  3.     import java.util.ArrayList;
  4.     // etc etc. etc
  5.  
  6.  
  7.     public class SomeServlet extends HttpServlet {
  8.  
  9.  
  10.         // ALL THE FOLLOWING ARE CONSTANTA IN THE SERVLET.
  11.         // THEIR VALUE DOES'T CHANGE DURING EXECUTION
  12.         private static final String SELECT_DOCUMENT_QUERY = "SELECT \n" +
  13.                                                         "   id,LineType, QtyTotal, ManufacturerPartNumber, Description, UnitCost,UnitPrice \n" +
  14.                                                         " FROM DocumentItems  \n" +
  15.                                                         " WHERE DocID=%s order by linenumber ";
  16.  
  17.         private static final String HTML_HEADER_TABLE ="<table class=inner><thead><colgroup><col id='col1'>"+
  18.                                                         "<col id='col2'><col id='col3'><col id='col4'><col id='col5'></colgroup>" +
  19.                                                         "<tr class='enetBlue'><th>Qty</th><th>Part Num</th><th>Description</th>"+
  20.                                                         "<th>Unit Cost</th><th>Unit Price</th></tr></thead><tbody>";
  21.  
  22.  
  23.         // These constants are the HTML Commbo for the given queries.
  24.         // If they are initialized once at the beginning will increase
  25.         // the servlets performace considerabily.
  26.         private static final String UNIT_MEASURES_COMBO = getCombo( "Unit Measure", "UnitMeasKey",
  27.                                                                     getListFrom( "select * from tciUnitMeasure where companyid like 'ENS' ") );
  28.  
  29.         private static final String ITEM_CLASS_COMBO    = getCombo( "Purchase Product Line", "PurchProdLine",
  30.                                                                     getListFrom( "select * from timPurchProdLine where companyID = 'ENS' ") );
  31.        
  32.         private static final String CLASS_KEY_COMBO     = getCombo( "Item Class :", "itemclasskey",
  33.                                                                    getListFrom( "select * from timItemClass where companyID = 'ENS' order by itemclassname desc") );
  34.  
  35.         // Use a class to separete domain objects from presentation
  36.         // This class becomes handy do pass data through methods.
  37.         class Document {
  38.             int lineType;
  39.             int qty;
  40.             String part;
  41.             String desc;
  42.             float cost;
  43.             float price;
  44.             String id;
  45.         }
  46.         // simple clas that holds a key/value pair
  47.         class ComboPair {
  48.             String key;
  49.             String value;
  50.             public ComboPair( String key, String value ) {
  51.                 this.key = key;
  52.                 this.value = value;
  53.             }
  54.         }
  55.  
  56.  
  57.         /*
  58.         * Finally the fixed code.
  59.         *
  60.         * Basically a method should do only one thig. If the method is doing a lot of things
  61.         * several functionality at the same time, it should delegate the details of the subfunctionality
  62.         * to another function. This way each function or method is easier to read/maintain/understand.
  63.         * This method should read like this:
  64.         *
  65.         * For a given docId,
  66.         *    - query the database and display details of the document
  67.         *    - if the document is not present in mas?
  68.         *         - create a form to inser it
  69.         *  
  70.         * differntiate each record with different style.
  71.         */
  72.         private String getDetails(String doc){
  73.             // Close each result set before openning a new one.
  74.             ResultSet rs = qw.DBquery( String.format( SELECT_DOCUMENT_QUERY, doc ));
  75.             List<Document> documents = new ArrayList<Document>();
  76.             while(rs.next()){
  77.                 documents.add( createDocumentFrom( rs ));
  78.             }
  79.             // Iterate through
  80.             StringBuilder resultingTable = new StringBuilder( HTML_HEADER_TABLE );
  81.             boolean isEven = false;// starts as odd
  82.             for( Document doc : documents ) {
  83.                 String clazz = getClassFor( doc , isEven );
  84.                 isEven = !isEven;
  85.  
  86.                 resultingTable.append("<tr class='"+clazz+"'>"+
  87.                             "<td>"+doc.qty+"</td>\n"+
  88.                             "<td>"+doc.part+"</td>\n"+
  89.                             "<td>"+doc.desc+"</td>\n"+
  90.                             "<td>"+doc.cost+"</td>\n"+
  91.                             "<td>"+doc.price+"</td></tr>\n");
  92.  
  93.                 if( needsInsertForm( clazz ) ) {
  94.                     resultingTable.append( getInsertForm( document ) );
  95.                 }
  96.  
  97.                 resultingTable.append("</tbody></table>");
  98.             }
  99.             return table;
  100.         }
  101.  
  102.        
  103.         /**
  104.          * This methods craates an instance of "Document".
  105.          * Instead of mixing the fetch code with the render code
  106.          * this method allows to separete the data from its presentation
  107.          */
  108.         private Document createDocumentFrom( ResultSet rs ) {
  109.             Document document = new Document();
  110.  
  111.             document.lineType = rs.getInt("LineType");
  112.             document.qty = rs.getInt("QtyTotal");
  113.             document.part = rs.getString("ManufacturerPartNumber");
  114.             document.desc = rs.getString("Description");
  115.             document.cost = rs.getFloat("UnitCost");
  116.             document.price = rs.getFloat("UnitPrice");
  117.             document.id = rs.getString("id");
  118.  
  119.             return document;
  120.         }
  121.  
  122.  
  123.  
  124.         // Computes the correct css class for the given document.
  125.         private static String getClassFor( Document document, boolean isEven ) {
  126.             String clazz = "red";
  127.             switch( document.lineType ) {
  128.                 case 2:
  129.                 case 3:
  130.                 case 4: clazz ="yellow";
  131.             }
  132.             if( document.qty == 0 ) {
  133.                 clazz = "yellow";
  134.             }
  135.            ResultSet rs = mas.DBquery( String.format("select itemkey from timitem where itemid = '%s'", document.part);
  136.            while (rs.next()) {
  137.                clazz = isEven? "even" : "odd";
  138.            }
  139.            rs.close();
  140.            return clazz;
  141.            
  142.         }
  143.         // This is an utility method that reads bettern when used in the
  144.         // main method.
  145.         // if( needsInsertForm( clazzz ) ) {
  146.         // is much clearer
  147.         private static boolean needsInsertForm( String clazz ) {
  148.             return "red".equals(clazz);
  149.         }
  150.  
  151.         // Creates the inser form for the given document
  152.         private static String getInsertForm( Document document ) {
  153.             StringBuilder form = new StringBuilder();
  154.  
  155.             form.append("<tr ><td colspan=5><table border=1><tr><td colspan=2>\n");
  156.             form.append("<form name=masinsert"+document.id+" method=get action=MASInsert>\n");
  157.             form.append("<input type=hidden name=\"partnumber"+document.id+"\" value=\""+document.part+"\">\n");
  158.             form.append("<input type=hidden name=\"itemdescription"+document.id+"\" value=\""+document.desc+"\">\n");
  159.             form.append("<input type=hidden name=\"itemcost"+document.id+"\" value=\""+document.cost+"\">\n");
  160.             form.append("<input type=hidden name=\"itemlistprice"+document.id+"\" value=\""+document.price+"\">\n");
  161.             form.append("</td><tr>\n");
  162.             //----------------------------------------------------------------------------------------------------------------------------                                     
  163.             //get unit measure key  
  164.             form.append(UNIT_MEASURES_COMBO);                                  
  165.  
  166.             //build ItemClass options from mas: Puchase ProductLine
  167.             form.append(ITEM_CLASS_COMBO);
  168.  
  169.             //build item classkey options
  170.             form.append( CLASS_KEY_COMBO);
  171.             //----------------------------------------------------------------------------------------------------------------------------
  172.             form.append("<tr><td colspan=2><input id='m"+document.id+"' type=\"button\" onclick=\"masinsert('"+ document.id +"')\" value=\"Add to MAS\"></td></tr>");
  173.             form.append("</table>\n";
  174.             form.append("</form>\n";
  175.             form.append("</td></tr>");
  176.             return form.toString();
  177.                            
  178.         }
  179.  
  180.         // Generates an html combo
  181.         // is a bit messy, but does the job. In total this function is called only 3 times during
  182.         // this servlet life.
  183.         private static final String getCombo( String columnName, String comboName, List<ComboPair> items  ) {
  184.             // Don't need to worry too much here about string concatenation, this is invoked only once.
  185.             StringBuilder builder = new StringBuilder(
  186.                               "<tr bgcolor=#990033>\n"+
  187.                               "     <td align=left valign=top>"+columnName+"</td>\n"+
  188.                               "     <td align=left valign=top>\n"+
  189.                               "         <select name=\""+comboName+"\">\n" );
  190.             for( ComboPair pair : items ) {
  191.                 builder.append(String.format("<option value=\"%s\">%s</option>\n", pair.key, pair.value));
  192.             }
  193.             builder.append("</select></td></tr>\n");
  194.             return builder.toString();
  195.         }
  196.  
  197.         // Utlity method that builds a list of key=value objects from the given query.
  198.         // This is used to query the catalogs.
  199.         private static final List<ComboPair> getListFrom( String query ) {
  200.                 ResultSet rs = mas.DBquery( query );
  201.                 List<ComboPair> list = new ArrayList<ComboPair>();
  202.                 try {
  203.                     while(rs.next()) {
  204.                         list.add( new ComboPair( rs.getString("UnitMeasKey"),
  205.                                                  rs.getString("UnitMeasID")));
  206.                     }
  207.                 } finally {
  208.                     if( rs != null ) try {
  209.                         rs.close();
  210.                     } catch( SQLException sqle ){}
  211.                 }
  212.                 return list;
  213.         }
  214.  
  215.        
  216.        
  217.  
  218.     }