1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 package org.openoffice.xmerge.converter.xml.sxc.pexcel;
25 
26 import java.io.IOException;
27 import java.util.Vector;
28 
29 import org.openoffice.xmerge.util.Debug;
30 
31 import org.openoffice.xmerge.converter.xml.sxc.SpreadsheetEncoder;
32 import org.openoffice.xmerge.converter.xml.sxc.Format;
33 import org.openoffice.xmerge.converter.xml.sxc.BookSettings;
34 import org.openoffice.xmerge.converter.xml.sxc.NameDefinition;
35 import org.openoffice.xmerge.converter.xml.sxc.pexcel.records.Workbook;
36 
37 /**
38  *  This class is used by {@link SxcDocumentSerializerImpl} to encode the Pocket Excel format.
39  *
40  *  @author  Martin Maher
41  */
42 final class PocketExcelEncoder extends SpreadsheetEncoder {
43 
44 	private Workbook wb;
45 
46     /**
47      *  Constructor creates a Pocket Excel WorkBook.
48      *
49      *  @param  name      The name of the WorkBook.
50      *  @param  password  The password for the WorkBook.
51      *
52      *  @throws  IOException  If any I/O error occurs.
53      */
PocketExcelEncoder(String name, String password)54     PocketExcelEncoder(String name, String password) throws IOException {
55 
56         super(name, password);
57 		wb = new Workbook(name);
58 
59     }
60 
61 
62     /**
63      *  This method creates a WorkSheet belonging to the
64      *  WorkBook.
65      *
66      *  @param  sheetName  The name of the WorkSheet.
67      *
68      *  @throws  IOException  If any I/O error occurs.
69      */
createWorksheet(String sheetName)70     public void createWorksheet(String sheetName) throws IOException {
71 
72 		wb.addWorksheet(sheetName);
73     }
74 
75 
76     /**
77      *  This method gets the number of sheets in the WorkBook.
78      *
79      *  @return  The number of sheets in the WorkBook.
80      */
getNumberOfSheets()81     public int getNumberOfSheets() {
82 
83 		Vector v = wb.getWorksheetNames();
84         return (v.size());
85     }
86 
87 
88     /**
89      *  This method returns the Workbook created.
90      *
91      *  @return  Returns a <code>Workbook</code>
92      *
93      *  @throws  IOException  If any I/O error occurs.
94      */
getWorkbook()95     public Workbook getWorkbook() throws IOException {
96 
97 		return wb;
98     }
99 
100     /**
101      *  This method converts a String containing a formula in infix notation
102 	 *  to a String in Reverse Polish Notation (RPN)
103      *
104      *  @return a parsed pexcel formula in RPN
105      */
parseFormula(String formula)106 	protected String parseFormula(String formula) {
107 
108 		Debug.log(Debug.TRACE,"Strip Formula (Before) : " + formula);
109 
110         StringBuffer inFormula = new StringBuffer(formula);
111         StringBuffer outFormula = new StringBuffer();
112 
113         boolean inBrace = false;
114         boolean firstCharAfterBrace = false;
115         boolean firstCharAfterColon = false;
116 
117         int len = inFormula.length();
118 
119         for (int in = 0; in < len; in++) {
120             switch (inFormula.charAt(in)) {
121             case '[':
122                 // We are now inside a StarOffice cell reference.
123                 // We also need to strip out the '['
124 				Debug.log(Debug.TRACE,"brace Found");
125                 inBrace = true;
126 
127                 // If the next character is a '.', we want to strip it out
128                 firstCharAfterBrace = true;
129                 break;
130 
131             case ']':
132                 // We are exiting a StarOffice cell reference
133                 // We are stripping out the ']'
134                 inBrace = false;
135                 break;
136 			case '.':
137 				if (inBrace == true && (firstCharAfterBrace == true ||
138 					firstCharAfterColon == true) ) {
139 
140 					Debug.log(Debug.TRACE,"dot Found and in brace");
141 					// Since we are in a StarOffice cell reference,
142 					// and we are the first character, we need to
143 					// strip out the '.'
144 					firstCharAfterBrace = false;
145 					firstCharAfterColon = false;
146 
147 				} else if(firstCharAfterColon == true) {
148 					firstCharAfterColon = false;
149 				} else {
150 					outFormula.append(inFormula.charAt(in));
151 				}
152 				break;
153 
154             case ':':
155                 // We have a cell range reference.
156                 // May need to strip out the leading '.'
157                 firstCharAfterColon = true;
158                 outFormula.append(inFormula.charAt(in));
159                 break;
160 
161             case ';':
162                 // StarOffice XML format uses ';' as a separator.  MiniCalc (and
163                 // many spreadsheets) use ',' as a separator instead.
164                 outFormula.append(',');
165                 break;
166 
167             default:
168                 // We hit valid data, lets add it to the formula string
169                 outFormula.append(inFormula.charAt(in));
170 
171                 // Need to make sure that firstCharAfterBrace is not true.
172                 firstCharAfterBrace = false;
173                 break;
174             }
175         }
176 
177 		Debug.log(Debug.TRACE,"Strip Formula (After) : " + outFormula);
178         return outFormula.toString();
179 	}
180 
181     /**
182      *  Add a cell to the current WorkSheet.
183      *
184      *  @param   row             The row number of the cell.
185      *  @param   column          The column number of the cell.
186      *  @param   fmt             The <code>Format</code> object describing
187      *                           the appearance of this cell.
188      *  @param   cellContents    The text or formula of the cell's contents.
189      *
190      *  @throws  IOException  If any I/O error occurs.
191      */
addCell(int row, int column, Format fmt, String cellContents)192     public void addCell(int row, int column, Format fmt, String cellContents) throws IOException {
193 
194 		if (cellContents.startsWith("=")) {
195 			cellContents = parseFormula(cellContents);
196 			Debug.log(Debug.TRACE,"Parsing Formula " + cellContents);
197 		}
198 		wb.addCell(row, column, fmt, cellContents);
199 	}
200 
201 
202     /**
203      *  Set the width of the columns in the WorkBook.
204      *
205      *  @param  columnWidths  An <code>IntArrayList</code> of column
206      *                        widths.
207      */
setColumnRows(Vector columnRows)208     public void setColumnRows(Vector columnRows) throws IOException {
209 
210 		wb.addColInfo(columnRows);
211     }
212 
213      /**
214      *  Set the width of the columns in the WorkBook.
215      *
216      *  @param  columnWidths  An <code>IntArrayList</code> of column
217      *                        widths.
218      */
setNameDefinition(NameDefinition nd)219     public void setNameDefinition(NameDefinition nd) throws IOException {
220 
221 		String parsedName = nd.getDefinition();
222 		nd.setDefinition(parseFormula(parsedName));
223 
224 		wb.addNameDefinition(nd);
225     }
226 
227      /**
228      *  Set the width of the columns in the WorkBook.
229      *
230      *  @param  columnWidths  An <code>IntArrayList</code> of column
231      *                        widths.
232      */
addSettings(BookSettings s)233     public void addSettings(BookSettings s) throws IOException {
234 
235 		wb.addSettings(s);
236     }
237 
238     /**
239      *  This method sets the format of a cell to <i>string</i>.
240      *
241      *  @param  format  The cell format-may already contain display info,
242      *                  such as alignment or font type.
243      *
244      *  @return  The updated format of the cell.
245      */
setFormatString(long format)246     private long setFormatString(long format) {
247 
248         return 0;
249     }
250 
251 
252     /**
253      *  Set a cell's formatting options via a separately create
254      *  <code>Format</code> object.
255      *
256      *  @param  row     The row number of the cell to be changed.
257      *  @param  column  The column number of the cell to be changed.
258      *  @param  fmt     Object containing formatting settings for
259      *                 this cell.
260      */
setCellFormat(int row, int column, Format fmt)261     public void setCellFormat(int row, int column, Format fmt) {
262 		Debug.log(Debug.TRACE,"bold : " + fmt.getAttribute(Format.BOLD) +
263 							",Italic : " + fmt.getAttribute(Format.ITALIC) +
264 							",Underline : " + fmt.getAttribute(Format.UNDERLINE));
265     }
266 
267 
268     /**
269      *  Get the names of the sheets in the WorkBook.
270      *
271      *  @param  sheet  The required sheet.
272      */
getSheetName(int sheet)273     public String getSheetName(int sheet) {
274 
275 		Vector v = wb.getWorksheetNames();
276 		String wsName = (String) (v.elementAt(sheet));
277 
278         return wsName;
279     }
280 
281 
282 }
283 
284