home *** CD-ROM | disk | FTP | other *** search
/ PC World 1998 October / PCWorld_1998-10_cd.bin / software / prehled / inprise / JSAMPLES.Z / ProviderBean.java < prev    next >
Text File  |  1998-05-08  |  8KB  |  224 lines

  1. /*
  2.  * Copyright (c) 1997-1998 Borland International, Inc. All Rights Reserved.
  3.  * 
  4.  * This SOURCE CODE FILE, which has been provided by Borland as part
  5.  * of a Borland product for use ONLY by licensed users of the product,
  6.  * includes CONFIDENTIAL and PROPRIETARY information of Borland.  
  7.  *
  8.  * USE OF THIS SOFTWARE IS GOVERNED BY THE TERMS AND CONDITIONS 
  9.  * OF THE LICENSE STATEMENT AND LIMITED WARRANTY FURNISHED WITH
  10.  * THE PRODUCT.
  11.  *
  12.  * IN PARTICULAR, YOU WILL INDEMNIFY AND HOLD BORLAND, ITS RELATED
  13.  * COMPANIES AND ITS SUPPLIERS, HARMLESS FROM AND AGAINST ANY CLAIMS
  14.  * OR LIABILITIES ARISING OUT OF THE USE, REPRODUCTION, OR DISTRIBUTION
  15.  * OF YOUR PROGRAMS, INCLUDING ANY CLAIMS OR LIABILITIES ARISING OUT OF
  16.  * OR RESULTING FROM THE USE, MODIFICATION, OR DISTRIBUTION OF PROGRAMS
  17.  * OR FILES CREATED FROM, BASED ON, AND/OR DERIVED FROM THIS SOURCE
  18.  * CODE FILE.
  19.  */
  20.  
  21. //Title:        Custom Providers and Resolvers
  22. //Version:      2.0
  23. //Copyright:    Copyright (c) 1998
  24. //Author:       Jens Ole Lauridsen
  25. //Company:      Borland International
  26. //Description:  Tutorial, example of provider and resolver.
  27.  
  28. package borland.samples.tutorial.dataset.providers;
  29.  
  30. import borland.jbcl.dataset.*;
  31. import borland.jbcl.util.Variant;
  32. import java.io.*;
  33. import java.math.BigDecimal;
  34.  
  35. // ProviderBean
  36. //   Provider   is an abstract base class for all providers
  37. //   LoadCancel is an interface allowing interruptions in the load
  38. //   DataLayout is an interface with constants describing the data layout in "data.txt"
  39. //
  40. public class ProviderBean extends Provider implements LoadCancel, DataLayout {
  41.  
  42.   // provideData = main provider method
  43.   // Parameters:
  44.   //   dataSet : StorageDataSet to receive the data.
  45.   //   toOpen  : Flag, that is true if this call happened during dataset.open().
  46.   //             Certain providers may optionally ignore such a request.
  47.   //             See the ExecuteOnOpen property for a QueryDescriptor.
  48.   //
  49.   public void provideData(StorageDataSet dataSet, boolean toOpen) throws DataSetException {
  50.  
  51.     // Definition of columns in the data:
  52.     //   (See the data file in data.txt)
  53.     Column[] columns = new Column[COLUMN_COUNT];
  54.     for (int i=0; i<COLUMN_COUNT; i++)
  55.       columns[i] = new Column( COLUMN_NAMES[i],
  56.                                COLUMN_CAPTIONS[i],
  57.                                COLUMN_TYPES[i] );
  58.  
  59.     // Now create the columns in the StorageDataSet.
  60.     //  The flags to this method are:
  61.     //    updateColumns:        true;  means merge columns into existing persistent columns.
  62.     //    keepExistingColumns:  false; means throw away any non persistent columns.
  63.     //    emptyRows:            true;  means empty the rows of the dataSet now.
  64.     //
  65.     // Returned is the ordinal map from our array of columns to the ordinal 
  66.     // in the dataset. Note, that the ordinal order will be the same as the 
  67.     // order as it was specified in replaceColumns, unless a user added some
  68.     // persistent columns with preferredOrdinal set.
  69.     //  
  70.     int[] columnMap = ProviderHelp.initData(dataSet, columns, true, false, true);
  71.     
  72.     // Optionally the rowId could be set here.
  73.     // The ResolverBean is the only cunsumer of this information.
  74.     dataSet.setAllRowIds(false);
  75.     Column rowid = dataSet.getColumn(ROWID_NAME);
  76.     rowid.setRowId(true);
  77.  
  78.     // Dont display the rowId column.
  79.     // The Column property "Hidden" is designed for Providers. It can
  80.     // be overridden by the "Visible" property in the designer.
  81.     rowid.setHidden(true);
  82.  
  83.     // Empty the dataSet for existing data:
  84.     dataSet.empty();
  85.  
  86.     // What is the maximum number of rows wanted ?
  87.     int maxRows = java.beans.Beans.isDesignTime() ? dataSet.getMaxDesignRows() : dataSet.getMaxRows();
  88.  
  89.     // Load the data:
  90.     if (maxRows != 0)
  91.       loadData(dataSet,maxRows,columnMap);
  92.   }
  93.  
  94.   // loadData = private method to load the actual data
  95.   // Parameters:
  96.   //   dataSet  : StorageDataSet to receive the data.
  97.   //   maxRows  : Maximal number of rows to load, (-1 = load all)
  98.   //   columnMap: Map from the data columns to the physical ordinals.
  99.   //
  100.   private void loadData(StorageDataSet dataSet, int maxRows, int[] columnMap) throws DataSetException {
  101.  
  102.     // Reset the cancel value:
  103.     cancel = false;
  104.     
  105.     // StorageDataSet.startLoading gives access to an internal array of Variants.
  106.     // This is the fastest way to load data into a DataSet.
  107.     //
  108.     Variant[] variants = dataSet.startLoading(this, RowStatus.LOADED, false);
  109.  
  110.     // Initialize a stream, such that we can close it before the method is exited.
  111.     //
  112.     FileInputStream fs = null;
  113.     
  114.     try {
  115.       // Open the text file: "data.txt", see context from the project tab
  116.       //
  117.       fs = new FileInputStream("data.txt");
  118.  
  119.       // Skip the first 2 lines. They contain an ansi ruler
  120.       //
  121.       skipLine(fs); 
  122.       skipLine(fs);
  123.  
  124.       // For each of the wanted rows:
  125.       //
  126.       for (int row = 0; row < maxRows || maxRows < 0; row++) {
  127.  
  128.         // For each of the columns defined by this provider:
  129.         //
  130.         for (int columnNo = 0; columnNo < columnMap.length; columnNo++) {
  131.  
  132.           // Get the ordinal of the column in the dataSet:
  133.           int  ordinal = columnMap[columnNo];
  134.  
  135.           // Read the String value of the field from the file:
  136.           String field = readField(fs,columnNo);
  137.  
  138.           // If the field is empty, record this as a NULL:
  139.           if (field.length() == 0)
  140.             variants[ordinal].setAssignedNull();
  141.           else {
  142.  
  143.             // Otherwise parse the text and store the value:
  144.             switch(variants[ordinal].getSetType()) {
  145.               case Variant.STRING:
  146.                 variants[ordinal].setString(field);
  147.                 break;
  148.               case Variant.INT:
  149.                 variants[ordinal].setInt( Integer.parseInt(field.trim()) );
  150.                 break;
  151.               case Variant.BIGDECIMAL:
  152.                 variants[ordinal].setBigDecimal( new BigDecimal(field) );
  153.                 break;
  154.                 
  155.               // There are no other types (see DataLayout.java)
  156.             }
  157.           }
  158.         }
  159.  
  160.         // StorageDataSet.loadRow() will save the row values in the
  161.         // variant array to the store of the dataSet.
  162.         dataSet.loadRow();
  163.  
  164.         // Skip the eol marker:
  165.         skipLine(fs);
  166.  
  167.         // Stop if the loading was cancelled by another thread:
  168.         if (cancel)
  169.           break;
  170.       } 
  171.     }
  172.     
  173.     // These error handlers are pretty bad...
  174.     catch (FileNotFoundException fnf) {
  175.       System.out.println("File: data.txt was not found");
  176.       // No Data to load...
  177.     }
  178.     catch (IOException ex) {
  179.       // Probably end of file marker...
  180.     }
  181.  
  182.     // Close the file:
  183.     if (fs != null) {
  184.       try {
  185.         fs.close();
  186.       }
  187.       catch (IOException ex) {
  188.         // Ignore...
  189.       }
  190.     }
  191.  
  192.     // Close the load buffer in the StorageDataSet:
  193.     dataSet.endLoading();
  194.   }
  195.  
  196.   // Skip up to the next line feed character:
  197.   private void skipLine(InputStream stream) throws IOException {
  198.     int ch = stream.read();
  199.     while (ch != '\n')
  200.       ch = stream.read();
  201.   }
  202.  
  203.   // Read a field from file. 
  204.   // The columns are setup in a fixed column format.
  205.   private String readField(InputStream stream, int columnNo) throws IOException {
  206.     int width = COLUMN_WIDTHS[columnNo];
  207.     byte[] buffer = new byte[width];
  208.     int len   = stream.read(buffer);
  209.     if (len < width)
  210.       throw new IOException("End of data");  // Cheap way to mark the eof...
  211.     String field = new String(buffer,0,width);
  212.     return field.trim();
  213.   }
  214.  
  215.   // The loading can be interrupted by calling this method.
  216.   // Another thread may call this method to stop a very slow load.
  217.   public void cancelLoad() {
  218.     cancel = true;
  219.   }
  220.   
  221.   boolean cancel;
  222. }
  223.  
  224.