From 70e958022610fd290c05f5c1ba4d1e20d4b90a7f Mon Sep 17 00:00:00 2001 From: Yegor Kozlov Date: Tue, 3 Nov 2009 23:54:58 +0000 Subject: [PATCH] avoid NPE when calling methods from the superclass and initialize XSSFChartSheet with a blank sheet, see Bugzilla 48087 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@832622 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/xssf/usermodel/XSSFChartSheet.java | 46 ++++++++-- .../xssf/usermodel/TestXSSFChartSheet.java | 84 ++++++++++++++++++ test-data/spreadsheet/chart_sheet.xlsx | Bin 0 -> 10795 bytes 3 files changed, 122 insertions(+), 8 deletions(-) create mode 100644 src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFChartSheet.java create mode 100644 test-data/spreadsheet/chart_sheet.xlsx diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChartSheet.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChartSheet.java index c3c1b61e07..f9aeb40c92 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChartSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChartSheet.java @@ -17,25 +17,34 @@ package org.apache.poi.xssf.usermodel; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; +import java.util.Map; +import java.util.HashMap; + import org.apache.poi.POIXMLException; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlOptions; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTChartsheet; import org.openxmlformats.schemas.spreadsheetml.x2006.main.ChartsheetDocument; +import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId; + +import javax.xml.namespace.QName; /** - * High level representation of of Sheet Parts that are of type 'chartsheet'. - * - * TODO: current verion extends XSSFSheet although both should extend AbstractSheet + * High level representation of Sheet Parts that are of type 'chartsheet'. + *

+ * Chart sheet is a special kind of Sheet that contains only chart and no data. + *

* * @author Yegor Kozlov */ public class XSSFChartSheet extends XSSFSheet { + private static final byte[] BLANK_WORKSHEET = blankWorksheet(); + protected CTChartsheet chartsheet; protected XSSFChartSheet(PackagePart part, PackageRelationship rel) { @@ -43,6 +52,9 @@ public class XSSFChartSheet extends XSSFSheet { } protected void read(InputStream is) throws IOException { + //initialize the supeclass with a blank worksheet + super.read(new ByteArrayInputStream(BLANK_WORKSHEET)); + try { chartsheet = ChartsheetDocument.Factory.parse(is).getChartsheet(); } catch (XmlException e){ @@ -51,17 +63,35 @@ public class XSSFChartSheet extends XSSFSheet { } /** - * Provide access to the CTWorksheet bean holding this sheet's data + * Provide access to the CTChartsheet bean holding this sheet's data * - * @return the CTWorksheet bean holding this sheet's data + * @return the CTChartsheet bean holding this sheet's data */ public CTChartsheet getCTChartsheet() { return chartsheet; } @Override - protected void commit() throws IOException { + protected void write(OutputStream out) throws IOException { + XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); + xmlOptions.setSaveSyntheticDocumentElement( + new QName(CTChartsheet.type.getName().getNamespaceURI(), "chartsheet")); + Map map = new HashMap(); + map.put(STRelationshipId.type.getName().getNamespaceURI(), "r"); + xmlOptions.setSaveSuggestedPrefixes(map); + chartsheet.save(out, xmlOptions); + + } + + private static byte[] blankWorksheet(){ + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + new XSSFSheet().write(out); + } catch (IOException e){ + throw new RuntimeException(e); + } + return out.toByteArray(); } } \ No newline at end of file diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFChartSheet.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFChartSheet.java new file mode 100644 index 0000000000..5ecb187547 --- /dev/null +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFChartSheet.java @@ -0,0 +1,84 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.xssf.usermodel; + +import org.apache.poi.ss.usermodel.BaseTestSheet; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.XSSFITestDataProvider; +import org.apache.poi.xssf.XSSFTestDataSamples; +import org.apache.poi.xssf.model.CommentsTable; +import org.apache.poi.xssf.model.StylesTable; +import org.apache.poi.xssf.usermodel.helpers.ColumnHelper; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComments; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXf; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPane; + + +public class TestXSSFChartSheet extends BaseTestSheet { + + @Override + protected XSSFITestDataProvider getTestDataProvider() { + return XSSFITestDataProvider.getInstance(); + } + + public void testXSSFFactory() { + XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("chart_sheet.xlsx"); + assertEquals(4, wb.getNumberOfSheets()); + + //the third sheet is of type 'chartsheet' + assertEquals("Chart1", wb.getSheetName(2)); + assertTrue(wb.getSheetAt(2) instanceof XSSFChartSheet); + assertEquals("Chart1", wb.getSheetAt(2).getSheetName()); + + } + + public void testGetAccessors() { + XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("chart_sheet.xlsx"); + XSSFChartSheet sheet = (XSSFChartSheet)wb.getSheetAt(2); + for(Row row : sheet) { + fail("Row iterator for chart sheets should return zero rows"); + } + //access to a arbitrary row + assertEquals(null, sheet.getRow(1)); + + //some basic get* accessors + assertEquals(0, sheet.getNumberOfComments()); + assertEquals(0, sheet.getNumHyperlinks()); + assertEquals(0, sheet.getNumMergedRegions()); + assertEquals(null, sheet.getActiveCell()); + assertEquals(true, sheet.getAutobreaks()); + assertEquals(null, sheet.getCellComment(0, 0)); + assertEquals(0, sheet.getColumnBreaks().length); + assertEquals(true, sheet.getRowSumsBelow()); + } + + /** + * YK: disable failing test from the superclass + */ + @Override + public void testDefaultColumnStyle() { + + } +} \ No newline at end of file diff --git a/test-data/spreadsheet/chart_sheet.xlsx b/test-data/spreadsheet/chart_sheet.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..44d771b06af6747af40b72f3ec9098150cb17b6a GIT binary patch literal 10795 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