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