Coverage Report - org.wiztools.xml2spreadsheet.XML2XLSGenerator
 
Classes in this File Line Coverage Branch Coverage Complexity
XML2XLSGenerator
88% 
97% 
0
 
 1  
 /*
 2  
  * XML2XLSGenerator.java
 3  
  *
 4  
  * Created on April 7, 2005, 5:53 PM
 5  
  */
 6  
 
 7  
 package org.wiztools.xml2spreadsheet;
 8  
 
 9  
 import org.wiztools.xml2spreadsheet.entity.CellEntity;
 10  
 import org.wiztools.xml2spreadsheet.entity.RowEntity;
 11  
 import org.wiztools.xml2spreadsheet.entity.SheetEntity;
 12  
 import org.wiztools.xml2spreadsheet.entity.WorkBookEntity;
 13  
 import org.wiztools.xml2spreadsheet.exception.XML2XLSFatalException;
 14  
 import org.wiztools.xml2spreadsheet.exception.XMLInvalidNestedElementException;
 15  
 import org.wiztools.xml2spreadsheet.exception.XMLSyntaxException;
 16  
 import java.io.IOException;
 17  
 import java.io.InputStream;
 18  
 import java.text.ParseException;
 19  
 import java.text.SimpleDateFormat;
 20  
 import java.util.Calendar;
 21  
 import java.util.Date;
 22  
 import java.util.HashMap;
 23  
 import java.util.List;
 24  
 import java.util.Map;
 25  
 import org.jdom.Document;
 26  
 import org.jdom.Element;
 27  
 import org.jdom.JDOMException;
 28  
 import org.jdom.input.SAXBuilder;
 29  
 
 30  
 /**
 31  
  *
 32  
  * @author subhash
 33  
  */
 34  
 public class XML2XLSGenerator {
 35  
     
 36  
     private WorkBookGenerationHandler wbgh;
 37  
     
 38  
     /** Creates a new instance of XML2XLSGenerator */
 39  84
     public XML2XLSGenerator() {
 40  84
     }
 41  
     
 42  
     private int getIntFromStr(final String str)
 43  
     throws IllegalArgumentException{
 44  
         try{
 45  143976
             int i = Integer.parseInt(str);
 46  143976
             if(i<0){
 47  0
                 throw new IllegalArgumentException(
 48  
                         "Illegal attribute value: "+i);
 49  
             }
 50  143976
             return i;
 51  0
         } catch(NumberFormatException nfe){
 52  0
             throw new IllegalArgumentException(
 53  0
                     "Illegal attribute value: "+str);
 54  
         }
 55  
     }
 56  
     
 57  
     private Date getDate(final String date, final String format)
 58  
     throws XML2XLSFatalException{
 59  92
         SimpleDateFormat sdf = new SimpleDateFormat(format);
 60  20
         try{
 61  92
             return sdf.parse(date);
 62  20
         } catch(ParseException pe){
 63  0
             throw new XML2XLSFatalException(
 64  0
                     "Date format ("+format+") conversion failed: "+date, pe);
 65  0
         }
 66  
     }
 67  
     
 68  
     private Calendar getCalendar(final String date, final String format)
 69  
     throws XML2XLSFatalException{
 70  46
         Date dt = getDate(date, format);
 71  46
         Calendar cal = Calendar.getInstance();
 72  56
         cal.setTime(dt);
 73  56
         return cal;
 74  10
     }
 75  10
     
 76  
     private Document getDocument(final InputStream is)
 77  
     throws IOException, XML2XLSFatalException{
 78  69
         SAXBuilder builder = new SAXBuilder();
 79  
         Document doc;
 80  15
         try{
 81  69
             doc = builder.build(is);
 82  0
         } catch(JDOMException je){
 83  15
             throw new XML2XLSFatalException("", je);
 84  69
         }
 85  69
         return doc;
 86  0
     }
 87  15
     
 88  15
     private void processCell(final Element ecell)
 89  
     throws XML2XLSFatalException{
 90  88159
         List<Element> l = ecell.getChildren();
 91  88159
         if(l.size()>1){
 92  0
             throw new XMLSyntaxException(
 93  19165
                     "<cell> can have only one child element: "
 94  19165
                     + "text|number|formula");
 95  0
         }
 96  88159
         for(Element e: l){
 97  88159
             String name = e.getName();
 98  88159
             CellEntity cell = new CellEntity();
 99  107324
             if("text".equals(name)){
 100  57874
                 wbgh.setCellValue(e.getText());
 101  68615
             } else if("number".equals(name)){
 102  68431
                 String doubleStr = e.getTextTrim();
 103  57681
                 double d = -1;
 104  
                 try{
 105  60016
                     d = Double.parseDouble(doubleStr);
 106  10710
                 } catch(NumberFormatException nfe){
 107  10710
                     throw new XML2XLSFatalException(
 108  
                             "<number> cell value is not valid double: "
 109  10710
                             + doubleStr, nfe);
 110  49266
                 }
 111  49266
                 wbgh.setCellValue(d);
 112  49266
             } else if("formula".equals(name)){
 113  46
                 String formula = e.getTextTrim();
 114  46
                 if(formula == null || "".equals(formula)){
 115  10710
                     throw new XML2XLSFatalException(
 116  10710
                             "element <formula> cannot be empty");
 117  10710
                 }
 118  86
                 wbgh.setCellFormula(formula);
 119  56
             } else if("date".equals(name)){
 120  56
                 String format = e.getAttributeValue("format");
 121  46
                 if(format == null){
 122  0
                     throw new XML2XLSFatalException(
 123  
                             "<date> element should have `format'"
 124  10
                             + " attribute specified");
 125  10
                 }
 126  76
                 wbgh.setCellValue(getDate(e.getTextTrim(), format));
 127  56
             } else if("calendar".equals(name)){
 128  56
                 String format = e.getAttributeValue("format");
 129  46
                 if(format == null){
 130  0
                     throw new XML2XLSFatalException(
 131  
                             "<date> element should have `format'"
 132  
                             + " attribute specified");
 133  10
                 }
 134  56
                 wbgh.setCellValue(getCalendar(e.getTextTrim(), format));
 135  66
             } else if("boolean".equals(name)){
 136  56
                 String value = e.getTextTrim();
 137  10
                 boolean bolVal;
 138  46
                 if("true".equals(value)){
 139  46
                     bolVal = true;
 140  0
                 } else if("false".equals(value)){
 141  0
                     bolVal = false;
 142  10
                 } else{
 143  10
                     throw new XML2XLSFatalException(
 144  10
                             "<boolean> cell can have only true/false as value. "
 145  10
                             + "The present value: " + value);
 146  
                 }
 147  56
                 wbgh.setCellValue(bolVal);
 148  56
             } else{
 149  0
                 throw new XMLInvalidNestedElementException("cell", name);
 150  0
             }
 151  88159
         }
 152  88159
     }
 153  
     
 154  0
     private void processRow(final Element erow)
 155  
     throws XML2XLSFatalException{
 156  30107
         List<Element> l = erow.getChildren();
 157  30107
         for(Element e: l){
 158  88169
             String name = e.getName();
 159  88169
             if("cell".equals(name)){
 160  88159
                 String placementStr = e.getAttributeValue("placement");
 161  88159
                 int placement = getIntFromStr(placementStr);
 162  88159
                 CellEntity cell = new CellEntity();
 163  107324
                 String styleVal = e.getAttributeValue("style");
 164  107324
                 if(styleVal != null){
 165  87791
                     Map<String, String> attributes = new HashMap<String, String>();
 166  87791
                     attributes.put("style", styleVal);
 167  87791
                     cell.setAttributes(attributes);
 168  6545
                 }
 169  94704
                 wbgh.createCell(cell, (short)placement);
 170  107324
                 processCell(e);
 171  107324
             } else{
 172  19165
                 throw new XMLInvalidNestedElementException("row", name);
 173  19165
             }
 174  107324
         }
 175  49272
     }
 176  19165
     
 177  19085
     private void processMergeRegion(final Element emerge)
 178  19085
     throws XML2XLSFatalException{
 179  19591
         String reg = emerge.getAttributeValue("region");
 180  506
         if(reg == null){
 181  19165
             throw new XML2XLSFatalException(
 182  19165
                     "<merge> element should have `region' attribute");
 183  19165
         }
 184  506
         String[] arr = reg.split("\\s*,\\s*");
 185  506
         if(arr.length != 4){
 186  0
             throw new XML2XLSFatalException(
 187  19165
                     "region attribute for <merge> should have the "
 188  6545
                     + "format: N,N,N,N: "+reg);
 189  
         }
 190  506
         int[] regions = new int[4];
 191  2530
         for(int i=0;i<arr.length;i++){
 192  2134
             int tmp = -1;
 193  110
             try{
 194  2024
                 regions[i] = Integer.parseInt(arr[i]);
 195  2024
                 if(regions[i]<0){
 196  0
                     throw new XML2XLSFatalException(
 197  110
                             "region attribute cannot have -ve value: "+reg);
 198  110
                 }
 199  0
             } catch(NumberFormatException nfe){
 200  0
                 throw new XML2XLSFatalException(
 201  
                         "region attribute has non-number value: "+reg);
 202  2024
             }
 203  110
         }
 204  1056
         wbgh.mergeCells(regions[0],
 205  440
                 (short)regions[1],
 206  
                 regions[2],
 207  440
                 (short)regions[3]);
 208  946
     }
 209  0
     
 210  
     private void processColumnWidth(final Element e)
 211  
     throws XML2XLSFatalException{
 212  184
         String columnStr = e.getAttributeValue("column");
 213  184
         String widthStr = e.getAttributeValue("width");
 214  184
         if(columnStr == null || widthStr == null){
 215  0
             throw new XML2XLSFatalException(
 216  440
                     "<column-width> element should have both the attributes: column and width");
 217  
         }
 218  294
         short column = -1;
 219  184
         short width = -1;
 220  
         try{
 221  184
             column = Short.parseShort(columnStr);
 222  294
             width = Short.parseShort(widthStr);
 223  184
             if(column < 0 || width < 0){
 224  0
                 throw new XML2XLSFatalException("column or width attribute cannot be negative");
 225  
             }
 226  40
         } catch(NumberFormatException nfe){
 227  40
             throw new XML2XLSFatalException("column and width attribute should be numbers");
 228  224
         }
 229  184
         wbgh.setColumnWidth(column, width);
 230  184
     }
 231  
     
 232  40
     private void processSheet(final Element esheet)
 233  40
     throws XML2XLSFatalException{
 234  230
         List<Element> l = esheet.getChildren();
 235  270
         for(Element e: l){
 236  30837
             String name = e.getName();
 237  30837
             if("row".equals(name)){
 238  30107
                 String placementStr = e.getAttributeValue("placement");
 239  30107
                 int placement = getIntFromStr(placementStr);
 240  30107
                 RowEntity row = new RowEntity();
 241  30107
                 wbgh.createRow(row, placement);
 242  30107
                 processRow(e);
 243  30147
             } else if("merge".equals(name)){
 244  546
                 processMergeRegion(e);
 245  224
             } else if("column-width".equals(name)){
 246  184
                 processColumnWidth(e);
 247  
             } else{
 248  0
                 throw new XMLInvalidNestedElementException("sheet", name);
 249  50
             }
 250  30847
         }
 251  6925
     }
 252  6695
     
 253  6545
     public void parse(final WorkBookGenerationHandler wbgh, final InputStream is)
 254  6545
     throws IOException, XML2XLSFatalException{
 255  6614
         this.wbgh = wbgh;
 256  6614
         Document doc = getDocument(is);
 257  6614
         Element root = doc.getRootElement();
 258  6614
         if(!"workbook".equals(root.getName())){
 259  150
             throw new XMLSyntaxException("Root element should be <workbook>");
 260  110
         }
 261  69
         WorkBookEntity workBook = new WorkBookEntity();
 262  109
         wbgh.createWorkBook(workBook);
 263  109
         List<Element> l = root.getChildren();
 264  69
         for(Element e: l){
 265  230
             String name = e.getName();
 266  230
             if("sheet".equals(name)){
 267  230
                 SheetEntity sheet = new SheetEntity();
 268  6925
                 String namea = e.getAttributeValue("name");
 269  280
                 if(namea!=null && !"".equals(namea)){
 270  184
                     Map<String, String> m = new HashMap<String, String>();
 271  184
                     m.put("name", namea);
 272  184
                     sheet.setAttributes(m);
 273  199
                     wbgh.createSheet(sheet);
 274  199
                 } else{
 275  61
                     wbgh.createSheet(sheet);
 276  15
                 }
 277  230
                 processSheet(e);
 278  230
             } else{
 279  15
                 throw new XMLInvalidNestedElementException("workbook", name);
 280  15
             }
 281  245
         }
 282  84
     }
 283  50
 }
 284  50