#64036 - Replace reflection calls in factories for Java 9+

use ServiceLoader for HSLF Metro Shapes

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1894298 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2021-10-16 00:00:50 +00:00
parent f406fe798f
commit dfbab3ff6a
17 changed files with 412 additions and 318 deletions

View File

@ -28,7 +28,7 @@ import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.sl.usermodel.Shape;
import org.apache.poi.sl.usermodel.MetroShapeProvider;
import org.apache.poi.util.Internal;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
@ -39,18 +39,21 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
* This is the helper class for HSLFMetroShape to dive into OOXML classes
*/
@Internal
public class XSLFMetroShape {
/*
* parses the metro bytes to a XSLF shape
*/
public static Shape<?,?> parseShape(byte[] metroBytes)
throws InvalidFormatException, IOException, XmlException {
PackagePartName shapePN = PackagingURIHelper.createPartName("/drs/shapexml.xml");
public class XSLFMetroShape implements MetroShapeProvider {
/** parses the metro bytes to a XSLF shape */
@Override
public XSLFShape parseShape(byte[] metroBytes) throws IOException {
try (OPCPackage pkg = OPCPackage.open(new UnsynchronizedByteArrayInputStream(metroBytes))) {
PackagePartName shapePN = PackagingURIHelper.createPartName("/drs/shapexml.xml");
PackagePart shapePart = pkg.getPart(shapePN);
if (shapePart == null) {
return null;
}
CTGroupShape gs = CTGroupShape.Factory.parse(shapePart.getInputStream(), DEFAULT_XML_OPTIONS);
XSLFGroupShape xgs = new XSLFGroupShape(gs, null);
return xgs.getShapes().get(0);
} catch (InvalidFormatException | XmlException e) {
throw new IOException("can't parse metro shape", e);
}
}
}

View File

@ -34,6 +34,7 @@ module org.apache.poi.ooxml {
provides org.apache.poi.ss.usermodel.WorkbookProvider with org.apache.poi.xssf.usermodel.XSSFWorkbookFactory;
provides org.apache.poi.sl.usermodel.SlideShowProvider with org.apache.poi.xslf.usermodel.XSLFSlideShowFactory;
provides org.apache.poi.sl.draw.ImageRenderer with org.apache.poi.xslf.draw.SVGImageRenderer;
provides org.apache.poi.sl.usermodel.MetroShapeProvider with org.apache.poi.xslf.usermodel.XSLFMetroShape;
exports org.apache.poi.xwpf.extractor;
exports org.apache.poi.xwpf.usermodel;

View File

@ -0,0 +1,18 @@
# ====================================================================
# 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.
# ====================================================================
org.apache.poi.xslf.usermodel.XSLFMetroShape

View File

@ -17,7 +17,10 @@
package org.apache.poi.xslf.usermodel;
import static org.apache.poi.sl.usermodel.BaseTestSlideShow.getColor;
import static org.apache.poi.sl.usermodel.TextRun.FieldType.DATE_TIME;
import static org.apache.poi.sl.usermodel.TextRun.FieldType.SLIDE_NUMBER;
import static org.apache.poi.xslf.usermodel.TestXSLFSimpleShape.getSpPr;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@ -27,17 +30,23 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.apache.poi.POIDataSamples;
import org.apache.poi.sl.usermodel.MasterSheet;
import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.Shape;
import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.sl.usermodel.SlideShowFactory;
import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
import org.apache.poi.sl.usermodel.TextRun;
import org.apache.poi.sl.usermodel.TextRun.FieldType;
import org.apache.poi.sl.usermodel.TextShape;
import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.xddf.usermodel.text.XDDFBodyProperties;
import org.apache.poi.xddf.usermodel.text.XDDFTextBody;
@ -66,7 +75,7 @@ class TestXSLFTextShape {
@Test
void testLayouts() throws IOException {
XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("layouts.pptx");
try (XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("layouts.pptx")) {
List<XSLFSlide> slide = ppt.getSlides();
@ -78,7 +87,7 @@ class TestXSLFTextShape {
verifySlide8(slide.get(7));
verifySlide10(slide.get(9));
ppt.close();
}
}
void verifySlide1(XSLFSlide slide){
@ -90,7 +99,7 @@ class TestXSLFTextShape {
XDDFTextBody tb1 = shape1.getTextBody();
XDDFBodyProperties tbp1 = tb1.getBodyProperties();
CTPlaceholder ph1 = shape1.getPlaceholderDetails().getCTPlaceholder(false);
assertEquals(STPlaceholderType.CTR_TITLE, ph1.getType());
assertSame(STPlaceholderType.CTR_TITLE, ph1.getType());
// anchor is not defined in the shape
assertNull(getSpPr(shape1).getXfrm());
@ -129,7 +138,7 @@ class TestXSLFTextShape {
XDDFTextBody tb2 = shape2.getTextBody();
XDDFBodyProperties tbp2 = tb2.getBodyProperties();
CTPlaceholder ph2 = shape2.getPlaceholderDetails().getCTPlaceholder(false);
assertEquals(STPlaceholderType.SUB_TITLE, ph2.getType());
assertSame(STPlaceholderType.SUB_TITLE, ph2.getType());
// anchor is not defined in the shape
assertNull(getSpPr(shape2).getXfrm());
@ -171,7 +180,7 @@ class TestXSLFTextShape {
XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0);
CTPlaceholder ph1 = shape1.getPlaceholderDetails().getCTPlaceholder(false);
assertEquals(STPlaceholderType.TITLE, ph1.getType());
assertSame(STPlaceholderType.TITLE, ph1.getType());
// anchor is not defined in the shape
assertNull(getSpPr(shape1).getXfrm());
@ -284,7 +293,7 @@ class TestXSLFTextShape {
XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0);
CTPlaceholder ph1 = shape1.getPlaceholderDetails().getCTPlaceholder(false);
assertEquals(STPlaceholderType.TITLE, ph1.getType());
assertSame(STPlaceholderType.TITLE, ph1.getType());
// anchor is not defined in the shape
assertNull(getSpPr(shape1).getXfrm());
@ -318,7 +327,7 @@ class TestXSLFTextShape {
XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
CTPlaceholder ph2 = shape2.getPlaceholderDetails().getCTPlaceholder(false);
assertEquals(STPlaceholderType.BODY, ph2.getType());
assertSame(STPlaceholderType.BODY, ph2.getType());
// anchor is not defined in the shape
assertNull(getSpPr(shape2).getXfrm());
@ -355,7 +364,7 @@ class TestXSLFTextShape {
XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0);
CTPlaceholder ph1 = shape1.getPlaceholderDetails().getCTPlaceholder(false);
assertEquals(STPlaceholderType.TITLE, ph1.getType());
assertSame(STPlaceholderType.TITLE, ph1.getType());
// anchor is not defined in the shape
assertNull(getSpPr(shape1).getXfrm());
@ -470,7 +479,7 @@ class TestXSLFTextShape {
XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0);
CTPlaceholder ph1 = shape1.getPlaceholderDetails().getCTPlaceholder(false);
assertEquals(STPlaceholderType.TITLE, ph1.getType());
assertSame(STPlaceholderType.TITLE, ph1.getType());
// anchor is not defined in the shape
assertNull(getSpPr(shape1).getXfrm());
@ -538,7 +547,7 @@ class TestXSLFTextShape {
XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0);
CTPlaceholder ph1 = shape1.getPlaceholderDetails().getCTPlaceholder(false);
assertEquals(STPlaceholderType.TITLE, ph1.getType());
assertSame(STPlaceholderType.TITLE, ph1.getType());
// anchor is not defined in the shape
assertNull(getSpPr(shape1).getXfrm());
@ -664,12 +673,12 @@ class TestXSLFTextShape {
@Test
void testTitleStyles() throws IOException {
XMLSlideShow ppt = new XMLSlideShow();
try (XMLSlideShow ppt = new XMLSlideShow()) {
XSLFSlideMaster master = ppt.getSlideMasters().get(0);
XSLFTheme theme = master.getTheme();
XSLFSlideLayout layout = master.getLayout(SlideLayout.TITLE);
XSLFSlide slide = ppt.createSlide(layout) ;
XSLFSlide slide = ppt.createSlide(layout);
assertSame(layout, slide.getSlideLayout());
assertSame(master, slide.getSlideMaster());
@ -691,7 +700,7 @@ class TestXSLFTextShape {
assertEquals(32.0, textRun.getFontSize(), 0);
lv1CPr.getLatin().setTypeface("Arial");
assertEquals("Arial", textRun.getFontFamily());
assertEquals(STTextAlignType.CTR, lv1PPr.getAlgn());
assertSame(STTextAlignType.CTR, lv1PPr.getAlgn());
assertEquals(TextAlign.CENTER, paragraph.getTextAlign());
lv1PPr.setAlgn(STTextAlignType.L);
assertEquals(TextAlign.LEFT, paragraph.getTextAlign());
@ -741,18 +750,17 @@ class TestXSLFTextShape {
assertEquals("Calibri", textRun.getFontFamily());
lv5PPr.setAlgn(STTextAlignType.CTR);
assertEquals(TextAlign.CENTER, paragraph.getTextAlign());
ppt.close();
}
}
@Test
void testBodyStyles() throws IOException {
XMLSlideShow ppt = new XMLSlideShow();
try (XMLSlideShow ppt = new XMLSlideShow()) {
XSLFSlideMaster master = ppt.getSlideMasters().get(0);
XSLFTheme theme = master.getTheme();
XSLFSlideLayout layout = master.getLayout(SlideLayout.TITLE_AND_CONTENT);
XSLFSlide slide = ppt.createSlide(layout) ;
XSLFSlide slide = ppt.createSlide(layout);
assertSame(layout, slide.getSlideLayout());
assertSame(master, slide.getSlideMaster());
@ -794,7 +802,7 @@ class TestXSLFTextShape {
assertEquals(33.0, r1.getFontSize(), 0);
lv1CPr.getLatin().setTypeface("Arial");
assertEquals("Arial", r1.getFontFamily());
assertEquals(STTextAlignType.L, lv1PPr.getAlgn());
assertSame(STTextAlignType.L, lv1PPr.getAlgn());
assertEquals(TextAlign.LEFT, p1.getTextAlign());
lv1PPr.setAlgn(STTextAlignType.R);
assertEquals(TextAlign.RIGHT, p1.getTextAlign());
@ -805,7 +813,7 @@ class TestXSLFTextShape {
assertEquals(33.0, r2.getFontSize(), 0);
lv2CPr.getLatin().setTypeface("Times");
assertEquals("Times", r2.getFontFamily());
assertEquals(STTextAlignType.L, lv2PPr.getAlgn());
assertSame(STTextAlignType.L, lv2PPr.getAlgn());
assertEquals(TextAlign.LEFT, p2.getTextAlign());
lv2PPr.setAlgn(STTextAlignType.R);
assertEquals(TextAlign.RIGHT, p2.getTextAlign());
@ -816,7 +824,7 @@ class TestXSLFTextShape {
assertEquals(25.0, r3.getFontSize(), 0);
lv3CPr.getLatin().setTypeface("Courier New");
assertEquals("Courier New", r3.getFontFamily());
assertEquals(STTextAlignType.L, lv3PPr.getAlgn());
assertSame(STTextAlignType.L, lv3PPr.getAlgn());
assertEquals(TextAlign.LEFT, p3.getTextAlign());
lv3PPr.setAlgn(STTextAlignType.R);
assertEquals(TextAlign.RIGHT, p3.getTextAlign());
@ -945,20 +953,33 @@ class TestXSLFTextShape {
assertEquals("Calibri", r3.getFontFamily());
lv3PPr.setAlgn(STTextAlignType.CTR);
assertEquals(TextAlign.CENTER, p3.getTextAlign());
ppt.close();
}
}
@Test
void metroBlob() throws IOException, ReflectiveOperationException {
assumeFalse(xslfOnly);
File f = POIDataSamples.getSlideShowInstance().getFile("bug52297.ppt");
SlideShow<?,?> ppt = SlideShowFactory.create(f);
POIDataSamples samples = POIDataSamples.getSlideShowInstance();
String textAct;
try (InputStream is = samples.openResourceAsStream("bug52297.ppt");
SlideShow<?,?> ppt = SlideShowFactory.create(is)) {
// check metro shapes on master sheet
MasterSheet<?, ?> master = ppt.getSlideMasters().get(0);
FieldType[] tl = master.getShapes().stream().
filter(f -> f instanceof TextShape).map(f -> (TextShape<?,?>)f).
flatMap(f -> ((List<? extends TextParagraph<?, ?, ? extends TextRun>>) f.getTextParagraphs()).stream()).
flatMap(f -> f.getTextRuns().stream()).
map(TextRun::getFieldType).
filter(Objects::nonNull).
toArray(FieldType[]::new);
assertArrayEquals(new FieldType[]{DATE_TIME, SLIDE_NUMBER, SLIDE_NUMBER}, tl);
// check metro shapes on slides
Shape<?, ?> sh = ppt.getSlides().get(1).getShapes().get(3);
XSLFAutoShape xsh = (XSLFAutoShape)sh.getClass().getMethod("getMetroShape").invoke(sh);
XSLFAutoShape xsh = (XSLFAutoShape) sh.getClass().getMethod("getMetroShape").invoke(sh);
String textExp = " ___ ___ ___ ________ __ _______ ___ ___________ __________ __ _____ ___ ___ ___ _______ ____ ______ ___________ _____________ ___ _______ ______ ____ ______ __ ___________ __________ ___ _________ _____ ________ __________ ___ _______ __________ ";
String textAct = xsh.getText();
ppt.close();
textAct = xsh.getText();
assertEquals(textExp, textAct);
}
}
}

View File

@ -32,6 +32,7 @@ module org.apache.poi.ooxml {
provides org.apache.poi.ss.usermodel.WorkbookProvider with org.apache.poi.xssf.usermodel.XSSFWorkbookFactory;
provides org.apache.poi.sl.usermodel.SlideShowProvider with org.apache.poi.xslf.usermodel.XSLFSlideShowFactory;
provides org.apache.poi.sl.draw.ImageRenderer with org.apache.poi.xslf.draw.SVGImageRenderer;
provides org.apache.poi.sl.usermodel.MetroShapeProvider with org.apache.poi.xslf.usermodel.XSLFMetroShape;
exports org.apache.poi.xwpf.extractor;
exports org.apache.poi.xwpf.usermodel;

View File

@ -17,7 +17,8 @@
package org.apache.poi.hslf.model;
import java.lang.reflect.Method;
import java.io.IOException;
import java.util.ServiceLoader;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -26,7 +27,10 @@ import org.apache.poi.ddf.EscherComplexProperty;
import org.apache.poi.ddf.EscherPropertyTypes;
import org.apache.poi.ddf.EscherTertiaryOptRecord;
import org.apache.poi.hslf.usermodel.HSLFShape;
import org.apache.poi.sl.usermodel.MetroShapeProvider;
import org.apache.poi.sl.usermodel.Shape;
import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.sl.usermodel.TextRun;
import org.apache.poi.util.Internal;
/**
@ -34,7 +38,10 @@ import org.apache.poi.util.Internal;
* containing an ooxml representation of the shape
*/
@Internal
public class HSLFMetroShape<T extends Shape<?,?>> {
public class HSLFMetroShape<
S extends Shape<S,P>,
P extends TextParagraph<S,P,? extends TextRun>
> {
private static final Logger LOGGER = LogManager.getLogger(HSLFMetroShape.class);
private final HSLFShape shape;
@ -68,22 +75,25 @@ public class HSLFMetroShape<T extends Shape<?,?>> {
* aren't in the classpath
*/
@SuppressWarnings("unchecked")
public T getShape() {
public Shape<S,P> getShape() {
byte[] metroBytes = getMetroBytes();
if (metroBytes == null) {
return null;
}
// org.apache.poi.xslf.usermodel.XSLFMetroShape
ClassLoader cl = getClass().getClassLoader();
ClassLoader cl = HSLFMetroShape.class.getClassLoader();
IOException lastError = null;
for (MetroShapeProvider msp : ServiceLoader.load(MetroShapeProvider.class, cl)) {
try {
Class<?> ms = cl.loadClass("org.apache.poi.xslf.usermodel.XSLFMetroShape");
Method m = ms.getMethod("parseShape", byte[].class);
return (T)m.invoke(null, new Object[]{metroBytes});
} catch (Exception e) {
LOGGER.atError().withThrowable(e).log("can't process metro blob, check if all dependencies for POI OOXML are in the classpath.");
return null;
return (Shape<S, P>) msp.parseShape(metroBytes);
} catch (IOException ex) {
lastError = ex;
break;
}
}
LOGGER.atError().withThrowable(lastError).log("can't process metro blob, check if all dependencies for POI OOXML are in the classpath.");
return null;
}
}

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.usermodel;
import java.awt.Color;
import java.util.List;
import java.util.stream.Stream;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -35,6 +36,7 @@ import org.apache.poi.sl.usermodel.MasterSheet;
import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.Shape;
import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.sl.usermodel.TextRun;
import org.apache.poi.sl.usermodel.TextShape;
@ -506,16 +508,14 @@ public final class HSLFTextRun implements TextRun {
}
}
if (ts.getSheet() instanceof MasterSheet) {
TextShape<?,? extends TextParagraph<?,?,? extends TextRun>> ms = ts.getMetroShape();
if (ms == null || ms.getTextParagraphs().isEmpty()) {
return null;
}
List<? extends TextRun> trList = ms.getTextParagraphs().get(0).getTextRuns();
if (trList.isEmpty()) {
return null;
}
return trList.get(0).getFieldType();
Shape<?,?> ms = (ts.getSheet() instanceof MasterSheet) ? ts.getMetroShape() : null;
if (ms instanceof TextShape) {
return Stream.of((TextShape<?,?>)ms).
flatMap(tsh -> ((List<? extends TextParagraph<?,?,? extends TextRun>>)tsh.getTextParagraphs()).stream()).
flatMap(tph -> tph.getTextRuns().stream()).
findFirst().
map(TextRun::getFieldType).
orElse(null);
}
return null;

View File

@ -51,6 +51,7 @@ import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.draw.DrawTextShape;
import org.apache.poi.sl.usermodel.Insets2D;
import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.Shape;
import org.apache.poi.sl.usermodel.ShapeContainer;
import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.sl.usermodel.TextRun;
@ -153,7 +154,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
/**
* Create a TextBox object and initialize it from the supplied Record container.
*
* @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
* @param escherRecord {@code EscherSpContainer} container which holds information about this shape
* @param parent the parent of the shape
*/
protected HSLFTextShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape,HSLFTextParagraph> parent){
@ -192,7 +193,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
/**
* When a textbox is added to a sheet we need to tell upper-level
* <code>PPDrawing</code> about it.
* {@code PPDrawing} about it.
*
* @param sh the sheet we are adding to
*/
@ -403,7 +404,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
/**
* Sets the type of alignment for the text.
* One of the <code>Anchor*</code> constants defined in this class.
* One of the {@code Anchor*} constants defined in this class.
*
* @param isCentered horizontal centered?
* @param vAlign vertical alignment
@ -572,7 +573,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
* Returns the value indicating word wrap.
*
* @return the value indicating word wrap.
* Must be one of the <code>Wrap*</code> constants defined in this class.
* Must be one of the {@code Wrap*} constants defined in this class.
*
* @see <a href="https://msdn.microsoft.com/en-us/library/dd948168(v=office.12).aspx">MSOWRAPMODE</a>
*/
@ -586,7 +587,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
* Specifies how the text should be wrapped
*
* @param wrap the value indicating how the text should be wrapped.
* Must be one of the <code>Wrap*</code> constants defined in this class.
* Must be one of the {@code Wrap*} constants defined in this class.
*/
public void setWordWrapEx(int wrap){
setEscherProperty(EscherPropertyTypes.TEXT__WRAPTEXT, wrap);
@ -841,7 +842,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
/**
* Returns the array of all hyperlinks in this text run
*
* @return the array of all hyperlinks in this text run or <code>null</code>
* @return the array of all hyperlinks in this text run or {@code null}
* if not found.
*/
public List<HSLFHyperlink> getHyperlinks() {
@ -904,8 +905,10 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
*
* @return null, if there's no alternative representation, otherwise the text shape
*/
public TextShape<?,? extends TextParagraph<?,?,? extends TextRun>> getMetroShape() {
HSLFMetroShape<TextShape<?,? extends TextParagraph<?,?,? extends TextRun>>> mbs = new HSLFMetroShape<>(this);
return mbs.getShape();
public <
S extends Shape<S,P>,
P extends TextParagraph<S,P,? extends TextRun>
> Shape<S,P> getMetroShape() {
return new HSLFMetroShape<S,P>(this).getShape();
}
}

View File

@ -23,6 +23,8 @@ module org.apache.poi.scratchpad {
requires org.apache.commons.codec;
requires org.apache.logging.log4j;
uses org.apache.poi.sl.usermodel.MetroShapeProvider;
provides org.apache.poi.extractor.ExtractorProvider with org.apache.poi.extractor.ole2.OLE2ScratchpadExtractorFactory;
provides org.apache.poi.sl.usermodel.SlideShowProvider with org.apache.poi.hslf.usermodel.HSLFSlideShowFactory;
provides org.apache.poi.sl.draw.ImageRenderer with org.apache.poi.hwmf.draw.HwmfImageRenderer, org.apache.poi.hemf.draw.HemfImageRenderer;

View File

@ -21,6 +21,8 @@ module org.apache.poi.scratchpad {
requires commons.math3;
requires org.apache.logging.log4j;
uses org.apache.poi.sl.usermodel.MetroShapeProvider;
provides org.apache.poi.extractor.ExtractorProvider with org.apache.poi.extractor.ole2.OLE2ScratchpadExtractorFactory;
provides org.apache.poi.sl.usermodel.SlideShowProvider with org.apache.poi.hslf.usermodel.HSLFSlideShowFactory;
provides org.apache.poi.sl.draw.ImageRenderer with org.apache.poi.hwmf.draw.HwmfImageRenderer, org.apache.poi.hemf.draw.HemfImageRenderer;

View File

@ -0,0 +1,31 @@
/* ====================================================================
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.sl.usermodel;
import java.io.IOException;
import org.apache.poi.util.Internal;
/**
* Experimental provider / loader for metro shapes.
* Metro shapes are xslf fragments stored in hslf shapes.
*/
@Internal
public interface MetroShapeProvider {
Shape<?,?> parseShape(byte[] metroBytes) throws IOException;
}

Binary file not shown.

View File

@ -24,6 +24,8 @@ module org.apache.poi.poi {
requires java.logging;
requires java.desktop;
uses org.apache.poi.sl.usermodel.MetroShapeProvider;
/* needed for CleanerUtil */
requires jdk.unsupported;