1*ef39d40dSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*ef39d40dSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*ef39d40dSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*ef39d40dSAndrew Rist  * distributed with this work for additional information
6*ef39d40dSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*ef39d40dSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*ef39d40dSAndrew Rist  * "License"); you may not use this file except in compliance
9*ef39d40dSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*ef39d40dSAndrew Rist  *
11*ef39d40dSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*ef39d40dSAndrew Rist  *
13*ef39d40dSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*ef39d40dSAndrew Rist  * software distributed under the License is distributed on an
15*ef39d40dSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*ef39d40dSAndrew Rist  * KIND, either express or implied.  See the License for the
17*ef39d40dSAndrew Rist  * specific language governing permissions and limitations
18*ef39d40dSAndrew Rist  * under the License.
19*ef39d40dSAndrew Rist  *
20*ef39d40dSAndrew Rist  *************************************************************/
21*ef39d40dSAndrew Rist 
22*ef39d40dSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir 
25cdf0e10cSrcweir package ifc.sheet;
26cdf0e10cSrcweir 
27cdf0e10cSrcweir import java.util.ArrayList;
28cdf0e10cSrcweir 
29cdf0e10cSrcweir import com.sun.star.beans.XPropertySet;
30cdf0e10cSrcweir import com.sun.star.container.XIndexAccess;
31cdf0e10cSrcweir import com.sun.star.container.XNamed;
32cdf0e10cSrcweir import com.sun.star.lang.IllegalArgumentException;
33cdf0e10cSrcweir import com.sun.star.sheet.*;
34cdf0e10cSrcweir import com.sun.star.table.CellAddress;
35cdf0e10cSrcweir import com.sun.star.table.CellRangeAddress;
36cdf0e10cSrcweir import com.sun.star.table.XCell;
37cdf0e10cSrcweir import com.sun.star.table.XCellCursor;
38cdf0e10cSrcweir import com.sun.star.table.XCellRange;
39cdf0e10cSrcweir import com.sun.star.uno.AnyConverter;
40cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime;
41cdf0e10cSrcweir 
42cdf0e10cSrcweir import lib.MultiMethodTest;
43cdf0e10cSrcweir import lib.Status;
44cdf0e10cSrcweir import lib.StatusException;
45cdf0e10cSrcweir 
46cdf0e10cSrcweir /**
47cdf0e10cSrcweir  * Testing <code>com.sun.star.sheet.XDataPilotTable2</code>
48cdf0e10cSrcweir  * interface methods :
49cdf0e10cSrcweir  * <ul>
50cdf0e10cSrcweir  *  <li><code> getDrillDownData()</code><li>
51cdf0e10cSrcweir  *  <li><code> getPositionData()</code></li>
52cdf0e10cSrcweir  *  <li><code> insertDrillDownSheet()</code></li>
53cdf0e10cSrcweir  *  <li><code> getOutputRangeByType</code></li>
54cdf0e10cSrcweir  * </ul>
55cdf0e10cSrcweir  *
56cdf0e10cSrcweir  * @see com.sun.star.sheet.XDataPilotTable2
57cdf0e10cSrcweir  * @see com.sun.star.table.CellAddress
58cdf0e10cSrcweir  *
59cdf0e10cSrcweir  */
60cdf0e10cSrcweir public class _XDataPilotTable2 extends MultiMethodTest
61cdf0e10cSrcweir {
62cdf0e10cSrcweir     private XSpreadsheetDocument xSheetDoc = null;
63cdf0e10cSrcweir     private XDataPilotTable2 xDPTab2 = null;
64cdf0e10cSrcweir     private CellRangeAddress mRangeWhole = null;
65cdf0e10cSrcweir     private CellRangeAddress mRangeTable = null;
66cdf0e10cSrcweir     private CellRangeAddress mRangeResult = null;
67cdf0e10cSrcweir     private ArrayList mDataFieldDims = null;
68cdf0e10cSrcweir     private ArrayList mResultCells = null;
69cdf0e10cSrcweir 
70cdf0e10cSrcweir     /**
71cdf0e10cSrcweir      * exception to be thrown when obtaining a result data for a cell fails
72cdf0e10cSrcweir      * (probably because the cell is not a result cell).
73cdf0e10cSrcweir      */
74cdf0e10cSrcweir     private class ResultCellFailure extends com.sun.star.uno.Exception {}
75cdf0e10cSrcweir 
before()76cdf0e10cSrcweir     protected void before()
77cdf0e10cSrcweir     {
78cdf0e10cSrcweir         Object o = tEnv.getObjRelation("DATAPILOTTABLE2");
79cdf0e10cSrcweir         xDPTab2 = (XDataPilotTable2)UnoRuntime.queryInterface(
80cdf0e10cSrcweir             XDataPilotTable2.class, o);
81cdf0e10cSrcweir 
82cdf0e10cSrcweir         if (xDPTab2 == null)
83cdf0e10cSrcweir             throw new StatusException(Status.failed("Relation not found"));
84cdf0e10cSrcweir 
85cdf0e10cSrcweir         xSheetDoc = (XSpreadsheetDocument)tEnv.getObjRelation("SHEETDOCUMENT");
86cdf0e10cSrcweir 
87cdf0e10cSrcweir         getOutputRanges();
88cdf0e10cSrcweir         buildDataFields();
89cdf0e10cSrcweir         try
90cdf0e10cSrcweir         {
91cdf0e10cSrcweir             buildResultCells();
92cdf0e10cSrcweir         }
93cdf0e10cSrcweir         catch (ResultCellFailure e)
94cdf0e10cSrcweir         {
95cdf0e10cSrcweir             e.printStackTrace(log);
96cdf0e10cSrcweir             throw new StatusException( "Failed to build result cells.", e);
97cdf0e10cSrcweir         }
98cdf0e10cSrcweir     }
99cdf0e10cSrcweir 
_getDrillDownData()100cdf0e10cSrcweir     public void _getDrillDownData()
101cdf0e10cSrcweir     {
102cdf0e10cSrcweir         boolean testResult = true;
103cdf0e10cSrcweir         int cellCount = mResultCells.size();
104cdf0e10cSrcweir         for (int i = 0; i < cellCount; ++i)
105cdf0e10cSrcweir         {
106cdf0e10cSrcweir             CellAddress addr = (CellAddress)mResultCells.get(i);
107cdf0e10cSrcweir             DataPilotTablePositionData posData = xDPTab2.getPositionData(addr);
108cdf0e10cSrcweir             DataPilotTableResultData resData = (DataPilotTableResultData)posData.PositionData;
109cdf0e10cSrcweir             int dim = ((Integer)mDataFieldDims.get(resData.DataFieldIndex)).intValue();
110cdf0e10cSrcweir             DataResult res = resData.Result;
111cdf0e10cSrcweir             double val = res.Value;
112cdf0e10cSrcweir 
113cdf0e10cSrcweir             Object[][] data = xDPTab2.getDrillDownData(addr);
114cdf0e10cSrcweir             double sum = 0.0;
115cdf0e10cSrcweir             if (data.length > 1)
116cdf0e10cSrcweir             {
117cdf0e10cSrcweir                 for (int row = 1; row < data.length; ++row)
118cdf0e10cSrcweir                 {
119cdf0e10cSrcweir                     Object o = data[row][dim];
120cdf0e10cSrcweir                     if (AnyConverter.isDouble(o))
121cdf0e10cSrcweir                         sum += ((Double)o).doubleValue();
122cdf0e10cSrcweir                 }
123cdf0e10cSrcweir             }
124cdf0e10cSrcweir             log.println(formatCell(addr) + ": " + data.length + " rows (" + (data.length-1) + " records)");
125cdf0e10cSrcweir 
126cdf0e10cSrcweir             if (val != sum)
127cdf0e10cSrcweir                 testResult = false;
128cdf0e10cSrcweir         }
129cdf0e10cSrcweir         tRes.tested("getDrillDownData()", testResult);
130cdf0e10cSrcweir     }
131cdf0e10cSrcweir 
_getPositionData()132cdf0e10cSrcweir     public void _getPositionData()
133cdf0e10cSrcweir     {
134cdf0e10cSrcweir         boolean testResult = false;
135cdf0e10cSrcweir 
136cdf0e10cSrcweir         do
137cdf0e10cSrcweir         {
138cdf0e10cSrcweir             CellAddress addr = new CellAddress();
139cdf0e10cSrcweir             addr.Sheet  = mRangeTable.Sheet;
140cdf0e10cSrcweir 
141cdf0e10cSrcweir             boolean rangeGood = true;
142cdf0e10cSrcweir             for (int x = mRangeTable.StartColumn; x <= mRangeTable.EndColumn && rangeGood; ++x)
143cdf0e10cSrcweir             {
144cdf0e10cSrcweir                 for (int y = mRangeTable.StartRow; y <= mRangeTable.EndRow && rangeGood; ++y)
145cdf0e10cSrcweir                 {
146cdf0e10cSrcweir                     addr.Column = x;
147cdf0e10cSrcweir                     addr.Row = y;
148cdf0e10cSrcweir                     log.println("checking " + formatCell(addr));
149cdf0e10cSrcweir                     DataPilotTablePositionData posData = xDPTab2.getPositionData(addr);
150cdf0e10cSrcweir                     if (posData.PositionType == DataPilotTablePositionType.NOT_IN_TABLE)
151cdf0e10cSrcweir                     {
152cdf0e10cSrcweir                         log.println("specified cell address not in table: " + formatCell(addr));
153cdf0e10cSrcweir                         rangeGood = false;
154cdf0e10cSrcweir                         continue;
155cdf0e10cSrcweir                     }
156cdf0e10cSrcweir 
157cdf0e10cSrcweir                     switch (posData.PositionType)
158cdf0e10cSrcweir                     {
159cdf0e10cSrcweir                     case DataPilotTablePositionType.NOT_IN_TABLE:
160cdf0e10cSrcweir                         break;
161cdf0e10cSrcweir                     case DataPilotTablePositionType.COLUMN_HEADER:
162cdf0e10cSrcweir                         printHeaderData(posData);
163cdf0e10cSrcweir                         break;
164cdf0e10cSrcweir                     case DataPilotTablePositionType.ROW_HEADER:
165cdf0e10cSrcweir                         printHeaderData(posData);
166cdf0e10cSrcweir                         break;
167cdf0e10cSrcweir                     case DataPilotTablePositionType.RESULT:
168cdf0e10cSrcweir                         printResultData(posData);
169cdf0e10cSrcweir                         break;
170cdf0e10cSrcweir                     case DataPilotTablePositionType.OTHER:
171cdf0e10cSrcweir                         break;
172cdf0e10cSrcweir                     default:
173cdf0e10cSrcweir                         log.println("unknown position");
174cdf0e10cSrcweir                     }
175cdf0e10cSrcweir                 }
176cdf0e10cSrcweir             }
177cdf0e10cSrcweir 
178cdf0e10cSrcweir             if (!rangeGood)
179cdf0e10cSrcweir             {
180cdf0e10cSrcweir                 log.println("table range check failed");
181cdf0e10cSrcweir                 break;
182cdf0e10cSrcweir             }
183cdf0e10cSrcweir 
184cdf0e10cSrcweir             testResult = true;
185cdf0e10cSrcweir         }
186cdf0e10cSrcweir         while (false);
187cdf0e10cSrcweir 
188cdf0e10cSrcweir         tRes.tested("getPositionData()", testResult);
189cdf0e10cSrcweir     }
190cdf0e10cSrcweir 
_insertDrillDownSheet()191cdf0e10cSrcweir     public void _insertDrillDownSheet()
192cdf0e10cSrcweir     {
193cdf0e10cSrcweir         boolean testResult = true;
194cdf0e10cSrcweir         int cellCount = mResultCells.size();
195cdf0e10cSrcweir         XSpreadsheets xSheets = xSheetDoc.getSheets();
196cdf0e10cSrcweir         XIndexAccess xIA = (XIndexAccess)UnoRuntime.queryInterface(
197cdf0e10cSrcweir             XIndexAccess.class, xSheets);
198cdf0e10cSrcweir         int sheetCount = xIA.getCount();
199cdf0e10cSrcweir         for (int i = 0; i < cellCount && testResult; ++i)
200cdf0e10cSrcweir         {
201cdf0e10cSrcweir             CellAddress addr = (CellAddress)mResultCells.get(i);
202cdf0e10cSrcweir 
203cdf0e10cSrcweir             Object[][] data = xDPTab2.getDrillDownData(addr);
204cdf0e10cSrcweir 
205cdf0e10cSrcweir             // sheet is always inserted at the current sheet position.
206cdf0e10cSrcweir             xDPTab2.insertDrillDownSheet(addr);
207cdf0e10cSrcweir 
208cdf0e10cSrcweir             int newSheetCount = xIA.getCount();
209cdf0e10cSrcweir             if (newSheetCount == sheetCount + 1)
210cdf0e10cSrcweir             {
211cdf0e10cSrcweir                 log.println("drill-down sheet for " + formatCell(addr) + " inserted");
212cdf0e10cSrcweir                 if (data.length < 2)
213cdf0e10cSrcweir                 {
214cdf0e10cSrcweir                     // There is no data for this result.  It should never have
215cdf0e10cSrcweir                     // inserted a drill-down sheet.
216cdf0e10cSrcweir                     log.println("new sheet inserted; however, there is no data for this result");
217cdf0e10cSrcweir                     testResult = false;
218cdf0e10cSrcweir                     continue;
219cdf0e10cSrcweir                 }
220cdf0e10cSrcweir 
221cdf0e10cSrcweir                 // Retrieve the object of the sheet just inserted.
222cdf0e10cSrcweir                 XSpreadsheet xSheet = null;
223cdf0e10cSrcweir                 try
224cdf0e10cSrcweir                 {
225cdf0e10cSrcweir                     xSheet = (XSpreadsheet)UnoRuntime.queryInterface(
226cdf0e10cSrcweir                         XSpreadsheet.class, xIA.getByIndex(addr.Sheet));
227cdf0e10cSrcweir                 }
228cdf0e10cSrcweir                 catch (com.sun.star.uno.Exception e)
229cdf0e10cSrcweir                 {
230cdf0e10cSrcweir                     e.printStackTrace();
231cdf0e10cSrcweir                     throw new StatusException("Failed to get the spreadsheet object.", e);
232cdf0e10cSrcweir                 }
233cdf0e10cSrcweir 
234cdf0e10cSrcweir                 // Check the integrity of the data on the inserted sheet.
235cdf0e10cSrcweir                 if (!checkDrillDownSheetContent(xSheet, data))
236cdf0e10cSrcweir                 {
237cdf0e10cSrcweir                     log.println("dataintegrity check on the inserted sheet failed");
238cdf0e10cSrcweir                     testResult = false;
239cdf0e10cSrcweir                     continue;
240cdf0e10cSrcweir                 }
241cdf0e10cSrcweir 
242cdf0e10cSrcweir                 log.println("  sheet data integrity check passed");
243cdf0e10cSrcweir 
244cdf0e10cSrcweir                 // Remove the sheet just inserted.
245cdf0e10cSrcweir 
246cdf0e10cSrcweir                 XNamed xNamed = (XNamed)UnoRuntime.queryInterface(XNamed.class, xSheet);
247cdf0e10cSrcweir                 String name = xNamed.getName();
248cdf0e10cSrcweir                 try
249cdf0e10cSrcweir                 {
250cdf0e10cSrcweir                     xSheets.removeByName(name);
251cdf0e10cSrcweir                 }
252cdf0e10cSrcweir                 catch (com.sun.star.uno.Exception e)
253cdf0e10cSrcweir                 {
254cdf0e10cSrcweir                     e.printStackTrace();
255cdf0e10cSrcweir                     throw new StatusException("Failed to removed the inserted sheet named " + name + ".", e);
256cdf0e10cSrcweir                 }
257cdf0e10cSrcweir             }
258cdf0e10cSrcweir             else if (newSheetCount == sheetCount)
259cdf0e10cSrcweir             {
260cdf0e10cSrcweir                 if (data.length > 1)
261cdf0e10cSrcweir                 {
262cdf0e10cSrcweir                     // There is data for this result.  It should have inserted
263cdf0e10cSrcweir                     // a new sheet.
264cdf0e10cSrcweir                     log.println("no new sheet is inserted, despite the data being present.");
265cdf0e10cSrcweir                     testResult = false;
266cdf0e10cSrcweir                 }
267cdf0e10cSrcweir             }
268cdf0e10cSrcweir             else
269cdf0e10cSrcweir             {
270cdf0e10cSrcweir                 log.println("what just happened!?");
271cdf0e10cSrcweir                 testResult = false;
272cdf0e10cSrcweir             }
273cdf0e10cSrcweir         }
274cdf0e10cSrcweir 
275cdf0e10cSrcweir         tRes.tested("insertDrillDownSheet()", testResult);
276cdf0e10cSrcweir     }
277cdf0e10cSrcweir 
_getOutputRangeByType()278cdf0e10cSrcweir     public void _getOutputRangeByType()
279cdf0e10cSrcweir     {
280cdf0e10cSrcweir         boolean testResult = false;
281cdf0e10cSrcweir 
282cdf0e10cSrcweir         do
283cdf0e10cSrcweir         {
284cdf0e10cSrcweir             // Let's make sure this doesn't cause a crash.  A range returned for an
285cdf0e10cSrcweir             // out-of-bound condition is undefined.
286cdf0e10cSrcweir             try
287cdf0e10cSrcweir             {
288cdf0e10cSrcweir                 CellRangeAddress rangeOutOfBound = xDPTab2.getOutputRangeByType(-1);
289cdf0e10cSrcweir                 log.println("exception not raised");
290cdf0e10cSrcweir                 break;
291cdf0e10cSrcweir             }
292cdf0e10cSrcweir             catch (IllegalArgumentException e)
293cdf0e10cSrcweir             {
294cdf0e10cSrcweir                 log.println("exception raised on invalid range type (good)");
295cdf0e10cSrcweir             }
296cdf0e10cSrcweir 
297cdf0e10cSrcweir             try
298cdf0e10cSrcweir             {
299cdf0e10cSrcweir                 CellRangeAddress rangeOutOfBound = xDPTab2.getOutputRangeByType(100);
300cdf0e10cSrcweir                 log.println("exception not raised");
301cdf0e10cSrcweir                 break;
302cdf0e10cSrcweir             }
303cdf0e10cSrcweir             catch (IllegalArgumentException e)
304cdf0e10cSrcweir             {
305cdf0e10cSrcweir                 log.println("exception raised on invalid range type (good)");
306cdf0e10cSrcweir             }
307cdf0e10cSrcweir 
308cdf0e10cSrcweir             // Check to make sure the whole range is not empty.
309cdf0e10cSrcweir             if (mRangeWhole.EndColumn - mRangeWhole.StartColumn <= 0 ||
310cdf0e10cSrcweir                 mRangeWhole.EndRow - mRangeWhole.EndColumn <= 0)
311cdf0e10cSrcweir             {
312cdf0e10cSrcweir                 log.println("whole range is empty");
313cdf0e10cSrcweir                 break;
314cdf0e10cSrcweir             }
315cdf0e10cSrcweir 
316cdf0e10cSrcweir             log.println("whole range is not empty (good)");
317cdf0e10cSrcweir 
318cdf0e10cSrcweir             // Table range must be of equal width with the whole range, and the same
319cdf0e10cSrcweir             // bottom.
320cdf0e10cSrcweir             if (mRangeTable.Sheet != mRangeWhole.Sheet ||
321cdf0e10cSrcweir                 mRangeTable.StartColumn != mRangeWhole.StartColumn ||
322cdf0e10cSrcweir                 mRangeTable.EndColumn != mRangeWhole.EndColumn ||
323cdf0e10cSrcweir                 mRangeTable.EndRow != mRangeWhole.EndRow)
324cdf0e10cSrcweir             {
325cdf0e10cSrcweir                 log.println("table range is incorrect");
326cdf0e10cSrcweir                 break;
327cdf0e10cSrcweir             }
328cdf0e10cSrcweir 
329cdf0e10cSrcweir             log.println("table range is correct");
330cdf0e10cSrcweir 
331cdf0e10cSrcweir             // Result range must be smaller than the table range, and must share the
332cdf0e10cSrcweir             // same lower-right corner.
333cdf0e10cSrcweir             if (mRangeResult.Sheet != mRangeTable.Sheet ||
334cdf0e10cSrcweir                 mRangeResult.StartColumn < mRangeTable.StartColumn ||
335cdf0e10cSrcweir                 mRangeResult.StartRow < mRangeTable.StartRow ||
336cdf0e10cSrcweir                 mRangeResult.EndColumn != mRangeTable.EndColumn ||
337cdf0e10cSrcweir                 mRangeResult.EndRow != mRangeTable.EndRow)
338cdf0e10cSrcweir                 break;
339cdf0e10cSrcweir 
340cdf0e10cSrcweir             log.println("result range is correct");
341cdf0e10cSrcweir 
342cdf0e10cSrcweir             testResult = true;
343cdf0e10cSrcweir         }
344cdf0e10cSrcweir         while (false);
345cdf0e10cSrcweir 
346cdf0e10cSrcweir         tRes.tested("getOutputRangeByType()", testResult);
347cdf0e10cSrcweir     }
348cdf0e10cSrcweir 
printHeaderData(DataPilotTablePositionData posData)349cdf0e10cSrcweir     private void printHeaderData(DataPilotTablePositionData posData)
350cdf0e10cSrcweir     {
351cdf0e10cSrcweir         DataPilotTableHeaderData header = (DataPilotTableHeaderData)posData.PositionData;
352cdf0e10cSrcweir         String posType = "";
353cdf0e10cSrcweir         if (posData.PositionType == DataPilotTablePositionType.COLUMN_HEADER)
354cdf0e10cSrcweir             posType = "column header";
355cdf0e10cSrcweir         else if (posData.PositionType == DataPilotTablePositionType.ROW_HEADER)
356cdf0e10cSrcweir             posType = "row header";
357cdf0e10cSrcweir 
358cdf0e10cSrcweir         log.println(posType + "; member name: " + header.MemberName + "; dimension: " +
359cdf0e10cSrcweir                     header.Dimension + "; hierarchy: " + header.Hierarchy +
360cdf0e10cSrcweir                     "; level: " + header.Level);
361cdf0e10cSrcweir     }
362cdf0e10cSrcweir 
printResultData(DataPilotTablePositionData posData)363cdf0e10cSrcweir     private void printResultData(DataPilotTablePositionData posData)
364cdf0e10cSrcweir     {
365cdf0e10cSrcweir         DataPilotTableResultData resultData = (DataPilotTableResultData)posData.PositionData;
366cdf0e10cSrcweir         int dataId = resultData.DataFieldIndex;
367cdf0e10cSrcweir         DataResult res = resultData.Result;
368cdf0e10cSrcweir         double val = res.Value;
369cdf0e10cSrcweir         int flags = res.Flags;
370cdf0e10cSrcweir         int filterCount = resultData.FieldFilters.length;
371cdf0e10cSrcweir         log.println("result; data field index: " + dataId + "; value: " + val + "; flags: " + flags +
372cdf0e10cSrcweir                     "; filter count: " + filterCount);
373cdf0e10cSrcweir 
374cdf0e10cSrcweir         for (int i = 0; i < filterCount; ++i)
375cdf0e10cSrcweir         {
376cdf0e10cSrcweir             DataPilotFieldFilter fil = resultData.FieldFilters[i];
377cdf0e10cSrcweir             log.println("  field name: " + fil.FieldName + "; match value: " + fil.MatchValue);
378cdf0e10cSrcweir         }
379cdf0e10cSrcweir     }
380cdf0e10cSrcweir 
formatCell(CellAddress addr)381cdf0e10cSrcweir     private String formatCell(CellAddress addr)
382cdf0e10cSrcweir     {
383cdf0e10cSrcweir         String str = "(" + addr.Column + "," + addr.Row + ")";
384cdf0e10cSrcweir         return str;
385cdf0e10cSrcweir     }
386cdf0e10cSrcweir 
printRange(String text, CellRangeAddress rangeAddr)387cdf0e10cSrcweir     private void printRange(String text, CellRangeAddress rangeAddr)
388cdf0e10cSrcweir     {
389cdf0e10cSrcweir         log.println(text + ": (" + rangeAddr.StartColumn + "," + rangeAddr.StartRow + ") - (" +
390cdf0e10cSrcweir                     rangeAddr.EndColumn + "," + rangeAddr.EndRow + ")");
391cdf0e10cSrcweir     }
392cdf0e10cSrcweir 
buildResultCells()393cdf0e10cSrcweir     private void buildResultCells() throws ResultCellFailure
394cdf0e10cSrcweir     {
395cdf0e10cSrcweir         if (mResultCells != null)
396cdf0e10cSrcweir             return;
397cdf0e10cSrcweir 
398cdf0e10cSrcweir         getOutputRanges();
399cdf0e10cSrcweir 
400cdf0e10cSrcweir         mResultCells = new ArrayList();
401cdf0e10cSrcweir         for (int x = mRangeResult.StartColumn; x <= mRangeResult.EndColumn; ++x)
402cdf0e10cSrcweir         {
403cdf0e10cSrcweir             for (int y = mRangeResult.StartRow; y <= mRangeResult.EndRow; ++y)
404cdf0e10cSrcweir             {
405cdf0e10cSrcweir                 CellAddress addr = new CellAddress();
406cdf0e10cSrcweir                 addr.Sheet = mRangeResult.Sheet;
407cdf0e10cSrcweir                 addr.Column = x;
408cdf0e10cSrcweir                 addr.Row = y;
409cdf0e10cSrcweir                 DataPilotTablePositionData posData = xDPTab2.getPositionData(addr);
410cdf0e10cSrcweir                 if (posData.PositionType != DataPilotTablePositionType.RESULT)
411cdf0e10cSrcweir                 {
412cdf0e10cSrcweir                     log.println(formatCell(addr) + ": this is not a result cell");
413cdf0e10cSrcweir                     throw new ResultCellFailure();
414cdf0e10cSrcweir                 }
415cdf0e10cSrcweir                 mResultCells.add(addr);
416cdf0e10cSrcweir             }
417cdf0e10cSrcweir         }
418cdf0e10cSrcweir     }
419cdf0e10cSrcweir 
buildDataFields()420cdf0e10cSrcweir     private void buildDataFields()
421cdf0e10cSrcweir     {
422cdf0e10cSrcweir         mDataFieldDims = new ArrayList();
423cdf0e10cSrcweir         XDataPilotDescriptor xDesc = (XDataPilotDescriptor)UnoRuntime.queryInterface(
424cdf0e10cSrcweir             XDataPilotDescriptor.class, xDPTab2);
425cdf0e10cSrcweir 
426cdf0e10cSrcweir         XIndexAccess xFields = xDesc.getDataPilotFields();
427cdf0e10cSrcweir         int fieldCount = xFields.getCount();
428cdf0e10cSrcweir         for (int i = 0; i < fieldCount; ++i)
429cdf0e10cSrcweir         {
430cdf0e10cSrcweir             try
431cdf0e10cSrcweir             {
432cdf0e10cSrcweir                 Object field = xFields.getByIndex(i);
433cdf0e10cSrcweir                 XPropertySet propSet = (XPropertySet)UnoRuntime.queryInterface(
434cdf0e10cSrcweir                     XPropertySet.class, field);
435cdf0e10cSrcweir                 DataPilotFieldOrientation orient =
436cdf0e10cSrcweir                     (DataPilotFieldOrientation)propSet.getPropertyValue("Orientation");
437cdf0e10cSrcweir                 if (orient == DataPilotFieldOrientation.DATA)
438cdf0e10cSrcweir                 {
439cdf0e10cSrcweir                     Integer item = new Integer(i);
440cdf0e10cSrcweir                     mDataFieldDims.add(item);
441cdf0e10cSrcweir                 }
442cdf0e10cSrcweir             }
443cdf0e10cSrcweir             catch (com.sun.star.uno.Exception e)
444cdf0e10cSrcweir             {
445cdf0e10cSrcweir                 e.printStackTrace(log);
446cdf0e10cSrcweir                 throw new StatusException( "Failed to get a field.", e);
447cdf0e10cSrcweir             }
448cdf0e10cSrcweir         }
449cdf0e10cSrcweir     }
450cdf0e10cSrcweir 
getOutputRanges()451cdf0e10cSrcweir     private void getOutputRanges()
452cdf0e10cSrcweir     {
453cdf0e10cSrcweir         if (mRangeWhole != null && mRangeTable != null && mRangeResult != null)
454cdf0e10cSrcweir             return;
455cdf0e10cSrcweir 
456cdf0e10cSrcweir         try
457cdf0e10cSrcweir         {
458cdf0e10cSrcweir             mRangeWhole = xDPTab2.getOutputRangeByType(DataPilotOutputRangeType.WHOLE);
459cdf0e10cSrcweir             printRange("whole range ", mRangeWhole);
460cdf0e10cSrcweir             mRangeTable = xDPTab2.getOutputRangeByType(DataPilotOutputRangeType.TABLE);
461cdf0e10cSrcweir             printRange("table range ", mRangeTable);
462cdf0e10cSrcweir             mRangeResult = xDPTab2.getOutputRangeByType(DataPilotOutputRangeType.RESULT);
463cdf0e10cSrcweir             printRange("result range", mRangeResult);
464cdf0e10cSrcweir         }
465cdf0e10cSrcweir         catch (IllegalArgumentException e)
466cdf0e10cSrcweir         {
467cdf0e10cSrcweir             e.printStackTrace(log);
468cdf0e10cSrcweir             throw new StatusException( "Failed to get output range by type.", e);
469cdf0e10cSrcweir         }
470cdf0e10cSrcweir     }
471cdf0e10cSrcweir 
checkDrillDownSheetContent(XSpreadsheet xSheet, Object[][] data)472cdf0e10cSrcweir     private boolean checkDrillDownSheetContent(XSpreadsheet xSheet, Object[][] data)
473cdf0e10cSrcweir     {
474cdf0e10cSrcweir         CellAddress lastCell = getLastUsedCellAddress(xSheet, 0, 0);
475cdf0e10cSrcweir         if (data.length <= 0 || lastCell.Row == 0 || lastCell.Column == 0)
476cdf0e10cSrcweir         {
477cdf0e10cSrcweir             log.println("empty data condition");
478cdf0e10cSrcweir             return false;
479cdf0e10cSrcweir         }
480cdf0e10cSrcweir 
481cdf0e10cSrcweir         if (data.length != lastCell.Row + 1 || data[0].length != lastCell.Column + 1)
482cdf0e10cSrcweir         {
483cdf0e10cSrcweir             log.println("data size differs");
484cdf0e10cSrcweir             return false;
485cdf0e10cSrcweir         }
486cdf0e10cSrcweir 
487cdf0e10cSrcweir         XCellRange xCR = null;
488cdf0e10cSrcweir         try
489cdf0e10cSrcweir         {
490cdf0e10cSrcweir             xCR = xSheet.getCellRangeByPosition(0, 0, lastCell.Column, lastCell.Row);
491cdf0e10cSrcweir         }
492cdf0e10cSrcweir         catch (com.sun.star.lang.IndexOutOfBoundsException e)
493cdf0e10cSrcweir         {
494cdf0e10cSrcweir             return false;
495cdf0e10cSrcweir         }
496cdf0e10cSrcweir 
497cdf0e10cSrcweir         XCellRangeData xCRD = (XCellRangeData)UnoRuntime.queryInterface(
498cdf0e10cSrcweir             XCellRangeData.class, xCR);
499cdf0e10cSrcweir 
500cdf0e10cSrcweir         Object[][] sheetData = xCRD.getDataArray();
501cdf0e10cSrcweir         for (int x = 0; x < sheetData.length; ++x)
502cdf0e10cSrcweir         {
503cdf0e10cSrcweir             for (int y = 0; y < sheetData[x].length; ++y)
504cdf0e10cSrcweir             {
505cdf0e10cSrcweir                 Object cell1 = sheetData[x][y];
506cdf0e10cSrcweir                 Object cell2 = data[x][y];
507cdf0e10cSrcweir                 if (AnyConverter.isString(cell1) && AnyConverter.isString(cell2))
508cdf0e10cSrcweir                 {
509cdf0e10cSrcweir                     String s1 = (String)cell1, s2 = (String)(cell2);
510cdf0e10cSrcweir                     if (!s1.equals(s2))
511cdf0e10cSrcweir                     {
512cdf0e10cSrcweir                         log.println("string cell values differ");
513cdf0e10cSrcweir                         return false;
514cdf0e10cSrcweir                     }
515cdf0e10cSrcweir                 }
516cdf0e10cSrcweir                 else if (AnyConverter.isDouble(cell1) && AnyConverter.isDouble(cell2))
517cdf0e10cSrcweir                 {
518cdf0e10cSrcweir                     double f1 = 0.0, f2 = 0.0;
519cdf0e10cSrcweir                     try
520cdf0e10cSrcweir                     {
521cdf0e10cSrcweir                         f1 = AnyConverter.toDouble(cell1);
522cdf0e10cSrcweir                         f2 = AnyConverter.toDouble(cell2);
523cdf0e10cSrcweir                     }
524cdf0e10cSrcweir                     catch (com.sun.star.lang.IllegalArgumentException e)
525cdf0e10cSrcweir                     {
526cdf0e10cSrcweir                         log.println("failed to convert cells to double");
527cdf0e10cSrcweir                         return false;
528cdf0e10cSrcweir                     }
529cdf0e10cSrcweir 
530cdf0e10cSrcweir                     if (f1 != f2)
531cdf0e10cSrcweir                     {
532cdf0e10cSrcweir                         log.println("numerical cell values differ");
533cdf0e10cSrcweir                         return false;
534cdf0e10cSrcweir                     }
535cdf0e10cSrcweir                 }
536cdf0e10cSrcweir                 else
537cdf0e10cSrcweir                 {
538cdf0e10cSrcweir                     log.println("cell types differ");
539cdf0e10cSrcweir                     return false;
540cdf0e10cSrcweir                 }
541cdf0e10cSrcweir             }
542cdf0e10cSrcweir         }
543cdf0e10cSrcweir 
544cdf0e10cSrcweir         return true;
545cdf0e10cSrcweir     }
546cdf0e10cSrcweir 
getLastUsedCellAddress(XSpreadsheet xSheet, int nCol, int nRow)547cdf0e10cSrcweir     private CellAddress getLastUsedCellAddress(XSpreadsheet xSheet, int nCol, int nRow)
548cdf0e10cSrcweir     {
549cdf0e10cSrcweir         try
550cdf0e10cSrcweir         {
551cdf0e10cSrcweir             XCellRange xRng = xSheet.getCellRangeByPosition(nCol, nRow, nCol, nRow);
552cdf0e10cSrcweir             XSheetCellRange xSCR = (XSheetCellRange)UnoRuntime.queryInterface(
553cdf0e10cSrcweir                 XSheetCellRange.class, xRng);
554cdf0e10cSrcweir 
555cdf0e10cSrcweir             XSheetCellCursor xCursor = xSheet.createCursorByRange(xSCR);
556cdf0e10cSrcweir             XCellCursor xCellCursor = (XCellCursor)UnoRuntime.queryInterface(
557cdf0e10cSrcweir                 XCellCursor.class, xCursor);
558cdf0e10cSrcweir 
559cdf0e10cSrcweir             xCellCursor.gotoEnd();
560cdf0e10cSrcweir             XCell xCell = xCursor.getCellByPosition(0, 0);
561cdf0e10cSrcweir             XCellAddressable xCellAddr = (XCellAddressable)UnoRuntime.queryInterface(
562cdf0e10cSrcweir                 XCellAddressable.class, xCell);
563cdf0e10cSrcweir 
564cdf0e10cSrcweir             return xCellAddr.getCellAddress();
565cdf0e10cSrcweir         }
566cdf0e10cSrcweir         catch (com.sun.star.lang.IndexOutOfBoundsException ex)
567cdf0e10cSrcweir         {
568cdf0e10cSrcweir         }
569cdf0e10cSrcweir         return null;
570cdf0e10cSrcweir     }
571cdf0e10cSrcweir }
572cdf0e10cSrcweir 
573