]> source.dussan.org Git - poi.git/commitdiff
OSGi support: register service providers in bundle activator
authorYegor Kozlov <yegor@apache.org>
Tue, 22 Sep 2020 12:42:18 +0000 (12:42 +0000)
committerYegor Kozlov <yegor@apache.org>
Tue, 22 Sep 2020 12:42:18 +0000 (12:42 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1881924 13f79535-47bb-0310-9956-ffa450edef68

osgi/pom.xml
osgi/src/main/java/org/apache/poi/osgi/Activator.java
osgi/src/test/java/org/apache/poi/osgi/BaseOSGiTestCase.java [new file with mode: 0755]
osgi/src/test/java/org/apache/poi/osgi/OSGiExtractorsIT.java [new file with mode: 0755]
osgi/src/test/java/org/apache/poi/osgi/OSGiSlideShowIT.java [new file with mode: 0755]
osgi/src/test/java/org/apache/poi/osgi/OSGiSpreadsheetIT.java
src/java/org/apache/poi/extractor/ExtractorFactory.java
src/java/org/apache/poi/sl/usermodel/SlideShowFactory.java
src/java/org/apache/poi/ss/usermodel/WorkbookFactory.java

index 483db264ef279a628ed940ce0033b5101786f912..967225244445087c992bb1fb37be53e75aba7832 100644 (file)
@@ -50,6 +50,9 @@
                 <extensions>true</extensions>
                 <configuration>
                     <instructions>
+                        <Bundle-Activator>
+                            org.apache.poi.osgi.Activator
+                        </Bundle-Activator>
                         <Export-Package>
                             org.apache.poi.*,
                             org.openxmlformats.schemas.*,
index 2f0212bd4edec63b4f28f84a852534162272312d..eef4ab4319e4b972308a638c844cbead2a31501d 100644 (file)
 
 package org.apache.poi.osgi;
 
+import org.apache.poi.extractor.ExtractorFactory;
+import org.apache.poi.extractor.MainExtractorFactory;
+import org.apache.poi.extractor.ole2.OLE2ScratchpadExtractorFactory;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowFactory;
+import org.apache.poi.hssf.usermodel.HSSFWorkbookFactory;
+import org.apache.poi.ooxml.extractor.POIXMLExtractorFactory;
+import org.apache.poi.sl.usermodel.SlideShowFactory;
+import org.apache.poi.ss.usermodel.WorkbookFactory;
+import org.apache.poi.xslf.usermodel.XSLFSlideShowFactory;
+import org.apache.poi.xssf.usermodel.XSSFWorkbookFactory;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 
 public class Activator implements BundleActivator {
-    public void start(BundleContext context) throws Exception {
+
+    @Override
+    public void start(BundleContext context) {
+        WorkbookFactory.addProvider(new HSSFWorkbookFactory());
+        WorkbookFactory.addProvider(new XSSFWorkbookFactory());
+
+        SlideShowFactory.addProvider(new HSLFSlideShowFactory());
+        SlideShowFactory.addProvider(new XSLFSlideShowFactory());
+
+        ExtractorFactory.addProvider(new OLE2ScratchpadExtractorFactory());
+        ExtractorFactory.addProvider(new POIXMLExtractorFactory());
+        ExtractorFactory.addProvider(new MainExtractorFactory());
     }
-    public void stop(BundleContext context) throws Exception {
+
+    @Override
+    public void stop(BundleContext context) {
+        WorkbookFactory.removeProvider(HSSFWorkbookFactory.class);
+        WorkbookFactory.removeProvider(XSSFWorkbookFactory.class);
+
+        SlideShowFactory.removeProvider(HSLFSlideShowFactory.class);
+        SlideShowFactory.removeProvider(XSLFSlideShowFactory.class);
+
+        ExtractorFactory.removeProvider(OLE2ScratchpadExtractorFactory.class);
+        ExtractorFactory.removeProvider(POIXMLExtractorFactory.class);
+        ExtractorFactory.removeProvider(MainExtractorFactory.class);
     }
 }
diff --git a/osgi/src/test/java/org/apache/poi/osgi/BaseOSGiTestCase.java b/osgi/src/test/java/org/apache/poi/osgi/BaseOSGiTestCase.java
new file mode 100755 (executable)
index 0000000..4b5178c
--- /dev/null
@@ -0,0 +1,49 @@
+/* ====================================================================
+   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.osgi;
+
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.osgi.framework.BundleContext;
+
+import javax.inject.Inject;
+import java.io.File;
+import java.io.IOException;
+
+import static org.ops4j.pax.exam.CoreOptions.*;
+
+/**
+ * Test to ensure that all our main formats can create, write
+ * and read back in, when running under OSGi
+ */
+public class BaseOSGiTestCase {
+
+    @Inject
+    private BundleContext bc;
+
+    @Configuration
+    public Option[] configuration() throws IOException {
+        String bundlePath = System.getProperty("bundle.filename");
+        if(bundlePath == null){
+            throw new IllegalStateException("-Dbundle.filename property is not set.");
+        }
+        return options(
+                junitBundles(),
+                bundle(new File(bundlePath).toURI().toURL().toString()));
+    }
+}
diff --git a/osgi/src/test/java/org/apache/poi/osgi/OSGiExtractorsIT.java b/osgi/src/test/java/org/apache/poi/osgi/OSGiExtractorsIT.java
new file mode 100755 (executable)
index 0000000..8ee1258
--- /dev/null
@@ -0,0 +1,120 @@
+/* ====================================================================
+   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.osgi;
+
+import org.apache.poi.extractor.ExtractorFactory;
+import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.sl.usermodel.Slide;
+import org.apache.poi.sl.usermodel.SlideShow;
+import org.apache.poi.sl.usermodel.TextBox;
+import org.apache.poi.sl.usermodel.TextShape;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xslf.usermodel.XMLSlideShow;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+
+import java.awt.*;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test to ensure that all our main formats can create, write
+ * and read back in, when running under OSGi
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class OSGiExtractorsIT extends BaseOSGiTestCase {
+
+
+    byte[] createSlideShow(SlideShow ppt) throws Exception {
+        Slide<?, ?> slide = ppt.createSlide();
+
+        TextBox<?, ?> box = slide.createTextBox();
+        box.setTextPlaceholder(TextShape.TextPlaceholder.TITLE);
+        box.setText("Hello, World!");
+        box.setAnchor(new Rectangle(36, 15, 648, 65));
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        ppt.write(out);
+        return out.toByteArray();
+    }
+
+    byte[] createWorkbook(Workbook wb) throws Exception {
+        Sheet s = wb.createSheet("OSGi");
+        s.createRow(0).createCell(0).setCellValue("Hello, World!");
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        wb.write(out);
+        return out.toByteArray();
+
+
+    }
+
+    /**
+     * this should invoke OLE2ScratchpadExtractorFactory
+     */
+    @Test
+    public void testHSLF() throws Exception {
+        byte[] bytes = createSlideShow(new HSLFSlideShow());
+        ByteArrayInputStream is = new ByteArrayInputStream(bytes);
+
+        String text = ExtractorFactory.createExtractor(is).getText().trim();
+        assertEquals("Hello, World!", text);
+    }
+
+    /**
+     * this should invoke POIXMLExtractorFactory
+     */
+    @Test
+    public void testXSLF() throws Exception {
+        byte[] bytes = createSlideShow(new XMLSlideShow());
+        ByteArrayInputStream is = new ByteArrayInputStream(bytes);
+
+        String text = ExtractorFactory.createExtractor(is).getText().trim();
+        assertEquals("Hello, World!", text);
+    }
+
+    @Test
+    public void testHSSF() throws Exception {
+        byte[] bytes = createWorkbook(new HSSFWorkbook());
+        ByteArrayInputStream is = new ByteArrayInputStream(bytes);
+
+        String text = ExtractorFactory.createExtractor(is).getText().trim();
+        assertEquals("OSGi\nHello, World!", text);
+    }
+
+    /**
+     * this should invoke POIXMLExtractorFactory
+     */
+    @Test
+    public void testXSSF() throws Exception {
+        byte[] bytes = createWorkbook(new XSSFWorkbook());
+        ByteArrayInputStream is = new ByteArrayInputStream(bytes);
+
+        String text = ExtractorFactory.createExtractor(is).getText().trim();
+        assertEquals("OSGi\nHello, World!", text);
+    }
+}
diff --git a/osgi/src/test/java/org/apache/poi/osgi/OSGiSlideShowIT.java b/osgi/src/test/java/org/apache/poi/osgi/OSGiSlideShowIT.java
new file mode 100755 (executable)
index 0000000..ef18f1c
--- /dev/null
@@ -0,0 +1,98 @@
+/* ====================================================================
+   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.osgi;
+
+import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.sl.usermodel.*;
+import org.apache.poi.xslf.usermodel.XMLSlideShow;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+
+import java.awt.*;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test to ensure that all our main formats can create, write
+ * and read back in, when running under OSGi
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class OSGiSlideShowIT extends BaseOSGiTestCase {
+
+
+    // create a workbook, validate and write back
+    void testSS(SlideShow ppt) throws Exception {
+        Slide<?, ?> slide = ppt.createSlide();
+
+        TextBox<?, ?> box1 = slide.createTextBox();
+        box1.setTextPlaceholder(TextShape.TextPlaceholder.TITLE);
+        box1.setText("HSLF in a Nutshell");
+        box1.setAnchor(new Rectangle(36, 15, 648, 65));
+
+        TextBox<?, ?> box2 = slide.createTextBox();
+        box2.setTextPlaceholder(TextShape.TextPlaceholder.BODY);
+        box2.setText(
+                "HSLF provides a way to read, create and modify MS PowerPoint presentations\r" +
+                        "Pure Java API - you don't need PowerPoint to read and write *.ppt files\r" +
+                        "Comprehensive support of PowerPoint objects\r" +
+                        "Rich text\r" +
+                        "Tables\r" +
+                        "Shapes\r" +
+                        "Pictures\r" +
+                        "Master slides\r" +
+                        "Access to low level data structures"
+        );
+
+        List<? extends TextParagraph<?, ?, ?>> tp = box2.getTextParagraphs();
+        for (int i : new byte[]{0, 1, 2, 8}) {
+            tp.get(i).getTextRuns().get(0).setFontSize(28d);
+        }
+        for (int i : new byte[]{3, 4, 5, 6, 7}) {
+            tp.get(i).getTextRuns().get(0).setFontSize(24d);
+            tp.get(i).setIndentLevel(1);
+        }
+        box2.setAnchor(new Rectangle(36, 80, 648, 400));
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ppt.write(baos);
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+
+        ppt = SlideShowFactory.create(bais);
+        assertEquals(1, ppt.getSlides().size());
+        slide = (Slide) ppt.getSlides().iterator().next();
+        assertEquals(2, slide.getShapes().size());
+    }
+
+    @Test
+    public void testHSLF() throws Exception {
+        testSS(new HSLFSlideShow());
+    }
+
+    @Test
+    public void testXSLF() throws Exception {
+        testSS(new XMLSlideShow());
+    }
+
+}
index ea139e7e50cb1b73b3950768293048bf70101965..0ea95602c9c0deb20a8ea4ac7f01c0b9706addbf 100644 (file)
 
 package org.apache.poi.osgi;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.ops4j.pax.exam.CoreOptions.bundle;
-import static org.ops4j.pax.exam.CoreOptions.junitBundles;
-import static org.ops4j.pax.exam.CoreOptions.options;
-
-import javax.inject.Inject;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.lang.invoke.MethodHandles;
-import java.util.Arrays;
-
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
-
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+import org.apache.poi.ss.usermodel.WorkbookFactory;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.ops4j.pax.exam.Configuration;
-import org.ops4j.pax.exam.Option;
 import org.ops4j.pax.exam.junit.PaxExam;
 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
-import org.ops4j.pax.exam.spi.reactors.PerMethod;
-import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import static org.junit.Assert.assertEquals;
 
 /**
  * Test to ensure that all our main formats can create, write
- *  and read back in, when running under OSGi
+ * and read back in, when running under OSGi
  */
 @RunWith(PaxExam.class)
-@ExamReactorStrategy(PerMethod.class)
-public class OSGiSpreadsheetIT {
-    private final static Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-    public static final String POI_BUNDLE_SYMBOLIC_NAME = "org.apache.poi.bundle";
+@ExamReactorStrategy(PerClass.class)
+public class OSGiSpreadsheetIT extends BaseOSGiTestCase {
 
-    @Inject
-    private BundleContext bc;
-
-    @Configuration
-    public Option[] configuration() throws IOException {
-        String bundlePath = System.getProperty("bundle.filename");
-        return options(
-                junitBundles(),
-                bundle(new File(bundlePath).toURI().toURL().toString()));
-    }
-
-    @Test
-    public void testBundleLoaded()  {
-        boolean hasBundle = Arrays.stream(bc.getBundles()).anyMatch(b ->
-                POI_BUNDLE_SYMBOLIC_NAME.equals(b.getSymbolicName()));
-        assertTrue(POI_BUNDLE_SYMBOLIC_NAME + " not found", hasBundle);
-    }
 
     // create a workbook, validate and write back
     void testWorkbook(Workbook wb) throws Exception {
-        logger.info("testing " + wb.getClass().getSimpleName());
-
         Sheet s = wb.createSheet("OSGi");
         s.createRow(0).createCell(0).setCellValue("With OSGi");
+        s.createRow(1).createCell(0).setCellFormula("SUM(A1:B3)");
 
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         wb.write(baos);
         ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
 
-        if(wb instanceof HSSFWorkbook)
-            wb = new HSSFWorkbook(bais);
-        else
-            wb = new XSSFWorkbook(bais);
+        wb = WorkbookFactory.create(bais);
         assertEquals(1, wb.getNumberOfSheets());
 
         s = wb.getSheet("OSGi");
         assertEquals("With OSGi", s.getRow(0).getCell(0).toString());
+        assertEquals("SUM(A1:B3)", s.getRow(1).getCell(0).toString());
 
 
     }
@@ -112,6 +74,12 @@ public class OSGiSpreadsheetIT {
 
     @Test
     public void testSXSSF() throws Exception {
-        testWorkbook(new SXSSFWorkbook());
+        testWorkbook(new XSSFWorkbook());
+    }
+
+    @Test
+    public void testFormulaEvaluation() throws Exception {
+        testWorkbook(new XSSFWorkbook());
     }
+
 }
index ccab16a213bc1f261b6a0ce8a588a6d4b1c32d8a..6b3ec00df6813b6bb6c4390b640472c91bacbba4 100644 (file)
@@ -309,4 +309,11 @@ public final class ExtractorFactory {
             "or you haven't provide the poi-ooxml*.jar and/or poi-scratchpad*.jar in the classpath/modulepath - FileMagic: "+fm);
     }
 
+    public static void addProvider(ExtractorProvider provider){
+        Singleton.INSTANCE.provider.add(provider);
+    }
+
+    public static void removeProvider(Class<? extends ExtractorProvider> provider){
+        Singleton.INSTANCE.provider.removeIf(p -> p.getClass().getName().equals(provider.getName()));
+    }
 }
index 8155fccb8daf029b87f48c9478f053d799c37f53..83d3ae6e70daefc97afbd61112e1013a79a73626 100644 (file)
@@ -292,4 +292,12 @@ public final class SlideShowFactory {
         throw new IOException("Your InputStream was neither an OLE2 stream, nor an OOXML stream " +
                                       "or you haven't provide the poi-ooxml*.jar in the classpath/modulepath - FileMagic: "+fm);
     }
+
+    public static void addProvider(SlideShowProvider<?,?> provider){
+        Singleton.INSTANCE.provider.add(provider);
+    }
+
+    public static void removeProvider(Class<? extends SlideShowProvider> provider){
+        Singleton.INSTANCE.provider.removeIf(p -> p.getClass().getName().equals(provider.getName()));
+    }
 }
index 965666904cb8199dab64b45aaf86aab9d03279f4..ede792368a1c0a8ba948a33f214bc7560d931709 100644 (file)
@@ -298,4 +298,12 @@ public final class WorkbookFactory {
         throw new IOException("Your InputStream was neither an OLE2 stream, nor an OOXML stream " +
             "or you haven't provide the poi-ooxml*.jar in the classpath/modulepath - FileMagic: "+fm);
     }
+
+    public static void addProvider(WorkbookProvider provider){
+        Singleton.INSTANCE.provider.add(provider);
+    }
+
+    public static void removeProvider(Class<? extends WorkbookProvider> provider){
+        Singleton.INSTANCE.provider.removeIf(p -> p.getClass().getName().equals(provider.getName()));
+    }
 }