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