Home » JCraft » jxl » write » biff » [javadoc | source]

    1   /*********************************************************************
    2   *
    3   *      Copyright (C) 2002 Andrew Khan
    4   *
    5   * This library is free software; you can redistribute it and/or
    6   * modify it under the terms of the GNU Lesser General Public
    7   * License as published by the Free Software Foundation; either
    8   * version 2.1 of the License, or (at your option) any later version.
    9   *
   10   * This library is distributed in the hope that it will be useful,
   11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13   * Lesser General Public License for more details.
   14   *
   15   * You should have received a copy of the GNU Lesser General Public
   16   * License along with this library; if not, write to the Free Software
   17   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
   18   ***************************************************************************/
   19   
   20   package jxl.write.biff;
   21   
   22   import jxl.common.Assert;
   23   import jxl.common.Logger;
   24   
   25   import jxl.WorkbookSettings;
   26   import jxl.biff.EncodedURLHelper;
   27   import jxl.biff.IntegerHelper;
   28   import jxl.biff.StringHelper;
   29   import jxl.biff.Type;
   30   import jxl.biff.WritableRecordData;
   31   
   32   /**
   33    * Stores the supporting workbook information.  For files written by
   34    * JExcelApi this will only reference internal sheets
   35    */
   36   class SupbookRecord extends WritableRecordData
   37   {
   38     /**
   39      * The logger
   40      */
   41     private static Logger logger = Logger.getLogger(SupbookRecord.class);
   42   
   43     /**
   44      * The type of this supbook record
   45      */
   46     private SupbookType type;
   47   
   48     /**
   49      * The data to be written to the binary file
   50      */
   51     private byte[] data;
   52   
   53     /**
   54      * The number of sheets - internal & external supbooks only
   55      */
   56     private int numSheets;
   57   
   58     /**
   59      * The name of the external file
   60      */
   61     private String fileName;
   62   
   63     /**
   64      * The names of the external sheets
   65      */
   66     private String[] sheetNames;
   67   
   68     /**
   69      * The workbook settings
   70      */
   71     private WorkbookSettings workbookSettings;
   72   
   73     /**
   74      * The type of supbook this refers to
   75      */
   76     private static class SupbookType {};
   77   
   78     public final static SupbookType INTERNAL = new SupbookType();
   79     public final static SupbookType EXTERNAL = new SupbookType();
   80     public final static SupbookType ADDIN    = new SupbookType();
   81     public final static SupbookType LINK     = new SupbookType();
   82     public final static SupbookType UNKNOWN  = new SupbookType();
   83     
   84     /**
   85      * Constructor for add in function names
   86      */
   87     public SupbookRecord()
   88     {
   89       super(Type.SUPBOOK);
   90       type = ADDIN;
   91     }
   92   
   93     /**
   94      * Constructor for internal sheets
   95      */
   96     public SupbookRecord(int sheets, WorkbookSettings ws)
   97     {
   98       super(Type.SUPBOOK);
   99   
  100       numSheets = sheets;
  101       type = INTERNAL;
  102       workbookSettings = ws;
  103     }
  104   
  105     /**
  106      * Constructor for external sheets
  107      *
  108      * @param fn the filename of the external supbook
  109      * @param ws the workbook settings
  110      */
  111     public SupbookRecord(String fn, WorkbookSettings ws)
  112     {
  113       super(Type.SUPBOOK);
  114   
  115       fileName = fn;
  116       numSheets = 1;
  117       sheetNames = new String[0];
  118       workbookSettings = ws;
  119   
  120       type = EXTERNAL;
  121     }
  122   
  123     /**
  124      * Constructor used when copying from an external workbook
  125      */
  126     public SupbookRecord(jxl.read.biff.SupbookRecord sr, WorkbookSettings ws)
  127     {
  128       super(Type.SUPBOOK);
  129   
  130       workbookSettings = ws;
  131       if (sr.getType() == sr.INTERNAL)
  132       {
  133         type = INTERNAL;
  134         numSheets = sr.getNumberOfSheets();
  135       }
  136       else if (sr.getType() == sr.EXTERNAL)
  137       {
  138         type = EXTERNAL;
  139         numSheets = sr.getNumberOfSheets();
  140         fileName = sr.getFileName();
  141         sheetNames = new String[numSheets];
  142   
  143         for (int i = 0; i < numSheets; i++)
  144         {
  145           sheetNames[i] = sr.getSheetName(i);
  146         }
  147       }
  148   
  149       if (sr.getType() == sr.ADDIN)
  150       {
  151         logger.warn("Supbook type is addin");
  152       }
  153     }
  154   
  155     /**
  156      * Initializes an internal supbook record
  157      * 
  158      * @param sr the read supbook record to copy from
  159      */
  160     private void initInternal(jxl.read.biff.SupbookRecord sr)
  161     {
  162       numSheets = sr.getNumberOfSheets();
  163       initInternal();
  164     }
  165   
  166     /**
  167      * Initializes an internal supbook record
  168      */
  169     private void initInternal()
  170     {
  171       data = new byte[4];
  172   
  173       IntegerHelper.getTwoBytes(numSheets, data, 0);
  174       data[2] = 0x1;
  175       data[3] = 0x4;    
  176       type = INTERNAL;
  177     }
  178   
  179     /**
  180      * Adjust the number of internal sheets.  Called by WritableSheet when
  181      * a sheet is added or or removed to the workbook
  182      *
  183      * @param sheets the new number of sheets
  184      */
  185     void adjustInternal(int sheets)
  186     {
  187       Assert.verify(type == INTERNAL);
  188       numSheets = sheets;
  189       initInternal();
  190     }
  191   
  192     /**
  193      * Initializes an external supbook record
  194      */
  195     private void initExternal()
  196     {
  197       int totalSheetNameLength = 0;
  198       for (int i = 0; i < numSheets; i++)
  199       {
  200         totalSheetNameLength += sheetNames[i].length();
  201       }
  202   
  203       byte[] fileNameData = EncodedURLHelper.getEncodedURL(fileName, 
  204                                                            workbookSettings);
  205       int dataLength = 2 + // numsheets
  206         4 + fileNameData.length +
  207         numSheets * 3 + totalSheetNameLength * 2;
  208         
  209       data = new byte[dataLength];
  210   
  211       IntegerHelper.getTwoBytes(numSheets, data, 0);
  212       
  213       // Add in the file name.  Precede with a byte denoting that it is a 
  214       // file name
  215       int pos = 2;
  216       IntegerHelper.getTwoBytes(fileNameData.length+1, data, pos);
  217       data[pos+2] = 0; // ascii indicator
  218       data[pos+3] = 1; // file name indicator
  219       System.arraycopy(fileNameData, 0, data, pos+4, fileNameData.length);
  220   
  221       pos += 4 + fileNameData.length;
  222   
  223       // Get the sheet names
  224       for (int i = 0; i < sheetNames.length; i++)
  225       {
  226         IntegerHelper.getTwoBytes(sheetNames[i].length(), data, pos);
  227         data[pos+2] = 1; // unicode indicator
  228         StringHelper.getUnicodeBytes(sheetNames[i], data, pos+3);
  229         pos += 3 + sheetNames[i].length() * 2;
  230       }
  231     }
  232   
  233     /**
  234      * Initializes the supbook record for add in functions
  235      */
  236     private void initAddin()
  237     {
  238       data = new byte[] {0x1, 0x0, 0x1, 0x3a};
  239     }
  240   
  241     /**
  242      * The binary data to be written out
  243      * 
  244      * @return the binary data
  245      */
  246     public byte[] getData()
  247     {
  248       if (type == INTERNAL)
  249       {
  250         initInternal();
  251       }
  252       else if (type == EXTERNAL)
  253       {
  254         initExternal();
  255       }
  256       else if (type == ADDIN)
  257       {
  258         initAddin();
  259       }
  260       else
  261       {
  262         logger.warn("unsupported supbook type - defaulting to internal");
  263         initInternal();
  264       }
  265   
  266       return data;
  267     }
  268   
  269     /**
  270      * Gets the type of this supbook record
  271      * 
  272      * @return the type of this supbook
  273      */
  274     public SupbookType getType()
  275     {
  276       return type;
  277     }
  278   
  279     /**
  280      * Gets the number of sheets.  This will only be non-zero for internal
  281      * and external supbooks
  282      *
  283      * @return the number of sheets
  284      */
  285     public int getNumberOfSheets()
  286     {
  287       return numSheets;
  288     }
  289   
  290     /**
  291      * Accessor for the file name
  292      *
  293      * @return the file name
  294      */
  295     public String getFileName()
  296     {
  297       return fileName;
  298     }
  299   
  300     /**
  301      * Adds the worksheet name to this supbook
  302      *
  303      * @param name the worksheet name
  304      * @return the index of this sheet in the supbook record
  305      */
  306     public int getSheetIndex(String s)
  307     {
  308       boolean found = false;
  309       int sheetIndex = 0;
  310       for (int i = 0; i < sheetNames.length && !found; i++)
  311       {
  312         if (sheetNames[i].equals(s))
  313         {
  314           found = true;
  315           sheetIndex = 0;
  316         }
  317       }
  318   
  319       if (found)
  320       {
  321         return sheetIndex;
  322       }
  323   
  324       // Grow the array
  325       String[] names = new String[sheetNames.length + 1];
  326       System.arraycopy(sheetNames, 0, names, 0, sheetNames.length);
  327       names[sheetNames.length] = s;
  328       sheetNames = names;
  329       return sheetNames.length - 1;
  330     }
  331   
  332     /**
  333      * Accessor for the sheet name
  334      * 
  335      * @param s the sheet index
  336      */
  337     public String getSheetName(int s)
  338     {
  339       return sheetNames[s];
  340     }
  341   }

Home » JCraft » jxl » write » biff » [javadoc | source]