Compare commits

..

1 Commits

1799 changed files with 15117 additions and 67959 deletions

View File

@ -1,7 +1,7 @@
# https://github.com/apache/infrastructure-asfyaml/blob/main/README.md # https://cwiki.apache.org/confluence/display/INFRA/Git+-+.asf.yaml+features
github: github:
description: "Mirror of Apache POI gitbox. The Java API for Microsoft Documents." description: "Mirror of Apache POI subversion. The Java API for Microsoft Documents."
homepage: https://poi.apache.org/ homepage: https://poi.apache.org/
labels: labels:
- poi - poi
@ -14,35 +14,10 @@ github:
- powerpoint - powerpoint
- visio - visio
dependabot_alerts: true
dependabot_updates: false
features: features:
# Enable wiki for documentation # Enable wiki for documentation
wiki: false wiki: false
# Enable issue management # Enable issue management
issues: true issues: false
# Enable projects for project management boards # Enable projects for project management boards
projects: false projects: false
# Enable github discussions
discussions: true
enabled_merge_buttons:
squash: true
merge: false
rebase: true
protected_branches:
trunk: {}
5.5.x: {}
asf-site: {}
notifications:
commits: commits@poi.apache.org
issues: dev@poi.apache.org
pullrequests: dev@poi.apache.org
discussions: dev@poi.apache.org
jobs: dev@poi.apache.org
publish:
whoami: asf-site

View File

@ -5,9 +5,9 @@ name: Java CI with Gradle
on: on:
push: push:
branches: [ trunk, 5.5.x ] branches: [ trunk ]
pull_request: pull_request:
branches: [ trunk, 5.5.x ] branches: [ trunk ]
permissions: {} permissions: {}
@ -17,15 +17,18 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v3
- name: Set up JDK - name: Set up JDK
uses: actions/setup-java@v5 uses: actions/setup-java@v3
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: '11' java-version: '11'
cache: 'gradle' cache: 'gradle'
- name: Verify Gradle wrapper
uses: gradle/wrapper-validation-action@v1
- name: Grant execute permission for gradlew - name: Grant execute permission for gradlew
run: chmod +x gradlew run: chmod +x gradlew

3
.gitignore vendored
View File

@ -37,6 +37,3 @@ TEST-org.apache.poi*.xml
/*/build/ /*/build/
dist dist
lib/ lib/
# Compiled module-info class-files
/poi*/src/*/java9/*.class

84
KEYS
View File

@ -2545,12 +2545,14 @@ bpjAhwE2YmGQ7oB+3V798HtAmceRNf8AY0GWrZswJlg7xUn+WJNwQ9uIHI1fxYHx
2Nr+AmDDs6ZOEI5zhwxioePw/Cg= 2Nr+AmDDs6ZOEI5zhwxioePw/Cg=
=9lKb =9lKb
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----
pub rsa2048 2018-05-02 [SC] [expires: 2026-05-11] pub rsa2048 2018-05-02 [SC] [expires: 2024-05-25]
6BA4DA8B1C88A49428A29C3D0C69C1EF41181E13 6BA4 DA8B 1C88 A494 28A2 9C3D 0C69 C1EF 4118 1E13
uid [ unknown] PJ Fanning (http://www.apache.org/) <fanningpj@apache.org> uid [ultimate] PJ Fanning <fanningpj@yahoo.com>
uid [ unknown] PJ Fanning (GitHub noreply address) <pjfanning@users.noreply.github.com> sig 3 0C69C1EF41181E13 2022-04-06 PJ Fanning <fanningpj@yahoo.com>
uid [ unknown] PJ Fanning <fanningpj@yahoo.com> uid [ultimate] PJ Fanning (http://www.apache.org/) <fanningpj@apache.org>
sub rsa2048 2018-05-02 [E] [expires: 2026-05-11] sig 3 0C69C1EF41181E13 2022-04-06 PJ Fanning <fanningpj@yahoo.com>
sub rsa2048 2018-05-02 [E] [expires: 2024-05-25]
sig 0C69C1EF41181E13 2022-04-06 PJ Fanning <fanningpj@yahoo.com>
-----BEGIN PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK-----
@ -2559,45 +2561,37 @@ ARFmtFPnwYwLTdz3ECqWWsC3RkI62079DweNasXV8nBz9sUt6mQqSMx3W/s6389/
k9iywPLvhHH7rpp05js8zwJoA8Fr1YwPtBjyhrxl58LQ5ihd/1f2ud2tnwQw1dI2 k9iywPLvhHH7rpp05js8zwJoA8Fr1YwPtBjyhrxl58LQ5ihd/1f2ud2tnwQw1dI2
8fuTS3QaKP4Zdx2diD5rYhkAecWaFRwxn1L7Tye5dfD1uPElPCHGKqfaeQXtl01u 8fuTS3QaKP4Zdx2diD5rYhkAecWaFRwxn1L7Tye5dfD1uPElPCHGKqfaeQXtl01u
TOwYB1p9tKPHvfni1qgD3QLWUJ2oyBGSA9IgEF5rm8LtR6vADKQwORjg99a7HE2h TOwYB1p9tKPHvfni1qgD3QLWUJ2oyBGSA9IgEF5rm8LtR6vADKQwORjg99a7HE2h
lDBZi/tmu23fgWSioiy084fB5GqmApK/681DABEBAAG0SFBKIEZhbm5pbmcgKEdp lDBZi/tmu23fgWSioiy084fB5GqmApK/681DABEBAAG0OlBKIEZhbm5pbmcgKGh0
dEh1YiBub3JlcGx5IGFkZHJlc3MpIDxwamZhbm5pbmdAdXNlcnMubm9yZXBseS5n dHA6Ly93d3cuYXBhY2hlLm9yZy8pIDxmYW5uaW5ncGpAYXBhY2hlLm9yZz6JAVQE
aXRodWIuY29tPokBVwQTAQgAQQIbAwULCQgHAgIiAgYVCgkICwIEFgIDAQIeBwIX EwEIAD4CGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQRrpNqLHIiklCiinD0M
gBYhBGuk2osciKSUKKKcPQxpwe9BGB4TBQJmJYbdBQkPGNgHAAoJEAxpwe9BGB4T acHvQRgeEwUCYk2YRAUJC2h2bgAKCRAMacHvQRgeE7nTB/4tZq9/gQcpCKgPVKI8
5Z4H/3sDqi2QozHbsUy2dm+xS105bpmiNn3aDYzEyjOBggypDWpG5fmlD6ya3Yfd MKtY/NWOc9nRr5LrNjY/qFU2Z2gMoUQT1fIBm6gjd9iI92QgLMeekuR2fXBBOx3y
H172auahZ1SK6t7Q7u97QdtrvMKTVBBq+DahkHnvw4nsPwBI00aTy616of1+CirZ JbiklXfQVGytEOochkemylwtaCZTHB61KWkemDfS+YeG3qBKwFa5B+zJvp7LqYdQ
lDPo912aLrWlouizuy6qeJE0EfB0PGXtuZP3E0yZHqgmIOBrQw5fJQtrka5WWK3C GrNFFgtHwkhNiviDN7JFxsMGM2IpopgvNYB72B35q3YnrDsgDNlD3eraKU25sMx7
AqO2Z1hZLh9ftheJtKSYX1gZnPEAWs3ZBG2tCk4+qAjB8y5kRvrJFpC36FkisYlg 2vNHABrdHzd1ZnKDA1hSV6any5Ifw4NJsPaM0RrmwuwoWkL7WHPftbqkM0zy6RIe
YTtAOSMHED/3YFsDsXFvLmrSkNBImjdAnRW59TD5XUgEMDZ9Dylz3/b4/gtNi2SX O+2tlKsJ6cKfOCYL9fbS7/UmkVVcrSLpJCCwmdsra3/57uha7TofDvl+R32CWzrv
9WSYWC60/3Jgxh4u3cTUnUtW2yC0IFBKIEZhbm5pbmcgPGZhbm5pbmdwakB5YWhv yWfXtCBQSiBGYW5uaW5nIDxmYW5uaW5ncGpAeWFob28uY29tPokBVAQTAQgAPgIb
by5jb20+iQFUBBMBCAA+AhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAFiEEa6Ta AwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgBYhBGuk2osciKSUKKKcPQxpwe9BGB4T
ixyIpJQoopw9DGnB70EYHhMFAmYlhuUFCQ8Y2AcACgkQDGnB70EYHhOecwgApleV BQJiTZhKBQkLaHZuAAoJEAxpwe9BGB4T58UH/RBEOnA9TDTKTi7T4y+R1/q2SUp+
9IOazPAk8pF0WfkslRWNrGHzaGoqO+WVhMS4doxR8bjqkrHwuI4c8Z2vCCMnKqb1 tMzv91jhmlaDvNnA2lGVFNGj1tdy1O7xoCEEw9diKCVqVwHecuBQCaLI70r1W4Qw
LF7djz9GXFGklvoyV7rQYrDx15bYWjtassvM4KExcnoPGxx9Kb7f0j0WSZwtwMUl qixjKJwDDnPoMKfhjuvHEHRZV0Pg+uZ50DxkFNn+bPPlXABGelliAPTvetK3ELPJ
XWvsrS0+BkbRz+PIpGtDJhlI++aRoZdWCz5j5st5HzmacC0GVuYGvRPj8uMW2LN5 EIRzVJkFsS0McHwXJgmIPAz8ZVlwd1/Xu21MIKOkPzgXML7uq4PN++L+mM4RmpGU
5HvGzlzqWIQ7l68KQPz7g5KIFKUrCPyzZS0m8Nj+gRWhF3+u3/1SY2hoCzobSMJj phOetyxLO1xf6ZixCoUnA7Ayi0hAKUAhu9acuc8SoDacfKm1EQ26SHUhOTNm0YCH
PNhEovdpi8h5qbUOpHn2OM7l8/nioRaJwAmcMTnmlh1lqeyxIFYnFIBT24o3aEtN PPfucHJbUgqSUOYjkEftOtT0ZqVGWS7tR3iEIJu90MJ6SJRovag7khCsYY65AQ0E
N2d1xg/moXvzNTq7yrQ6UEogRmFubmluZyAoaHR0cDovL3d3dy5hcGFjaGUub3Jn Wulz1gEIAORuS4e+Ek+d+0gBMlnigNJ2HoQalKFaERf5K/iQZY4E6Z2ahJ4UFIj7
LykgPGZhbm5pbmdwakBhcGFjaGUub3JnPokBVAQTAQgAPgIbAwULCQgHAgYVCgkI ri3isWgOleP+REJJPfeSrWQ5XgdklDlHHyv4O5iMkEFWQHttiaTuvdomDncQrNRP
CwIEFgIDAQIeAQIXgBYhBGuk2osciKSUKKKcPQxpwe9BGB4TBQJmJYblBQkPGNgH TaIOe9iQgfQzDw6mqsb7ZWd5ICA8Krd97BwNHjq/CZ9+WrU6GDc6ImissLVVGGdk
AAoJEAxpwe9BGB4TgwMIAJj3aQYKSxt9iyIP5nFhIWAFSPZcZ0gRB6jYMuANVoJE EGO7qZTqNUCeH4Znm/00mNMI4OH8xkwA2vzV5o3J5116zIuv29XQDtcSM+9NQ/Hd
yelbhIziN2dXLOjHWpia2x9p7krxY6ZLtogkL4MjfVpCaaXwsaYOq6LeuPN27/Pt sjKIA0OpDyWE7Ek/SO+/CvkylwaOcmkuf33ADNjpF4BsBxn7L9XI1WJDtRaMkpbq
9rRcDz7j5lA9u9MShc6O8lwNbVReCWR08H0oiEdS09xwZY3aiZniptRBeK+mcsNc MsymIxi35VUOGD+ms+72CcUStfYj4NEAEQEAAYkBPAQYAQgAJgIbDBYhBGuk2osc
Zw7kNmPHC79WaI6Rb/qnPLHJDD0l8vrVSShgmEeVJJoC/YjuVzKoiy2BmjSOpOLF iKSUKKKcPQxpwe9BGB4TBQJiTZhrBQkLaHaVAAoJEAxpwe9BGB4TfjUH/24Q/H5u
d88NlquWbvLO6j2tzboUs+93Kc4MwG57hwRIqS7wfsENkecSRj23KQN0UOpxgwz7 vXlb/Dpx4eFcyLhRVgREoMwwAlzM5GKInHO1W7SHeD7iVR8H1XQVHTgUBNBQ1bUd
b0+ii9F9jsddEqqpXspcM8zaacf+FpIwO6rk7v1U8LG5AQ0EWulz1gEIAORuS4e+ f2R2fyNAbSgCP9VooN6Q/+uTjRsm5gRD7KY5NHxjTC/SZMwKNy/haXQk/qSjDLUy
Ek+d+0gBMlnigNJ2HoQalKFaERf5K/iQZY4E6Z2ahJ4UFIj7ri3isWgOleP+REJJ cD/2fQovuSLgoqZrTvyvz9e4JhFPk0i1it7I6KWnyyLGOItKc3Cv4p/vkD1ldYKN
PfeSrWQ5XgdklDlHHyv4O5iMkEFWQHttiaTuvdomDncQrNRPTaIOe9iQgfQzDw6m XBhAxmErC9KHQK8pNi8y5z+F1JuZV74i3FRWa+3L2730qIDfR9K3jGIqOow59iqZ
qsb7ZWd5ICA8Krd97BwNHjq/CZ9+WrU6GDc6ImissLVVGGdkEGO7qZTqNUCeH4Zn c8cQLjcGU9lL4dzHh5Hcph8OC5U2aZaJOuMpCndD6XXPvq5/3QQU5rMqP//6tuVi
m/00mNMI4OH8xkwA2vzV5o3J5116zIuv29XQDtcSM+9NQ/HdsjKIA0OpDyWE7Ek/ aAMwT8RaYPiJJPI=
SO+/CvkylwaOcmkuf33ADNjpF4BsBxn7L9XI1WJDtRaMkpbqMsymIxi35VUOGD+m =2Ips
s+72CcUStfYj4NEAEQEAAYkBPAQYAQgAJgIbDBYhBGuk2osciKSUKKKcPQxpwe9B
GB4TBQJmJYcPBQkPGNg5AAoJEAxpwe9BGB4TTswH/3RmARIBV2LV72Sqk3rBcKLG
mY808npRuL6tQDVnrFPl9J8Q1/zItINYUc+2p8rHPW/N/5vyun4oVF9mT+Swqmuy
FkciQ8vCTdPlocGsGmb8eIKSvkzyRb3B8RkiXq2btDQBCVqVWbB6fh3FSI8L5442
r/IAQOKyd5wDGP2vDt1wGQ+0aV60gO2lWXOMi6U7dvt/+9vFaMciNdeZt7llNFIF
OzQuaMAqRP8viuuA29GAsy59x92LWEhm6RRSyU6rMGqfhbHQEs6FZ0x6zuBq8Ru7
T9wf/cc6uGGG6BqnjxFbWL/g9XJeU8gDxQ+ElJbYDXHT255g8kb92mHbJziPbxM=
=WUaV
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----
pub 2048R/1556F3A4 2016-10-04 pub 2048R/1556F3A4 2016-10-04
uid Greg Woolsey <gwoolsey@apache.org> uid Greg Woolsey <gwoolsey@apache.org>

View File

@ -1,4 +1,6 @@
# Apache POI™
Apache POI
======================
A Java library for reading and writing Microsoft Office binary and OOXML file formats. A Java library for reading and writing Microsoft Office binary and OOXML file formats.
@ -33,45 +35,36 @@ And lower-level, supporting components:
| Components named H??F are for reading or writing OLE2 binary formats. | Components named H??F are for reading or writing OLE2 binary formats.
| Components named X??F are for reading or writing OpenOffice XML (OOXML) formats. | Components named X??F are for reading or writing OpenOffice XML (OOXML) formats.
# Getting started Getting started
------------------
Website: https://poi.apache.org/ Website: https://poi.apache.org/
[Mailing lists](https://poi.apache.org/mailinglists.html): `Mailing lists`_:
* [Developers](https://lists.apache.org/list.html?dev@poi.apache.org) * `Developers`_
* [Users](https://lists.apache.org/list.html?user@poi.apache.org) Including Announcements * `Users`_
* [General](https://lists.apache.org/list.html?general@poi.apache.org) * `General`_ (release announcements)
## Bug trackers Bug tracker:
* [Bugzilla](https://bz.apache.org/bugzilla/buglist.cgi?product=POI) * `Bugzilla`_
* [GitHub](https://github.com/apache/poi/issues) * `GitHub pull requests`_
## Source code Source code:
* https://github.com/apache/poi * Official `Apache Subversion repo`_ at apache.org
* `ViewVC repo browser`_ at apache.org
* `GitHub git mirror`_ at github.com
Requires Java 11 or later. `trunk` branch is used for 6.0.0 development. POI 4 and 5 releases require Java 8 or later. Requires Java 1.8 or later.
Contributing
------------------
## Jars * Download and install svn or git, Java JDK 1.8+, and Apache Ant 1.8+ or Gradle
A good resource for finding the published jars and forming build tool dependency definitions is https://mvnrepository.com/artifact/org.apache.poi. * Check out the code from svn or git
* poi - main jar, including shared interfaces
* poi-scratchpad - extra classes to support legacy MS file formats (`H**F`)
* poi-ooxml - support for newer OOXML file formats (`X**F`)
* poi-ooxml-lite - generated classes based on MS XSDs used by poi-ooxml (only includes the most commonly used classes)
* poi-ooxml-full - generated classes based on MS XSDs (can be used instead of poi-ooxml-lite if you need support for less commonly used features)
* poi-excelant - tools for working with Excel files in Apache Ant scripts
* poi-examples
# Contributing
* Download and install git, Java JDK 11+, and Apache Ant 1.8+ or Gradle
* Check out the code from git
* Import the project into Eclipse or your favorite IDE * Import the project into Eclipse or your favorite IDE
@ -89,12 +82,25 @@ A good resource for finding the published jars and forming build tool dependency
* Scratchpad (Binary formats): poi-scratchpad/src/main/java/org/apache/poi/ * Scratchpad (Binary formats): poi-scratchpad/src/main/java/org/apache/poi/
* Examples: poi-examples/src/main/java/org/apache/poi/ * Examples: poi-examples/src/main/java/org/apache/poi/
* More info: [How To Build page](https://poi.apache.org/devel/) * More info: `How To Build page`_ at apache.org
# Building jar files Building jar files
------------------
To build the jar files for poi, poi-ooxml, poi-ooxml-lite, poi-ooxml-full and poi-examples:: To build the jar files for poi, poi-ooxml, poi-ooxml-lite, poi-ooxml-full and poi-examples::
./gradlew jar ./gradlew jar
gradlew jar gradlew jar
.. _Mailing lists: https://poi.apache.org/mailinglists.html
.. _Developers: https://lists.apache.org/list.html?dev@poi.apache.org
.. _Users: https://lists.apache.org/list.html?user@poi.apache.org
.. _General: https://lists.apache.org/list.html?general@poi.apache.org
.. _Bugzilla: https://bz.apache.org/bugzilla/buglist.cgi?product=POI
.. _GitHub pull requests: https://github.com/apache/poi/pulls
.. _Apache Subversion repo: https://svn.apache.org/repos/asf/poi/trunk
.. _ViewVC repo browser: https://svn.apache.org/viewvc/poi/trunk
.. _GitHub git mirror: https://github.com/apache/poi
.. _How To Build page: http://poi.apache.org/devel/

View File

@ -1,9 +1,4 @@
# Security # Security
If you suspect you have found a security vulnerability in Apache POI code, please read https://www.apache.org/security/ If you suspect you have found a security vulnerability in Apache POI code, please read https://www.apache.org/security/
for how to report the issue. Please do not report the details publicly until the report is reviewed. for how to report the issue. Please do not report the details publicly until the report is reviewed.
## Secure Processing
We strongly discourage users of Apache POI from using the lib to parse documents from untrusted sources. For more details,
please read https://poi.apache.org/security.html.

View File

@ -24,33 +24,55 @@ import javax.xml.xpath.XPathFactory
buildscript { buildscript {
repositories { repositories {
maven { url = 'https://plugins.gradle.org/m2/' } maven { url 'https://plugins.gradle.org/m2/' }
mavenCentral() mavenCentral()
} }
dependencies {
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.4.0.2513'
}
} }
plugins { plugins {
id 'base' id 'base'
id 'com.dorongold.task-tree' version '4.0.1' id 'com.dorongold.task-tree' version '2.1.0'
id 'org.nosphere.apache.rat' version '0.8.1' id 'org.nosphere.apache.rat' version '0.7.1'
id 'distribution' id 'distribution'
id "com.github.spotbugs" version '5.0.12'
// 6.2.0+ requires JDK 11 id 'de.thetaphi.forbiddenapis' version '3.3'
// this is the version of the Gradle plugin, it usually includes a id 'com.github.jk1.dependency-license-report' version '2.0'
// different version of spotbugs itself id 'org.cyclonedx.bom' version '1.7.1'
// Latest spotbugs: https://github.com/spotbugs/spotbugs
// Latest gradle plugin: https://plugins.gradle.org/plugin/com.github.spotbugs
id 'com.github.spotbugs' version '6.4.8'
id 'de.thetaphi.forbiddenapis' version '3.10'
id 'org.sonarqube' version '7.2.2.6593'
id 'org.cyclonedx.bom' version '2.4.1'
id 'com.adarshr.test-logger' version '4.0.0'
} }
repositories { repositories {
mavenCentral() mavenCentral()
// maven { url 'https://repository.apache.org/content/repositories/staging' } //maven { url 'https://repository.apache.org/content/repositories/staging' }
}
import com.github.jk1.license.render.*
import com.github.jk1.license.importer.*
licenseReport {
// Select projects to examine for dependencies.
// Defaults to current project and all its subprojects
projects = [project] + project.subprojects
// Adjust the configurations to fetch dependencies, e.g. for Android projects. Default is 'runtimeClasspath'
configurations = ['runtimeClasspath']
// Use 'ALL' to dynamically resolve all configurations:
// configurations = ALL
// Don't include artifacts of project's own group into the report
excludeOwnGroup = true
// Don't exclude bom dependencies.
// If set to true, then all boms will be excluded from the report
excludeBoms = false
// Set custom report renderer, implementing ReportRenderer.
// Yes, you can write your own to support any format necessary.
renderers = [new XmlReportRenderer('third-party-libs.xml', 'Back-End Libraries')]
} }
// Only add the plugin for Sonar if enabled // Only add the plugin for Sonar if enabled
@ -59,8 +81,7 @@ if (project.hasProperty('enableSonar')) {
apply plugin: 'org.sonarqube' apply plugin: 'org.sonarqube'
} }
boolean isCIBuild = false boolean isCIBuild = false;
String dateSuffix = new Date().format('yyyyMMdd')
// For help converting an Ant build to a Gradle build, see // For help converting an Ant build to a Gradle build, see
// https://docs.gradle.org/current/userguide/ant.html // https://docs.gradle.org/current/userguide/ant.html
@ -74,8 +95,8 @@ configurations {
} }
dependencies { dependencies {
antLibs("org.junit.jupiter:junit-jupiter:5.13.4") antLibs("org.junit.jupiter:junit-jupiter:5.9.0")
antLibs("org.apache.ant:ant-junitlauncher:1.10.15") antLibs("org.apache.ant:ant-junitlauncher:1.10.12")
} }
ant.taskdef(name: "junit", ant.taskdef(name: "junit",
@ -84,9 +105,20 @@ ant.taskdef(name: "junit",
wrapper { wrapper {
gradleVersion = '8.14.3' gradleVersion = '7.5'
} }
task adjustWrapperPropertiesFile {
doLast {
ant.replaceregexp(match:'^#.*', replace:'', flags:'g', byline:true) {
fileset(dir: project.projectDir, includes: 'gradle/wrapper/gradle-wrapper.properties')
}
new File(project.projectDir, 'gradle/wrapper/gradle-wrapper.properties').with { it.text = it.readLines().findAll { it }.sort().join('\n') }
ant.fixcrlf(file: 'gradle/wrapper/gradle-wrapper.properties', eol: 'lf')
}
}
wrapper.finalizedBy adjustWrapperPropertiesFile
group = 'org.apache.poi' group = 'org.apache.poi'
/** /**
@ -96,7 +128,7 @@ allprojects {
// apply plugin: 'eclipse' // apply plugin: 'eclipse'
apply plugin: 'idea' apply plugin: 'idea'
version = '6.0.0-SNAPSHOT' version = '5.2.3'
} }
/** /**
@ -110,94 +142,71 @@ subprojects {
apply plugin: 'signing' apply plugin: 'signing'
apply plugin: 'de.thetaphi.forbiddenapis' apply plugin: 'de.thetaphi.forbiddenapis'
apply plugin: 'com.github.spotbugs' apply plugin: 'com.github.spotbugs'
apply plugin: 'org.cyclonedx.bom'
apply plugin: 'com.adarshr.test-logger'
ext { ext {
bouncyCastleVersion = '1.83' bouncyCastleVersion = '1.70'
commonsCodecVersion = '1.21.0' commonsCodecVersion = '1.15'
commonsCompressVersion = '1.28.0' commonsCompressVersion = '1.21'
commonsIoVersion = '2.21.0' commonsIoVersion = '2.11.0'
commonsMathVersion = '3.6.1' commonsMathVersion = '3.6.1'
junitVersion = '5.13.4' junitVersion = '5.9.0'
log4jVersion = '2.25.3' log4jVersion = '2.18.0'
mockitoVersion = '5.21.0' mockitoVersion = '4.8.0'
hamcrestVersion = '3.0' hamcrestVersion = '2.2'
xmlbeansVersion = '5.3.0' xmlbeansVersion = '5.1.1'
batikVersion = '1.19' batikVersion = '1.14'
graphics2dVersion = '3.0.5' graphics2dVersion = '0.40'
pdfboxVersion = '3.0.6' pdfboxVersion = '2.0.26'
saxonVersion = '12.9' saxonVersion = '11.4'
xmlSecVersion = '3.0.6'
apiGuardianVersion = '1.1.2' apiGuardianVersion = '1.1.2'
jdkVersion = (project.properties['jdkVersion'] ?: '11') as int jdkVersion = (project.properties['jdkVersion'] ?: '8') as int
// see https://github.com/gradle/gradle/blob/master/subprojects/jvm-services/src/main/java/org/gradle/internal/jvm/inspection/JvmVendor.java // see https://github.com/gradle/gradle/blob/master/subprojects/jvm-services/src/main/java/org/gradle/internal/jvm/inspection/JvmVendor.java
jdkVendor = (project.properties['jdkVendor'] ?: '') as String jdkVendor = (project.properties['jdkVendor'] ?: '') as String
JAVA9_SRC = 'src/main/java9' JAVA9_SRC = 'src/main/java9'
JAVA9_OUT = layout.buildDirectory.dir('classes/java9/main/').get().asFile.absolutePath JAVA9_OUT = "${buildDir}/classes/java9/main/"
TEST9_SRC = 'src/test/java9' TEST9_SRC = 'src/test/java9'
TEST9_OUT = layout.buildDirectory.dir('classes/java9/test/').get().asFile.absolutePath TEST9_OUT = "${buildDir}/classes/java9/test/"
VERSIONS9 = '/META-INF/versions/9' VERSIONS9 = 'META-INF/versions/9'
NO_SCRATCHPAD = (findProperty("scratchpad.ignore") == "true") NO_SCRATCHPAD = (findProperty("scratchpad.ignore") == "true")
SAXON_TEST = (findProperty("saxon.test") == "true") SAXON_TEST = (findProperty("saxon.test") == "true")
} }
configurations { configurations {
configureEach { all {
resolutionStrategy { resolutionStrategy {
force "commons-io:commons-io:${commonsIoVersion}" force "commons-io:commons-io:${commonsIoVersion}"
force 'org.slf4j:slf4j-api:2.0.17' force 'org.slf4j:slf4j-api:1.7.36'
force 'com.fasterxml.woodstox:woodstox-core:7.1.1' force 'com.fasterxml.woodstox:woodstox-core:6.3.1'
} }
} }
} }
tasks.withType(JavaCompile).configureEach { tasks.withType(JavaCompile) {
options.encoding = 'UTF-8' options.encoding = 'UTF-8'
options.compilerArgs += '-Xlint:unchecked' options.compilerArgs << '-Xlint:unchecked'
options.deprecation = true options.deprecation = true
options.incremental = true options.incremental = true
} }
tasks.withType(Test).configureEach {
systemProperty "file.encoding", "UTF-8"
}
tasks.withType(Javadoc).configureEach {
options.encoding = 'UTF-8'
}
tasks.withType(AbstractArchiveTask).configureEach {
preserveFileTimestamps = false
reproducibleFileOrder = true
}
repositories { repositories {
mavenCentral() mavenCentral()
// maven { url 'https://repository.apache.org/content/repositories/staging' } //maven { url 'https://repository.apache.org/content/repositories/staging' }
} }
dependencies { dependencies {
api platform("org.apache.logging.log4j:log4j-bom:${log4jVersion}") testImplementation "org.junit.jupiter:junit-jupiter:${junitVersion}"
api 'org.apache.logging.log4j:log4j-api'
testImplementation platform("org.junit:junit-bom:${junitVersion}")
testImplementation 'org.junit.jupiter:junit-jupiter'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testImplementation "org.mockito:mockito-core:${mockitoVersion}" testImplementation "org.mockito:mockito-core:${mockitoVersion}"
testImplementation "org.hamcrest:hamcrest:${hamcrestVersion}" testImplementation "org.hamcrest:hamcrest:${hamcrestVersion}"
testImplementation 'org.apache.logging.log4j:log4j-core' testImplementation "org.apache.logging.log4j:log4j-core:${log4jVersion}"
if (SAXON_TEST) {
testRuntimeOnly("net.sf.saxon:Saxon-HE:${saxonVersion}") {
exclude group: 'xml-apis', module: 'xml-apis'
}
}
} }
java { java {
toolchain { toolchain {
languageVersion = JavaLanguageVersion.of(jdkVersion) languageVersion.set(JavaLanguageVersion.of(jdkVersion))
if (jdkVendor != '') vendor = JvmVendorSpec.matching(jdkVendor) if (jdkVendor != '') vendor.set(JvmVendorSpec.matching(jdkVendor))
} }
withJavadocJar() withJavadocJar()
withSourcesJar() withSourcesJar()
@ -207,7 +216,7 @@ subprojects {
failOnError = true failOnError = true
maxMemory = "1024M" maxMemory = "1024M"
javadocTool = javaToolchains.javadocToolFor { javadocTool = javaToolchains.javadocToolFor {
languageVersion = JavaLanguageVersion.of(jdkVersion) languageVersion = JavaLanguageVersion.of(jdkVersion >= 17 ? 17 : 11)
} }
doFirst { doFirst {
@ -215,90 +224,30 @@ subprojects {
addBooleanOption('html5', true) addBooleanOption('html5', true)
addBooleanOption('Xdoclint:all,-missing', true) addBooleanOption('Xdoclint:all,-missing', true)
links 'https://poi.apache.org/apidocs/dev/' links 'https://poi.apache.org/apidocs/dev/'
if (jdkVersion >= 23) links 'https://docs.oracle.com/en/java/javase/23/docs/api/' else links 'https://docs.oracle.com/en/java/javase/11/docs/api/' links 'https://docs.oracle.com/javase/8/docs/api/'
links 'https://xmlbeans.apache.org/docs/5.0.0/' links 'https://xmlbeans.apache.org/docs/5.0.0/'
links 'https://www.javadocs.dev/org.apache.commons/commons-compress/1.28.0/' links 'https://commons.apache.org/proper/commons-compress/apidocs/'
use = true use = true
splitIndex = true splitIndex = true
source = "11" source = "1.8"
} }
} }
} }
// helper-target to get a directory with all third-party libraries // helper-target to get a directory with all third-party libraries
// this is used for mass-regression-testing // this is used for mass-regression-testing
tasks.register('getDeps', Copy) { task getDeps(type: Copy) {
from sourceSets.main.runtimeClasspath from sourceSets.main.runtimeClasspath
into 'build/runtime/' into 'build/runtime/'
} }
tasks.withType(Jar).configureEach { tasks.withType(Jar) {
duplicatesStrategy = DuplicatesStrategy.FAIL duplicatesStrategy = 'fail'
destinationDirectory = file("../build/dist/maven/${base.archivesName.get()}") destinationDirectory = file("../build/dist/maven/${project.archivesBaseName}")
doLast { doLast {
// make sure we do not have distribution jar-files with different versions ant.checksum(file: it.archivePath, algorithm: 'SHA-256', fileext: '.sha256', format: 'MD5SUM')
// in the build-dir as those lead to strange errors about "duplicate modules" ant.checksum(file: it.archivePath, algorithm: 'SHA-512', fileext: '.sha512', format: 'MD5SUM')
// when building java9 JPMS class files ("java9")
ant.delete(failOnError: true, verbose: true) {
fileset(dir: "../build/dist/maven/${base.archivesName.get()}", erroronmissingdir: false) {
include(name: '*.jar')
exclude(name: "*${version}.jar")
exclude(name: "*${version}-sources.jar")
include(name: '*.jar.asc')
exclude(name: "*${version}.jar.asc")
exclude(name: "*${version}-sources.jar.asc")
include(name: '*.jar.sha256')
exclude(name: "*${version}.jar.sha256")
exclude(name: "*${version}-sources.jar.sha256")
include(name: '*.jar.sha512')
exclude(name: "*${version}.jar.sha512")
exclude(name: "*${version}-sources.jar.sha512")
include(name: '*.pom')
exclude(name: "*${version}.pom")
include(name: '*.pom.asc')
exclude(name: "*${version}.pom.asc")
}
}
// use failOnError=false for -javadoc and -tests as not all modules create this directory
ant.delete(failOnError: false, verbose: true) {
fileset(dir: "../build/dist/maven/${base.archivesName.get()}-javadoc", erroronmissingdir: false) {
include(name: '*-javadoc.jar')
exclude(name: "*${version}-javadoc.jar")
include(name: '*-javadoc.jar.asc')
exclude(name: "*${version}-javadoc.jar.asc")
include(name: '*-javadoc.jar.sha256')
exclude(name: "*${version}-javadoc.jar.sha256")
include(name: '*-javadoc.jar.sha512')
exclude(name: "*${version}-javadoc.jar.sha512")
}
}
ant.delete(failOnError: false, verbose: true) {
fileset(dir: "../build/dist/maven/${base.archivesName.get()}-tests", erroronmissingdir: false) {
include(name: '*-tests.jar')
exclude(name: "*${version}-tests.jar")
include(name: '*-tests.jar.asc')
exclude(name: "*${version}-tests.jar.asc")
include(name: '*-tests.jar.sha256')
exclude(name: "*${version}-tests.jar.sha256")
include(name: '*-tests.jar.sha512')
exclude(name: "*${version}-tests.jar.sha512")
}
}
ant.checksum(file: it.archiveFile.get().asFile, algorithm: 'SHA-256', fileext: '.sha256', format: 'MD5SUM')
ant.checksum(file: it.archiveFile.get().asFile, algorithm: 'SHA-512', fileext: '.sha512', format: 'MD5SUM')
} }
} }
@ -326,19 +275,15 @@ subprojects {
javadocJar { javadocJar {
// if javadocs and binaries are in the same directory, JPMS complaints about duplicated modules // if javadocs and binaries are in the same directory, JPMS complaints about duplicated modules
// in the module-path // in the module-path
destinationDirectory = file("../build/dist/maven/${base.archivesName.get()}-javadoc") destinationDirectory = file("../build/dist/maven/${project.archivesBaseName}-javadoc")
} }
sourcesJar { sourcesJar {
destinationDirectory = file("../build/dist/maven/${base.archivesName.get()}") destinationDirectory = file("../build/dist/maven/${project.archivesBaseName}")
exclude 'META-INF/services/**' exclude 'META-INF/services/**'
} }
test { test {
// use US locale for tests
systemProperty "user.language", "en"
systemProperty "user.country", "US"
// make XML test-results available for Jenkins CI // make XML test-results available for Jenkins CI
useJUnitPlatform() useJUnitPlatform()
reports { reports {
@ -346,8 +291,8 @@ subprojects {
} }
javaLauncher = javaToolchains.launcherFor { javaLauncher = javaToolchains.launcherFor {
languageVersion = JavaLanguageVersion.of(jdkVersion) languageVersion.set(JavaLanguageVersion.of(jdkVersion))
if (jdkVendor != '') vendor = JvmVendorSpec.matching(jdkVendor) if (jdkVendor != '') vendor.set(JvmVendorSpec.matching(jdkVendor))
} }
// Exclude some tests that are not actually tests or do not run cleanly on purpose // Exclude some tests that are not actually tests or do not run cleanly on purpose
@ -362,11 +307,11 @@ subprojects {
// set heap size for the test JVM(s) // set heap size for the test JVM(s)
minHeapSize = "128m" minHeapSize = "128m"
maxHeapSize = "2g" maxHeapSize = "1G"
// Specifying the local via system properties did not work, so we set them this way // Specifying the local via system properties did not work, so we set them this way
jvmArgs += [ jvmArgs << [
'-Djava.awt.headless=true', '-Djava.awt.headless=true',
'-Djavax.xml.stream.XMLInputFactory=com.sun.xml.internal.stream.XMLInputFactoryImpl', '-Djavax.xml.stream.XMLInputFactory=com.sun.xml.internal.stream.XMLInputFactoryImpl',
"-Dversion.id=${project.version}", "-Dversion.id=${project.version}",
@ -375,18 +320,18 @@ subprojects {
] ]
// detect if running on Jenkins/CI // detect if running on Jenkins/CI
isCIBuild |= Boolean.valueOf(System.getenv("CI_BUILD")) isCIBuild |= Boolean.valueOf(System.getenv("CI_BUILD"));
if (isCIBuild) { if (isCIBuild) {
System.out.println("Run with reduced parallelism for CI build") System.out.println("Run with reduced parallelism for CI build");
jvmArgs += [ jvmArgs += [
// Strictly serial // Strictly serial
'-Djunit.jupiter.execution.parallel.enabled=false', // '-Djunit.jupiter.execution.parallel.enabled=false',
// OR parallel on 2 threads // OR parallel on 2 threads
//'-Djunit.jupiter.execution.parallel.config.strategy=fixed', '-Djunit.jupiter.execution.parallel.config.strategy=fixed',
//'-Djunit.jupiter.execution.parallel.config.fixed.parallelism=2' '-Djunit.jupiter.execution.parallel.config.fixed.parallelism=2'
] ]
maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1 maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
} else { } else {
@ -421,25 +366,27 @@ subprojects {
systemProperties['java.locale.providers'] = 'JRE,CLDR' systemProperties['java.locale.providers'] = 'JRE,CLDR'
doFirst { doFirst {
// some options were removed in JDK 18 if (jdkVersion > 8) {
if (jdkVersion < 18) { // some options were removed in JDK 18
if (jdkVersion < 18) {
jvmArgs += [
'--illegal-access=warn',
]
}
jvmArgs += [ jvmArgs += [
'--illegal-access=warn', // see https://github.com/java9-modularity/gradle-modules-plugin/issues/97
// opposed to the recommendation there, it doesn't work to add ... to the dependencies
// testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.7.1'
// gradles gradle-worker.jar is still not a JPMS module and thus runs as unnamed module
'--add-exports','org.junit.platform.commons/org.junit.platform.commons.util=org.apache.poi.poi',
'--add-exports','org.junit.platform.commons/org.junit.platform.commons.util=ALL-UNNAMED',
'--add-exports','org.junit.platform.commons/org.junit.platform.commons.logging=ALL-UNNAMED',
'-Dsun.reflect.debugModuleAccessChecks=true',
'-Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true',
] ]
} }
jvmArgs += [
// see https://github.com/java9-modularity/gradle-modules-plugin/issues/97
// opposed to the recommendation there, it doesn't work to add ... to the dependencies
// testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.13.2'
// gradles gradle-worker.jar is still not a JPMS module and thus runs as unnamed module
'--add-exports','org.junit.platform.commons/org.junit.platform.commons.util=org.apache.poi.poi',
'--add-exports','org.junit.platform.commons/org.junit.platform.commons.util=ALL-UNNAMED',
'--add-exports','org.junit.platform.commons/org.junit.platform.commons.logging=ALL-UNNAMED',
'-Dsun.reflect.debugModuleAccessChecks=true',
'-Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true',
]
} }
jacoco { jacoco {
@ -452,7 +399,7 @@ subprojects {
} }
jacoco { jacoco {
toolVersion = '0.8.13' toolVersion = '0.8.8'
} }
jacocoTestReport { jacocoTestReport {
@ -469,9 +416,9 @@ subprojects {
// https://docs.sonarqube.org/display/SONARQUBE52/Analyzing+with+SonarQube+Scanner+for+Gradle // https://docs.sonarqube.org/display/SONARQUBE52/Analyzing+with+SonarQube+Scanner+for+Gradle
// for documentation of properties. // for documentation of properties.
// //
// Some additional properties are currently set in the Jenkins-DSL, see jenkins/create_jobs.groovy // Some additional properties are currently set in the Jenkins-DSL, see jenksin/create_jobs.groovy
// //
sonar { sonarqube {
properties { properties {
// as we currently use build/<module>/ as project-basedir, we need to tell Sonar to use // as we currently use build/<module>/ as project-basedir, we need to tell Sonar to use
// the root-folder as "basedir" for the projects // the root-folder as "basedir" for the projects
@ -498,20 +445,29 @@ subprojects {
} }
forbiddenApisTest { forbiddenApisTest {
// forbiddenapis:3.8 bundled signatures max supported version is 23 // forbiddenapis bundled signatures max supported version is 17
targetCompatibility = (JavaVersion.VERSION_23.isCompatibleWith(JavaVersion.current()) ? JavaVersion.current() : JavaVersion.VERSION_23) // also see https://github.com/policeman-tools/forbidden-apis/issues/191
targetCompatibility = (JavaVersion.VERSION_17.isCompatibleWith(JavaVersion.current()) ? JavaVersion.current() : JavaVersion.VERSION_17)
} }
forbiddenApisMain { forbiddenApisMain {
signaturesFiles += files('../src/resources/devtools/forbidden-signatures-prod.txt') signaturesFiles += files('../src/resources/devtools/forbidden-signatures-prod.txt')
targetCompatibility = (JavaVersion.VERSION_23.isCompatibleWith(JavaVersion.current()) ? JavaVersion.current() : JavaVersion.VERSION_23) targetCompatibility = (JavaVersion.VERSION_17.isCompatibleWith(JavaVersion.current()) ? JavaVersion.current() : JavaVersion.VERSION_17)
} }
task jenkins
jenkins.dependsOn build
jenkins.dependsOn check
jenkins.dependsOn javadoc
jenkins.dependsOn jacocoTestReport
jenkins.dependsOn rat
jenkins.dependsOn getDeps
publishing { publishing {
publications { publications {
POI(MavenPublication) { POI(MavenPublication) {
groupId = 'org.apache.poi' groupId 'org.apache.poi'
artifactId = base.archivesName.get() artifactId project.archivesBaseName
from components.java from components.java
@ -592,9 +548,9 @@ subprojects {
} }
} }
generatePomFileForPOIPublication.destination = "../build/dist/maven/${base.archivesName.get()}/${base.archivesName.get()}-${project.version}.pom" generatePomFileForPOIPublication.destination = "../build/dist/maven/${project.archivesBaseName}/${project.archivesBaseName}-${project.version}.pom"
tasks.withType(GenerateModuleMetadata).configureEach { tasks.withType(GenerateModuleMetadata) {
enabled = false enabled = false
} }
@ -611,7 +567,6 @@ subprojects {
spotbugs { spotbugs {
ignoreFailures = true ignoreFailures = true
showStackTraces = false showStackTraces = false
maxHeapSize = '2g'
} }
build { build {
@ -622,14 +577,14 @@ subprojects {
} }
// initial try to provide a combined JavaDoc, grouping is still missing here, though! // initial try to provide a combined JavaDoc, grouping is still missing here, though!
tasks.register('allJavaDoc', Javadoc) { task allJavaDoc(type: Javadoc) {
var prj = [project(':poi'), project(':poi-excelant'), project(':poi-ooxml'), project(':poi-scratchpad')] var prj = [ project(':poi'), project(':poi-excelant'), project(':poi-ooxml'), project(':poi-scratchpad') ]
source prj.collect { it.sourceSets.main.allJava } source prj.collect { it.sourceSets.main.allJava }
// for possible settings see https://docs.gradle.org/current/dsl/org.gradle.api.tasks.javadoc.Javadoc.html // for possible settings see https://docs.gradle.org/current/dsl/org.gradle.api.tasks.javadoc.Javadoc.html
classpath = files(subprojects.collect { it.sourceSets.main.compileClasspath }) classpath = files(subprojects.collect { it.sourceSets.main.compileClasspath })
destinationDir = layout.buildDirectory.dir('docs/javadoc').get().asFile destinationDir = file("${buildDir}/docs/javadoc")
maxMemory = "2048M" maxMemory="2048M"
// for possible options see https://docs.gradle.org/current/javadoc/org/gradle/external/javadoc/StandardJavadocDocletOptions.html // for possible options see https://docs.gradle.org/current/javadoc/org/gradle/external/javadoc/StandardJavadocDocletOptions.html
options.use = true options.use = true
@ -644,7 +599,7 @@ tasks.register('allJavaDoc', Javadoc) {
options.group('SS - Common Spreadsheet Format', 'org.apache.poi.ss*') options.group('SS - Common Spreadsheet Format', 'org.apache.poi.ss*')
options.group('HSSF - Horrible Spreadsheet Format', 'org.apache.poi.hssf*') options.group('HSSF - Horrible Spreadsheet Format', 'org.apache.poi.hssf*')
options.group('XSSF - Open Office XML Spreadsheet Format', 'org.apache.poi.xssf*') options.group('XSSF - Open Office XML Spreadsheet Format', 'org.apache.poi.xssf*')
options.group('SL - Common Slideshow Format', 'org.apache.poi.sl*') options.group('SL - Common Slideshow Format', 'org.apache.poi.sl*')
options.group('HSLF - Horrible Slideshow Format', 'org.apache.poi.hslf*', 'org.apache.poi.hwmf*', 'org.apache.poi.hemf*') options.group('HSLF - Horrible Slideshow Format', 'org.apache.poi.hslf*', 'org.apache.poi.hwmf*', 'org.apache.poi.hemf*')
options.group('XSLF - Open Office XML Slideshow Format', 'org.apache.poi.xslf*') options.group('XSLF - Open Office XML Slideshow Format', 'org.apache.poi.xslf*')
options.group('HWPF - Horrible Word Processor Format', 'org.apache.poi.hwpf*') options.group('HWPF - Horrible Word Processor Format', 'org.apache.poi.hwpf*')
@ -660,6 +615,9 @@ tasks.register('allJavaDoc', Javadoc) {
// options.group('Examples', 'org.apache.poi.examples*') // options.group('Examples', 'org.apache.poi.examples*')
} }
task jenkins(dependsOn: ['replaceVersion', subprojects.build, 'binDistZip','binDistTar','srcDistZip','srcDistTar']) {}
clean { clean {
delete "${rootDir}/build/dist" delete "${rootDir}/build/dist"
} }
@ -705,9 +663,7 @@ rat {
"osgi/README.md", "osgi/README.md",
"src/resources/ooxml-lite-report.*", "src/resources/ooxml-lite-report.*",
// ignore svn conflict artifacts // ignore svn conflict artifacts
"**/module-info.*", "**/module-info.*"
"poi-examples/src/main/groovy/settings.gradle",
"poi-examples/src/main/groovy/.gradle/**"
] ]
/* /*
@ -721,24 +677,6 @@ rat {
verbose.set(true) verbose.set(true)
} }
task jenkins(dependsOn: [
'replaceVersion',
subprojects.build,
subprojects.check,
subprojects.javadoc,
subprojects.jacocoTestReport,
subprojects.getDeps,
'srcDistZip',
'srcDistTar',
rat
]) {}
task jenkinsLite(dependsOn: [
'replaceVersion',
subprojects.build,
subprojects.test
]) {}
/*task downloadJarsToLibs() { /*task downloadJarsToLibs() {
def f = new File("$projectDir/../lib/ooxml/xmlbeans-5.0.0.jar") def f = new File("$projectDir/../lib/ooxml/xmlbeans-5.0.0.jar")
if (!f.exists()) { if (!f.exists()) {
@ -750,14 +688,14 @@ task jenkinsLite(dependsOn: [
//compileJava.dependsOn 'downloadJarsToLibs' //compileJava.dependsOn 'downloadJarsToLibs'
tasks.register('replaceVersion') { task replaceVersion() {
outputs.upToDateWhen { false } outputs.upToDateWhen { false }
var version = subprojects[0].version var version = subprojects[0].version
var tokens = [ var tokens = [
['osgi', 'pom.xml', '(packaging>\\n\\s*<version>)[0-9.]+(?:-SNAPSHOT|-RC\\d+)?', "\\1${version}"], [ 'osgi', 'pom.xml', '(packaging>\\n\\s*<version>)[0-9.]+(?:-SNAPSHOT|-RC\\d+)?', "\\1${version}" ],
['osgi', 'pom.xml', '(<poi.version>)[0-9.]+(?:-SNAPSHOT|-RC\\d+)?', "\\1${version}"] [ 'osgi', 'pom.xml', '(<poi.version>)[0-9.]+(?:-SNAPSHOT|-RC\\d+)?', "\\1${version}" ]
// [ '.', 'build.gradle', ' version = \'[0-9.]+(?:-SNAPSHOT)?\'', " version = '${version}'" ] // [ '.', 'build.gradle', ' version = \'[0-9.]+(?:-SNAPSHOT)?\'', " version = '${version}'" ]
] ]
doLast { doLast {
@ -781,13 +719,54 @@ task zipJavadocs(type: Zip, dependsOn: allJavaDoc) {
archiveExtension = 'jar' archiveExtension = 'jar'
} }
tasks.withType(Tar).configureEach { tasks.withType(Tar) {
compression = Compression.GZIP compression = Compression.GZIP
archiveExtension = 'tgz' archiveExtension = 'tgz'
} }
distributions { distributions {
var version = subprojects[0].version
var date = new Date().format('yyyyMMdd')
var poiDep = project(':poi').configurations.getAt('compileClasspath')
var ooxmlImp = project(':poi-ooxml').configurations.getAt('compileClasspath')
bin {
distributionBaseName = "poi-bin-${version}-${date}"
contents {
from('build/dist/maven') {
include "**/*${version}.jar"
exclude "**/*lite-agent*.jar"
exclude "**/*integration*.jar"
}
from('build/dist') { include 'poi-javadoc*.jar'}
from('legal') { exclude 'HEADER' }
from(poiDep) { include "**/*.jar" }
from(ooxmlImp) { include "**/*.jar" }
includeEmptyDirs = false
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
eachFile {
String root = "poi-bin-${version}/"
if (name.startsWith('poi')) {
path = root + name
} else if (poiDep.contains(file)) {
path = root + 'lib/' + name
} else if (name =~ /^(batik|bc|fontbox|graphics|pdfbox|xml-apis|xmlgraphics|xmlsec)/) {
path = root + 'auxiliary/' + name
} else if (ooxmlImp.contains(file)) {
path = root + 'ooxml-lib/' + name
} else {
path = root + name
}
}
}
}
src { src {
distributionBaseName = "poi-src-${version}-${date}"
contents { contents {
from('.') { from('.') {
exclude '*/build/**' exclude '*/build/**'
@ -833,14 +812,14 @@ distributions {
exclude '**/*-saved.xls' exclude '**/*-saved.xls'
} }
from('legal') { exclude 'HEADER' } from('legal') { exclude 'HEADER' }
includeEmptyDirs = false
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
} }
} }
} }
tasks.register('soLinkCheck') { binDistZip.dependsOn 'zipJavadocs', ':poi-ooxml-lite:jar'
binDistTar.dependsOn 'zipJavadocs', ':poi-ooxml-lite:jar'
task soLinkCheck() {
doLast { doLast {
def path = ant.path { def path = ant.path {
fileset(dir: '.', includes: '**/*.java') { fileset(dir: '.', includes: '**/*.java') {
@ -861,30 +840,28 @@ tasks.register('soLinkCheck') {
} }
var srcDep = [ var srcDep = [
':poi:compileJava9', ':poi:cacheJava9',
':poi:compileTest9', ':poi:cacheTest9',
':poi-ooxml-full:compileJava9', ':poi-ooxml-full:cacheJava9',
':poi-ooxml-lite-agent:compileJava9', ':poi-ooxml-lite-agent:cacheJava9',
':poi-ooxml:compileJava9', ':poi-ooxml:cacheJava9',
':poi-ooxml:compileTest9', ':poi-ooxml:cacheTest9',
':poi-scratchpad:compileJava9', ':poi-scratchpad:cacheJava9',
':poi-scratchpad:compileTest9', ':poi-scratchpad:cacheTest9',
':poi-excelant:compileJava9', ':poi-excelant:cacheJava9',
':poi-excelant:compileTest9', ':poi-excelant:cacheTest9',
':poi-examples:compileJava9', ':poi-examples:cacheJava9',
':poi-integration:compileTest9', ':poi-integration:cacheTest9',
':poi-ooxml-lite:compileJava9', ':poi-ooxml-lite:cacheJava9',
':poi-ooxml-lite:generateModuleInfo' ':poi-ooxml-lite:generateModuleInfo'
] ]
srcDistTar.setArchiveFileName("apache-poi-src-${subprojects[0].version}-${dateSuffix}.tgz")
srcDistZip.setArchiveFileName("apache-poi-src-${subprojects[0].version}-${dateSuffix}.zip")
srcDistTar.dependsOn srcDep srcDistTar.dependsOn srcDep
srcDistZip.dependsOn srcDep srcDistZip.dependsOn srcDep
soLinkCheck.dependsOn srcDep soLinkCheck.dependsOn srcDep
rat.dependsOn soLinkCheck rat.dependsOn soLinkCheck
tasks.register('fixDistDir') { task fixDistDir {
doLast { doLast {
ant.mkdir(dir: 'build/dist') ant.mkdir(dir: 'build/dist')
ant.move(todir: 'build/dist') { ant.move(todir: 'build/dist') {
@ -893,5 +870,26 @@ tasks.register('fixDistDir') {
} }
} }
binDistZip.finalizedBy fixDistDir
binDistTar.finalizedBy fixDistDir
srcDistZip.finalizedBy fixDistDir srcDistZip.finalizedBy fixDistDir
srcDistTar.finalizedBy fixDistDir srcDistTar.finalizedBy fixDistDir
cyclonedxBom {
// includeConfigs is the list of configuration names to include when generating the BOM (leave empty to include every configuration)
includeConfigs = ["runtimeClasspath"]
// skipConfigs is a list of configuration names to exclude when generating the BOM
//skipConfigs = ["compileClasspath", "testCompileClasspath"]
// Specified the type of project being built. Defaults to 'library'
projectType = "library"
// Specified the version of the CycloneDX specification to use. Defaults to 1.4.
schemaVersion = "1.4"
// Boms destination directory (defaults to build/reports)
destination = file("build/reports")
// The file name for the generated BOMs (before the file format suffix). Defaults to 'bom'
outputName = "pom-${project.version}.bom"
// The file format generated, can be xml, json or all for generating both
outputFormat = "xml"
// Exclude BOM Serial Number
includeBomSerialNumber = true
}

674
build.xml

File diff suppressed because it is too large Load Diff

View File

@ -35,62 +35,6 @@
<programming-language>Java</programming-language> <programming-language>Java</programming-language>
<category rdf:resource="https://projects.apache.org/category/content" /> <category rdf:resource="https://projects.apache.org/category/content" />
<category rdf:resource="https://projects.apache.org/category/library" /> <category rdf:resource="https://projects.apache.org/category/library" />
<release>
<Version>
<name>Apache POI 5.5.1</name>
<created>2025-11-30</created>
<revision>5.5.1</revision>
</Version>
</release>
<release>
<Version>
<name>Apache POI 5.5.0</name>
<created>2025-11-15</created>
<revision>5.5.0</revision>
</Version>
</release>
<release>
<Version>
<name>Apache POI 5.4.1</name>
<created>2025-04-06</created>
<revision>5.4.1</revision>
</Version>
</release>
<release>
<Version>
<name>Apache POI 5.4.0</name>
<created>2025-01-08</created>
<revision>5.4.0</revision>
</Version>
</release>
<release>
<Version>
<name>Apache POI 5.3.0</name>
<created>2024-07-02</created>
<revision>5.3.0</revision>
</Version>
</release>
<release>
<Version>
<name>Apache POI 5.2.5</name>
<created>2023-11-25</created>
<revision>5.2.5</revision>
</Version>
</release>
<release>
<Version>
<name>Apache POI 5.2.4</name>
<created>2023-09-28</created>
<revision>5.2.4</revision>
</Version>
</release>
<release>
<Version>
<name>Apache POI 5.2.3</name>
<created>2022-09-16</created>
<revision>5.2.3</revision>
</Version>
</release>
<release> <release>
<Version> <Version>
<name>Apache POI 5.2.2</name> <name>Apache POI 5.2.2</name>
@ -267,10 +211,10 @@
</Version> </Version>
</release> </release>
<repository> <repository>
<GitRepository> <SVNRepository>
<location rdf:resource="https://github.com/apache/poi.git"/> <location rdf:resource="https://svn.apache.org/repos/asf/poi/"/>
<browse rdf:resource="https://github.com/apache/poi/"/> <browse rdf:resource="https://svn.apache.org/viewvc/poi/"/>
</GitRepository> </SVNRepository>
</repository> </repository>
<maintainer> <maintainer>
<foaf:Person> <foaf:Person>

View File

@ -51,13 +51,6 @@ org.apache.openjpa.lib.util.J2DoPrivHelper$7.run
serp.bytecode.BCClass.read serp.bytecode.BCClass.read
serp.util.Strings.toClass serp.util.Strings.toClass
# Logging
java.util.logging.Logger.findSystemResourceBundle
java.util.logging.LogManager.readPrimordialConfiguration
org.slf4j.LoggerFactory.getLogger
org.apache.log4j.FileAppender.setFile
org.apache.logging.log4j.core.config.ConfigurationSource.getConfigurationSource
# Java # Java
sun.util.resources.LocaleData.getBundle sun.util.resources.LocaleData.getBundle
sun.util.LocaleServiceProviderPool.<init> sun.util.LocaleServiceProviderPool.<init>
@ -70,14 +63,16 @@ sun.font.SunFontManager.loadFonts
sun.font.FontManagerFactory.getInstance sun.font.FontManagerFactory.getInstance
sun.font.TrueTypeFont.open sun.font.TrueTypeFont.open
sun.reflect.misc.MethodUtil.<clinit> sun.reflect.misc.MethodUtil.<clinit>
java.util.logging.Logger.findSystemResourceBundle
java.util.logging.LogManager.readPrimordialConfiguration
java.text.BreakIterator.getBundle java.text.BreakIterator.getBundle
sun.java2d.SunGraphicsEnvironment.<init> sun.java2d.SunGraphicsEnvironment.<init>
org.kohsuke.file_leak_detector.AgentMain.runHttpServer org.kohsuke.file_leak_detector.AgentMain.runHttpServer
org.apache.log4j.FileAppender.setFile
org.apache.logging.log4j.core.config.ConfigurationSource.getConfigurationSource
sun.launcher.LauncherHelper.validateMainClass sun.launcher.LauncherHelper.validateMainClass
sun.util.locale.provider.RuleBasedBreakIterator$1.run sun.util.locale.provider.RuleBasedBreakIterator$1.run
java.util.ServiceLoader$LazyIterator.hasNextService java.util.ServiceLoader$LazyIterator.hasNextService
java.util.ServiceLoader$LazyClassPathLookupIterator.nextProviderClass
java.lang.ClassLoader.loadClass
# other third party libs # other third party libs
net.bytebuddy.dynamic.ClassFileLocator$ForClassLoader.locate net.bytebuddy.dynamic.ClassFileLocator$ForClassLoader.locate

View File

@ -1,11 +1,11 @@
# Specifies the JVM arguments used for the daemon process. # Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings. # The setting is particularly useful for tweaking memory settings.
# Less than 2G definitely slows things down. Increased to 3G due to OOM issues on ci-builds.apache.org. # Less than 2G definitely slows things down. -XX:+HeapDumpOnOutOfMemoryError
# -XX:+HeapDumpOnOutOfMemoryError org.gradle.jvmargs=-Xmx2G -Dfile.encoding=UTF-8
org.gradle.jvmargs=-Xmx3G -Dfile.encoding=UTF-8
# Activating will be much faster, but break the build of 'poi-ooxml-lite' # Activating will be much faster, but break the build of 'poi-ooxml-lite'
org.gradle.caching=true # @todo: look into poi-ooxml-lite task generateModuleInfo and enforce running whatever is needed before
org.gradle.caching=false
# Modularise your project and enable parallel build # Modularise your project and enable parallel build
org.gradle.parallel=true org.gradle.parallel=true

Binary file not shown.

View File

@ -1,7 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

41
gradlew vendored
View File

@ -15,8 +15,6 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# #
# SPDX-License-Identifier: Apache-2.0
#
############################################################################## ##############################################################################
# #
@ -57,7 +55,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.
@ -82,11 +80,13 @@ do
esac esac
done done
# This is normally unused APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# shellcheck disable=SC2034
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum
@ -114,7 +114,7 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;; NONSTOP* ) nonstop=true ;;
esac esac
CLASSPATH="\\\"\\\"" CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
@ -133,29 +133,22 @@ location of your Java installation."
fi fi
else else
JAVACMD=java JAVACMD=java
if ! command -v java >/dev/null 2>&1 which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #( case $MAX_FD in #(
max*) max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) || MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit" warn "Could not query maximum file descriptor limit"
esac esac
case $MAX_FD in #( case $MAX_FD in #(
'' | soft) :;; #( '' | soft) :;; #(
*) *)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" || ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD" warn "Could not set maximum file descriptor limit to $MAX_FD"
esac esac
@ -200,20 +193,16 @@ if "$cygwin" || "$msys" ; then
done done
fi fi
# Collect all arguments for the java command;
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# Collect all arguments for the java command: # * put everything else in single quotes, so that it's not re-expanded.
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \ set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \ "-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \ -classpath "$CLASSPATH" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ org.gradle.wrapper.GradleWrapperMain \
"$@" "$@"
# Stop when "xargs" is not available. # Stop when "xargs" is not available.

185
gradlew.bat vendored
View File

@ -1,94 +1,91 @@
@rem @rem
@rem Copyright 2015 the original author or authors. @rem Copyright 2015 the original author or authors.
@rem @rem
@rem Licensed under the Apache License, Version 2.0 (the "License"); @rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License. @rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at @rem You may obtain a copy of the License at
@rem @rem
@rem https://www.apache.org/licenses/LICENSE-2.0 @rem https://www.apache.org/licenses/LICENSE-2.0
@rem @rem
@rem Unless required by applicable law or agreed to in writing, software @rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS, @rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and @rem See the License for the specific language governing permissions and
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@rem SPDX-License-Identifier: Apache-2.0
@rem @if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@if "%DEBUG%"=="" @echo off @rem
@rem ########################################################################## @rem Gradle startup script for Windows
@rem @rem
@rem Gradle startup script for Windows @rem ##########################################################################
@rem
@rem ########################################################################## @rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
set DIRNAME=%~dp0 set APP_BASE_NAME=%~n0
if "%DIRNAME%"=="" set DIRNAME=. set APP_HOME=%DIRNAME%
@rem This is normally unused
set APP_BASE_NAME=%~n0 @rem Resolve any "." and ".." in APP_HOME to make it shorter.
set APP_HOME=%DIRNAME% for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Resolve any "." and ".." in APP_HOME to make it shorter. @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. @rem Find java.exe
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" if defined JAVA_HOME goto findJavaFromJavaHome
@rem Find java.exe set JAVA_EXE=java.exe
if defined JAVA_HOME goto findJavaFromJavaHome %JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 echo.
if %ERRORLEVEL% equ 0 goto execute echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 echo location of your Java installation.
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2 goto fail
echo location of your Java installation. 1>&2
:findJavaFromJavaHome
goto fail set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=% if exist "%JAVA_EXE%" goto execute
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
echo.
if exist "%JAVA_EXE%" goto execute echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 echo location of your Java installation.
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2 goto fail
echo location of your Java installation. 1>&2
:execute
goto fail @rem Setup the command line
:execute set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Setup the command line
set CLASSPATH= @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
@rem Execute Gradle :end
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* @rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:end
@rem End local scope for the variables with windows NT shell :fail
if %ERRORLEVEL% equ 0 goto mainEnd rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
:fail set EXIT_CODE=%ERRORLEVEL%
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of if %EXIT_CODE% equ 0 set EXIT_CODE=1
rem the _cmd.exe /c_ return code! if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
set EXIT_CODE=%ERRORLEVEL% exit /b %EXIT_CODE%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% :mainEnd
exit /b %EXIT_CODE% if "%OS%"=="Windows_NT" endlocal
:mainEnd :omega
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@ -1,20 +1,3 @@
/* ====================================================================
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.
==================================================================== */
// This script is used as input to the Jenkins Job DSL plugin to create all the build-jobs that // This script is used as input to the Jenkins Job DSL plugin to create all the build-jobs that
// Apache POI uses on the public Jenkins instance at https://ci-builds.apache.org/job/POI/ // Apache POI uses on the public Jenkins instance at https://ci-builds.apache.org/job/POI/
// //
@ -31,31 +14,45 @@ def xercesUrl = 'https://repo1.maven.org/maven2/xerces/xercesImpl/2.6.1/xercesIm
def xercesLib = './xercesImpl-2.6.1.jar' def xercesLib = './xercesImpl-2.6.1.jar'
def poijobs = [ def poijobs = [
[ name: 'POI-DSL-1.8', [ name: 'POI-DSL-1.8', trigger: 'H */12 * * *'
jdk: '1.8',
trigger: 'H */12 * * *',
jenkinsLite: true,
disabled: true // JDK 8 is no longer supported by POI 6
], ],
[ name: 'POI-DSL-1.8-branch-5.5.x', [ name: 'POI-DSL-OpenJDK', jdk: 'OpenJDK 1.8', trigger: 'H */12 * * *',
jdk: '1.8', // only a limited set of nodes still have OpenJDK 8 (on Ubuntu) installed
branch: '5.5.x', slaves: 'ubuntu',
trigger: 'H */12 * * *', skipcigame: true
jenkinsLite: true,
], ],
// [ name: 'POI-DSL-1.10', jdk: '1.10', trigger: triggerSundays, skipcigame: true,
// // let's save some CPU cycles here, 10 had EOL in September 2018
// disabled: true
// ],
[ name: 'POI-DSL-1.11', jdk: '1.11', trigger: triggerSundays, skipcigame: true [ name: 'POI-DSL-1.11', jdk: '1.11', trigger: triggerSundays, skipcigame: true
], ],
// [ name: 'POI-DSL-1.12', jdk: '1.12', trigger: triggerSundays, skipcigame: true,
// // let's save some CPU cycles here, 12 is not a LTS and JDK 13 is GA as of 17 September 2019
// disabled: true
// ],
// [ name: 'POI-DSL-1.13', jdk: '1.13', trigger: triggerSundays, skipcigame: true,
// // let's save some CPU cycles here, 13 is not a LTS and JDK 14 is GA as of 17 March 2020
// disabled: true
// ],
// [ name: 'POI-DSL-1.14', jdk: '1.14', trigger: triggerSundays, skipcigame: true,
// // let's save some CPU cycles here, 14 is not a LTS and JDK 15 is GA as of 15 September 2020
// disabled: true
// ],
[ name: 'POI-DSL-1.15', jdk: '1.15', trigger: triggerSundays, skipcigame: true,
// let's save some CPU cycles here, 15 is not a LTS and JDK 16 is GA
disabled: true
],
[ name: 'POI-DSL-1.16', jdk: '1.16', trigger: 'H */12 * * *', skipcigame: true,
// let's save some CPU cycles here, 16 is not a LTS and JDK 17 is GA
disabled: true
],
[ name: 'POI-DSL-1.17', jdk: '1.17', trigger: 'H */12 * * *', skipcigame: true [ name: 'POI-DSL-1.17', jdk: '1.17', trigger: 'H */12 * * *', skipcigame: true
], ],
[ name: 'POI-DSL-1.21', jdk: '1.21', trigger: 'H */12 * * *', skipcigame: true [ name: 'POI-DSL-1.18', jdk: '1.18', trigger: triggerSundays, skipcigame: true
], ],
[ name: 'POI-DSL-1.24', jdk: '1.24', trigger: triggerSundays, skipcigame: true, // Use Ant build for as Gradle 7.5 does not support Java 19 yet (change to gradle: true when we have Gradle support)
], [ name: 'POI-DSL-1.19', jdk: '1.19', trigger: triggerSundays, skipcigame: true, useAnt: true
[ name: 'POI-DSL-1.25', jdk: '1.25', trigger: triggerSundays, skipcigame: true, skipSpotbugs: true,
// use Ant for building until Gradle supports JDK 25
// see https://docs.gradle.org/current/userguide/compatibility.html
// and https://github.com/gradle/gradle/issues/31625
useAnt: true
], ],
// Use Ant-build for now as selecting IBM JDK via toolchain does not work (yet) // Use Ant-build for now as selecting IBM JDK via toolchain does not work (yet)
[ name: 'POI-DSL-IBM-JDK', jdk: 'IBMJDK', trigger: triggerSundays, skipcigame: true, useAnt: true [ name: 'POI-DSL-IBM-JDK', jdk: 'IBMJDK', trigger: triggerSundays, skipcigame: true, useAnt: true
@ -66,11 +63,17 @@ def poijobs = [
// the property triggers using Xerces as XML Parser and previously showed some exception that can occur // the property triggers using Xerces as XML Parser and previously showed some exception that can occur
properties: ["-Dadditionaljar=${xercesLib}"] properties: ["-Dadditionaljar=${xercesLib}"]
], ],
// [ name: 'POI-DSL-Maven', trigger: 'H */4 * * *', maven: true,
// // not needed any more now that we use Gradle for SonarQube
// disabled: true
// ],
[ name: 'POI-DSL-regenerate-javadoc', trigger: triggerSundays, javadoc: true [ name: 'POI-DSL-regenerate-javadoc', trigger: triggerSundays, javadoc: true
], ],
// it was impossible to make this run stable in Gradle, thus disabling this for now // it was impossible to make this run stable in Gradle, thus disabling this for now
[ name: 'POI-DSL-API-Check', trigger: '@daily', apicheck: true, disabled: true, useAnt: true [ name: 'POI-DSL-API-Check', trigger: '@daily', apicheck: true, disabled: true, useAnt: true
], ],
// [ name: 'POI-DSL-Gradle', trigger: triggerSundays, email: 'centic@apache.org'
// ],
[ name: 'POI-DSL-no-scratchpad', trigger: triggerSundays, noScratchpad: true [ name: 'POI-DSL-no-scratchpad', trigger: triggerSundays, noScratchpad: true
], ],
[ name: 'POI-DSL-saxon-test', trigger: triggerSundays, saxonTest: true [ name: 'POI-DSL-saxon-test', trigger: triggerSundays, saxonTest: true
@ -80,32 +83,34 @@ def poijobs = [
// // replaced by Gradle-based build now // // replaced by Gradle-based build now
// disabled: true // disabled: true
// ], // ],
[ name: 'POI-DSL-SonarQube-Gradle', jdk: '1.17', trigger: 'H 7 * * *', sonar: true, skipcigame: true [ name: 'POI-DSL-SonarQube-Gradle', jdk: '1.11', trigger: 'H 7 * * *', sonar: true, skipcigame: true
], ],
[ name: 'POI-DSL-Windows-1.8', [ name: 'POI-DSL-Windows-1.8', trigger: 'H */12 * * *', windows: true, slaves: 'Windows'
trigger: 'H */12 * * *',
windows: true,
slaves: 'Windows',
jenkinsLite: true,
disabled: true // JDK 8 is no longer supported by POI 6
], ],
[ name: 'POI-DSL-Windows-1.11', jdk: '1.11', trigger: triggerSundays, windows: true, slaves: 'Windows', // [ name: 'POI-DSL-Windows-1.12', jdk: '1.12', trigger: triggerSundays, windows: true, slaves: 'Windows', skipcigame: true,
jenkinsLite: true // // let's save some CPU cycles here, 12 is not a LTS and JDK 13 is GA now
// disabled: true
// ],
// [ name: 'POI-DSL-Windows-1.14', jdk: '1.14', trigger: triggerSundays, windows: true, slaves: 'Windows', skipcigame: true,
// // let's only verify the latest two JDKs
// disabled: true
// ],
[ name: 'POI-DSL-Windows-1.15', jdk: '1.15', trigger: triggerSundays, windows: true, slaves: 'Windows', skipcigame: true,
// let's save some CPU cycles here, 14 is not a LTS and JDK 15 is GA as of 15 September 2020
disabled: true
],
[ name: 'POI-DSL-Windows-1.16', jdk: '1.16', trigger: 'H */12 * * *', windows: true, slaves: 'Windows', skipcigame: true,
// let's save some CPU cycles here, 16 is not a LTS and JDK 17 is GA
disabled: true
], ],
[ name: 'POI-DSL-Windows-1.17', jdk: '1.17', trigger: 'H */12 * * *', windows: true, slaves: 'Windows', skipcigame: true [ name: 'POI-DSL-Windows-1.17', jdk: '1.17', trigger: 'H */12 * * *', windows: true, slaves: 'Windows', skipcigame: true
], ],
[ name: 'POI-DSL-Windows-1.21', jdk: '1.21', trigger: 'H */12 * * *', windows: true, slaves: 'Windows', skipcigame: true [ name: 'POI-DSL-Windows-1.18', jdk: '1.18', trigger: triggerSundays, windows: true, slaves: 'Windows', skipcigame: true
], ],
[ name: 'POI-DSL-Windows-1.24', jdk: '1.24', trigger: triggerSundays, windows: true, slaves: 'Windows', skipcigame: true, [ name: 'POI-DSL-Github-PullRequests', trigger: '', githubpr: true, skipcigame: true,
], // ensure the file which is needed from the separate documentation module does exist
[ name: 'POI-DSL-Windows-1.25', jdk: '1.25', trigger: triggerSundays, windows: true, slaves: 'Windows', skipcigame: true, // as we are checking out from git, we do not have the reference checked out here
skipSpotbugs: true, addShell: 'mkdir -p src/documentation\ntouch src/documentation/RELEASE-NOTES.txt'
// use Ant for building until Gradle supports JDK 24
// see https://docs.gradle.org/current/userguide/compatibility.html
// and https://github.com/gradle/gradle/issues/31625
useAnt: true
],
[ name: 'POI-DSL-Github-PullRequests', trigger: '', skipcigame: true, disabled: true
], ],
] ]
@ -114,25 +119,23 @@ def xmlbeansjobs = [
], ],
[ name: 'POI-XMLBeans-DSL-1.11', jdk: '1.11', trigger: triggerSundays, skipcigame: true, [ name: 'POI-XMLBeans-DSL-1.11', jdk: '1.11', trigger: triggerSundays, skipcigame: true,
], ],
[ name: 'POI-XMLBeans-DSL-1.17', jdk: '1.17', trigger: 'H */12 * * *', skipcigame: true, [ name: 'POI-XMLBeans-DSL-1.16', jdk: '1.16', trigger: triggerSundays, skipcigame: true,
], // let's save some CPU cycles here, 16 is not a LTS and JDK 17 is GA
[ name: 'POI-XMLBeans-DSL-1.21', jdk: '1.21', trigger: 'H */12 * * *', skipcigame: true,
],
[ name: 'POI-XMLBeans-DSL-1.24', jdk: '1.24', trigger: triggerSundays, skipcigame: true,
disabled: true disabled: true
], ],
[ name: 'POI-XMLBeans-DSL-1.25', jdk: '1.25', trigger: triggerSundays, skipcigame: true, [ name: 'POI-XMLBeans-DSL-1.17', jdk: '1.17', trigger: triggerSundays, skipcigame: true,
], ],
[ name: 'POI-XMLBeans-DSL-Sonar', jdk: '1.17', trigger: triggerSundays, skipcigame: true, [ name: 'POI-XMLBeans-DSL-1.18', jdk: '1.18', trigger: triggerSundays, skipcigame: true,
],
[ name: 'POI-XMLBeans-DSL-Sonar', jdk: '1.11', trigger: triggerSundays, skipcigame: true,
sonar: true sonar: true
] ]
] ]
def gitBase = 'https://github.com/apache/poi.git' def svnBase = 'https://svn.apache.org/repos/asf/poi/trunk'
def xmlbeansGitBase = 'https://github.com/apache/xmlbeans.git' def xmlbeansSvnBase = 'https://svn.apache.org/repos/asf/xmlbeans/trunk'
def defaultJdk = '1.11' def defaultJdk = '1.8'
def defaultBranch = 'trunk'
def defaultTrigger = 'H/15 * * * *' // check SCM every 60/15 = 4 minutes def defaultTrigger = 'H/15 * * * *' // check SCM every 60/15 = 4 minutes
def defaultEmail = 'dev@poi.apache.org' def defaultEmail = 'dev@poi.apache.org'
def defaultAnt = 'ant_1.10_latest' def defaultAnt = 'ant_1.10_latest'
@ -142,14 +145,19 @@ def defaultMaven = 'maven_3_latest'
def defaultSlaves = '(ubuntu)&&!beam&&!cloud-slave&&!H29' def defaultSlaves = '(ubuntu)&&!beam&&!cloud-slave&&!H29'
def jdkMapping = [ def jdkMapping = [
'1.8': [ jenkinsJdk: 'jdk_1.8_latest', jdkVersion: 8, jdkVendor: '' ], '1.8': [ jenkinsJdk: 'jdk_1.8_latest', jdkVersion: 8, jdkVendor: 'oracle' ],
'1.11': [ jenkinsJdk: 'jdk_11_latest', jdkVersion: 11, jdkVendor: '' ], '1.10': [ jenkinsJdk: 'jdk_10_latest', jdkVersion: 10, jdkVendor: 'oracle' ],
'1.11': [ jenkinsJdk: 'jdk_11_latest', jdkVersion: 11, jdkVendor: 'oracle' ],
'1.12': [ jenkinsJdk: 'jdk_12_latest', jdkVersion: 12, jdkVendor: '' ],
'1.13': [ jenkinsJdk: 'jdk_13_latest', jdkVersion: 13, jdkVendor: '' ],
'1.14': [ jenkinsJdk: 'jdk_14_latest', jdkVersion: 14, jdkVendor: '' ],
'1.15': [ jenkinsJdk: 'jdk_15_latest', jdkVersion: 15, jdkVendor: '' ],
'1.16': [ jenkinsJdk: 'jdk_16_latest', jdkVersion: 16, jdkVendor: '' ],
'1.17': [ jenkinsJdk: 'jdk_17_latest', jdkVersion: 17, jdkVendor: '' ], '1.17': [ jenkinsJdk: 'jdk_17_latest', jdkVersion: 17, jdkVendor: '' ],
'1.21': [ jenkinsJdk: 'jdk_21_latest', jdkVersion: 21, jdkVendor: '' ], '1.18': [ jenkinsJdk: 'jdk_18_latest', jdkVersion: 18, jdkVendor: '' ],
'1.24': [ jenkinsJdk: 'jdk_24_latest', jdkVersion: 24, jdkVendor: '' ], '1.19': [ jenkinsJdk: 'jdk_19_latest', jdkVersion: 19, jdkVendor: '' ],
'1.25': [ jenkinsJdk: 'jdk_25_latest', jdkVersion: 25, jdkVendor: '' ], 'OpenJDK 1.8': [ jenkinsJdk: 'adoptopenjdk_hotspot_8u282', jdkVersion: 8, jdkVendor: 'adoptopenjdk' ],
// one of the few IBM JDKs that is still supported on ci-builds.apache.org 'IBMJDK': [ jenkinsJdk: 'ibmjdk_1.8.0_261', jdkVersion: 8, jdkVendor: 'ibm' ]
'IBMJDK': [ jenkinsJdk: 'ibm_semeru_21.0.2_13', jdkVersion: 21, jdkVendor: 'ibm' ]
] ]
static def shellEx(def context, String cmd, def poijob) { static def shellEx(def context, String cmd, def poijob) {
@ -167,7 +175,7 @@ Apache POI - the Java API for Microsoft Documents
</p> </p>
<p> <p>
<b>This is an automatically generated Job Config, do not edit it here! <b>This is an automatically generated Job Config, do not edit it here!
Instead change the Jenkins Job DSL at <a href="https://github.com/apache/poi/blob/trunk/jenkins/">https://github.com/apache/poi/blob/trunk/jenkins/</a>, Instead change the Jenkins Job DSL at <a href="https://svn.apache.org/repos/asf/poi/trunk/jenkins">https://svn.apache.org/repos/asf/poi/trunk/jenkins</a>,
see <a href="https://github.com/jenkinsci/job-dsl-plugin/wiki">https://github.com/jenkinsci/job-dsl-plugin/wiki</a> see <a href="https://github.com/jenkinsci/job-dsl-plugin/wiki">https://github.com/jenkinsci/job-dsl-plugin/wiki</a>
for more details about the DSL.</b> for more details about the DSL.</b>
</p>''' </p>'''
@ -186,9 +194,9 @@ def apicheckDesc = '''
def sonarDesc = ''' def sonarDesc = '''
<p> <p>
<b><a href="lastSuccessfulBuild/spotbugs/" target="_blank">Spotbugs report of latest build</a></b> - <b><a href="lastSuccessfulBuild/findbugsResult/" target="_blank">Findbugs report of latest build</a></b> -
<b><a href="https://sonarcloud.io/dashboard?id=poi-parent" target="_blank">Sonar reports</a></b> - <b><a href="https://sonarcloud.io/dashboard?id=poi-parent" target="_blank">Sonar reports</a></b> -
<b><a href="lastSuccessfulBuild/jacoco/" target="_blank">Coverage of latest build</a></b> <b><a href="lastSuccessfulBuild/artifact/build/coverage/index.html" target="_blank">Coverage of latest build</a></b>
</p> </p>
''' '''
@ -197,9 +205,10 @@ def shellCmdsUnix =
rm -rf examples excelant integrationtest main ooxml ooxml-schema scratchpad build.javacheck.xml rm -rf examples excelant integrationtest main ooxml ooxml-schema scratchpad build.javacheck.xml
# show which files are currently modified in the working copy # show which files are currently modified in the working copy
git status || true svn status || true
# make sure no changed module-class-files or ooxml-lite-report-files are lingering on # make sure no changed module-class-files or ooxml-lite-report-files are lingering on
git reset --hard || true svn revert poi*/src/*/java9/module-info.* || true
svn revert src/resources/ooxml-lite-report.* || true
# print out information about which exact version of java we are using # print out information about which exact version of java we are using
echo Java-Home: $JAVA_HOME echo Java-Home: $JAVA_HOME
@ -232,9 +241,9 @@ exit 0'''
def shellCmdsWin = def shellCmdsWin =
'''@echo off '''@echo off
:: show which files are currently modified in the working copy :: show which files are currently modified in the working copy
git status svn status
:: make sure no changed module-class-files are lingering on :: make sure no changed module-class-files are lingering on
git reset --hard svn revert poi*\\src\\*\\java9\\module-info.*
:: print out information about which exact version of java we are using :: print out information about which exact version of java we are using
echo Java-Home: %JAVA_HOME% echo Java-Home: %JAVA_HOME%
@ -252,7 +261,6 @@ poijobs.each { poijob ->
def email = poijob.email ?: defaultEmail def email = poijob.email ?: defaultEmail
def slaves = poijob.slaves ?: defaultSlaves + (poijob.slaveAdd ?: '') def slaves = poijob.slaves ?: defaultSlaves + (poijob.slaveAdd ?: '')
def antRT = poijob.windows ? defaultAntWindows : defaultAnt def antRT = poijob.windows ? defaultAntWindows : defaultAnt
def checkoutBranch = poijob.branch ?: defaultBranch
job('POI/' + poijob.name) { job('POI/' + poijob.name) {
if (poijob.disabled) { if (poijob.disabled) {
@ -268,6 +276,11 @@ poijobs.each { poijob ->
environmentVariables { environmentVariables {
env('LANG', 'en_US.UTF-8') env('LANG', 'en_US.UTF-8')
env('CI_BUILD', 'TRUE') env('CI_BUILD', 'TRUE')
if(jdkKey == '1.10') {
// when using JDK 9/10 for running Ant, we need to provide more modules for the forbidden-api-checks task
// on JDK 11 and newer there is no such module any more, so do not add it here
env('ANT_OPTS', '--add-modules=java.xml.bind --add-opens=java.xml/com.sun.org.apache.xerces.internal.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED')
}
env('FORREST_HOME', poijob.windows ? 'f:\\jenkins\\tools\\forrest\\latest' : '/home/jenkins/tools/forrest/latest') env('FORREST_HOME', poijob.windows ? 'f:\\jenkins\\tools\\forrest\\latest' : '/home/jenkins/tools/forrest/latest')
} }
@ -297,17 +310,50 @@ poijobs.each { poijob ->
} }
jdk(jdkMapping.get(jdkKey).jenkinsJdk) jdk(jdkMapping.get(jdkKey).jenkinsJdk)
scm { scm {
git { if (poijob.githubpr) {
remote { git {
url(gitBase) remote {
github('apache/poi')
refspec('+refs/pull/*:refs/remotes/origin/pr/*')
}
branch('${sha1}')
}
} else {
svn(svnBase) { svnNode ->
svnNode / browser(class: 'hudson.scm.browsers.ViewSVN') /
url << 'https://svn.apache.org/viewcvs.cgi/?root=Apache-SVN'
} }
branch("*/${checkoutBranch}")
} }
} }
checkoutRetryCount(3) checkoutRetryCount(3)
triggers { if (poijob.githubpr) {
scm(trigger) throttleConcurrentBuilds {
maxPerNode(1)
maxTotal(1)
}
parameters {
/* plugin not available:
gitParam('sha1') {
description('Pull request')
type('BRANCH')
}*/
stringParam('sha1', 'origin/pr/9/head', 'Provide a branch-spec, e.g. origin/pr/9/head')
}
triggers {
pullRequestBuildTrigger()
/*githubPullRequest {
admins(['centic9', 'poi-benchmark', 'tballison', 'gagravarr', 'onealj', 'pjfanning', 'Alain-Bearez'])
userWhitelist(['centic9', 'poi-benchmark', 'tballison', 'gagravarr', 'onealj', 'pjfanning', 'Alain-Bearez'])
orgWhitelist(['apache'])
cron('H/5 * * * *')
triggerPhrase('OK to test')
}*/
}
} else {
triggers {
scm(trigger)
}
} }
def shellcmds = (poijob.windows ? shellCmdsWin : shellCmdsUnix).replace('POIJOBSHELL', poijob.shell ?: '') def shellcmds = (poijob.windows ? shellCmdsWin : shellCmdsUnix).replace('POIJOBSHELL', poijob.shell ?: '')
@ -339,7 +385,7 @@ poijobs.each { poijob ->
gradle { gradle {
switches('-PenableSonar') switches('-PenableSonar')
switches('-Dsonar.token=${POI_SONAR_TOKEN}') switches('-Dsonar.login=${POI_SONAR_TOKEN}')
switches('-Dsonar.organization=apache') switches('-Dsonar.organization=apache')
switches('-Dsonar.projectKey=poi-parent') switches('-Dsonar.projectKey=poi-parent')
switches('-Dsonar.host.url=https://sonarcloud.io') switches('-Dsonar.host.url=https://sonarcloud.io')
@ -350,26 +396,26 @@ poijobs.each { poijob ->
tasks('clean') tasks('clean')
tasks('check') tasks('check')
tasks('jacocoTestReport') tasks('jacocoTestReport')
tasks('sonar') tasks('sonarqube')
useWrapper(true) useWrapper(true)
} }
} }
publishers { publishers {
// in archive, junit and jacoco publishers, matches beneath build/*/build/... are for Gradle-build results // in archive, junit and jacoco publishers, matches beneath build/*/build/... are for Gradle-build results
archiveArtifacts('build/dist/*.tar.gz,*/build/reports/**,poi-integration/build/test-results/**,*/build/libs/*.jar') archiveArtifacts('build/dist/*.tar.gz,*/build/reports/**,poi-integration/build/test-results/**,*/build/libs/*.jar')
archiveJunit('*/build/test-results/**/TEST-*.xml') { archiveJunit('*/build/test-results/**/TEST-*.xml') {
testDataPublishers { testDataPublishers {
publishTestStabilityData() publishTestStabilityData()
} }
} }
jacocoCodeCoverage { jacocoCodeCoverage {
classPattern('*/build/classes') classPattern('*/build/classes')
execPattern('*/build/*.exec,*/build/jacoco/*.exec') execPattern('*/build/*.exec,*/build/jacoco/*.exec')
sourcePattern('*/src/main/java') sourcePattern('*/src/main/java')
exclusionPattern('com/microsoft/**,org/openxmlformats/**,org/etsi/**,org/w3/**,schemaorg*/**,schemasMicrosoft*/**,org/apache/poi/hdf/model/hdftypes/definitions/*.class,org/apache/poi/hwpf/model/types/*.class,org/apache/poi/hssf/usermodel/DummyGraphics2d.class,org/apache/poi/sl/draw/binding/*.class') exclusionPattern('com/microsoft/**,org/openxmlformats/**,org/etsi/**,org/w3/**,schemaorg*/**,schemasMicrosoft*/**,org/apache/poi/hdf/model/hdftypes/definitions/*.class,org/apache/poi/hwpf/model/types/*.class,org/apache/poi/hssf/usermodel/DummyGraphics2d.class,org/apache/poi/sl/draw/binding/*.class')
} }
if (!poijob.skipcigame) { if (!poijob.skipcigame) {
configure { project -> configure { project ->
project / publishers << 'hudson.plugins.cigame.GamePublisher' {} project / publishers << 'hudson.plugins.cigame.GamePublisher' {}
} }
@ -390,11 +436,7 @@ poijobs.each { poijob ->
} }
gradle { gradle {
if (poijob.jenkinsLite) { tasks('clean jenkins')
tasks('clean jenkinsLite')
} else {
tasks('clean jenkins')
}
useWrapper(true) useWrapper(true)
if (poijob.noScratchpad) { if (poijob.noScratchpad) {
switches('-Pscratchpad.ignore=true') switches('-Pscratchpad.ignore=true')
@ -411,51 +453,44 @@ poijobs.each { poijob ->
} else { } else {
ant { ant {
targets(['clean', 'jenkins'] + (poijob.properties ?: [])) targets(['clean', 'jenkins'] + (poijob.properties ?: []))
prop('coverage.enabled', !poijob.skipSpotbugs) prop('coverage.enabled', true)
// Properties did not work, so I had to use targets instead // Properties did not work, so I had to use targets instead
//properties(poijob.properties ?: '') //properties(poijob.properties ?: '')
antInstallation(antRT) antInstallation(antRT)
} }
if(!poijob.skipSourceBuild) { ant {
ant { targets(['run'] + (poijob.properties ?: []))
targets(['run'] + (poijob.properties ?: [])) buildFile('poi-integration/build.xml')
buildFile('poi-integration/build.xml') // Properties did not work, so I had to use targets instead
// Properties did not work, so I had to use targets instead //properties(poijob.properties ?: '')
//properties(poijob.properties ?: '') antInstallation(antRT)
antInstallation(antRT)
}
} }
} }
} }
publishers { publishers {
if (!poijob.skipSpotbugs) { recordIssues {
recordIssues { tools {
tools { spotBugs {
spotBugs { pattern('*/build/reports/spotbugs/*.xml')
pattern('*/build/reports/spotbugs/*.xml') reportEncoding('UTF-8')
reportEncoding('UTF-8')
}
} }
} }
} }
// in archive, junit and jacoco publishers, matches beneath build/*/build/... are for Gradle-build results // in archive, junit and jacoco publishers, matches beneath build/*/build/... are for Gradle-build results
archiveArtifacts('build/dist/*.zip,build/dist/*.tgz,build/dist/maven/*/*.jar,build/dist/maven/*/*.pom,build/dist/maven/*/*.asc,build/dist/maven/*/*.sha256,build/dist/maven/*/*.sha512,build/coverage/**,*/build/reports/*.bom.*,build/hs_err*.log') archiveArtifacts('build/dist/*.zip,build/dist/*.tgz,build/dist/maven/*/*.jar,build/coverage/**,build/hs_err*.log')
/* this plugin is currently missing on the Apache Jenkins instance
warnings(['Java Compiler (javac)', 'JavaDoc Tool'], null) { warnings(['Java Compiler (javac)', 'JavaDoc Tool'], null) {
resolveRelativePaths() resolveRelativePaths()
} */ }
archiveJunit('*/build/test-results/**/TEST-*.xml') { archiveJunit('*/build/test-results/**/TEST-*.xml') {
testDataPublishers { testDataPublishers {
publishTestStabilityData() publishTestStabilityData()
} }
} }
if (!poijob.skipSpotbugs) { jacocoCodeCoverage {
jacocoCodeCoverage { classPattern('*/build/classes')
classPattern('*/build/classes') execPattern('*/build/*.exec,*/build/jacoco/*.exec')
execPattern('*/build/*.exec,*/build/jacoco/*.exec') sourcePattern('*/src/main/java')
sourcePattern('*/src/main/java') exclusionPattern('com/microsoft/**,org/openxmlformats/**,org/etsi/**,org/w3/**,schemaorg*/**,schemasMicrosoft*/**,org/apache/poi/hdf/model/hdftypes/definitions/*.class,org/apache/poi/hwpf/model/types/*.class,org/apache/poi/hssf/usermodel/DummyGraphics2d.class,org/apache/poi/sl/draw/binding/*.class')
exclusionPattern('com/microsoft/**,org/openxmlformats/**,org/etsi/**,org/w3/**,schemaorg*/**,schemasMicrosoft*/**,org/apache/poi/hdf/model/hdftypes/definitions/*.class,org/apache/poi/hwpf/model/types/*.class,org/apache/poi/hssf/usermodel/DummyGraphics2d.class,org/apache/poi/sl/draw/binding/*.class')
}
} }
if (!poijob.skipcigame) { if (!poijob.skipcigame) {
@ -467,6 +502,15 @@ poijobs.each { poijob ->
} }
} }
if (poijob.githubpr) {
configure {
it / 'properties' << 'com.cloudbees.jenkins.plugins.git.vmerge.JobPropertyImpl'(plugin: 'git-validated-merge') {
credentialsId('ASF_Cloudbees_Jenkins_ci-builds')
postBuildPushFailureHandler(class: 'com.cloudbees.jenkins.plugins.git.vmerge.pbph.PushFailureIsFailure')
}
}
}
} }
} }
@ -490,8 +534,11 @@ xmlbeansjobs.each { xjob ->
label(slaves) label(slaves)
environmentVariables { environmentVariables {
env('LANG', 'en_US.UTF-8') env('LANG', 'en_US.UTF-8')
if (jdkKey == '1.11' || jdkKey == '1.17' || jdkKey == '1.21' if(jdkKey == '1.10') {
|| jdkKey == '1.23' || jdkKey == '1.24' || jdkKey == '1.25') { // when using JDK 9/10 for running Ant, we need to provide more modules for the forbidden-api-checks task
// on JDK 11 and newer there is no such module any more, so do not add it here
env('ANT_OPTS', '--add-modules=java.xml.bind --add-opens=java.xml/com.sun.org.apache.xerces.internal.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED')
} else if (jdkKey == '1.11' || jdkKey == '1.12' || jdkKey == '1.13' || jdkKey == '1.14' || jdkKey == '1.15' || jdkKey == '1.16' || jdkKey == '1.17' || jdkKey == '1.18' || jdkKey == '1.19') {
env('ANT_OPTS', '--add-opens=java.xml/com.sun.org.apache.xerces.internal.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED') env('ANT_OPTS', '--add-opens=java.xml/com.sun.org.apache.xerces.internal.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED')
} }
// will be needed for forbidden-apis-check: env('ANT_HOME', xjob.windows ? 'f:\\jenkins\\tools\\ant\\latest' : '/usr/share/ant') // will be needed for forbidden-apis-check: env('ANT_HOME', xjob.windows ? 'f:\\jenkins\\tools\\ant\\latest' : '/usr/share/ant')
@ -514,11 +561,9 @@ xmlbeansjobs.each { xjob ->
} }
jdk(jdkMapping.get(jdkKey).jenkinsJdk) jdk(jdkMapping.get(jdkKey).jenkinsJdk)
scm { scm {
git { svn(xmlbeansSvnBase) { svnNode ->
remote { svnNode / browser(class: 'hudson.scm.browsers.ViewSVN') /
url(xmlbeansGitBase) url << 'https://svn.apache.org/viewcvs.cgi/?root=Apache-SVN'
}
branch('*/trunk')
} }
} }
checkoutRetryCount(3) checkoutRetryCount(3)
@ -539,7 +584,7 @@ xmlbeansjobs.each { xjob ->
gradle { gradle {
if (xjob.sonar) { if (xjob.sonar) {
switches('-PenableSonar') switches('-PenableSonar')
switches('-Dsonar.token=${POI_SONAR_TOKEN}') switches('-Dsonar.login=${POI_SONAR_TOKEN}')
switches('-Dsonar.organization=apache') switches('-Dsonar.organization=apache')
switches('-Dsonar.projectKey=apache_xmlbeans') switches('-Dsonar.projectKey=apache_xmlbeans')
switches('-Dsonar.host.url=https://sonarcloud.io') switches('-Dsonar.host.url=https://sonarcloud.io')
@ -552,18 +597,17 @@ xmlbeansjobs.each { xjob ->
tasks('jenkins') tasks('jenkins')
tasks('jacocoTestReport') tasks('jacocoTestReport')
if (xjob.sonar) { if (xjob.sonar) {
tasks('sonar') tasks('sonarqube')
} }
useWrapper(true) useWrapper(true)
} }
} }
publishers { publishers {
archiveArtifacts('build/libs/xmlbeans*.jar,build/distributions/*,build/reports/*.bom.*,build/hs_err*.log') archiveArtifacts('build/libs/xmlbeans*.jar,build/distributions/*,build/hs_err*.log')
/* this plugin is currently missing on the Apache Jenkins instance
warnings(['Java Compiler (javac)', 'JavaDoc Tool'], null) { warnings(['Java Compiler (javac)', 'JavaDoc Tool'], null) {
resolveRelativePaths() resolveRelativePaths()
} */ }
archiveJunit('build/test-results/test/TEST-*.xml') { archiveJunit('build/test-results/test/TEST-*.xml') {
testDataPublishers { testDataPublishers {
publishTestStabilityData() publishTestStabilityData()
@ -611,56 +655,60 @@ Unfortunately we often see builds break because of changes/new machines...''')
} }
axes { axes {
jdk( jdk(
'jdk_8_latest', 'jdk_1.8_latest',
'jdk_10_latest',
'jdk_11_latest', 'jdk_11_latest',
/* don't look for JDKs that are out of support
'jdk_12_latest',
'jdk_13_latest',
'jdk_14_latest',
'jdk_15_latest',
'jdk_16_latest',*/
'jdk_17_latest', 'jdk_17_latest',
'jdk_21_latest', 'jdk_18_latest',
'jdk_23_latest', 'jdk_19_latest',
'jdk_24_latest', 'adoptopenjdk_hotspot_8u282',
'jdk_25_latest', 'ibmjdk_1.8.0_261'
'jdk_26_latest',
'ibm_semeru_21.0.2_13'
) )
// Note H50 is reserved according to its node-description // Note H50 is reserved according to it's node-descripion
label('Nodes','builds22','builds23','builds24','builds25','builds26','builds27','builds28','builds29','builds30','builds31','builds32','builds33','builds34','builds35','builds36','builds37','builds38','builds39','builds40','builds50','builds56','builds57','builds58','builds59','builds60', label('Nodes','H22','H23','H24','H25','H26','H27','H28','H29','H30','H31','H32','H33','H34','H35','H36','H37','H38','H39','H40','H41','H42','H43','H44','H48','lucene1','lucene2','master')
'jenkins-win-azr-1','jenkins-win-azr-2','jenkins-win-azr-3','jenkins-win-azr-4','jenkins-win-azr-5','jenkins-win-azr-6','jenkins-win-azr-7','jenkins-win-azr-8','jenkins-win-azr-10','jenkins-win-azr-11','jenkins-win-azr-12')
} }
steps { steps {
conditionalSteps { conditionalSteps {
condition { condition {
fileExists('/usr', BaseDir.WORKSPACE) fileExists('/usr', BaseDir.WORKSPACE)
} }
runner('DontRun') runner('DontRun')
steps { steps {
shell( shell(
'''which git || true '''which svn || true
which javac which javac
javac -version javac -version
echo '<?xml version="1.0"?><project name="POI Build" default="test"><target name="test"><echo>Using Ant: ${ant.version} from ${ant.home}</echo></target></project>' > build.xml echo '<?xml version="1.0"?><project name="POI Build" default="test"><target name="test"><echo>Using Ant: ${ant.version} from ${ant.home}</echo></target></project>' > build.xml
''') ''')
ant { ant {
antInstallation(defaultAnt) antInstallation(defaultAnt)
} }
shell( shell(
'''which mvn || true '''which mvn || true
mvn -version || true mvn -version || true
echo '<project><modelVersion>4.0.0</modelVersion><groupId>org.apache.poi</groupId><artifactId>build-tst</artifactId><version>1.0.0</version></project>' > pom.xml echo '<project><modelVersion>4.0.0</modelVersion><groupId>org.apache.poi</groupId><artifactId>build-tst</artifactId><version>1.0.0</version></project>' > pom.xml
''') ''')
maven { maven {
goals('package') goals('package')
mavenInstallation(defaultMaven) mavenInstallation(defaultMaven)
} }
} }
} }
conditionalSteps { conditionalSteps {
condition { condition {
fileExists('c:\\windows', BaseDir.WORKSPACE) fileExists('c:\\windows', BaseDir.WORKSPACE)
} }
runner('DontRun') runner('DontRun')
steps { steps {
batchFile( batchFile(
'''@echo off '''@echo off
echo . echo .
where javac.exe where javac.exe
echo . echo .
@ -668,10 +716,71 @@ javac -version
echo . echo .
echo ^<?xml version=^"1.0^"?^>^<project name=^"POI Build^" default=^"test^"^>^<target name=^"test^"^>^<echo^>Using Ant: ${ant.version} from ${ant.home}, ant detected Java ${ant.java.version} (may be different than actual Java sometimes...), using Java: ${java.version}/${java.runtime.version}/${java.vm.version}/${java.vm.name} from ${java.vm.vendor} on ${os.name}: ${os.version}^</echo^>^</target^>^</project^> > build.xml echo ^<?xml version=^"1.0^"?^>^<project name=^"POI Build^" default=^"test^"^>^<target name=^"test^"^>^<echo^>Using Ant: ${ant.version} from ${ant.home}, ant detected Java ${ant.java.version} (may be different than actual Java sometimes...), using Java: ${java.version}/${java.runtime.version}/${java.vm.version}/${java.vm.name} from ${java.vm.vendor} on ${os.name}: ${os.version}^</echo^>^</target^>^</project^> > build.xml
''') ''')
ant { ant {
antInstallation(defaultAntWindows) antInstallation(defaultAntWindows)
} }
} }
} }
} }
} }
/* I tried to put the view into a sub-folder/sub-view, but failed, there are multiple related
plugins so this is all a bit confusing :(, see also https://issues.apache.org/jira/browse/INFRA-14002
dashboardView("P/POI-new") {
columns {
status()
weather()
configureProject()
buildButton()
cronTrigger()
lastBuildConsole()
name()
lastSuccess()
lastFailure()
lastDuration()
//lastSuccessDescription()
jacoco()
}
description("<table>\n" +
" <tr>\n" +
" <td><img src=\"https://poi.apache.org/images/project-header.png\" /></td>\n" +
" <td> \n" +
" <p>Apache POI - the Java API for Microsoft Documents</p>\n" +
" <p><b>Most of the POI Jobs are automatically generated by Jenkins Job DSL\n" +
" at <a href=\"https://svn.apache.org/repos/asf/poi/trunk/jenkins\">https://svn.apache.org/repos/asf/poi/trunk/jenkins</a>,<br/>\n" +
" see <a href=\"https://github.com/jenkinsci/job-dsl-plugin/wiki\">https://github.com/jenkinsci/job-dsl-plugin/wiki</a>\n" +
" for more details about the DSL.</b>\n" +
" </p>\n" +
" <p>\n" +
" <b><a href=\"job/POI-DSL-1.8/lastSuccessfulBuild/findbugsResult/\" target=\"_blank\">Findbugs report of latest build</a></b> -\n" +
" <b><a href=\"https://sonarcloud.io/dashboard?id=poi-parent\" target=\"_blank\">Sonar reports</a></b> -\n" +
" <b><a href=\"job/POI-DSL-1.8/lastSuccessfulBuild/artifact/build/coverage/index.html\" target=\"_blank\">Coverage of latest build</a></b>\n" +
" </p>\n" +
" </td>\n" +
" </tr>\n" +
"</table>")
filterBuildQueue(false)
filterExecutors(false)
// Job selection
jobs {*/
//regex(/.*POI.*/)
/*}
// Layout
topPortlets {
jenkinsJobsList {
displayName('POI jobs')
}
}
leftPortlets {
testStatisticsChart()
}
rightPortlets {
testTrendChart()
}
bottomPortlets {
testStatisticsGrid()
buildStatistics()
}
}*/

View File

@ -222,16 +222,74 @@ Office Open XML schemas (poi-ooxml-full-*.jar)
Furthermore, both Microsoft and Adobe have granted patent licenses Furthermore, both Microsoft and Adobe have granted patent licenses
to this work [3,4,5]. to this work [3,4,5].
[1] https://www.ecma-international.org/publications/standards/Ecma-376.htm [1] http://www.ecma-international.org/publications/standards/Ecma-376.htm
[2] https://www.ecma-international.org/memento/Ecmabylaws.htm [2] http://www.ecma-international.org/memento/Ecmabylaws.htm
[3] https://www.microsoft.com/openspecifications/en/us/programs/osp/default.aspx [3] http://www.microsoft.com/openspecifications/en/us/programs/osp/default.aspx
[4] https://www.ecma-international.org/publications/files/ECMA-ST/Ecma%20PATENT/ [4] http://www.ecma-international.org/publications/files/ECMA-ST/Ecma%20PATENT/
Patent%20statements%20ok/ECMA-376%20Edition%202%20Microsoft%20Patent%20Declaration.pdf Patent%20statements%20ok/ECMA-376%20Edition%202%20Microsoft%20Patent%20Declaration.pdf
[5] https://www.ecma-international.org/publications/files/ECMA-ST/Ecma%20PATENT/ [5] http://www.ecma-international.org/publications/files/ECMA-ST/Ecma%20PATENT/
Patent%20statements%20ok/ECMA-376%20Adobe%20Patent%20Declaration.pdf Patent%20statements%20ok/ECMA-376%20Adobe%20Patent%20Declaration.pdf
org.apache.poi.util.ReplacingInputStream is based on code from Bouncy Castle library (bcprov-*.jar, bcpg-*.jar, bcpkix-*.jar)
Copyright (c) 2000 - 2021 The Legion of the Bouncy Castle Inc.
(https://www.bouncycastle.org)
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
CurvesAPI / Curve API
BSD License
Copyright (c) 2000-2015 www.hamcrest.org
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer. Redistributions in
binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution. Neither the name of Hamcrest nor
the names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Log4j 2 library (log4j-api-*.jar)
Apache License Version 2.0
inbot-utils (https://github.com/Inbot/inbot-utils) inbot-utils (https://github.com/Inbot/inbot-utils)
The MIT License (MIT) The MIT License (MIT)
@ -254,15 +312,4 @@ inbot-utils (https://github.com/Inbot/inbot-utils)
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
ExceptionUtils is derived from `scala.util.control.NonFatal` in scala-library
which was released under the Apache 2.0 license.
Copyright (c) 2002-2023 EPFL
Copyright (c) 2011-2023 Lightbend, Inc.
The POI Source Release bundles the Gradle Wrapper. (https://docs.gradle.org/current/userguide/gradle_wrapper.html)
This is released under the Apache License, v2.0.
Copyright © 2015-2021 the original authors.
The wrapper.gradle file was developed by the Apache Kafka project and is released under the Apache License, v2.0.

View File

@ -1,5 +1,5 @@
Apache POI Apache POI
Copyright 2003-2026 The Apache Software Foundation Copyright 2003-2022 The Apache Software Foundation
This product includes software developed at This product includes software developed at
The Apache Software Foundation (https://www.apache.org/). The Apache Software Foundation (https://www.apache.org/).
@ -24,13 +24,3 @@ This product contains parts of the eID Applet project
Copyright (c) 2009-2018 Copyright (c) 2009-2018
FedICT (federal ICT department of Belgium), e-Contract.be BVBA (https://www.e-contract.be), FedICT (federal ICT department of Belgium), e-Contract.be BVBA (https://www.e-contract.be),
Bart Hanssens from FedICT Bart Hanssens from FedICT
ExceptionUtils is derived from `scala.util.control.NonFatal` in scala-library
which was released under the Apache 2.0 license.
Copyright (c) 2002-2023 EPFL
Copyright (c) 2011-2023 Lightbend, Inc.
Scala includes software developed at
LAMP/EPFL (https://lamp.epfl.ch/) and
Lightbend, Inc. (https://www.lightbend.com/).

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
lib.stored/svnant-1.3.1.jar Normal file

Binary file not shown.

View File

@ -21,15 +21,15 @@ The bundle embeds all the jars from lib/main:
Required to render WMF/EMF images. The OSGi bundle is provided by ServiceMix and available in Maven Central: https://mvnrepository.com/artifact/org.apache.servicemix.bundles/org.apache.servicemix.bundles.batik/1.14_1 Required to render WMF/EMF images. The OSGi bundle is provided by ServiceMix and available in Maven Central: https://mvnrepository.com/artifact/org.apache.servicemix.bundles/org.apache.servicemix.bundles.batik/1.14_1
2. Saxon 2. Saxon
Required if using as the XSLT and XQuery Processor engine in XML Beans. Required if using as the XSLT and XQuery Processor engine in XML Beans.
Available in Maven Central: https://mvnrepository.com/artifact/net.sf.saxon/Saxon-HE/12.3 Available in Maven Central (but version might be too old): https://mvnrepository.com/artifact/net.sf.saxon/saxon/8.9.0.4-osgi
3. Apache XML Security for Java, Bouncy Castle and XML Commons Resolver 3. Apache XML Security for Java, Bouncy Castle and XML Commons Resolver
These are required to sign or validate signed Office documents. The OSGi bundles are available in Maven Central: These are required to sign or validate signed Office documents. The OSGi bundles are available in Maven Central:
- Apache XML Security for Java: https://mvnrepository.com/artifact/org.apache.santuario/xmlsec/3.0.6 - Apache XML Security for Java: https://mvnrepository.com/artifact/org.apache.santuario/xmlsec/3.0.0 (use v2.3.0 with POI v5.2.2)
- XML Commons Resolver: https://mvnrepository.com/artifact/xml-resolver/xml-resolver/1.2-osgi - XML Commons Resolver: https://mvnrepository.com/artifact/xml-resolver/xml-resolver/1.2-osgi
- Bouncy Castle: https://mvnrepository.com/artifact/org.bouncycastle/bcprov-ext-jdk18on/1.82, https://mvnrepository.com/artifact/org.bouncycastle/bcpkix-jdk18on/1.82 - Bouncy Castle: https://mvnrepository.com/artifact/org.bouncycastle/bcprov-ext-jdk15on/1.70, https://mvnrepository.com/artifact/org.bouncycastle/bcpkix-jdk15on/1.70
4. PDFBox and PDFBox Graphics2D 4. PDFBox and PDFBox Graphics2D
Required to render to PDF documents. Required to render to PDF documents.
The required jars can be downloaded from: The required jars can be downloaded from:

View File

@ -24,13 +24,13 @@
<groupId>org.apache.poi</groupId> <groupId>org.apache.poi</groupId>
<artifactId>poi-bundle</artifactId> <artifactId>poi-bundle</artifactId>
<packaging>bundle</packaging> <packaging>bundle</packaging>
<version>6.0.0-SNAPSHOT</version> <version>5.2.3</version>
<name>Apache POI OSGi bundle</name> <name>Apache POI OSGi bundle</name>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<poi.version>6.0.0-SNAPSHOT</poi.version> <poi.version>5.2.3</poi.version>
<pax.exam.version>4.14.0</pax.exam.version> <pax.exam.version>4.12.0</pax.exam.version>
</properties> </properties>
<build> <build>
@ -39,8 +39,8 @@
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version> <version>3.8.0</version>
<configuration> <configuration>
<source>11</source> <source>1.8</source>
<target>11</target> <target>1.8</target>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>
@ -176,7 +176,7 @@
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
<scope>test</scope> <scope>test</scope>
<version>4.13.2</version> <version>4.13.1</version>
</dependency> </dependency>
<!-- Pax Exam --> <!-- Pax Exam -->
@ -231,7 +231,7 @@
<dependency> <dependency>
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId> <artifactId>log4j-core</artifactId>
<version>2.25.3</version> <version>2.18.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -57,7 +57,7 @@ public class OSGiExtractorsIT extends BaseOSGiTestCase {
box.setText("Hello, World!"); box.setText("Hello, World!");
box.setAnchor(new Rectangle(36, 15, 648, 65)); box.setAnchor(new Rectangle(36, 15, 648, 65));
UnsynchronizedByteArrayOutputStream out = UnsynchronizedByteArrayOutputStream.builder().get(); UnsynchronizedByteArrayOutputStream out = new UnsynchronizedByteArrayOutputStream();
ppt.write(out); ppt.write(out);
return out.toByteArray(); return out.toByteArray();
} }
@ -66,7 +66,7 @@ public class OSGiExtractorsIT extends BaseOSGiTestCase {
Sheet s = wb.createSheet("OSGi"); Sheet s = wb.createSheet("OSGi");
s.createRow(0).createCell(0).setCellValue("Hello, World!"); s.createRow(0).createCell(0).setCellValue("Hello, World!");
UnsynchronizedByteArrayOutputStream out = UnsynchronizedByteArrayOutputStream.builder().get(); UnsynchronizedByteArrayOutputStream out = new UnsynchronizedByteArrayOutputStream();
wb.write(out); wb.write(out);
return out.toByteArray(); return out.toByteArray();

View File

@ -75,7 +75,7 @@ public class OSGiSlideShowIT extends BaseOSGiTestCase {
} }
box2.setAnchor(new Rectangle(36, 80, 648, 400)); box2.setAnchor(new Rectangle(36, 80, 648, 400));
try (UnsynchronizedByteArrayOutputStream baos = UnsynchronizedByteArrayOutputStream.builder().get()) { try (UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream()) {
ppt.write(baos); ppt.write(baos);
try (InputStream bais = baos.toInputStream()) { try (InputStream bais = baos.toInputStream()) {
ppt = SlideShowFactory.create(bais); ppt = SlideShowFactory.create(bais);

View File

@ -48,7 +48,7 @@ public class OSGiSpreadsheetIT extends BaseOSGiTestCase {
s.createRow(0).createCell(0).setCellValue("With OSGi"); s.createRow(0).createCell(0).setCellValue("With OSGi");
s.createRow(1).createCell(0).setCellFormula("SUM(A1:B3)"); s.createRow(1).createCell(0).setCellFormula("SUM(A1:B3)");
try (UnsynchronizedByteArrayOutputStream baos = UnsynchronizedByteArrayOutputStream.builder().get()) { try (UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream()) {
wb.write(baos); wb.write(baos);
try (InputStream bais = baos.toInputStream()) { try (InputStream bais = baos.toInputStream()) {
wb = WorkbookFactory.create(bais); wb = WorkbookFactory.create(bais);

View File

@ -19,7 +19,9 @@ import java.util.regex.Pattern
sourceSets { sourceSets {
main { main {
output.dir(JAVA9_OUT, builtBy: 'compileJava9') if (jdkVersion > 8) {
output.dir(JAVA9_OUT, builtBy: 'cacheJava9')
}
} }
} }
@ -35,39 +37,63 @@ dependencies {
implementation project(path: ':poi-scratchpad', configuration: 'archives') implementation project(path: ':poi-scratchpad', configuration: 'archives')
} }
implementation "org.apache.logging.log4j:log4j-api:${log4jVersion}"
testImplementation(project(path: ':poi-ooxml', configuration: 'tests')) { testImplementation(project(path: ':poi-ooxml', configuration: 'tests')) {
if (NO_SCRATCHPAD) { if (NO_SCRATCHPAD) {
exclude group: 'org.apache.poi', module: 'poi-scratchpad' exclude group: 'org.apache.poi', module: 'poi-scratchpad'
} }
} }
testImplementation project(path: ':poi', configuration: 'tests') testImplementation project(path: ':poi', configuration: 'tests')
if (SAXON_TEST) {
testRuntimeOnly "net.sf.saxon:Saxon-HE:${saxonVersion}"
}
} }
final String MODULE_NAME = 'org.apache.poi.examples' final String MODULE_NAME = 'org.apache.poi.examples'
final Pattern MODULE_REGEX = ~'\\.jar$' final Pattern MODULE_REGEX = ~'\\.jar$'
final List MODULE_COMPILE_PATH = sourceSets.main.compileClasspath.findAll{ it.path =~ MODULE_REGEX }.collect{ it.parent }.unique() final List MODULE_COMPILE_PATH = sourceSets.main.compileClasspath.findAll{ it.path =~ MODULE_REGEX }.collect{ it.parent }.unique()
tasks.register('compileJava9', JavaCompile) { task compileJava9(type: JavaCompile) {
dependsOn 'compileJava', ':poi-ooxml:jar', ':poi-scratchpad:jar' dependsOn 'compileJava', ':poi-ooxml:jar', ':poi-scratchpad:jar'
javaCompiler = javaToolchains.compilerFor { javaCompiler = javaToolchains.compilerFor {
languageVersion = JavaLanguageVersion.of(Math.max(11, jdkVersion)) languageVersion = JavaLanguageVersion.of(jdkVersion >= 17 ? 17 : 11)
if (jdkVendor != '') vendor = JvmVendorSpec.matching(jdkVendor)
} }
sourceCompatibility = 11
targetCompatibility = 11
destinationDirectory = file(JAVA9_OUT + VERSIONS9) destinationDirectory = file(JAVA9_OUT + VERSIONS9)
source = file(JAVA9_SRC) source = file(JAVA9_SRC)
classpath = files() classpath = files()
options.compilerArgs = [ options.compilerArgs = [
'--patch-module', "${MODULE_NAME}=${sourceSets.main.output.classesDirs.asPath}", '--patch-module', "${MODULE_NAME}=${sourceSets.main.output.classesDirs.asPath}",
'--module-path', files(MODULE_COMPILE_PATH).asPath '--module-path', files(MODULE_COMPILE_PATH).asPath
] ]
onlyIf {
jdkVersion > 8
}
}
task cacheJava9(type: Copy) {
dependsOn 'compileJava9'
from(file(JAVA9_OUT + VERSIONS9))
into(JAVA9_SRC)
} }
jar { jar {
dependsOn compileJava9 dependsOn cacheJava9
destinationDirectory = file("../build/dist/maven/${base.archivesName.get()}") destinationDirectory = file("../build/dist/maven/${project.archivesBaseName}")
if (jdkVersion == 8) {
into('META-INF/versions/9') {
from JAVA9_SRC include '*.class'
}
}
manifest { manifest {
attributes('Automatic-Module-Name': MODULE_NAME, 'Multi-Release': 'true') attributes('Automatic-Module-Name': MODULE_NAME, 'Multi-Release': 'true')
@ -87,22 +113,3 @@ sourcesJar {
from("$projectDir/../legal/NOTICE") from("$projectDir/../legal/NOTICE")
} }
} }
cyclonedxBom {
// includeConfigs is the list of configuration names to include when generating the BOM (leave empty to include every configuration)
includeConfigs = ["runtimeClasspath"]
// skipConfigs is a list of configuration names to exclude when generating the BOM
//skipConfigs = ["compileClasspath", "testCompileClasspath"]
// Specified the type of project being built. Defaults to 'library'
projectType = "library"
// Specified the version of the CycloneDX specification to use. Defaults to 1.4.
schemaVersion = "1.4"
// Boms destination directory (defaults to build/reports)
destination = file("build/reports")
// The file name for the generated BOMs (before the file format suffix). Defaults to 'bom'
outputName = "poi-examples-${project.version}.bom"
// The file format generated, can be xml, json or all for generating both
outputFormat = "all"
// Exclude BOM Serial Number
includeBomSerialNumber = true
}

View File

@ -36,7 +36,7 @@ WorkbookFactory.create(f,null,true).withCloseable { workbook ->
def sheet = workbook.getSheetAt(sheetNum) def sheet = workbook.getSheetAt(sheetNum)
sheet.each { row -> sheet.each { row ->
def nonEmptyCells = row.grep { c -> c.getCellType() != CellType.BLANK } def nonEmptyCells = row.grep { c -> c.getCellType() != Cell.CELL_TYPE_BLANK }
println " Row ${row.getRowNum()} has ${nonEmptyCells.size()} non-empty cells:" println " Row ${row.getRowNum()} has ${nonEmptyCells.size()} non-empty cells:"
nonEmptyCells.each { c -> nonEmptyCells.each { c ->
def cRef = [c] as CellReference def cRef = [c] as CellReference
@ -52,7 +52,7 @@ WorkbookFactory.create(f,null,true).withCloseable { workbook ->
ns1.createRow(1).createCell(0).setCellValue("TODO - Populate with data") ns1.createRow(1).createCell(0).setCellValue("TODO - Populate with data")
Sheet ns2 = workbook.createSheet("Generated 2") Sheet ns2 = workbook.createSheet("Generated 2")
exportHeader(ns2, headerStyle, "This is a demo sheet", exportHeader(ns2, headerStyle, "This is a demo sheet",
["ID","Title","Date","Author","Num"] as String[]) ["ID","Title","Date","Author","Num"] as String[])
ns2.createRow(2).createCell(0).setCellValue(1) ns2.createRow(2).createCell(0).setCellValue(1)
ns2.createRow(3).createCell(0).setCellValue(4) ns2.createRow(3).createCell(0).setCellValue(4)

View File

@ -21,11 +21,10 @@ apply plugin: 'groovy'
repositories { repositories {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
implementation 'org.codehaus.groovy:groovy-all:2.4.21' compile 'org.codehaus.groovy:groovy-all:2.4.13'
implementation 'org.apache.poi:poi:5.3.0' compile 'org.apache.poi:poi:5.0.0'
implementation 'org.apache.poi:poi-ooxml:5.3.0' compile 'org.apache.poi:poi-ooxml:5.0.0'
} }
// Our files are in the current directory // Our files are in the current directory
@ -34,11 +33,11 @@ sourceSets {
} }
// Run out read demo by default // Run out read demo by default
tasks.withType(JavaExec).configureEach { tasks.withType(JavaExec) {
classpath = sourceSets.main.runtimeClasspath classpath = sourceSets.main.runtimeClasspath
} }
tasks.register('runScript', JavaExec) { task runScript(type: JavaExec) {
mainClass = "SpreadSheetDemo" main = "SpreadSheetDemo"
args = ["../../../../test-data/spreadsheet/Simple.xls"] args = ["../../../test-data/spreadsheet/Simple.xls"]
} }
defaultTasks 'runScript' defaultTasks 'runScript'

View File

@ -1 +0,0 @@
// empty file required to have a standalone build

View File

@ -21,7 +21,7 @@ package org.apache.poi.examples.crypt;
import java.io.File; import java.io.File;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Paths;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.util.Optional; import java.util.Optional;
import java.util.function.Predicate; import java.util.function.Predicate;
@ -72,7 +72,7 @@ public final class OOXMLPasswordsTry {
}; };
// Try each password in turn, reporting progress // Try each password in turn, reporting progress
try (Stream<String> lines = Files.lines(Path.of(words))) { try (Stream<String> lines = Files.lines(Paths.get(words))) {
Optional<String> found = lines.filter(counter).filter(w -> isValid(d, w)).findFirst(); Optional<String> found = lines.filter(counter).filter(w -> isValid(d, w)).findFirst();
System.out.println(found.map(s -> "Password found: " + s).orElse("Error - No password matched")); System.out.println(found.map(s -> "Password found: " + s).orElse("Error - No password matched"));
} }

View File

@ -174,8 +174,8 @@ public final class CopyCompare {
for (int i=0; i<path.length(); i++) { for (int i=0; i<path.length(); i++) {
String subDir = path.getComponent(i); String subDir = path.getComponent(i);
if (de.hasEntryCaseInsensitive(subDir)) { if (de.hasEntry(subDir)) {
de = (DirectoryEntry)de.getEntryCaseInsensitive(subDir); de = (DirectoryEntry)de.getEntry(subDir);
} else { } else {
de = de.createDirectory(subDir); de = de.createDirectory(subDir);
if (i == path.length()-1) { if (i == path.length()-1) {

View File

@ -158,7 +158,7 @@ public final class WriteAuthorAndTitle {
for (int i=0; i<path.length(); i++) { for (int i=0; i<path.length(); i++) {
String subDir = path.getComponent(i); String subDir = path.getComponent(i);
de = (de.hasEntryCaseInsensitive(subDir)) ? (DirectoryEntry)de.getEntryCaseInsensitive(subDir) : de.createDirectory(subDir); de = (de.hasEntry(subDir)) ? (DirectoryEntry)de.getEntry(subDir) : de.createDirectory(subDir);
} }
de.createDocument(event.getName(), is); de.createDocument(event.getName(), is);

View File

@ -253,10 +253,6 @@ public class XLS2CSVmra implements HSSFListener {
// Format // Format
thisStr = formatListener.formatNumberDateCell(numrec); thisStr = formatListener.formatNumberDateCell(numrec);
if (thisStr.contains(",")) {
thisStr = '"' + thisStr + '"';
}
break; break;
case RKRecord.sid: case RKRecord.sid:
RKRecord rkrec = (RKRecord) record; RKRecord rkrec = (RKRecord) record;

View File

@ -16,21 +16,15 @@
==================================================================== */ ==================================================================== */
package org.apache.poi.ss.usermodel; package org.apache.poi.examples.hssf.usermodel;
import org.apache.poi.util.Removal;
/** /**
* The CellPropertyCategory enum represents the different categories of cell properties. * Placeholder Class - this is now handled in the Common SS example
* Each category is used to classify and organize the cell properties based on their characteristics. * @deprecated in 5.1.0 - use {@link org.apache.poi.examples.ss.AddDimensionedImage}
*
* @since 5.4.0
*/ */
public enum CellPropertyCategory { @Removal(version="6.0.0")
@Deprecated
SHORT, public class AddDimensionedImage extends org.apache.poi.examples.ss.AddDimensionedImage {
COLOR, }
INT,
BOOL,
BORDER_TYPE,
OTHER
}

View File

@ -75,7 +75,7 @@ public class EventExample implements HSSFListener {
System.out.println("Cell found with value " + numrec.getValue() System.out.println("Cell found with value " + numrec.getValue()
+ " at row " + numrec.getRow() + " and column " + numrec.getColumn()); + " at row " + numrec.getRow() + " and column " + numrec.getColumn());
break; break;
// SSTRecords store an array of unique strings used in Excel. // SSTRecords store a array of unique strings used in Excel.
case SSTRecord.sid: case SSTRecord.sid:
sstrec = (SSTRecord) record; sstrec = (SSTRecord) record;
for (int k = 0; k < sstrec.getNumUniqueStrings(); k++) for (int k = 0; k < sstrec.getNumUniqueStrings(); k++)

View File

@ -23,6 +23,7 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFCellStyle;
@ -31,7 +32,6 @@ import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.logging.PoiLogManager;
/** /**
* This class contains code that demonstrates how to insert plain, numbered * This class contains code that demonstrates how to insert plain, numbered
@ -50,7 +50,7 @@ import org.apache.poi.logging.PoiLogManager;
*/ */
@SuppressWarnings({"java:S106","java:S4823"}) @SuppressWarnings({"java:S106","java:S4823"})
public class InCellLists { public class InCellLists {
private static final Logger LOG = PoiLogManager.getLogger(InCellLists.class); private static final Logger LOG = LogManager.getLogger(InCellLists.class);
// This character looks like a solid, black, loser case letter 'o' // This character looks like a solid, black, loser case letter 'o'
@ -190,7 +190,7 @@ public class InCellLists {
String formatString = InCellLists.BULLET_CHARACTER + " @"; String formatString = InCellLists.BULLET_CHARACTER + " @";
int formatIndex = format.getFormat(formatString); int formatIndex = format.getFormat(formatString);
// Construct an HSSFCellStyle and set its data format to use the // Construct an HSSFCellStyle and set it's data formt to use the
// object created above. // object created above.
HSSFCellStyle bulletStyle = workbook.createCellStyle(); HSSFCellStyle bulletStyle = workbook.createCellStyle();
bulletStyle.setDataFormat((short)formatIndex); bulletStyle.setDataFormat((short)formatIndex);
@ -248,8 +248,8 @@ public class InCellLists {
int increment) { int increment) {
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
int itemNumber = startingValue; int itemNumber = startingValue;
// Note that again, an HSSFCellStyle object is required and that // Note that again, an HSSFCellStye object is required and that
// its wrap text property should be set to 'true' // it's wrap text property should be set to 'true'
HSSFCellStyle wrapStyle = workbook.createCellStyle(); HSSFCellStyle wrapStyle = workbook.createCellStyle();
wrapStyle.setWrapText(true); wrapStyle.setWrapText(true);
// Note that the basic method is identical to the listInCell() method // Note that the basic method is identical to the listInCell() method
@ -282,7 +282,7 @@ public class InCellLists {
HSSFCell cell) { HSSFCell cell) {
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
// Note that again, an HSSFCellStye object is required and that // Note that again, an HSSFCellStye object is required and that
// its wrap text property should be set to 'true' // it's wrap text property should be set to 'true'
HSSFCellStyle wrapStyle = workbook.createCellStyle(); HSSFCellStyle wrapStyle = workbook.createCellStyle();
wrapStyle.setWrapText(true); wrapStyle.setWrapText(true);
// Note that the basic method is identical to the listInCell() method // Note that the basic method is identical to the listInCell() method
@ -318,7 +318,7 @@ public class InCellLists {
HSSFCell cell) { HSSFCell cell) {
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
// Note that again, an HSSFCellStye object is required and that // Note that again, an HSSFCellStye object is required and that
// its wrap text property should be set to 'true' // it's wrap text property should be set to 'true'
HSSFCellStyle wrapStyle = workbook.createCellStyle(); HSSFCellStyle wrapStyle = workbook.createCellStyle();
wrapStyle.setWrapText(true); wrapStyle.setWrapText(true);
// Step through the ArrayList of MultilLevelListItem instances. // Step through the ArrayList of MultilLevelListItem instances.
@ -381,7 +381,7 @@ public class InCellLists {
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
int highLevelItemNumber = highLevelStartingValue; int highLevelItemNumber = highLevelStartingValue;
// Note that again, an HSSFCellStye object is required and that // Note that again, an HSSFCellStye object is required and that
// its wrap text property should be set to 'true' // it's wrap text property should be set to 'true'
HSSFCellStyle wrapStyle = workbook.createCellStyle(); HSSFCellStyle wrapStyle = workbook.createCellStyle();
wrapStyle.setWrapText(true); wrapStyle.setWrapText(true);
// Step through the ArrayList of MultilLevelListItem instances. // Step through the ArrayList of MultilLevelListItem instances.
@ -436,7 +436,7 @@ public class InCellLists {
HSSFCell cell) { HSSFCell cell) {
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
// Note that again, an HSSFCellStye object is required and that // Note that again, an HSSFCellStye object is required and that
// its wrap text property should be set to 'true' // it's wrap text property should be set to 'true'
HSSFCellStyle wrapStyle = workbook.createCellStyle(); HSSFCellStyle wrapStyle = workbook.createCellStyle();
wrapStyle.setWrapText(true); wrapStyle.setWrapText(true);
// Step through the ArrayList of MultilLevelListItem instances. // Step through the ArrayList of MultilLevelListItem instances.

View File

@ -192,7 +192,7 @@ public final class OfficeDrawing {
private static int loadPicture( String path, HSSFWorkbook wb ) throws IOException { private static int loadPicture( String path, HSSFWorkbook wb ) throws IOException {
int pictureIndex; int pictureIndex;
try (FileInputStream fis = new FileInputStream(path); try (FileInputStream fis = new FileInputStream(path);
UnsynchronizedByteArrayOutputStream bos = UnsynchronizedByteArrayOutputStream.builder().get()) { UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream()) {
IOUtils.copy(fis, bos); IOUtils.copy(fis, bos);
pictureIndex = wb.addPicture(bos.toByteArray(), Workbook.PICTURE_TYPE_PNG); pictureIndex = wb.addPicture(bos.toByteArray(), Workbook.PICTURE_TYPE_PNG);
} }

View File

@ -22,12 +22,12 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.logging.PoiLogManager;
/** /**
* Creates outlines. * Creates outlines.
@ -35,7 +35,7 @@ import org.apache.poi.logging.PoiLogManager;
public class Outlines implements Closeable { public class Outlines implements Closeable {
public static void main(String[] args) public static void main(String[] args)
throws IOException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { throws IOException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Logger LOGGER = PoiLogManager.getLogger(Outlines.class); Logger LOGGER = LogManager.getLogger(Outlines.class);
for (int i=1; i<=13; i++) { for (int i=1; i<=13; i++) {
try (Outlines o = new Outlines()) { try (Outlines o = new Outlines()) {
String log = (String) Outlines.class.getDeclaredMethod("test" + i).invoke(o); String log = (String) Outlines.class.getDeclaredMethod("test" + i).invoke(o);

View File

@ -59,7 +59,7 @@ public final class Word2Forrest
{ {
Paragraph p = r.getParagraph (x); Paragraph p = r.getParagraph (x);
String text = p.text (); String text = p.text ();
if (text.trim().isEmpty()) if (text.trim ().length () == 0)
{ {
continue; continue;
} }

View File

@ -135,7 +135,7 @@ import java.util.Locale;
* <p> * <p>
* Note that the final four method calls all pass the same value and seem to * Note that the final four method calls all pass the same value and seem to
* indicate that the images top left hand corner is aligned with the top left * indicate that the images top left hand corner is aligned with the top left
* hand corner of cell A1 and that its bottom right hand corner is also * hand corner of cell A1 and that it's bottom right hand corner is also
* aligned with the top left hand corner of cell A1. Yet, running this code * aligned with the top left hand corner of cell A1. Yet, running this code
* would see the image fully occupying cell A1. That is the result of the * would see the image fully occupying cell A1. That is the result of the
* values passed to parameters three and four; these I have referred to as * values passed to parameters three and four; these I have referred to as
@ -406,7 +406,7 @@ public class AddDimensionedImage {
* the image, adjusts the columns width if necessary and creates then * the image, adjusts the columns width if necessary and creates then
* returns a ClientAnchorDetail object that facilitates construction of * returns a ClientAnchorDetail object that facilitates construction of
* an ClientAnchor that will fix the image on the sheet and establish * an ClientAnchor that will fix the image on the sheet and establish
* its size. * it's size.
* *
* @param sheet A reference to the sheet that will 'contain' the image. * @param sheet A reference to the sheet that will 'contain' the image.
* @param colNumber A primitive int that contains the index number of a * @param colNumber A primitive int that contains the index number of a
@ -483,7 +483,7 @@ public class AddDimensionedImage {
// Mow many co-ordinate positions are there per millimetre? // Mow many co-ordinate positions are there per millimetre?
colCoordinatesPerMM = ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS / colCoordinatesPerMM = ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS /
colWidthMM; colWidthMM;
// Given the width of the image, what should be its co-ordinate? // Given the width of the image, what should be it's co-ordinate?
pictureWidthCoordinates = (int) (reqImageWidthMM * colCoordinatesPerMM); pictureWidthCoordinates = (int) (reqImageWidthMM * colCoordinatesPerMM);
} else { } else {
pictureWidthCoordinates = (int) reqImageWidthMM * pictureWidthCoordinates = (int) reqImageWidthMM *
@ -500,7 +500,7 @@ public class AddDimensionedImage {
* the image, adjusts the rows height if necessary and creates then * the image, adjusts the rows height if necessary and creates then
* returns a ClientAnchorDetail object that facilitates construction of * returns a ClientAnchorDetail object that facilitates construction of
* a ClientAnchor that will fix the image on the sheet and establish * a ClientAnchor that will fix the image on the sheet and establish
* its size. * it's size.
* *
* @param sheet A reference to the sheet that will 'contain' the image. * @param sheet A reference to the sheet that will 'contain' the image.
* @param rowNumber A primitive int that contains the index number of a * @param rowNumber A primitive int that contains the index number of a
@ -528,7 +528,7 @@ public class AddDimensionedImage {
int pictureHeightCoordinates; int pictureHeightCoordinates;
ClientAnchorDetail rowClientAnchorDetail = null; ClientAnchorDetail rowClientAnchorDetail = null;
// Get the row and its height // Get the row and it's height
row = sheet.getRow(rowNumber); row = sheet.getRow(rowNumber);
if (row == null) { if (row == null) {
// Create row if it does not exist. // Create row if it does not exist.
@ -624,7 +624,7 @@ public class AddDimensionedImage {
colWidthMM = ConvertImageUnits.widthUnits2Millimetres( colWidthMM = ConvertImageUnits.widthUnits2Millimetres(
(short) (sheet.getColumnWidth(toColumn))); (short) (sheet.getColumnWidth(toColumn)));
// Note use of the cell border width constant. Testing with an image // Note use of the cell border width constant. Testing with an image
// declared to fit exactly into one column demonstrated that its // declared to fit exactly into one column demonstrated that it's
// width was greater than the width of the column the POI returned. // width was greater than the width of the column the POI returned.
// Further, this difference was a constant value that I am assuming // Further, this difference was a constant value that I am assuming
// related to the cell's borders. Either way, that difference needs // related to the cell's borders. Either way, that difference needs
@ -632,7 +632,7 @@ public class AddDimensionedImage {
totalWidthMM += (colWidthMM + ConvertImageUnits.CELL_BORDER_WIDTH_MILLIMETRES); totalWidthMM += (colWidthMM + ConvertImageUnits.CELL_BORDER_WIDTH_MILLIMETRES);
toColumn++; toColumn++;
} }
// De-rement by one the last column value. // De-crement by one the last column value.
toColumn--; toColumn--;
// Highly unlikely that this will be true but, if the width of a series // Highly unlikely that this will be true but, if the width of a series
// of columns is exactly equal to the required width of the image, then // of columns is exactly equal to the required width of the image, then

View File

@ -19,10 +19,8 @@
package org.apache.poi.examples.ss; package org.apache.poi.examples.ss;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List; import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
@ -95,7 +93,7 @@ public final class ConditionalFormats {
if (wb instanceof XSSFWorkbook) { if (wb instanceof XSSFWorkbook) {
file += "x"; file += "x";
} }
try (OutputStream out = Files.newOutputStream(Path.of(file))) { try (FileOutputStream out = new FileOutputStream(file)) {
wb.write(out); wb.write(out);
} }
System.out.println("Generated: " + file); System.out.println("Generated: " + file);
@ -203,7 +201,7 @@ public final class ConditionalFormats {
if (rn%10 == 0) { if (rn%10 == 0) {
str = str + "x10 "; str = str + "x10 ";
} }
if (str.isEmpty()) { if (str.length() == 0) {
str = "nothing special..."; str = "nothing special...";
} }
r.createCell(1).setCellValue("It is " + str); r.createCell(1).setCellValue("It is " + str);
@ -287,7 +285,7 @@ public final class ConditionalFormats {
/** /**
* Use Excel conditional formatting to hide the duplicate values, * Use Excel conditional formatting to hide the duplicate values,
* and make the list easier to read. In this example, when the table is sorted by Region, * and make the list easier to read. In this example, when the table is sorted by Region,
* the second (and subsequent) occurrences of each region name will have white font colour. * the second (and subsequent) occurences of each region name will have white font colour.
*/ */
static void hideDupplicates(Sheet sheet) { static void hideDupplicates(Sheet sheet) {
sheet.createRow(0).createCell(0).setCellValue("City"); sheet.createRow(0).createCell(0).setCellValue("City");
@ -311,7 +309,7 @@ public final class ConditionalFormats {
sheetCF.addConditionalFormatting(regions, rule1); sheetCF.addConditionalFormatting(regions, rule1);
sheet.getRow(1).createCell(1).setCellValue("<== the second (and subsequent) " + sheet.getRow(1).createCell(1).setCellValue("<== the second (and subsequent) " +
"occurrences of each region name will have white font colour. " + "occurences of each region name will have white font colour. " +
"Condition: Formula Is =A2=A1 (White Font)"); "Condition: Formula Is =A2=A1 (White Font)");
} }

View File

@ -77,7 +77,7 @@ public class LinkedDropDownLists {
LinkedDropDownLists.buildDataSheet(sheet); LinkedDropDownLists.buildDataSheet(sheet);
// Build the first data validation to occupy cell A1. Note // Build the first data validation to occupy cell A1. Note
// that it retrieves its data from the named area or region called // that it retrieves it's data from the named area or region called
// CHOICES. Further information about this can be found in the // CHOICES. Further information about this can be found in the
// static buildDataSheet() method below. // static buildDataSheet() method below.
CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0); CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);

View File

@ -70,25 +70,21 @@ public final class SSPerformanceTest {
if(warmup) { if(warmup) {
System.out.println("Performing a warmup run first"); System.out.println("Performing a warmup run first");
runWithArgs(type, rows, cols, saveFile, System.currentTimeMillis()); runWithArgs(type, rows, cols, saveFile);
} }
System.out.println("Performing test-run");
long timeStarted = System.currentTimeMillis(); long timeStarted = System.currentTimeMillis();
runWithArgs(type, rows, cols, saveFile, timeStarted); runWithArgs(type, rows, cols, saveFile);
long timeFinished = System.currentTimeMillis(); long timeFinished = System.currentTimeMillis();
System.out.printf(Locale.ROOT, "Elapsed %.2f seconds for arguments %s%n", ((double)timeFinished - timeStarted) / 1000, Arrays.toString(args)); System.out.printf(Locale.ROOT, "Elapsed %.2f seconds for arguments %s%n", ((double)timeFinished - timeStarted) / 1000, Arrays.toString(args));
} }
private static void runWithArgs(String type, int rows, int cols, boolean saveFile, long timeStarted) throws IOException { private static void runWithArgs(String type, int rows, int cols, boolean saveFile) throws IOException {
try (Workbook workBook = createWorkbook(type)) { try (Workbook workBook = createWorkbook(type)) {
boolean isHType = workBook instanceof HSSFWorkbook; boolean isHType = workBook instanceof HSSFWorkbook;
addContent(workBook, isHType, rows, cols); addContent(workBook, isHType, rows, cols);
long timeFinished = System.currentTimeMillis();
System.out.printf(Locale.ROOT, "Elapsed %.2f seconds before save%n", ((double)timeFinished - timeStarted) / 1000);
if (saveFile) { if (saveFile) {
String fileName = type + "_" + rows + "_" + cols + "." + getFileSuffix(type); String fileName = type + "_" + rows + "_" + cols + "." + getFileSuffix(type);
saveFile(workBook, fileName); saveFile(workBook, fileName);

View File

@ -28,8 +28,8 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.ArrayList; import java.util.ArrayList;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.apache.poi.logging.PoiLogManager;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DataFormatter; import org.apache.poi.ss.usermodel.DataFormatter;
@ -134,7 +134,7 @@ import org.apache.poi.ss.usermodel.WorkbookFactory;
*/ */
@SuppressWarnings({"java:S106","java:S4823","java:S1192"}) @SuppressWarnings({"java:S106","java:S4823","java:S1192"})
public class ToCSV { public class ToCSV {
private static final Logger LOG = PoiLogManager.getLogger(ToCSV.class); private static final Logger LOG = LogManager.getLogger(ToCSV.class);
private Workbook workbook; private Workbook workbook;
private ArrayList<ArrayList<String>> csvData; private ArrayList<ArrayList<String>> csvData;
@ -327,7 +327,7 @@ public class ToCSV {
} }
// Step through each of the files in the source folder and for each // Step through each of the files in the source folder and for each
// open the workbook, convert its contents to CSV format and then // open the workbook, convert it's contents to CSV format and then
// save the resulting file away into the folder specified by the // save the resulting file away into the folder specified by the
// contents of the destination variable. Note that the name of the // contents of the destination variable. Note that the name of the
// csv file will be created by taking the name of the Excel file, // csv file will be created by taking the name of the Excel file,
@ -342,7 +342,7 @@ public class ToCSV {
// Open the workbook // Open the workbook
this.openWorkbook(excelFile); this.openWorkbook(excelFile);
// Convert its contents into a CSV file // Convert it's contents into a CSV file
this.convertToCSV(); this.convertToCSV();
// Build the name of the csv folder from that of the Excel workbook. // Build the name of the csv folder from that of the Excel workbook.
@ -451,7 +451,7 @@ public class ToCSV {
// from this 'row' ArrayList one at a time and to write the Strings // from this 'row' ArrayList one at a time and to write the Strings
// away to a StringBuilder thus assembling a single line for inclusion // away to a StringBuilder thus assembling a single line for inclusion
// in the CSV file. If a row was empty or if it was short, then // in the CSV file. If a row was empty or if it was short, then
// the ArrayList that contains its data will also be shorter than // the ArrayList that contains it's data will also be shorter than
// some of the others. Therefore, it is necessary to check within // some of the others. Therefore, it is necessary to check within
// the for loop to ensure that the ArrayList contains data to be // the for loop to ensure that the ArrayList contains data to be
// processed. If it does, then an element will be recovered and // processed. If it does, then an element will be recovered and
@ -689,7 +689,7 @@ public class ToCSV {
// It is not wise to have such a wide catch clause - Exception is very // It is not wise to have such a wide catch clause - Exception is very
// close to being at the top of the inheritance hierarchy - though it // close to being at the top of the inheritance hierarchy - though it
// will suffice for this example as it is really not possible to recover // will suffice for this example as it is really not possible to recover
// easily from an exceptional set of circumstances at this point in the // easilly from an exceptional set of circumstances at this point in the
// program. It should however, ideally be replaced with one or more // program. It should however, ideally be replaced with one or more
// catch clauses optimised to handle more specific problems. // catch clauses optimised to handle more specific problems.
catch(Exception ex) { catch(Exception ex) {

View File

@ -320,7 +320,7 @@ public final class ToHtml {
private String styleName(CellStyle style) { private String styleName(CellStyle style) {
if (style == null) { if (style == null) {
style = wb.getCellStyleAt(0); style = wb.getCellStyleAt((short) 0);
} }
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
try (Formatter fmt = new Formatter(sb, Locale.ROOT)) { try (Formatter fmt = new Formatter(sb, Locale.ROOT)) {

View File

@ -19,11 +19,9 @@
package org.apache.poi.examples.util; package org.apache.poi.examples.util;
import org.apache.poi.util.DefaultTempFileCreationStrategy;
import org.apache.poi.util.TempFile;
import java.io.File; import java.io.File;
import java.nio.file.Path;
import org.apache.poi.util.TempFile;
public final class TempFileUtils { public final class TempFileUtils {
private TempFileUtils() { private TempFileUtils() {
@ -31,7 +29,8 @@ public final class TempFileUtils {
@SuppressWarnings("java:S106") @SuppressWarnings("java:S106")
public static void checkTempFiles() { public static void checkTempFiles() {
File tempDir = Path.of(System.getProperty(TempFile.JAVA_IO_TMPDIR), DefaultTempFileCreationStrategy.POIFILES).toFile(); String tmpDir = System.getProperty(TempFile.JAVA_IO_TMPDIR) + "/poifiles";
File tempDir = new File(tmpDir);
if(tempDir.exists()) { if(tempDir.exists()) {
String[] tempFiles = tempDir.list(); String[] tempFiles = tempDir.list();
if(tempFiles != null && tempFiles.length > 0) { if(tempFiles != null && tempFiles.length > 0) {

View File

@ -1,251 +1,251 @@
/* /*
* ==================================================================== * ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0 * 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 not use this file except in compliance with
* the License. You may obtain a copy of the License at * the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* ==================================================================== * ====================================================================
*/ */
package org.apache.poi.xslf.usermodel; package org.apache.poi.xslf.usermodel;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.URL; import java.net.URL;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.xml.namespace.QName; import javax.xml.namespace.QName;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName; import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackagingURIHelper; import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.openxml4j.opc.TargetMode; import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.sl.usermodel.PictureData.PictureType; import org.apache.poi.sl.usermodel.PictureData.PictureType;
import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlCursor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTHyperlink; import org.openxmlformats.schemas.drawingml.x2006.main.CTHyperlink;
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId; import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps; import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps;
import org.openxmlformats.schemas.presentationml.x2006.main.CTExtension; import org.openxmlformats.schemas.presentationml.x2006.main.CTExtension;
import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture; import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture;
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide; import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide;
import org.openxmlformats.schemas.presentationml.x2006.main.CTTLCommonMediaNodeData; import org.openxmlformats.schemas.presentationml.x2006.main.CTTLCommonMediaNodeData;
import org.openxmlformats.schemas.presentationml.x2006.main.CTTLCommonTimeNodeData; import org.openxmlformats.schemas.presentationml.x2006.main.CTTLCommonTimeNodeData;
import org.openxmlformats.schemas.presentationml.x2006.main.CTTimeNodeList; import org.openxmlformats.schemas.presentationml.x2006.main.CTTimeNodeList;
import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeIndefinite; import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeIndefinite;
import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeNodeFillType; import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeNodeFillType;
import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeNodeRestartType; import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeNodeRestartType;
import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeNodeType; import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeNodeType;
import com.xuggle.mediatool.IMediaReader; import com.xuggle.mediatool.IMediaReader;
import com.xuggle.mediatool.MediaListenerAdapter; import com.xuggle.mediatool.MediaListenerAdapter;
import com.xuggle.mediatool.ToolFactory; import com.xuggle.mediatool.ToolFactory;
import com.xuggle.mediatool.event.IVideoPictureEvent; import com.xuggle.mediatool.event.IVideoPictureEvent;
import com.xuggle.xuggler.Global; import com.xuggle.xuggler.Global;
import com.xuggle.xuggler.IContainer; import com.xuggle.xuggler.IContainer;
import com.xuggle.xuggler.io.InputOutputStreamHandler; import com.xuggle.xuggler.io.InputOutputStreamHandler;
/** /**
* Adding multiple videos to a slide * Adding multiple videos to a slide
* *
* need the Xuggler 5.4 jars: * need the Xuggler 5.4 jars:
* &lt;repositories&gt; * &lt;repositories&gt;
* &lt;repository&gt; * &lt;repository&gt;
* &lt;id&gt;xuggle repo&lt;/id&gt; * &lt;id&gt;xuggle repo&lt;/id&gt;
* &lt;url&gt;http://xuggle.googlecode.com/svn/trunk/repo/share/java/&lt;/url&gt; * &lt;url&gt;http://xuggle.googlecode.com/svn/trunk/repo/share/java/&lt;/url&gt;
* &lt;/repository&gt; * &lt;/repository&gt;
* &lt;/repositories&gt; * &lt;/repositories&gt;
* ... * ...
* &lt;dependency&gt; * &lt;dependency&gt;
* &lt;groupId&gt;xuggle&lt;/groupId&gt; * &lt;groupId&gt;xuggle&lt;/groupId&gt;
* &lt;artifactId&gt;xuggle-xuggler&lt;/artifactId&gt; * &lt;artifactId&gt;xuggle-xuggler&lt;/artifactId&gt;
* &lt;version&gt;5.4&lt;/version&gt; * &lt;version&gt;5.4&lt;/version&gt;
* &lt;/dependency&gt; * &lt;/dependency&gt;
* *
* @see <a href="http://stackoverflow.com/questions/15197300/apache-poi-xslf-adding-movie-to-the-slide">Apache POI XSLF Adding movie to the slide</a> * @see <a href="http://stackoverflow.com/questions/15197300/apache-poi-xslf-adding-movie-to-the-slide">Apache POI XSLF Adding movie to the slide</a>
* @see <a href="http://apache-poi.1045710.n5.nabble.com/Question-about-embedded-video-in-PPTX-files-tt5718461.html">Question about embedded video in PPTX files</a> * @see <a href="http://apache-poi.1045710.n5.nabble.com/Question-about-embedded-video-in-PPTX-files-tt5718461.html">Question about embedded video in PPTX files</a>
*/ */
public class AddVideoToPptx { public class AddVideoToPptx {
static DecimalFormat df_time = new DecimalFormat("0.####"); static DecimalFormat df_time = new DecimalFormat("0.####");
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
URL video = new URL("http://archive.org/download/test-mpeg/test-mpeg.mpg"); URL video = new URL("http://archive.org/download/test-mpeg/test-mpeg.mpg");
// URL video = new URL("file:test-mpeg.mpg"); // URL video = new URL("file:test-mpeg.mpg");
XMLSlideShow pptx = new XMLSlideShow(); XMLSlideShow pptx = new XMLSlideShow();
// add video file // add video file
String videoFileName = video.getPath().substring(video.getPath().lastIndexOf('/')+1); String videoFileName = video.getPath().substring(video.getPath().lastIndexOf('/')+1);
PackagePartName partName = PackagingURIHelper.createPartName("/ppt/media/"+videoFileName); PackagePartName partName = PackagingURIHelper.createPartName("/ppt/media/"+videoFileName);
PackagePart part = pptx.getPackage().createPart(partName, "video/mpeg"); PackagePart part = pptx.getPackage().createPart(partName, "video/mpeg");
OutputStream partOs = part.getOutputStream(); OutputStream partOs = part.getOutputStream();
InputStream fis = video.openStream(); InputStream fis = video.openStream();
byte buf[] = new byte[1024]; byte buf[] = new byte[1024];
for (int readBytes; (readBytes = fis.read(buf)) != -1; partOs.write(buf, 0, readBytes)); for (int readBytes; (readBytes = fis.read(buf)) != -1; partOs.write(buf, 0, readBytes));
fis.close(); fis.close();
partOs.close(); partOs.close();
XSLFSlide slide1 = pptx.createSlide(); XSLFSlide slide1 = pptx.createSlide();
XSLFPictureShape pv1 = addPreview(pptx, slide1, part, 5, 50, 50); XSLFPictureShape pv1 = addPreview(pptx, slide1, part, 5, 50, 50);
addVideo(pptx, slide1, part, pv1, 5); addVideo(pptx, slide1, part, pv1, 5);
addTimingInfo(slide1, pv1); addTimingInfo(slide1, pv1);
XSLFPictureShape pv2 = addPreview(pptx, slide1, part, 9, 50, 250); XSLFPictureShape pv2 = addPreview(pptx, slide1, part, 9, 50, 250);
addVideo(pptx, slide1, part, pv2, 9); addVideo(pptx, slide1, part, pv2, 9);
addTimingInfo(slide1, pv2); addTimingInfo(slide1, pv2);
FileOutputStream fos = new FileOutputStream("pptx-with-video.pptx"); FileOutputStream fos = new FileOutputStream("pptx-with-video.pptx");
pptx.write(fos); pptx.write(fos);
fos.close(); fos.close();
pptx.close(); pptx.close();
} }
static XSLFPictureShape addPreview(XMLSlideShow pptx, XSLFSlide slide1, PackagePart videoPart, double seconds, int x, int y) throws IOException { static XSLFPictureShape addPreview(XMLSlideShow pptx, XSLFSlide slide1, PackagePart videoPart, double seconds, int x, int y) throws IOException {
// get preview after 5 sec. // get preview after 5 sec.
IContainer ic = IContainer.make(); IContainer ic = IContainer.make();
InputOutputStreamHandler iosh = new InputOutputStreamHandler(videoPart.getInputStream()); InputOutputStreamHandler iosh = new InputOutputStreamHandler(videoPart.getInputStream());
if (ic.open(iosh, IContainer.Type.READ, null) < 0) return null; if (ic.open(iosh, IContainer.Type.READ, null) < 0) return null;
IMediaReader mediaReader = ToolFactory.makeReader(ic); IMediaReader mediaReader = ToolFactory.makeReader(ic);
// stipulate that we want BufferedImages created in BGR 24bit color space // stipulate that we want BufferedImages created in BGR 24bit color space
mediaReader.setBufferedImageTypeToGenerate(BufferedImage.TYPE_3BYTE_BGR); mediaReader.setBufferedImageTypeToGenerate(BufferedImage.TYPE_3BYTE_BGR);
ImageSnapListener isl = new ImageSnapListener(seconds); ImageSnapListener isl = new ImageSnapListener(seconds);
mediaReader.addListener(isl); mediaReader.addListener(isl);
// read out the contents of the media file and // read out the contents of the media file and
// dispatch events to the attached listener // dispatch events to the attached listener
while (!isl.hasFired && mediaReader.readPacket() == null) ; while (!isl.hasFired && mediaReader.readPacket() == null) ;
mediaReader.close(); mediaReader.close();
ic.close(); ic.close();
// add snapshot // add snapshot
BufferedImage image1 = isl.image; BufferedImage image1 = isl.image;
ByteArrayOutputStream bos = new ByteArrayOutputStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(image1, "jpeg", bos); ImageIO.write(image1, "jpeg", bos);
XSLFPictureData snap = pptx.addPicture(bos.toByteArray(), PictureType.JPEG); XSLFPictureData snap = pptx.addPicture(bos.toByteArray(), PictureType.JPEG);
XSLFPictureShape pic1 = slide1.createPicture(snap); XSLFPictureShape pic1 = slide1.createPicture(snap);
pic1.setAnchor(new Rectangle(x, y, image1.getWidth(), image1.getHeight())); pic1.setAnchor(new Rectangle(x, y, image1.getWidth(), image1.getHeight()));
return pic1; return pic1;
} }
static void addVideo(XMLSlideShow pptx, XSLFSlide slide1, PackagePart videoPart, XSLFPictureShape pic1, double seconds) throws IOException { static void addVideo(XMLSlideShow pptx, XSLFSlide slide1, PackagePart videoPart, XSLFPictureShape pic1, double seconds) throws IOException {
// add video shape // add video shape
PackagePartName partName = videoPart.getPartName(); PackagePartName partName = videoPart.getPartName();
PackageRelationship prsEmbed1 = slide1.getPackagePart().addRelationship(partName, TargetMode.INTERNAL, "http://schemas.microsoft.com/office/2007/relationships/media"); PackageRelationship prsEmbed1 = slide1.getPackagePart().addRelationship(partName, TargetMode.INTERNAL, "http://schemas.microsoft.com/office/2007/relationships/media");
PackageRelationship prsExec1 = slide1.getPackagePart().addRelationship(partName, TargetMode.INTERNAL, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/video"); PackageRelationship prsExec1 = slide1.getPackagePart().addRelationship(partName, TargetMode.INTERNAL, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/video");
CTPicture xpic1 = (CTPicture)pic1.getXmlObject(); CTPicture xpic1 = (CTPicture)pic1.getXmlObject();
CTHyperlink link1 = xpic1.getNvPicPr().getCNvPr().addNewHlinkClick(); CTHyperlink link1 = xpic1.getNvPicPr().getCNvPr().addNewHlinkClick();
link1.setId(""); link1.setId("");
link1.setAction("ppaction://media"); link1.setAction("ppaction://media");
// add video relation // add video relation
CTApplicationNonVisualDrawingProps nvPr = xpic1.getNvPicPr().getNvPr(); CTApplicationNonVisualDrawingProps nvPr = xpic1.getNvPicPr().getNvPr();
nvPr.addNewVideoFile().setLink(prsExec1.getId()); nvPr.addNewVideoFile().setLink(prsExec1.getId());
CTExtension ext = nvPr.addNewExtLst().addNewExt(); CTExtension ext = nvPr.addNewExtLst().addNewExt();
// see http://msdn.microsoft.com/en-us/library/dd950140(v=office.12).aspx // see http://msdn.microsoft.com/en-us/library/dd950140(v=office.12).aspx
ext.setUri("{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}"); ext.setUri("{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}");
String p14Ns = "http://schemas.microsoft.com/office/powerpoint/2010/main"; String p14Ns = "http://schemas.microsoft.com/office/powerpoint/2010/main";
try (XmlCursor cur = ext.newCursor()) { try (XmlCursor cur = ext.newCursor()) {
cur.toEndToken(); cur.toEndToken();
cur.beginElement(new QName(p14Ns, "media", "p14")); cur.beginElement(new QName(p14Ns, "media", "p14"));
cur.insertNamespace("p14", p14Ns); cur.insertNamespace("p14", p14Ns);
cur.insertAttributeWithValue(new QName(STRelationshipId.type.getName().getNamespaceURI(), "embed"), prsEmbed1.getId()); cur.insertAttributeWithValue(new QName(STRelationshipId.type.getName().getNamespaceURI(), "embed"), prsEmbed1.getId());
cur.beginElement(new QName(p14Ns, "trim", "p14")); cur.beginElement(new QName(p14Ns, "trim", "p14"));
cur.insertAttributeWithValue("st", df_time.format(seconds*1000.0)); cur.insertAttributeWithValue("st", df_time.format(seconds*1000.0));
} }
} }
static void addTimingInfo(XSLFSlide slide1, XSLFPictureShape pic1) { static void addTimingInfo(XSLFSlide slide1, XSLFPictureShape pic1) {
// add slide timing information, so video can be controlled // add slide timing information, so video can be controlled
CTSlide xslide = slide1.getXmlObject(); CTSlide xslide = slide1.getXmlObject();
CTTimeNodeList ctnl; CTTimeNodeList ctnl;
if (!xslide.isSetTiming()) { if (!xslide.isSetTiming()) {
CTTLCommonTimeNodeData ctn = xslide.addNewTiming().addNewTnLst().addNewPar().addNewCTn(); CTTLCommonTimeNodeData ctn = xslide.addNewTiming().addNewTnLst().addNewPar().addNewCTn();
ctn.setDur(STTLTimeIndefinite.INDEFINITE); ctn.setDur(STTLTimeIndefinite.INDEFINITE);
ctn.setRestart(STTLTimeNodeRestartType.NEVER); ctn.setRestart(STTLTimeNodeRestartType.NEVER);
ctn.setNodeType(STTLTimeNodeType.TM_ROOT); ctn.setNodeType(STTLTimeNodeType.TM_ROOT);
ctnl = ctn.addNewChildTnLst(); ctnl = ctn.addNewChildTnLst();
} else { } else {
ctnl = xslide.getTiming().getTnLst().getParArray(0).getCTn().getChildTnLst(); ctnl = xslide.getTiming().getTnLst().getParArray(0).getCTn().getChildTnLst();
} }
CTTLCommonMediaNodeData cmedia = ctnl.addNewVideo().addNewCMediaNode(); CTTLCommonMediaNodeData cmedia = ctnl.addNewVideo().addNewCMediaNode();
cmedia.setVol(80000); cmedia.setVol(80000);
CTTLCommonTimeNodeData ctn = cmedia.addNewCTn(); CTTLCommonTimeNodeData ctn = cmedia.addNewCTn();
ctn.setFill(STTLTimeNodeFillType.HOLD); ctn.setFill(STTLTimeNodeFillType.HOLD);
ctn.setDisplay(false); ctn.setDisplay(false);
ctn.addNewStCondLst().addNewCond().setDelay(STTLTimeIndefinite.INDEFINITE); ctn.addNewStCondLst().addNewCond().setDelay(STTLTimeIndefinite.INDEFINITE);
cmedia.addNewTgtEl().addNewSpTgt().setSpid(""+pic1.getShapeId()); cmedia.addNewTgtEl().addNewSpTgt().setSpid(""+pic1.getShapeId());
} }
static class ImageSnapListener extends MediaListenerAdapter { static class ImageSnapListener extends MediaListenerAdapter {
final double SECONDS_BETWEEN_FRAMES; final double SECONDS_BETWEEN_FRAMES;
final long MICRO_SECONDS_BETWEEN_FRAMES; final long MICRO_SECONDS_BETWEEN_FRAMES;
boolean hasFired = false; boolean hasFired = false;
BufferedImage image = null; BufferedImage image = null;
// The video stream index, used to ensure we display frames from one and // The video stream index, used to ensure we display frames from one and
// only one video stream from the media container. // only one video stream from the media container.
int mVideoStreamIndex = -1; int mVideoStreamIndex = -1;
// Time of last frame write // Time of last frame write
long mLastPtsWrite = Global.NO_PTS; long mLastPtsWrite = Global.NO_PTS;
public ImageSnapListener(double seconds) { public ImageSnapListener(double seconds) {
SECONDS_BETWEEN_FRAMES = seconds; SECONDS_BETWEEN_FRAMES = seconds;
MICRO_SECONDS_BETWEEN_FRAMES = MICRO_SECONDS_BETWEEN_FRAMES =
(long)(Global.DEFAULT_PTS_PER_SECOND * SECONDS_BETWEEN_FRAMES); (long)(Global.DEFAULT_PTS_PER_SECOND * SECONDS_BETWEEN_FRAMES);
} }
@Override @Override
public void onVideoPicture(IVideoPictureEvent event) { public void onVideoPicture(IVideoPictureEvent event) {
if (event.getStreamIndex() != mVideoStreamIndex) { if (event.getStreamIndex() != mVideoStreamIndex) {
// if the selected video stream id is not yet set, go ahead an // if the selected video stream id is not yet set, go ahead an
// select this lucky video stream // select this lucky video stream
if (mVideoStreamIndex != -1) return; if (mVideoStreamIndex != -1) return;
mVideoStreamIndex = event.getStreamIndex(); mVideoStreamIndex = event.getStreamIndex();
} }
long evtTS = event.getTimeStamp(); long evtTS = event.getTimeStamp();
// if uninitialized, back date mLastPtsWrite to get the very first frame // if uninitialized, back date mLastPtsWrite to get the very first frame
if (mLastPtsWrite == Global.NO_PTS) if (mLastPtsWrite == Global.NO_PTS)
mLastPtsWrite = Math.max(0, evtTS - MICRO_SECONDS_BETWEEN_FRAMES); mLastPtsWrite = Math.max(0, evtTS - MICRO_SECONDS_BETWEEN_FRAMES);
// if its time to write the next frame // if it's time to write the next frame
if (evtTS - mLastPtsWrite >= MICRO_SECONDS_BETWEEN_FRAMES) { if (evtTS - mLastPtsWrite >= MICRO_SECONDS_BETWEEN_FRAMES) {
if (!hasFired) { if (!hasFired) {
image = event.getImage(); image = event.getImage();
hasFired = true; hasFired = true;
} }
// update last write time // update last write time
mLastPtsWrite += MICRO_SECONDS_BETWEEN_FRAMES; mLastPtsWrite += MICRO_SECONDS_BETWEEN_FRAMES;
} }
} }
} }
} }

View File

@ -25,7 +25,7 @@ import java.io.FileOutputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -64,7 +64,7 @@ public final class BarChartDemo {
} }
try (FileInputStream argIS = new FileInputStream(args[0]); try (FileInputStream argIS = new FileInputStream(args[0]);
BufferedReader modelReader = Files.newBufferedReader(Path.of(args[1]), StandardCharsets.UTF_8)) { BufferedReader modelReader = Files.newBufferedReader(Paths.get(args[1]), StandardCharsets.UTF_8)) {
String chartTitle = modelReader.readLine(); // first line is chart title String chartTitle = modelReader.readLine(); // first line is chart title
String seriesText = modelReader.readLine(); String seriesText = modelReader.readLine();

View File

@ -26,7 +26,7 @@ import java.io.FileOutputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -72,7 +72,7 @@ public final class ChartFromScratch {
return; return;
} }
try (BufferedReader modelReader = Files.newBufferedReader(Path.of(args[0]), StandardCharsets.UTF_8)) { try (BufferedReader modelReader = Files.newBufferedReader(Paths.get(args[0]), StandardCharsets.UTF_8)) {
String chartTitle = modelReader.readLine(); // first line is chart title String chartTitle = modelReader.readLine(); // first line is chart title
String seriesText = modelReader.readLine(); String seriesText = modelReader.readLine();
@ -180,10 +180,6 @@ public final class ChartFromScratch {
chart.setTitleText(chartTitle); chart.setTitleText(chartTitle);
chart.setTitleOverlay(false); chart.setTitleOverlay(false);
chart.setAutoTitleDeleted(false); chart.setAutoTitleDeleted(false);
// temporary workaround for https://bz.apache.org/bugzilla/show_bug.cgi?id=67510
if (bottomAxis.hasNumberFormat()) bottomAxis.setNumberFormat("@");
if (leftAxis.hasNumberFormat()) leftAxis.setNumberFormat("#,##0.00");
} }
private static final int COLUMN_LANGUAGES = 0; private static final int COLUMN_LANGUAGES = 0;

View File

@ -41,7 +41,7 @@ import java.io.FileOutputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -64,7 +64,7 @@ public final class DoughnutChartFromScratch {
return; return;
} }
try (BufferedReader modelReader = Files.newBufferedReader(Path.of(args[0]), StandardCharsets.UTF_8)) { try (BufferedReader modelReader = Files.newBufferedReader(Paths.get(args[0]), StandardCharsets.UTF_8)) {
String chartTitle = modelReader.readLine(); // first line is chart title String chartTitle = modelReader.readLine(); // first line is chart title
String seriesText = modelReader.readLine(); String seriesText = modelReader.readLine();

View File

@ -25,7 +25,7 @@ import java.io.FileOutputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -61,7 +61,7 @@ public final class PieChartDemo {
} }
try (FileInputStream argIS = new FileInputStream(args[0]); try (FileInputStream argIS = new FileInputStream(args[0]);
BufferedReader modelReader = Files.newBufferedReader(Path.of(args[1]), StandardCharsets.UTF_8)) { BufferedReader modelReader = Files.newBufferedReader(Paths.get(args[1]), StandardCharsets.UTF_8)) {
String chartTitle = modelReader.readLine(); // first line is chart title String chartTitle = modelReader.readLine(); // first line is chart title
try (XMLSlideShow pptx = new XMLSlideShow(argIS)) { try (XMLSlideShow pptx = new XMLSlideShow(argIS)) {

View File

@ -1,12 +1,12 @@
10 languages with most speakers as first language 10 languages with most speakers as first language
countries,speakers,language countries,speakers,language
58,315,العربية 58,315,العربية
4,243,বাংলা 4,243,বাংলা
38,1299,中文 38,1299,中文
118,378,English 118,378,English
4,260,हिन्दी 4,260,हिन्दी
2,128,日本語 2,128,日本語
15,223,português 15,223,português
6,119,ਪੰਜਾਬੀ 6,119,ਪੰਜਾਬੀ
18,154,Русский язык 18,154,Русский язык
31,442,español 31,442,español

View File

@ -1,4 +1,4 @@
My Chart My Chart
First 1.0 First 1.0
Second 3.0 Second 3.0
Third 4.0 Third 4.0

View File

@ -136,7 +136,7 @@ public class FromHowTo {
if(nextIsString && StringUtil.isNotBlank(lastContents)) { if(nextIsString && StringUtil.isNotBlank(lastContents)) {
Integer idx = Integer.valueOf(lastContents); Integer idx = Integer.valueOf(lastContents);
lastContents = lruCache.get(idx); lastContents = lruCache.get(idx);
if (lastContents == null && !lruCache.containsKey(idx) && sst != null) { if (lastContents == null && !lruCache.containsKey(idx)) {
lastContents = sst.getItemAt(idx).getString(); lastContents = sst.getItemAt(idx).getString();
lruCache.put(idx, lastContents); lruCache.put(idx, lastContents);
} }

View File

@ -20,12 +20,12 @@
package org.apache.poi.examples.xssf.eventusermodel; package org.apache.poi.examples.xssf.eventusermodel;
import java.io.InputStream; import java.io.InputStream;
import java.util.Iterator;
import org.apache.poi.examples.xssf.usermodel.LoadPasswordProtectedXlsx; import org.apache.poi.examples.xssf.usermodel.LoadPasswordProtectedXlsx;
import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.poifs.crypt.temp.AesZipFileZipEntrySource; import org.apache.poi.poifs.crypt.temp.AesZipFileZipEntrySource;
import org.apache.poi.xssf.eventusermodel.XSSFReader; import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.eventusermodel.XSSFReader.SheetIterator;
/** /**
* An example that loads a password protected workbook and counts the sheets. * An example that loads a password protected workbook and counts the sheets.
@ -48,12 +48,11 @@ public final class LoadPasswordProtectedXlsxStreaming {
try (AesZipFileZipEntrySource source = AesZipFileZipEntrySource.createZipEntrySource(inputStream); try (AesZipFileZipEntrySource source = AesZipFileZipEntrySource.createZipEntrySource(inputStream);
OPCPackage pkg = OPCPackage.open(source)) { OPCPackage pkg = OPCPackage.open(source)) {
XSSFReader reader = new XSSFReader(pkg); XSSFReader reader = new XSSFReader(pkg);
Iterator<InputStream> iter = reader.getSheetsData(); SheetIterator iter = (SheetIterator)reader.getSheetsData();
int count = 0; int count = 0;
while(iter.hasNext()) { while(iter.hasNext()) {
try (InputStream stream = iter.next()) { iter.next();
count++; count++;
}
} }
System.out.println("sheet count: " + count); System.out.println("sheet count: " + count);
} }

View File

@ -212,7 +212,7 @@ public class XLSX2CSV {
styles, null, strings, sheetHandler, formatter, false); styles, null, strings, sheetHandler, formatter, false);
sheetParser.setContentHandler(handler); sheetParser.setContentHandler(handler);
sheetParser.parse(sheetSource); sheetParser.parse(sheetSource);
} catch (ParserConfigurationException e) { } catch(ParserConfigurationException e) {
throw new RuntimeException("SAX parser appears to be broken - " + e.getMessage()); throw new RuntimeException("SAX parser appears to be broken - " + e.getMessage());
} }
} }
@ -234,12 +234,7 @@ public class XLSX2CSV {
String sheetName = iter.getSheetName(); String sheetName = iter.getSheetName();
this.output.println(); this.output.println();
this.output.println(sheetName + " [index=" + index + "]:"); this.output.println(sheetName + " [index=" + index + "]:");
processSheet(styles, strings, new SheetToCSV(), stream);
try {
processSheet(styles, strings, new SheetToCSV(), stream);
} catch (NumberFormatException e) {
throw new IOException("Failed to parse sheet " + sheetName, e);
}
} }
++index; ++index;
} }

View File

@ -53,13 +53,12 @@ public class DeferredGeneration {
try (FileOutputStream fileOut = new FileOutputStream("DeferredGeneration.xlsx")) { try (FileOutputStream fileOut = new FileOutputStream("DeferredGeneration.xlsx")) {
wb.write(fileOut); wb.write(fileOut);
// writeAvoidingTempFiles was added as an experimental change in POI 5.1.0 //writeAvoidingTempFiles was added as an experimental change in POI 5.1.0
// wb.writeAvoidingTempFiles(fileOut); //wb.writeAvoidingTempFiles(fileOut);
} finally {
//the dispose call is necessary to ensure temp files are removed
wb.dispose();
} }
// finally {
// the dispose call is no longer necessary to ensure temp files are removed
// wb.dispose();
// }
System.out.println("wrote DeferredGeneration.xlsx"); System.out.println("wrote DeferredGeneration.xlsx");
} }
} }

View File

@ -46,11 +46,10 @@ public class Outlining {
try (FileOutputStream fileOut = new FileOutputStream("outlining_collapsed.xlsx")) { try (FileOutputStream fileOut = new FileOutputStream("outlining_collapsed.xlsx")) {
wb2.write(fileOut); wb2.write(fileOut);
} finally {
//the dispose call is necessary to ensure temp files are removed
wb2.dispose();
} }
// finally {
// the dispose call is no longer necessary to ensure temp files are removed
// wb2.dispose();
// }
} }
} }
} }

View File

@ -58,7 +58,8 @@ public final class SavePasswordProtectedXlsx {
TempFileUtils.checkTempFiles(); TempFileUtils.checkTempFiles();
String filename = args[0]; String filename = args[0];
String password = args[1]; String password = args[1];
try (SXSSFWorkbookWithCustomZipEntrySource wb = new SXSSFWorkbookWithCustomZipEntrySource()) { SXSSFWorkbookWithCustomZipEntrySource wb = new SXSSFWorkbookWithCustomZipEntrySource();
try {
for(int i = 0; i < 10; i++) { for(int i = 0; i < 10; i++) {
SXSSFSheet sheet = wb.createSheet("Sheet" + i); SXSSFSheet sheet = wb.createSheet("Sheet" + i);
for(int r = 0; r < 1000; r++) { for(int r = 0; r < 1000; r++) {
@ -77,6 +78,10 @@ public final class SavePasswordProtectedXlsx {
} finally { } finally {
tempData.dispose(); tempData.dispose();
} }
} finally {
wb.close();
//the dispose call is necessary to ensure temp files are removed
wb.dispose();
} }
TempFileUtils.checkTempFiles(); TempFileUtils.checkTempFiles();
} }

View File

@ -104,10 +104,6 @@ public final class BarChart {
solidFillSeries(data, 0, PresetColor.CHARTREUSE); solidFillSeries(data, 0, PresetColor.CHARTREUSE);
solidFillSeries(data, 1, PresetColor.TURQUOISE); solidFillSeries(data, 1, PresetColor.TURQUOISE);
// temporary workaround for https://bz.apache.org/bugzilla/show_bug.cgi?id=67510
if (bottomAxis.hasNumberFormat()) bottomAxis.setNumberFormat("@");
if (leftAxis.hasNumberFormat()) leftAxis.setNumberFormat("#,##0.00");
// Write the output to a file // Write the output to a file
try (FileOutputStream fileOut = new FileOutputStream("ooxml-bar-chart.xlsx")) { try (FileOutputStream fileOut = new FileOutputStream("ooxml-bar-chart.xlsx")) {
wb.write(fileOut); wb.write(fileOut);

View File

@ -35,8 +35,8 @@ import java.util.Random;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipFile; import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.apache.poi.logging.PoiLogManager;
import org.apache.poi.openxml4j.opc.internal.ZipHelper; import org.apache.poi.openxml4j.opc.internal.ZipHelper;
import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.FillPatternType;
@ -77,7 +77,7 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook;
* See <a href="https://poi.apache.org/spreadsheet/how-to.html#sxssf">SXSSF (Streaming Usermodel API)</a>. * See <a href="https://poi.apache.org/spreadsheet/how-to.html#sxssf">SXSSF (Streaming Usermodel API)</a>.
*/ */
public final class BigGridDemo { public final class BigGridDemo {
private static final Logger LOG = PoiLogManager.getLogger(BigGridDemo.class); private static final Logger LOG = LogManager.getLogger(BigGridDemo.class);
private static final Random rnd = new Random(); private static final Random rnd = new Random();

View File

@ -38,7 +38,7 @@ public final class CustomXMLMapping {
for (XSSFMap map : wb.getCustomXMLMappings()) { for (XSSFMap map : wb.getCustomXMLMappings()) {
XSSFExportToXml exporter = new XSSFExportToXml(map); XSSFExportToXml exporter = new XSSFExportToXml(map);
UnsynchronizedByteArrayOutputStream os = UnsynchronizedByteArrayOutputStream.builder().get(); UnsynchronizedByteArrayOutputStream os = new UnsynchronizedByteArrayOutputStream();
exporter.exportToXML(os, true); exporter.exportToXML(os, true);
String xml = os.toString(StandardCharsets.UTF_8); String xml = os.toString(StandardCharsets.UTF_8);
System.out.println(xml); System.out.println(xml);

View File

@ -105,10 +105,6 @@ public final class LineChart {
solidLineSeries(data, 0, PresetColor.CHARTREUSE); solidLineSeries(data, 0, PresetColor.CHARTREUSE);
solidLineSeries(data, 1, PresetColor.TURQUOISE); solidLineSeries(data, 1, PresetColor.TURQUOISE);
// temporary workaround for https://bz.apache.org/bugzilla/show_bug.cgi?id=67510
if (bottomAxis.hasNumberFormat()) bottomAxis.setNumberFormat("@");
if (leftAxis.hasNumberFormat()) leftAxis.setNumberFormat("#,##0.00");
// Write the output to a file // Write the output to a file
try (FileOutputStream fileOut = new FileOutputStream("ooxml-line-chart.xlsx")) { try (FileOutputStream fileOut = new FileOutputStream("ooxml-line-chart.xlsx")) {
wb.write(fileOut); wb.write(fileOut);

View File

@ -99,10 +99,6 @@ public final class ScatterChart {
solidLineSeries(data, 0, PresetColor.CHARTREUSE); solidLineSeries(data, 0, PresetColor.CHARTREUSE);
solidLineSeries(data, 1, PresetColor.TURQUOISE); solidLineSeries(data, 1, PresetColor.TURQUOISE);
// temporary workaround for https://bz.apache.org/bugzilla/show_bug.cgi?id=67510
if (bottomAxis.hasNumberFormat()) bottomAxis.setNumberFormat("@");
if (leftAxis.hasNumberFormat()) leftAxis.setNumberFormat("#,##0.00");
// Write the output to a file // Write the output to a file
try (FileOutputStream fileOut = new FileOutputStream("ooxml-scatter-chart.xlsx")) { try (FileOutputStream fileOut = new FileOutputStream("ooxml-scatter-chart.xlsx")) {
wb.write(fileOut); wb.write(fileOut);

View File

@ -26,7 +26,7 @@ import java.io.FileOutputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -63,7 +63,7 @@ public final class BarChartExample {
} }
try (FileInputStream argIS = new FileInputStream(args[0]); try (FileInputStream argIS = new FileInputStream(args[0]);
BufferedReader modelReader = Files.newBufferedReader(Path.of(args[1]), StandardCharsets.UTF_8)) { BufferedReader modelReader = Files.newBufferedReader(Paths.get(args[1]), StandardCharsets.UTF_8)) {
String chartTitle = modelReader.readLine(); // first line is chart title String chartTitle = modelReader.readLine(); // first line is chart title
String seriesText = modelReader.readLine(); String seriesText = modelReader.readLine();

View File

@ -24,7 +24,7 @@ import java.io.FileOutputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -67,7 +67,7 @@ public final class ChartFromScratch {
return; return;
} }
try (BufferedReader modelReader = Files.newBufferedReader(Path.of(args[0]), StandardCharsets.UTF_8)) { try (BufferedReader modelReader = Files.newBufferedReader(Paths.get(args[0]), StandardCharsets.UTF_8)) {
String chartTitle = modelReader.readLine(); // first line is chart title String chartTitle = modelReader.readLine(); // first line is chart title
String seriesText = modelReader.readLine(); String seriesText = modelReader.readLine();
@ -146,10 +146,6 @@ public final class ChartFromScratch {
chart.setTitleText(chartTitle); chart.setTitleText(chartTitle);
chart.setTitleOverlay(false); chart.setTitleOverlay(false);
chart.setAutoTitleDeleted(false); chart.setAutoTitleDeleted(false);
// temporary workaround for https://bz.apache.org/bugzilla/show_bug.cgi?id=67510
if (bottomAxis.hasNumberFormat()) bottomAxis.setNumberFormat("@");
if (leftAxis.hasNumberFormat()) leftAxis.setNumberFormat("#,##0.00");
} }
private static final int COLUMN_LANGUAGES = 0; private static final int COLUMN_LANGUAGES = 0;

View File

@ -22,10 +22,10 @@ import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.poi.common.usermodel.PictureType;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units; import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.BreakType; import org.apache.poi.xwpf.usermodel.BreakType;
import org.apache.poi.xwpf.usermodel.Document;
import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun; import org.apache.poi.xwpf.usermodel.XWPFRun;
@ -45,30 +45,30 @@ public final class SimpleImages {
XWPFRun r = p.createRun(); XWPFRun r = p.createRun();
for (String imgFile : args) { for (String imgFile : args) {
PictureType format; int format;
if (imgFile.endsWith(".emf")) { if (imgFile.endsWith(".emf")) {
format = PictureType.EMF; format = Document.PICTURE_TYPE_EMF;
} else if (imgFile.endsWith(".wmf")) { } else if (imgFile.endsWith(".wmf")) {
format = PictureType.WMF; format = Document.PICTURE_TYPE_WMF;
} else if (imgFile.endsWith(".pict")) { } else if (imgFile.endsWith(".pict")) {
format = PictureType.PICT; format = Document.PICTURE_TYPE_PICT;
} else if (imgFile.endsWith(".jpeg") || imgFile.endsWith(".jpg")) { } else if (imgFile.endsWith(".jpeg") || imgFile.endsWith(".jpg")) {
format = PictureType.JPEG; format = Document.PICTURE_TYPE_JPEG;
} else if (imgFile.endsWith(".png")) { } else if (imgFile.endsWith(".png")) {
format = PictureType.PNG; format = Document.PICTURE_TYPE_PNG;
} else if (imgFile.endsWith(".dib")) { } else if (imgFile.endsWith(".dib")) {
format = PictureType.DIB; format = Document.PICTURE_TYPE_DIB;
} else if (imgFile.endsWith(".gif")) { } else if (imgFile.endsWith(".gif")) {
format = PictureType.GIF; format = Document.PICTURE_TYPE_GIF;
} else if (imgFile.endsWith(".tiff")) { } else if (imgFile.endsWith(".tiff")) {
format = PictureType.TIFF; format = Document.PICTURE_TYPE_TIFF;
} else if (imgFile.endsWith(".eps")) { } else if (imgFile.endsWith(".eps")) {
format = PictureType.EPS; format = Document.PICTURE_TYPE_EPS;
} else if (imgFile.endsWith(".bmp")) { } else if (imgFile.endsWith(".bmp")) {
format = PictureType.BMP; format = Document.PICTURE_TYPE_BMP;
} else if (imgFile.endsWith(".wpg")) { } else if (imgFile.endsWith(".wpg")) {
format = PictureType.WPG; format = Document.PICTURE_TYPE_WPG;
} else { } else {
System.err.println("Unsupported picture: " + imgFile + System.err.println("Unsupported picture: " + imgFile +
". Expected emf|wmf|pict|jpeg|png|dib|gif|tiff|eps|bmp|wpg"); ". Expected emf|wmf|pict|jpeg|png|dib|gif|tiff|eps|bmp|wpg");

View File

@ -44,7 +44,7 @@ import org.apache.poi.xwpf.usermodel.XWPFDocument;
* SpreadsheetML workbook embedded into the document.<p> * SpreadsheetML workbook embedded into the document.<p>
* *
* This code was successfully tested with the following file from the POI test collection: * This code was successfully tested with the following file from the POI test collection:
* test-data/document/EmbeddedDocument.docx * http://svn.apache.org/repos/asf/poi/trunk/test-data/document/EmbeddedDocument.docx
*/ */
@SuppressWarnings({"java:S106","java:S4823","java:S1192"}) @SuppressWarnings({"java:S106","java:S4823","java:S1192"})
public class UpdateEmbeddedDoc { public class UpdateEmbeddedDoc {

View File

@ -1,12 +1,12 @@
10 languages with most speakers as first language 10 languages with most speakers as first language
countries,speakers,language countries,speakers,language
58,315,العربية 58,315,العربية
4,243,বাংলা 4,243,বাংলা
38,1299,中文 38,1299,中文
118,378,English 118,378,English
4,260,हिन्दी 4,260,हिन्दी
2,128,日本語 2,128,日本語
15,223,português 15,223,português
6,119,ਪੰਜਾਬੀ 6,119,ਪੰਜਾਬੀ
18,154,Русский язык 18,154,Русский язык
31,442,español 31,442,español

Binary file not shown.

View File

@ -1,115 +0,0 @@
/* ====================================================================
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.examples.hssf.eventusermodel;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.record.NumberRecord;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.junit.jupiter.api.Test;
class TestXLS2CSVmra {
@Test
void test() throws Exception {
XLS2CSVmra.main(new String[] { HSSFTestDataSamples.getSampleFile("SampleSS.xls").getAbsolutePath() });
}
@Test
void testWithMinCols() throws Exception {
XLS2CSVmra.main(new String[] { HSSFTestDataSamples.getSampleFile("SampleSS.xls").getAbsolutePath(), "100" });
}
@Test
void testProcess() throws IOException {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
PrintStream out = new PrintStream(outStream, false, StandardCharsets.UTF_8.name());
XLS2CSVmra cvs = new XLS2CSVmra(
new POIFSFileSystem(new FileInputStream(HSSFTestDataSamples.getSampleFile("SampleSS.xls").getAbsolutePath())),
out, -1);
cvs.process();
outStream.flush();
assertEquals(sanitize("\n"
+ "First Sheet [1]:\n"
+ "\"Test spreadsheet\"\n"
+ "\"2nd row\",\"2nd row 2nd column\"\n"
+ "\n"
+ "\"This one is red\"\n"
+ "\n"
+ "Sheet Number 2 [2]:\n"
+ "\"Start of 2nd sheet\"\n"
+ "\"Sheet 2 row 2\"\n"
+ "\n"
+ "\"I'm in bold blue, on a yellow background\"\n"
+ "\n"
+ "\"cb=1\",\"cb=10\",\"cb=2\",\"cb=sum\"\n"
+ "1,10,2,13\n"
+ "\n"
+ "Sheet3 [3]:\n"), sanitize(new String(outStream.toByteArray(), StandardCharsets.UTF_8)));
}
@Test
void testProcessNumberRecord() throws IOException {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
PrintStream out = new PrintStream(outStream, false, StandardCharsets.UTF_8.name());
XLS2CSVmra cvs = new XLS2CSVmra(
new POIFSFileSystem(new FileInputStream(HSSFTestDataSamples.getSampleFile("empty.xls").getAbsolutePath())),
out, -1);
// need to call process() first to initialize members
cvs.process();
outStream.flush();
assertEquals(sanitize("\n"
+ "Лист1 [1]:\n"
+ "\n"
+ "Лист2 [2]:\n"
+ "\n"
+ "Лист3 [3]:\n"), sanitize(new String(outStream.toByteArray(), StandardCharsets.UTF_8)));
NumberRecord record = new NumberRecord();
record.setValue(1.243);
cvs.processRecord(record);
outStream.flush();
assertEquals(sanitize("\n"
+ "Лист1 [1]:\n"
+ "\n"
+ "Лист2 [2]:\n"
+ "\n"
+ "Лист3 [3]:\n"
+ "1.243"), sanitize(new String(outStream.toByteArray(), StandardCharsets.UTF_8)));
}
private String sanitize(String str) {
return str.replace("\r\n", "\n");
}
}

View File

@ -18,31 +18,24 @@
package org.apache.poi.integration; package org.apache.poi.integration;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream; import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
import org.apache.poi.examples.xssf.eventusermodel.XLSX2CSV; import org.apache.poi.examples.xssf.eventusermodel.XLSX2CSV;
import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess; import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.xssf.XSSFTestDataSamples; import org.apache.poi.xssf.XSSFTestDataSamples;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import net.bytebuddy.utility.RandomString;
public class TestXLSX2CSV { public class TestXLSX2CSV {
private PrintStream err; private PrintStream err;
private final UnsynchronizedByteArrayOutputStream errorBytes = UnsynchronizedByteArrayOutputStream.builder().get(); private final UnsynchronizedByteArrayOutputStream errorBytes = new UnsynchronizedByteArrayOutputStream();
@BeforeEach @BeforeEach
public void setUp() throws UnsupportedEncodingException { public void setUp() throws UnsupportedEncodingException {
@ -84,7 +77,7 @@ public class TestXLSX2CSV {
@Test @Test
public void testSampleFile() throws Exception { public void testSampleFile() throws Exception {
final UnsynchronizedByteArrayOutputStream outputBytes = UnsynchronizedByteArrayOutputStream.builder().get(); final UnsynchronizedByteArrayOutputStream outputBytes = new UnsynchronizedByteArrayOutputStream();
PrintStream out = new PrintStream(outputBytes, true, StandardCharsets.UTF_8.name()); PrintStream out = new PrintStream(outputBytes, true, StandardCharsets.UTF_8.name());
// The package open is instantaneous, as it should be. // The package open is instantaneous, as it should be.
@ -101,28 +94,9 @@ public class TestXLSX2CSV {
assertTrue(output.contains(",\"hello, xssf\",,\"hello, xssf\""), "Had: " + output); assertTrue(output.contains(",\"hello, xssf\",,\"hello, xssf\""), "Had: " + output);
} }
@Test
public void testInvalidSampleFile() throws Exception {
final UnsynchronizedByteArrayOutputStream outputBytes = UnsynchronizedByteArrayOutputStream.builder().get();
PrintStream out = new PrintStream(outputBytes, true, StandardCharsets.UTF_8.name());
// The package open is instantaneous, as it should be.
try (OPCPackage p = OPCPackage.open(XSSFTestDataSamples.getSampleFile("clusterfuzz-testcase-minimized-XLSX2CSVFuzzer-5025401116950528.xlsx").getAbsolutePath(), PackageAccess.READ)) {
XLSX2CSV xlsx2csv = new XLSX2CSV(p, out, -1);
assertThrows(POIXMLException.class,
xlsx2csv::process);
}
String errorOutput = errorBytes.toString(StandardCharsets.UTF_8);
assertEquals("", errorOutput);
String output = outputBytes.toString(StandardCharsets.UTF_8);
assertEquals("", output, "Had: " + output);
}
@Test @Test
public void testMinColumns() throws Exception { public void testMinColumns() throws Exception {
final UnsynchronizedByteArrayOutputStream outputBytes = UnsynchronizedByteArrayOutputStream.builder().get(); final UnsynchronizedByteArrayOutputStream outputBytes = new UnsynchronizedByteArrayOutputStream();
PrintStream out = new PrintStream(outputBytes, true, StandardCharsets.UTF_8.name()); PrintStream out = new PrintStream(outputBytes, true, StandardCharsets.UTF_8.name());
// The package open is instantaneous, as it should be. // The package open is instantaneous, as it should be.
@ -135,87 +109,7 @@ public class TestXLSX2CSV {
assertEquals("", errorOutput); assertEquals("", errorOutput);
String output = outputBytes.toString(StandardCharsets.UTF_8); String output = outputBytes.toString(StandardCharsets.UTF_8);
assertTrue(output.contains("\"Lorem\",111,,,"), "Had: " + output); assertTrue(output.contains("\"Lorem\",111,,,"), "Had: " + output);
assertTrue(output.contains(",\"hello, xssf\",,\"hello, xssf\","), "Had: " + output); assertTrue(output.contains(",\"hello, xssf\",,\"hello, xssf\","), "Had: " + output);
}
@Disabled("Used for local micro-benchmarking")
@Test
public void microBenchmark() {
checkReplace("str");
checkReplace("str.123");
checkReplace("str.123,");
checkReplace("str,,,.123,,,,");
for (int i = 0; i < 1000;i++) {
checkReplace(RandomString.make(20));
}
for (int i = 0;i < 10;i++) {
long start = System.currentTimeMillis();
String str = RandomString.make(100) + "\"\"" + RandomString.make(100) + "\"\"" + RandomString.make(100);
String expected = str.replace("\"", "\"\"");
for (int j = 0;j < 300000;j++) {
//assertEquals(expected, replaceString(str, "\"", "\"\""));
assertEquals(expected, replaceDirect(str, "\"", "\"\""));
}
System.out.println(" , " + (System.currentTimeMillis() - start));
}
// Java 8: replaceString: 1001, 921, 1264, 1019, 1258, 990, 1089, 1430, 1153, 907
// Java 8: replaceDirect: 375, 282, 240, 246, 264, 271, 258, 250, 263, 259
// Java 11: replaceString: 510, 218, 202, 205, 202, 198, 202, 198, 208, 201
// Java 11: replaceDirect: 384, 228, 204, 201, 201, 200, 206, 196, 200, 200
//
// => On Java 8, a custom implementation would make sense, however on Java 9
// String.replace() was optimized so that it does not make any difference
// anymore!
}
private void checkReplace(String orig) {
assertEquals(replaceString(orig, ",", "."), replaceDirect(orig, ",", "."),
"Did have a difference with " + orig);
}
public static String replaceString(String originalStr, String oldStr, String newStr) {
return originalStr.replace(oldStr, newStr);
}
public static String replaceDirect(String originalStr, String oldStr, String newStr) {
int p = originalStr.indexOf(oldStr);
if (p == -1) {
return originalStr;
} else {
StringBuilder result = new StringBuilder();
result.append(originalStr, 0, p);
result.append(newStr);
int q = p + oldStr.length();
while ((p = originalStr.indexOf(oldStr, q)) != -1) {
result.append(originalStr, q, p);
result.append(newStr);
q = p + oldStr.length();
}
result.append(originalStr, q, originalStr.length());
return result.toString();
}
}
@Test
public void testDeepFile() {
// returns with some System.err
try {
assertThrows(IOException.class,
() -> XLSX2CSV.main(new String[] { XSSFTestDataSamples.getSampleFile("deep-data.xlsx").getAbsolutePath() }));
} catch (Throwable e) {
// restore output-streams again to get proper error output
System.setErr(err);
throw e;
}
String output = errorBytes.toString(StandardCharsets.UTF_8);
assertFalse(output.contains("Not found"), "Had: " + output);
System.out.println(output);
} }
} }

View File

@ -23,15 +23,19 @@ configurations {
sourceSets { sourceSets {
main { main {
output.dir(JAVA9_OUT, builtBy: 'compileJava9') if (jdkVersion > 8) {
output.dir(JAVA9_OUT, builtBy: 'cacheJava9')
}
} }
test { test {
output.dir(TEST9_OUT, builtBy: 'compileTest9') if (jdkVersion > 8) {
output.dir(TEST9_OUT, builtBy: 'cacheTest9')
}
} }
} }
dependencies { dependencies {
api 'org.apache.ant:ant:1.10.15' api 'org.apache.ant:ant:1.10.12'
api project(':poi-ooxml') api project(':poi-ooxml')
compileOnly project(path: ':poi-ooxml', configuration: 'archives') compileOnly project(path: ':poi-ooxml', configuration: 'archives')
@ -41,10 +45,14 @@ dependencies {
testImplementation(project(path: ':poi-ooxml', configuration: 'tests')) { testImplementation(project(path: ':poi-ooxml', configuration: 'tests')) {
exclude group: 'org.apache.poi', module: 'poi-scratchpad' exclude group: 'org.apache.poi', module: 'poi-scratchpad'
} }
testImplementation 'com.google.guava:guava:33.5.0-jre' testImplementation 'com.google.guava:guava:31.1-jre'
testImplementation "org.apache.logging.log4j:log4j-slf4j2-impl:${log4jVersion}" testImplementation "org.apache.logging.log4j:log4j-slf4j18-impl:${log4jVersion}"
testImplementation 'org.slf4j:slf4j-simple:2.0.17' testImplementation 'org.slf4j:slf4j-simple:1.7.36'
testRuntimeOnly "org.apiguardian:apiguardian-api:${apiGuardianVersion}" testRuntimeOnly "org.apiguardian:apiguardian-api:${apiGuardianVersion}"
if (SAXON_TEST) {
testRuntimeOnly "net.sf.saxon:Saxon-HE:${saxonVersion}"
}
} }
final String MODULE_NAME = 'org.apache.poi.excelant' final String MODULE_NAME = 'org.apache.poi.excelant'
@ -57,45 +65,71 @@ final String OOXML_LITE_AGENT = "../build/dist/maven/poi-ooxml-lite-agent/poi-oo
final String OOXML_LITE_REPORT = '../src/resources/ooxml-lite-report' final String OOXML_LITE_REPORT = '../src/resources/ooxml-lite-report'
final String OOXML_LITE_INCLUDES = "^(com/microsoft/schemas|org/(etsi|openxmlformats|w3/)|org/apache/poi/schemas)" final String OOXML_LITE_INCLUDES = "^(com/microsoft/schemas|org/(etsi|openxmlformats|w3/)|org/apache/poi/schemas)"
tasks.register('compileJava9', JavaCompile) { task compileJava9(type: JavaCompile) {
dependsOn 'compileJava', ':poi-ooxml:jar', ':poi-scratchpad:jar' dependsOn 'compileJava', ':poi-ooxml:jar', ':poi-scratchpad:jar'
javaCompiler = javaToolchains.compilerFor { javaCompiler = javaToolchains.compilerFor {
languageVersion = JavaLanguageVersion.of(Math.max(11, jdkVersion)) languageVersion = JavaLanguageVersion.of(jdkVersion >= 17 ? 17 : 11)
if (jdkVendor != '') vendor = JvmVendorSpec.matching(jdkVendor)
} }
sourceCompatibility = 11
targetCompatibility = 11
destinationDirectory = file(JAVA9_OUT + VERSIONS9) destinationDirectory = file(JAVA9_OUT + VERSIONS9)
source = file(JAVA9_SRC) source = file(JAVA9_SRC)
classpath = files() classpath = files()
options.compilerArgs = [ options.compilerArgs = [
'--patch-module', "${MODULE_NAME}=${sourceSets.main.output.classesDirs.asPath}", '--patch-module', "${MODULE_NAME}=${sourceSets.main.output.classesDirs.asPath}",
'--module-path', files(MAIN_MODULE_PATH).asPath '--module-path', files(MAIN_MODULE_PATH).asPath
] ]
onlyIf {
jdkVersion > 8
}
} }
tasks.register('compileTest9', JavaCompile) { task cacheJava9(type: Copy) {
dependsOn 'compileJava9'
from(file(JAVA9_OUT + VERSIONS9))
into(JAVA9_SRC)
}
task compileTest9(type: JavaCompile) {
dependsOn 'compileTestJava', ':poi-ooxml:jar', ':poi-scratchpad:jar' dependsOn 'compileTestJava', ':poi-ooxml:jar', ':poi-scratchpad:jar'
javaCompiler = javaToolchains.compilerFor { javaCompiler = javaToolchains.compilerFor {
languageVersion = JavaLanguageVersion.of(Math.max(11, jdkVersion)) languageVersion = JavaLanguageVersion.of(jdkVersion)
if (jdkVendor != '') vendor = JvmVendorSpec.matching(jdkVendor)
} }
sourceCompatibility = 11
targetCompatibility = 11
destinationDirectory = file(TEST9_OUT + VERSIONS9) destinationDirectory = file(TEST9_OUT + VERSIONS9)
source = file(TEST9_SRC) source = file(TEST9_SRC)
options.compilerArgs = [ options.compilerArgs = [
'--patch-module', "${MODULE_NAME}=${(sourceSets.main.output.classesDirs + sourceSets.test.output.classesDirs).asPath}", '--patch-module', "${MODULE_NAME}=${(sourceSets.main.output.classesDirs + sourceSets.test.output.classesDirs).asPath}",
'--module-path', files(TEST_MODULE_PATH).asPath '--module-path', files(TEST_MODULE_PATH).asPath
] ]
classpath = files() classpath = files()
onlyIf {
jdkVersion > 8
}
} }
jar { task cacheTest9(type: Copy) {
dependsOn compileJava9 dependsOn 'compileTest9'
destinationDirectory = file("../build/dist/maven/${base.archivesName.get()}") from(file(TEST9_OUT + VERSIONS9))
into(TEST9_SRC)
}
jar {
dependsOn cacheJava9
destinationDirectory = file("../build/dist/maven/${project.archivesBaseName}")
if (jdkVersion == 8) {
into('META-INF/versions/9') {
from JAVA9_SRC include '*.class'
}
}
manifest { manifest {
attributes('Automatic-Module-Name': MODULE_NAME, 'Multi-Release': 'true') attributes('Automatic-Module-Name': MODULE_NAME, 'Multi-Release': 'true')
@ -118,12 +152,18 @@ sourcesJar {
// Create a separate jar for test-code to depend on it in other projects // Create a separate jar for test-code to depend on it in other projects
// See http://stackoverflow.com/questions/5144325/gradle-test-dependency // See http://stackoverflow.com/questions/5144325/gradle-test-dependency
task testJar(type: Jar, dependsOn: [ testClasses, compileTest9 ] ) { task testJar(type: Jar, dependsOn: [ testClasses, cacheTest9 ] ) {
destinationDirectory = file("../build/dist/maven/${base.archivesName.get()}-tests") destinationDirectory = file("../build/dist/maven/${project.archivesBaseName}-tests")
setArchiveClassifier 'tests' classifier 'tests'
// ignore second module-info.class from main // ignore second module-info.class from main
duplicatesStrategy = DuplicatesStrategy.EXCLUDE duplicatesStrategy = 'exclude'
if (jdkVersion == 8) {
into('META-INF/versions/9') {
from TEST9_SRC include '*.class'
}
}
from sourceSets.test.output + sourceSets.main.output from sourceSets.test.output + sourceSets.main.output
@ -142,9 +182,13 @@ test {
doFirst { doFirst {
jvmArgs += [ jvmArgs += [
"-javaagent:${OOXML_LITE_AGENT}=${OOXML_LITE_REPORT}|${OOXML_LITE_INCLUDES}", "-javaagent:${OOXML_LITE_AGENT}=${OOXML_LITE_REPORT}|${OOXML_LITE_INCLUDES}",
'--add-modules', MODULE_NAME,
'--module-path', '../build/dist/maven/poi-excelant-tests' + File.pathSeparator + files(TEST_MODULE_PATH).asPath,
] ]
if (jdkVersion > 8) {
jvmArgs += [
'--add-modules', MODULE_NAME,
'--module-path', '../build/dist/maven/poi-excelant-tests' + File.pathSeparator + files(TEST_MODULE_PATH).asPath,
]
}
} }
} }
@ -158,22 +202,3 @@ publishing {
} }
} }
} }
cyclonedxBom {
// includeConfigs is the list of configuration names to include when generating the BOM (leave empty to include every configuration)
includeConfigs = ["runtimeClasspath"]
// skipConfigs is a list of configuration names to exclude when generating the BOM
//skipConfigs = ["compileClasspath", "testCompileClasspath"]
// Specified the type of project being built. Defaults to 'library'
projectType = "library"
// Specified the version of the CycloneDX specification to use. Defaults to 1.4.
schemaVersion = "1.4"
// Boms destination directory (defaults to build/reports)
destination = file("build/reports")
// The file name for the generated BOMs (before the file format suffix). Defaults to 'bom'
outputName = "poi-excelant-${project.version}.bom"
// The file format generated, can be xml, json or all for generating both
outputFormat = "all"
// Exclude BOM Serial Number
includeBomSerialNumber = true
}

View File

@ -37,7 +37,7 @@ import org.apache.tools.ant.Task;
* <p> * <p>
* In order to use this tag you must write a class that implements the * In order to use this tag you must write a class that implements the
* {@code IExcelAntWorkbookHandler} interface. After writing the * {@code IExcelAntWorkbookHandler} interface. After writing the
* class you should package it and its dependencies into a jar file to * class you should package it and it's dependencies into a jar file to
* add as library in your Ant build file. * add as library in your Ant build file.
*/ */
public class ExcelAntHandlerTask extends Task { public class ExcelAntHandlerTask extends Task {

View File

@ -27,7 +27,7 @@ import java.util.Map;
*/ */
public final class ExcelAntWorkbookUtilFactory { public final class ExcelAntWorkbookUtilFactory {
private static final Map<String, ExcelAntWorkbookUtil> workbookUtilMap = new HashMap<>(); private static Map<String, ExcelAntWorkbookUtil> workbookUtilMap;
private ExcelAntWorkbookUtilFactory() { private ExcelAntWorkbookUtilFactory() {
} }
@ -41,14 +41,16 @@ public final class ExcelAntWorkbookUtilFactory {
* a freshly instantiated one if none did exist before. * a freshly instantiated one if none did exist before.
*/ */
public static ExcelAntWorkbookUtil getInstance(String fileName) { public static ExcelAntWorkbookUtil getInstance(String fileName) {
synchronized (workbookUtilMap) { if(workbookUtilMap == null) {
if(workbookUtilMap.containsKey(fileName)) { workbookUtilMap = new HashMap<>();
return workbookUtilMap.get(fileName);
}
ExcelAntWorkbookUtil wbu = new ExcelAntWorkbookUtil(fileName);
workbookUtilMap.put(fileName, wbu);
return wbu;
} }
if(workbookUtilMap.containsKey(fileName)) {
return workbookUtilMap.get(fileName);
}
ExcelAntWorkbookUtil wbu = new ExcelAntWorkbookUtil(fileName);
workbookUtilMap.put(fileName, wbu);
return wbu;
} }
} }

Binary file not shown.

View File

@ -18,7 +18,6 @@
module org.apache.poi.excelant { module org.apache.poi.excelant {
requires ant; requires ant;
requires transitive org.apache.poi.poi;
requires org.apache.poi.ooxml; requires org.apache.poi.ooxml;
exports org.apache.poi.ss.excelant; exports org.apache.poi.ss.excelant;

View File

@ -28,7 +28,7 @@ import org.junit.platform.launcher.TestIdentifier;
/** /**
* Custom listener class for Ants junitlauncher, because it chomps the important running details * Custom listener class for Ants junitlauncher, because it chomps the important running details
* *
* @see <a href="https://bz.apache.org/bugzilla/show_bug.cgi?id=64836">Bug 64836 - junitlauncher poor summary</a> * @see <a href="https://bz.apache.org/bugzilla/show_bug.cgi?id=64836">Bug 64836 - junitlaucher poor summary</a>
**/ **/
public class Junit5Progress implements TestExecutionListener { public class Junit5Progress implements TestExecutionListener {
private final AtomicInteger numSkippedInTestSet = new AtomicInteger(); private final AtomicInteger numSkippedInTestSet = new AtomicInteger();
@ -76,17 +76,17 @@ public class Junit5Progress implements TestExecutionListener {
String summary = String.format("Tests run: %d, Failures: %d, Aborted: %d, Skipped: %d, Time elapsed: %f sec", totalTestsInClass, String summary = String.format("Tests run: %d, Failures: %d, Aborted: %d, Skipped: %d, Time elapsed: %f sec", totalTestsInClass,
this.numFailedInTestSet.get(), this.numAbortedInTestSet.get(), this.numSkippedInTestSet.get(), numSeconds); this.numFailedInTestSet.get(), this.numAbortedInTestSet.get(), this.numSkippedInTestSet.get(), numSeconds);
println(summary); println(summary);
} else { } else if (testIdentifier.isTest()) {
switch (testExecutionResult.getStatus()) { switch (testExecutionResult.getStatus()) {
case SUCCESSFUL: case SUCCESSFUL:
this.numSucceededInTestSet.incrementAndGet(); this.numSucceededInTestSet.incrementAndGet();
break; break;
case ABORTED: case ABORTED:
println(" Aborted: " + testIdentifier.getDisplayName() + ": " + testExecutionResult.getThrowable().orElse(null)); println(" Aborted: " + testIdentifier.getDisplayName());
this.numAbortedInTestSet.incrementAndGet(); this.numAbortedInTestSet.incrementAndGet();
break; break;
case FAILED: case FAILED:
println(" Failed: " + testIdentifier.getDisplayName() + ": " + testExecutionResult.getThrowable().orElse(null)); println(" Failed: " + testIdentifier.getDisplayName());
this.numFailedInTestSet.incrementAndGet(); this.numFailedInTestSet.incrementAndGet();
break; break;
} }

Binary file not shown.

View File

@ -1,3 +1,5 @@
import java.util.regex.Pattern
/* ==================================================================== /* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with contributor license agreements. See the NOTICE file distributed with
@ -15,10 +17,8 @@
limitations under the License. limitations under the License.
==================================================================== */ ==================================================================== */
import java.util.regex.Pattern
final String TEST9_SRC = 'src/test/java9' final String TEST9_SRC = 'src/test/java9'
final String TEST9_OUT = layout.buildDirectory.dir('classes/java9/test/').get().asFile.absolutePath final String TEST9_OUT = "${buildDir}/classes/java9/test/"
final String VERSIONS9 = 'META-INF/versions/9' final String VERSIONS9 = 'META-INF/versions/9'
final boolean IBMVM = System.getProperty("java.vendor").contains("IBM") final boolean IBMVM = System.getProperty("java.vendor").contains("IBM")
@ -29,7 +29,9 @@ configurations {
sourceSets { sourceSets {
test { test {
output.dir(TEST9_OUT, builtBy: 'compileTest9') if (jdkVersion > 8) {
output.dir(TEST9_OUT, builtBy: 'cacheTest9')
}
if (IBMVM) { if (IBMVM) {
java { java {
exclude '**/HeapDump**' exclude '**/HeapDump**'
@ -39,9 +41,9 @@ sourceSets {
} }
dependencies { dependencies {
testImplementation 'org.apache.ant:ant:1.10.15' testImplementation 'org.apache.ant:ant:1.10.12'
testImplementation 'org.apache.commons:commons-collections4:4.5.0' testImplementation 'org.apache.commons:commons-collections4:4.4'
testImplementation 'com.google.guava:guava:33.5.0-jre' testImplementation 'com.google.guava:guava:31.1-jre'
misc(project(':poi-ooxml')) { misc(project(':poi-ooxml')) {
capabilities { capabilities {
@ -75,9 +77,13 @@ dependencies {
} }
} }
testImplementation project(path: ':poi-ooxml-lite-agent', configuration: 'archives') testImplementation project(path: ':poi-ooxml-lite-agent', configuration: 'archives')
testImplementation "org.apache.logging.log4j:log4j-slf4j2-impl:${log4jVersion}" testImplementation "org.apache.logging.log4j:log4j-slf4j18-impl:${log4jVersion}"
testImplementation 'org.slf4j:slf4j-simple:2.0.17' testImplementation 'org.slf4j:slf4j-simple:1.7.36'
testRuntimeOnly "org.apiguardian:apiguardian-api:${apiGuardianVersion}" testRuntimeOnly "org.apiguardian:apiguardian-api:${apiGuardianVersion}"
if (SAXON_TEST) {
testRuntimeOnly "net.sf.saxon:Saxon-HE:${saxonVersion}"
}
} }
final String MODULE_NAME = 'org.apache.poi.stress' final String MODULE_NAME = 'org.apache.poi.stress'
@ -90,26 +96,43 @@ final String OOXML_LITE_AGENT = "../build/dist/maven/poi-ooxml-lite-agent/poi-oo
final String OOXML_LITE_REPORT = '../src/resources/ooxml-lite-report' final String OOXML_LITE_REPORT = '../src/resources/ooxml-lite-report'
final String OOXML_LITE_INCLUDES = "^(com/microsoft/schemas|org/(etsi|openxmlformats|w3/)|org/apache/poi/schemas)" final String OOXML_LITE_INCLUDES = "^(com/microsoft/schemas|org/(etsi|openxmlformats|w3/)|org/apache/poi/schemas)"
tasks.register('compileTest9', JavaCompile) { java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(jdkVersion))
if (jdkVendor != '') vendor.set(JvmVendorSpec.matching(jdkVendor))
}
}
task compileTest9(type: JavaCompile) {
dependsOn 'compileTestJava', ':poi-ooxml:testJar', ':poi-scratchpad:testJar', ':poi-examples:jar' dependsOn 'compileTestJava', ':poi-ooxml:testJar', ':poi-scratchpad:testJar', ':poi-examples:jar'
javaCompiler = javaToolchains.compilerFor { javaCompiler = javaToolchains.compilerFor {
languageVersion = JavaLanguageVersion.of(Math.max(11, jdkVersion)) languageVersion = JavaLanguageVersion.of(jdkVersion)
if (jdkVendor != '') vendor = JvmVendorSpec.matching(jdkVendor)
} }
sourceCompatibility = 11
targetCompatibility = 11
destinationDirectory = file(TEST9_OUT + VERSIONS9) destinationDirectory = file(TEST9_OUT + VERSIONS9)
source = file(TEST9_SRC) source = file(TEST9_SRC)
options.compilerArgs = [ options.compilerArgs = [
'--patch-module', "${MODULE_NAME}=${(sourceSets.main.output.classesDirs + sourceSets.test.output.classesDirs).asPath}", '--patch-module', "${MODULE_NAME}=${(sourceSets.main.output.classesDirs + sourceSets.test.output.classesDirs).asPath}",
'--module-path', files(MODULE_COMPILE_PATH).asPath '--module-path', files(MODULE_COMPILE_PATH).asPath
] ]
classpath = files() classpath = files()
onlyIf {
jdkVersion > 8
}
} }
task cacheTest9(type: Copy) {
dependsOn 'compileTest9'
from(file(TEST9_OUT + VERSIONS9))
into(TEST9_SRC)
}
jar { jar {
destinationDirectory = file("../build/dist/maven/${base.archivesName.get()}") destinationDirectory = file("../build/dist/maven/${project.archivesBaseName}")
manifest { manifest {
attributes('Automatic-Module-Name': MODULE_NAME, 'Multi-Release': 'true') attributes('Automatic-Module-Name': MODULE_NAME, 'Multi-Release': 'true')
@ -118,12 +141,18 @@ jar {
// Create a separate jar for test-code to depend on it in other projects // Create a separate jar for test-code to depend on it in other projects
// See http://stackoverflow.com/questions/5144325/gradle-test-dependency // See http://stackoverflow.com/questions/5144325/gradle-test-dependency
task testJar(type: Jar, dependsOn: [ testClasses, compileTest9 ] ) { task testJar(type: Jar, dependsOn: [ testClasses, cacheTest9 ] ) {
destinationDirectory = file("../build/dist/maven/${base.archivesName.get()}-tests") destinationDirectory = file("../build/dist/maven/${project.archivesBaseName}-tests")
setArchiveClassifier 'tests' classifier 'tests'
// ignore second module-info.class from main // ignore second module-info.class from main
duplicatesStrategy = DuplicatesStrategy.EXCLUDE duplicatesStrategy = 'exclude'
if (jdkVersion == 8) {
into('META-INF/versions/9') {
from TEST9_SRC include '*.class'
}
}
from sourceSets.test.output + sourceSets.main.output from sourceSets.test.output + sourceSets.main.output
@ -147,22 +176,24 @@ test {
doFirst { doFirst {
jvmArgs += [ jvmArgs += [
"-javaagent:${OOXML_LITE_AGENT}=${OOXML_LITE_REPORT}|${OOXML_LITE_INCLUDES}", "-javaagent:${OOXML_LITE_AGENT}=${OOXML_LITE_REPORT}|${OOXML_LITE_INCLUDES}",
'--add-modules', MODULE_NAME,
'--module-path', '../build/dist/maven/poi-integration-tests' + File.pathSeparator + files(MODULE_RUNTIME_PATH).asPath,
] ]
if (jdkVersion > 8) {
jvmArgs += [
'--add-modules', MODULE_NAME,
'--module-path', '../build/dist/maven/poi-integration-tests' + File.pathSeparator + files(MODULE_RUNTIME_PATH).asPath,
]
}
if (NO_SCRATCHPAD) { if (NO_SCRATCHPAD) {
systemProperty 'scratchpad.ignore', 'true' systemProperty 'scratchpad.ignore', 'true'
} }
} }
} }
javadoc { javadoc.onlyIf { false }
enabled = false
}
sourcesJar { javadocJar.onlyIf { false }
enabled = false
} sourcesJar.onlyIf { false }
generateMetadataFileForPOIPublication.enabled = false generateMetadataFileForPOIPublication.enabled = false
publishPOIPublicationToMavenLocal.enabled = false publishPOIPublicationToMavenLocal.enabled = false

View File

@ -27,14 +27,11 @@ Before running this, you should execute the "jar" target in the main build.gradl
<property name="dist" value="../build/dist"/> <property name="dist" value="../build/dist"/>
<property name="build" value="../build/distsourcebuild"/> <property name="build" value="../build/distsourcebuild"/>
<!-- Gradle is executed in ../build/poi-<version>, so three ".." are needed to use gradle from the root-dir --> <condition property="gradle.executable" value="../gradlew.bat" else="../gradlew">
<condition property="gradle.executable" value="../../../gradlew.bat" else="../../../gradlew">
<os family="windows" /> <os family="windows" />
</condition> </condition>
<target name="init" depends=""> <target name="init" depends="">
<echo message="Using Ant: ${ant.version} from ${ant.home}, Ant detected Java ${ant.java.version} (may be different than actual Java sometimes...)" />
<echo message="Using Java: ${java.version}/${java.runtime.version}/${java.vm.version}/${java.vm.name} from ${java.vm.vendor} on ${os.name}: ${os.version}" />
</target> </target>
<target name="run" depends="init,runSourceBuild,runCompileTest"/> <target name="run" depends="init,runSourceBuild,runCompileTest"/>
@ -51,14 +48,14 @@ Before running this, you should execute the "jar" target in the main build.gradl
<date xmlns="antlib:org.apache.tools.ant.types.resources.comparators"/> <date xmlns="antlib:org.apache.tools.ant.types.resources.comparators"/>
<resources> <resources>
<fileset dir="${dist}"> <fileset dir="${dist}">
<include name="apache-poi-src-*.zip"/> <include name="poi-src-*.zip"/>
</fileset> </fileset>
</resources> </resources>
</sort> </sort>
</last> </last>
</pathconvert> </pathconvert>
<echo message="Found source package with pattern 'apache-poi-src-*.zip' in ${dist} at '${srcpackage}'. Run Gradle-task 'srcDistZip' in the main directory if it is missing"/> <echo message="Found source package at ${srcpackage}"/>
<unzip src="${srcpackage}" dest="${build}" failOnEmptyArchive="true"/> <unzip src="${srcpackage}" dest="${build}" failOnEmptyArchive="true"/>
<!-- look for name of sub-dir, do this dynamically as it changes with every (beta|rc)-release --> <!-- look for name of sub-dir, do this dynamically as it changes with every (beta|rc)-release -->
@ -77,7 +74,7 @@ Before running this, you should execute the "jar" target in the main build.gradl
<!-- finally call Ant on the extracted source to check if we can build the packages --> <!-- finally call Ant on the extracted source to check if we can build the packages -->
<echo message="Building in temporary dir ${dirversion}/"/> <echo message="Building in temporary dir ${dirversion}/"/>
<!--ant dir="${dirversion}" target="assemble" inheritAll="false" inheritRefs="false" useNativeBasedir="true"/--> <!--ant dir="${dirversion}" target="assemble" inheritAll="false" inheritRefs="false" useNativeBasedir="true"/-->
<exec executable="${gradle.executable}" dir="${dirversion}" failonerror="true"> <exec executable="${gradle.executable}" dir="." failonerror="true">
<arg value="assemble" /> <arg value="assemble" />
</exec> </exec>
</target> </target>
@ -94,9 +91,9 @@ Before running this, you should execute the "jar" target in the main build.gradl
<sort> <sort>
<resources> <resources>
<fileset dir="${dist}"> <fileset dir="${dist}">
<include name="**/poi-6.*.jar"/> <include name="**/poi-5.*.jar"/>
<include name="**/poi-ooxml-6.*.jar"/> <include name="**/poi-ooxml-5.*.jar"/>
<include name="**/poi-ooxml-lite-6.*.jar"/> <include name="**/poi-ooxml-lite-5.*.jar"/>
<exclude name="**/*-javadoc*"/> <exclude name="**/*-javadoc*"/>
<exclude name="**/*-sources*"/> <exclude name="**/*-sources*"/>
</fileset> </fileset>
@ -126,7 +123,7 @@ Before running this, you should execute the "jar" target in the main build.gradl
<echo message="Compiling examples without linking to scratchpad.jar to ensure that only some specific ones require this jar"/> <echo message="Compiling examples without linking to scratchpad.jar to ensure that only some specific ones require this jar"/>
<javac srcdir="../poi-examples/src/main/java" destdir="${build}" <javac srcdir="../poi-examples/src/main/java" destdir="${build}"
target="11" source="11" debug="true" target="1.8" source="1.8" debug="true"
encoding="ASCII" fork="yes" includeantruntime="false" encoding="ASCII" fork="yes" includeantruntime="false"
excludes="org/apache/poi/examples/hslf/**,org/apache/poi/examples/hsmf/**,org/apache/poi/examples/hwmf/**,**/EmbeddedObjects.java,**/EmeddedObjects.java,**/LoadEmbedded.java,**/Word2Forrest.java" excludes="org/apache/poi/examples/hslf/**,org/apache/poi/examples/hsmf/**,org/apache/poi/examples/hwmf/**,**/EmbeddedObjects.java,**/EmeddedObjects.java,**/LoadEmbedded.java,**/Word2Forrest.java"
classpath="${jarpackage}" classpathref="libs"> classpath="${jarpackage}" classpathref="libs">
@ -137,10 +134,10 @@ Before running this, you should execute the "jar" target in the main build.gradl
<sort> <sort>
<resources> <resources>
<fileset dir="${dist}"> <fileset dir="${dist}">
<include name="**/poi-6.*.jar"/> <include name="**/poi-5.*.jar"/>
<include name="**/poi-ooxml-6.*.jar"/> <include name="**/poi-ooxml-5.*.jar"/>
<include name="**/poi-ooxml-lite-6.*.jar"/> <include name="**/poi-ooxml-lite-5.*.jar"/>
<include name="**/poi-scratchpad-6.*.jar"/> <include name="**/poi-scratchpad-5.*.jar"/>
<exclude name="**/*-javadoc*"/> <exclude name="**/*-javadoc*"/>
<exclude name="**/*-sources*"/> <exclude name="**/*-sources*"/>
</fileset> </fileset>
@ -150,7 +147,7 @@ Before running this, you should execute the "jar" target in the main build.gradl
<echo message="Compiling all examples with the additional scratchpad.jar"/> <echo message="Compiling all examples with the additional scratchpad.jar"/>
<javac srcdir="../poi-examples/src/main/java" destdir="${build}" <javac srcdir="../poi-examples/src/main/java" destdir="${build}"
target="11" source="11" debug="true" target="1.8" source="1.8" debug="true"
encoding="ASCII" fork="yes" includeantruntime="false" encoding="ASCII" fork="yes" includeantruntime="false"
classpath="${jarpackagescratchpad}" classpathref="libs"> classpath="${jarpackagescratchpad}" classpathref="libs">
</javac> </javac>

View File

@ -37,6 +37,7 @@ import org.apache.poi.hpsf.extractor.HPSFPropertiesExtractor;
import org.apache.poi.hssf.extractor.EventBasedExcelExtractor; import org.apache.poi.hssf.extractor.EventBasedExcelExtractor;
import org.apache.poi.ooxml.POIXMLException; import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.ss.extractor.ExcelExtractor; import org.apache.poi.ss.extractor.ExcelExtractor;
import org.apache.poi.util.IOUtils;
/** /**
* Base class with things that can be run for any supported file handler * Base class with things that can be run for any supported file handler
@ -87,78 +88,54 @@ public abstract class AbstractFileHandler implements FileHandler {
long length = file.length(); long length = file.length();
long modified = file.lastModified(); long modified = file.lastModified();
POITextExtractor extractor = null;
String fileAndParentName = file.getParentFile().getName() + "/" + file.getName(); String fileAndParentName = file.getParentFile().getName() + "/" + file.getName();
try { try {
handleExtractingAsStream(file);
// fix windows absolute paths for exception message tracking // fix windows absolute paths for exception message tracking
String relPath = file.getPath().replaceAll(".*test-data", "test-data").replace('\\', '/'); String relPath = file.getPath().replaceAll(".*test-data", "test-data").replace('\\', '/');
try (POITextExtractor extractor = ExtractorFactory.createExtractor(file)) { extractor = ExtractorFactory.createExtractor(file);
assertNotNull(extractor, "Should get a POITextExtractor but had none for file " + relPath); assertNotNull(extractor, "Should get a POITextExtractor but had none for file " + relPath);
assertNotNull(extractor.getText(), "Should get some text but had none for file " + relPath); assertNotNull(extractor.getText(), "Should get some text but had none for file " + relPath);
// also try metadata // also try metadata
POITextExtractor metadataExtractor = extractor.getMetadataTextExtractor(); @SuppressWarnings("resource")
assertNotNull(metadataExtractor.getText()); POITextExtractor metadataExtractor = extractor.getMetadataTextExtractor();
assertNotNull(metadataExtractor.getText());
assertFalse(EXPECTED_EXTRACTOR_FAILURES.contains(fileAndParentName), assertFalse(EXPECTED_EXTRACTOR_FAILURES.contains(fileAndParentName),
"Expected Extraction to fail for file " + relPath + " and handler " + this + ", but did not fail!"); "Expected Extraction to fail for file " + relPath + " and handler " + this + ", but did not fail!");
assertEquals(length, file.length(), "File should not be modified by extractor"); assertEquals(length, file.length(), "File should not be modified by extractor");
assertEquals(modified, file.lastModified(), "File should not be modified by extractor"); assertEquals(modified, file.lastModified(), "File should not be modified by extractor");
if (extractor instanceof POIOLE2TextExtractor) { handleExtractingAsStream(file);
POIOLE2TextExtractor ole2Extractor = (POIOLE2TextExtractor) extractor;
ole2Extractor.getRoot();
if (!(ole2Extractor instanceof EventBasedExcelExtractor)) {
ole2Extractor.getSummaryInformation();
ole2Extractor.getDocSummaryInformation();
}
try (HPSFPropertiesExtractor hpsfExtractor = new HPSFPropertiesExtractor(ole2Extractor)) { if (extractor instanceof POIOLE2TextExtractor) {
assertNotNull(hpsfExtractor.getDocumentSummaryInformationText()); try (HPSFPropertiesExtractor hpsfExtractor = new HPSFPropertiesExtractor((POIOLE2TextExtractor) extractor)) {
assertNotNull(hpsfExtractor.getSummaryInformationText()); assertNotNull(hpsfExtractor.getDocumentSummaryInformationText());
String text = hpsfExtractor.getText(); assertNotNull(hpsfExtractor.getSummaryInformationText());
//System.out.println(text); String text = hpsfExtractor.getText();
assertNotNull(text); //System.out.println(text);
}
if (ole2Extractor.getRoot() != null && !Boolean.getBoolean("scratchpad.ignore")) {
POITextExtractor[] embedded = ExtractorFactory.getEmbeddedDocsTextExtractors(ole2Extractor);
try {
for (POITextExtractor poiTextExtractor : embedded) {
poiTextExtractor.getText();
poiTextExtractor.getDocument();
poiTextExtractor.getFilesystem();
POITextExtractor metaData = poiTextExtractor.getMetadataTextExtractor();
metaData.getFilesystem();
metaData.getText();
}
} finally {
for (POITextExtractor embeddedExtractor : embedded) {
embeddedExtractor.close();
}
}
}
}
// test again with including formulas and cell-comments as this caused some bugs
if (extractor instanceof ExcelExtractor &&
// comment-extraction and formula extraction are not well supported in event based extraction
!(extractor instanceof EventBasedExcelExtractor)) {
((ExcelExtractor) extractor).setFormulasNotResults(true);
String text = extractor.getText();
assertNotNull(text);
// */
((ExcelExtractor) extractor).setIncludeCellComments(true);
text = extractor.getText();
assertNotNull(text); assertNotNull(text);
} }
} }
// test again with including formulas and cell-comments as this caused some bugs
if (extractor instanceof ExcelExtractor &&
// comment-extraction and formula extraction are not well supported in event based extraction
!(extractor instanceof EventBasedExcelExtractor)) {
((ExcelExtractor) extractor).setFormulasNotResults(true);
String text = extractor.getText();
assertNotNull(text);
// */
((ExcelExtractor) extractor).setIncludeCellComments(true);
text = extractor.getText();
assertNotNull(text);
}
} catch (IOException | POIXMLException e) { } catch (IOException | POIXMLException e) {
Exception prevE = e; Exception prevE = e;
Throwable cause; Throwable cause;
@ -182,6 +159,8 @@ public abstract class AbstractFileHandler implements FileHandler {
if (!e.getMessage().contains("POI Scratchpad jar missing") || !Boolean.getBoolean("scratchpad.ignore")) { if (!e.getMessage().contains("POI Scratchpad jar missing") || !Boolean.getBoolean("scratchpad.ignore")) {
throw e; throw e;
} }
} finally {
IOUtils.closeQuietly(extractor);
} }
} }
@ -191,11 +170,6 @@ public abstract class AbstractFileHandler implements FileHandler {
assertNotNull(streamExtractor); assertNotNull(streamExtractor);
assertNotNull(streamExtractor.getText()); assertNotNull(streamExtractor.getText());
POITextExtractor metadataTextExtractor = streamExtractor.getMetadataTextExtractor();
assertNotNull(metadataTextExtractor);
assertNotNull(metadataTextExtractor.getText());
} }
} }
} }

View File

@ -29,8 +29,6 @@ public enum FileHandlerKnown {
HSLF, HSLF,
HSMF, HSMF,
HSSF, HSSF,
HEMF,
HWMF,
HWPF, HWPF,
OPC, OPC,
POIFS, POIFS,

View File

@ -1,85 +0,0 @@
/* ====================================================================
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.stress;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import org.apache.poi.hemf.record.emf.HemfRecord;
import org.apache.poi.hemf.record.emf.HemfRecordType;
import org.apache.poi.hemf.record.emf.HemfText;
import org.apache.poi.hemf.usermodel.HemfPicture;
import org.junit.jupiter.api.Test;
public class HEMFFileHandler implements FileHandler {
@Override
public void handleExtracting(File file) throws Exception {
try (InputStream stream = new BufferedInputStream(new FileInputStream(file))) {
HemfPicture picture = new HemfPicture(stream);
// mimic a bit what e.g. Tika does to extract some information from .emf files
for (HemfRecord record : picture.getRecords()) {
if (record.getEmfRecordType().equals(HemfRecordType.extTextOutW)) {
assertInstanceOf(HemfText.EmfExtTextOutW.class, record);
HemfText.EmfExtTextOutW textOut = (HemfText.EmfExtTextOutW) record;
textOut.getText(StandardCharsets.UTF_16LE);
} else if (record.getEmfRecordType().equals(HemfRecordType.extTextOutA)) {
assertInstanceOf(HemfText.EmfExtTextOutA.class, record);
HemfText.EmfExtTextOutA textOut = (HemfText.EmfExtTextOutA) record;
textOut.getText(StandardCharsets.UTF_8);
}
}
}
}
@Override
public void handleAdditional(File file) throws Exception {
// no additional checks for now
}
@Override
public void handleFile(InputStream stream, String path) throws Exception {
HemfPicture picture = new HemfPicture(stream);
for (HemfRecord record : picture.getRecords()) {
record.getEmfRecordType();
record.getGenericRecordType();
}
BufferedImage dest = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
picture.draw(dest.createGraphics(), new Rectangle2D.Double(0, 0, 256, 256));
}
@Test
void test() throws Exception {
String file = "test-data/slideshow/wrench.emf";
try (InputStream stream = new BufferedInputStream(new FileInputStream(file))) {
handleFile(stream, file);
}
handleExtracting(new File(file));
}
}

View File

@ -45,16 +45,22 @@ public class HPBFFileHandler extends POIFSFileHandler {
void test() throws Exception { void test() throws Exception {
File file = new File("test-data/publisher/SampleBrochure.pub"); File file = new File("test-data/publisher/SampleBrochure.pub");
try (InputStream stream = new FileInputStream(file)) { InputStream stream = new FileInputStream(file);
try {
handleFile(stream, file.getPath()); handleFile(stream, file.getPath());
} finally {
stream.close();
} }
handleExtracting(file); handleExtracting(file);
try (InputStream stream = new FileInputStream(file)) { stream = new FileInputStream(file);
try {
try (PublisherTextExtractor extractor = new PublisherTextExtractor(stream)) { try (PublisherTextExtractor extractor = new PublisherTextExtractor(stream)) {
assertNotNull(extractor.getText()); assertNotNull(extractor.getText());
} }
} finally {
stream.close();
} }
} }

View File

@ -43,6 +43,8 @@ import org.apache.poi.util.TempFile;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
public class HPSFFileHandler extends POIFSFileHandler { public class HPSFFileHandler extends POIFSFileHandler {
private static final String NL = System.getProperty("line.separator");
private static final ThreadLocal<File> copyOutput = ThreadLocal.withInitial(HPSFFileHandler::getTempFile); private static final ThreadLocal<File> copyOutput = ThreadLocal.withInitial(HPSFFileHandler::getTempFile);
static final Set<String> EXCLUDES_HANDLE_ADD = StressTestUtils.unmodifiableHashSet( static final Set<String> EXCLUDES_HANDLE_ADD = StressTestUtils.unmodifiableHashSet(
@ -101,7 +103,7 @@ public class HPSFFileHandler extends POIFSFileHandler {
private static boolean hasPropertyStream(POIFSFileSystem poifs, String streamName) throws IOException { private static boolean hasPropertyStream(POIFSFileSystem poifs, String streamName) throws IOException {
DirectoryNode root = poifs.getRoot(); DirectoryNode root = poifs.getRoot();
if (!root.hasEntryCaseInsensitive(streamName)) { if (!root.hasEntry(streamName)) {
return false; return false;
} }
try (DocumentInputStream dis = root.createDocumentInputStream(streamName)) { try (DocumentInputStream dis = root.createDocumentInputStream(streamName)) {
@ -138,10 +140,12 @@ public class HPSFFileHandler extends POIFSFileHandler {
try (InputStream stream = new FileInputStream(path)) { try (InputStream stream = new FileInputStream(path)) {
handleFile(stream, path); handleFile(stream, path);
} }
}
File file = new File(path); // a test-case to test this locally without executing the full TestAllFiles
@Test
void testExtractor() {
File file = new File("test-data/hpsf/TestBug44375.xls");
assertDoesNotThrow(() -> handleExtracting(file)); assertDoesNotThrow(() -> handleExtracting(file));
handleAdditional(file);
} }
} }

View File

@ -23,15 +23,15 @@ import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.InputStream; import java.io.InputStream;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.apache.poi.logging.PoiLogManager;
import org.apache.poi.hslf.usermodel.HSLFSlideShow; import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl; import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
public class HSLFFileHandler extends SlideShowHandler { public class HSLFFileHandler extends SlideShowHandler {
private static final Logger LOGGER = PoiLogManager.getLogger(HSLFFileHandler.class); private static final Logger LOGGER = LogManager.getLogger(HSLFFileHandler.class);
@Override @Override
public void handleFile(InputStream stream, String path) throws Exception { public void handleFile(InputStream stream, String path) throws Exception {
@ -84,8 +84,6 @@ public class HSLFFileHandler extends SlideShowHandler {
} }
handleExtracting(file); handleExtracting(file);
handleAdditional(file);
} }
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {

View File

@ -1,93 +0,0 @@
/* ====================================================================
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.stress;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.charset.Charset;
import org.apache.poi.hwmf.record.HwmfFont;
import org.apache.poi.hwmf.record.HwmfRecord;
import org.apache.poi.hwmf.record.HwmfRecordType;
import org.apache.poi.hwmf.record.HwmfText;
import org.apache.poi.hwmf.usermodel.HwmfPicture;
import org.apache.poi.util.LocaleUtil;
import org.junit.jupiter.api.Test;
public class HWMFFileHandler implements FileHandler {
@Override
public void handleExtracting(File file) throws Exception {
try (InputStream stream = new BufferedInputStream(new FileInputStream(file))) {
HwmfPicture picture = new HwmfPicture(stream);
Charset charset = LocaleUtil.CHARSET_1252;
// mimic a bit what e.g. Tika does to extract some information from .wmf files
for (HwmfRecord record : picture.getRecords()) {
if (record.getWmfRecordType().equals(HwmfRecordType.createFontIndirect)) {
HwmfFont font = ((HwmfText.WmfCreateFontIndirect) record).getFont();
charset = (font.getCharset() == null || font.getCharset().getCharset() == null) ?
LocaleUtil.CHARSET_1252 : font.getCharset().getCharset();
}
if (record.getWmfRecordType().equals(HwmfRecordType.extTextOut)) {
assertInstanceOf(HwmfText.WmfExtTextOut.class, record);
HwmfText.WmfExtTextOut textOut = (HwmfText.WmfExtTextOut) record;
textOut.getText(charset);
} else if (record.getWmfRecordType().equals(HwmfRecordType.textOut)) {
assertInstanceOf(HwmfText.WmfTextOut.class, record);
HwmfText.WmfTextOut textOut = (HwmfText.WmfTextOut) record;
textOut.getText(charset);
}
}
}
}
@Override
public void handleAdditional(File file) throws Exception {
// no additional checks for now
}
@Override
public void handleFile(InputStream stream, String path) throws Exception {
HwmfPicture picture = new HwmfPicture(stream);
for (HwmfRecord record : picture.getRecords()) {
record.getWmfRecordType();
record.getGenericRecordType();
}
BufferedImage dest = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
picture.draw(dest.createGraphics());
}
@Test
void test() throws Exception {
String file = "test-data/slideshow/santa.wmf";
try (InputStream stream = new BufferedInputStream(new FileInputStream(file))) {
handleFile(stream, file);
}
handleExtracting(new File(file));
}
}

View File

@ -19,11 +19,10 @@ package org.apache.poi.stress;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.BufferedInputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.io.PushbackInputStream; import java.io.PushbackInputStream;
import java.nio.file.Files;
import java.util.Set; import java.util.Set;
import org.apache.poi.openxml4j.opc.ContentTypes; import org.apache.poi.openxml4j.opc.ContentTypes;
@ -62,13 +61,17 @@ public class OPCFileHandler extends AbstractFileHandler {
} }
} }
@Override
public void handleExtracting(File file) {
// text-extraction is not possible currently for these types of files
}
// a test-case to test this locally without executing the full TestAllFiles // a test-case to test this locally without executing the full TestAllFiles
@Test @Test
void test() throws Exception { void test() throws Exception {
File file = new File("test-data/diagram/test.vsdx"); File file = new File("test-data/diagram/test.vsdx");
try (InputStream stream = new BufferedInputStream( try (InputStream stream = new PushbackInputStream(new FileInputStream(file), 100000)) {
new PushbackInputStream(Files.newInputStream(file.toPath()), 100000))) {
handleFile(stream, file.getPath()); handleFile(stream, file.getPath());
} }

View File

@ -57,7 +57,7 @@ public class POIFSFileHandler extends AbstractFileHandler {
} }
protected void handlePOIDocument(POIDocument doc) throws Exception { protected void handlePOIDocument(POIDocument doc) throws Exception {
try (UnsynchronizedByteArrayOutputStream out = UnsynchronizedByteArrayOutputStream.builder().get()) { try (UnsynchronizedByteArrayOutputStream out = new UnsynchronizedByteArrayOutputStream()) {
doc.write(out); doc.write(out);
try (InputStream in = out.toInputStream(); try (InputStream in = out.toInputStream();

View File

@ -40,7 +40,7 @@ public final class POIXMLDocumentHandler {
protected static boolean isEncrypted(InputStream stream) throws IOException { protected static boolean isEncrypted(InputStream stream) throws IOException {
if (FileMagic.valueOf(stream) == FileMagic.OLE2) { if (FileMagic.valueOf(stream) == FileMagic.OLE2) {
try (POIFSFileSystem poifs = new POIFSFileSystem(stream)) { try (POIFSFileSystem poifs = new POIFSFileSystem(stream)) {
if (poifs.getRoot().hasEntryCaseInsensitive(Decryptor.DEFAULT_POIFS_ENTRY)) { if (poifs.getRoot().hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) {
return true; return true;
} }
} }

View File

@ -29,7 +29,6 @@ import java.lang.ref.WeakReference;
import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream; import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
import org.apache.poi.sl.draw.Drawable; import org.apache.poi.sl.draw.Drawable;
import org.apache.poi.sl.usermodel.GroupShape; import org.apache.poi.sl.usermodel.GroupShape;
import org.apache.poi.sl.usermodel.MasterSheet;
import org.apache.poi.sl.usermodel.Notes; import org.apache.poi.sl.usermodel.Notes;
import org.apache.poi.sl.usermodel.PictureData; import org.apache.poi.sl.usermodel.PictureData;
import org.apache.poi.sl.usermodel.Shape; import org.apache.poi.sl.usermodel.Shape;
@ -50,7 +49,7 @@ public abstract class SlideShowHandler extends POIFSFileHandler {
readPictures(ss); readPictures(ss);
// write out the file // write out the file
UnsynchronizedByteArrayOutputStream out = UnsynchronizedByteArrayOutputStream.builder().get(); UnsynchronizedByteArrayOutputStream out = new UnsynchronizedByteArrayOutputStream();
ss.write(out); ss.write(out);
readContent(ss); readContent(ss);
@ -77,11 +76,8 @@ public abstract class SlideShowHandler extends POIFSFileHandler {
} }
} }
MasterSheet<?, ?> masterSheet = s.getMasterSheet(); for (Shape<?,?> shape : s.getMasterSheet()) {
if (masterSheet != null) { readShapes(shape);
for (Shape<?,?> shape : masterSheet) {
readShapes(shape);
}
} }
} }
} }

View File

@ -37,8 +37,6 @@ public abstract class SpreadsheetHandler extends AbstractFileHandler {
// try to access some of the content // try to access some of the content
readContent(wb); readContent(wb);
extractEmbedded(wb);
// write out the file // write out the file
writeToArray(wb); writeToArray(wb);
@ -63,7 +61,7 @@ public abstract class SpreadsheetHandler extends AbstractFileHandler {
} }
private UnsynchronizedByteArrayOutputStream writeToArray(Workbook wb) throws IOException { private UnsynchronizedByteArrayOutputStream writeToArray(Workbook wb) throws IOException {
UnsynchronizedByteArrayOutputStream stream = UnsynchronizedByteArrayOutputStream.builder().get(); UnsynchronizedByteArrayOutputStream stream = new UnsynchronizedByteArrayOutputStream();
wb.write(stream); wb.write(stream);
return stream; return stream;
} }

View File

@ -46,7 +46,7 @@ public class StressMap {
private final Pattern SCRATCH_HANDLER = Pattern.compile("(HSLF|HWPF|HSMF|HMEF)"); private final Pattern SCRATCH_HANDLER = Pattern.compile("(HSLF|HWPF|HSMF|HMEF)");
public void load(File mapFile) throws IOException { public void load(File mapFile) throws IOException {
try (Workbook wb = WorkbookFactory.create(mapFile, null, true)) { try (Workbook wb = WorkbookFactory.create(mapFile)) {
readExMap(wb.getSheet("Exceptions")); readExMap(wb.getSheet("Exceptions"));
readHandlerMap(wb.getSheet("Handlers")); readHandlerMap(wb.getSheet("Handlers"));
} }
@ -119,7 +119,7 @@ public class StressMap {
Row row = iter.next(); Row row = iter.next();
if (SCRATCH_IGNORE && handlerIdx > -1) { if (SCRATCH_IGNORE && handlerIdx > -1) {
String handler = row.getCell(handlerIdx) == null ? "" : row.getCell(handlerIdx).getStringCellValue(); String handler = row.getCell(handlerIdx).getStringCellValue();
if (SCRATCH_HANDLER.matcher(handler).find()) { if (SCRATCH_HANDLER.matcher(handler).find()) {
// ignore exception of ignored files // ignore exception of ignored files
continue; continue;

View File

@ -36,7 +36,6 @@ import java.util.stream.Stream;
import org.apache.poi.POIDataSamples; import org.apache.poi.POIDataSamples;
import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey; import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.DirectoryScanner;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.function.Executable; import org.junit.jupiter.api.function.Executable;
import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode; import org.junit.jupiter.api.parallel.ExecutionMode;
@ -50,12 +49,12 @@ import org.opentest4j.AssertionFailedError;
* to reveal problems which are introduced, but not covered (yet) by unit tests. * to reveal problems which are introduced, but not covered (yet) by unit tests.
* *
* This test looks for any file under the test-data directory and tries to do some useful * This test looks for any file under the test-data directory and tries to do some useful
* processing with it based on its type. * processing with it based on it's type.
* *
* The test is implemented as a junit {@link ParameterizedTest} test, which leads * The test is implemented as a junit {@link ParameterizedTest} test, which leads
* to one test-method call for each file (currently around 950 files are handled). * to one test-method call for each file (currently around 950 files are handled).
* *
* There is a mapping of extension to implementations of the interface * There is a a mapping of extension to implementations of the interface
* {@link FileHandler} which defines how the file is loaded and which actions are * {@link FileHandler} which defines how the file is loaded and which actions are
* tried with the file. * tried with the file.
* *
@ -96,19 +95,14 @@ public class TestAllFiles {
"poifs/protected_sha512.xlsx", "poifs/protected_sha512.xlsx",
"poifs/60320-protected.xlsx", "poifs/60320-protected.xlsx",
"poifs/protected_sha512.xlsx", "poifs/protected_sha512.xlsx",
// stress docs
"document/deep-table-cell.docx",
// invalid files
"spreadsheet/bug69769.xlsx",
// NOTE: Expected failures should usually be added in file "stress.xls" instead
// of being listed here in order to also verify the expected exception details!
}; };
// cheap workaround of skipping the few problematic files // cheap workaround of skipping the few problematic files
public static final String[] SCAN_EXCLUDES_NOSCRATCHPAD = concat(SCAN_EXCLUDES, new String[] { public static final String[] SCAN_EXCLUDES_NOSCRATCHPAD = {
"**/.svn/**",
"lost+found",
"**/.git/**",
"**/ExternalEntityInText.docx", //the DocType (DTD) declaration causes this to fail
"**/right-to-left.xlsx", //the threaded comments in this file cause XSSF clone to fail "**/right-to-left.xlsx", //the threaded comments in this file cause XSSF clone to fail
"document/word2.doc", "document/word2.doc",
"document/cpansearch.perl.org_src_tobyink_acme-rundoc-0.001_word-lib_hello_world.docm", "document/cpansearch.perl.org_src_tobyink_acme-rundoc-0.001_word-lib_hello_world.docm",
@ -124,39 +118,17 @@ public class TestAllFiles {
"spreadsheet/testEXCEL_3.xls", "spreadsheet/testEXCEL_3.xls",
"spreadsheet/testEXCEL_4.xls", "spreadsheet/testEXCEL_4.xls",
"poifs/unknown_properties.msg", "poifs/unknown_properties.msg",
"publisher/clusterfuzz-testcase-minimized-POIHPBFFuzzer-4701121678278656.pub",
"hsmf/clusterfuzz-testcase-minimized-POIHSMFFuzzer-4848576776503296.msg", // exclude files failing on windows nodes, because of limited JCE policies
"hsmf/clusterfuzz-testcase-minimized-POIHSMFFuzzer-5336473854148608.msg", "document/bug53475-password-is-pass.docx",
"slideshow/clusterfuzz-testcase-minimized-POIHSLFFuzzer-6416153805979648.ppt", "poifs/60320-protected.xlsx",
"slideshow/clusterfuzz-testcase-minimized-POIHSLFFuzzer-6710128412590080.ppt", "poifs/protected_sha512.xlsx",
"publisher/clusterfuzz-testcase-minimized-POIHPBFFuzzer-4701121678278656.pub", "poifs/60320-protected.xlsx",
"spreadsheet/clusterfuzz-testcase-minimized-POIHSSFFuzzer-5285517825277952.xls", "poifs/protected_sha512.xlsx",
"spreadsheet/clusterfuzz-testcase-minimized-POIHSSFFuzzer-6322470200934400.xls", };
"document/clusterfuzz-testcase-minimized-POIHWPFFuzzer-5418937293340672.doc",
"document/clusterfuzz-testcase-minimized-POIHWPFFuzzer-5440721166139392.doc",
"diagram/clusterfuzz-testcase-minimized-POIHDGFFuzzer-5947849161179136.vsd",
"spreadsheet/clusterfuzz-testcase-minimized-POIHSSFFuzzer-5436547081830400.xls",
"spreadsheet/clusterfuzz-testcase-minimized-POIHSSFFuzzer-4819588401201152.xls",
"diagram/clusterfuzz-testcase-minimized-POIVisioFuzzer-4537225637134336.vsd",
"spreadsheet/clusterfuzz-testcase-minimized-POIHSSFFuzzer-6537773940867072.xls",
"spreadsheet/clusterfuzz-testcase-minimized-POIHSSFFuzzer-4977868385681408.xls",
"spreadsheet/clusterfuzz-testcase-minimized-POIHSSFFuzzer-4651309315719168.xls",
"document/clusterfuzz-testcase-POIHWPFFuzzer-5696094627495936.doc",
"spreadsheet/clusterfuzz-testcase-minimized-POIHSSFFuzzer-4657005060816896.xls",
"diagram/clusterfuzz-testcase-minimized-POIHDGFFuzzer-4913778037489664.vsd",
"diagram/clusterfuzz-testcase-minimized-POIHDGFFuzzer-6478389109981184.vsd",
"publisher/clusterfuzz-testcase-minimized-POIHPBFFuzzer-4918886059278336.pub",
"publisher/clusterfuzz-testcase-minimized-POIHPBFFuzzer-4918886059278336.pub",
"publisher/clusterfuzz-testcase-minimized-POIHPBFFuzzer-6325615354773504.pub",
"spreadsheet/clusterfuzz-testcase-minimized-POIHSSFFuzzer-4734163573080064.xls",
"spreadsheet/rde.imf.ru_sites_default_files_rde_documents_vodootvedenie_2020.xlsb.xls",
"publisher/clusterfuzz-testcase-minimized-POIHPBFFuzzer-6325615354773504.pub",
});
private static final Set<String> EXPECTED_FAILURES = StressTestUtils.unmodifiableHashSet( private static final Set<String> EXPECTED_FAILURES = StressTestUtils.unmodifiableHashSet(
"document/truncated62886.docx", "document/truncated62886.docx"
// this document fails with IBM JDK because of a different exception being thrown
"spreadsheet/clusterfuzz-testcase-minimized-POIXSSFFuzzer-5089447305609216.xlsx"
); );
public static Stream<Arguments> allfiles(String testName) throws IOException { public static Stream<Arguments> allfiles(String testName) throws IOException {
@ -178,7 +150,6 @@ public class TestAllFiles {
continue; continue;
} }
boolean found = false;
for (FileHandlerKnown handler : sm.getHandler(file)) { for (FileHandlerKnown handler : sm.getHandler(file)) {
ExcInfo info1 = sm.getExcInfo(file, testName, handler); ExcInfo info1 = sm.getExcInfo(file, testName, handler);
if (info1 == null || info1.isValid(testName, handler.name())) { if (info1 == null || info1.isValid(testName, handler.name())) {
@ -189,13 +160,8 @@ public class TestAllFiles {
(info1 != null) ? info1.getExClazz() : null, (info1 != null) ? info1.getExClazz() : null,
(info1 != null) ? info1.getExMessage() : null (info1 != null) ? info1.getExMessage() : null
)); ));
found = true;
} }
} }
if (!found) {
System.out.println("Could not find a handler for " + file);
}
} }
return result.stream(); return result.stream();
@ -218,7 +184,7 @@ public class TestAllFiles {
FileHandler fileHandler = handler.getHandler(); FileHandler fileHandler = handler.getHandler();
assertNotNull(fileHandler, "Did not find a handler for file " + file); assertNotNull(fileHandler, "Did not find a handler for file " + file);
Executable exec = () -> fileHandler.handleExtracting(new File(ROOT_DIR, file)); Executable exec = () -> fileHandler.handleExtracting(new File(ROOT_DIR, file));
verify(file, exec, exClass, exMessage, password, fileHandler); verify(file, exec, exClass, exMessage, password);
} finally { } finally {
Thread.currentThread().setName(threadName); Thread.currentThread().setName(threadName);
} }
@ -234,19 +200,12 @@ public class TestAllFiles {
String threadName = Thread.currentThread().getName(); String threadName = Thread.currentThread().getName();
try { try {
Thread.currentThread().setName("Handle - " + file + " - " + handler); Thread.currentThread().setName("Handle - " + file + " - " + handler);
// Some of the tests hang in JDK 8 due to Graphics-Rendering issues in JDK itself,
// therefore we do not run some tests here
Assumptions.assumeFalse(isJava8() && (
file.endsWith("23884_defense_FINAL_OOimport_edit.ppt")
), "Some files hang in JDK graphics rendering on Java 8 due to a JDK bug");
System.out.println("Running handleFiles on "+file); System.out.println("Running handleFiles on "+file);
FileHandler fileHandler = handler.getHandler(); FileHandler fileHandler = handler.getHandler();
assertNotNull(fileHandler, "Did not find a handler for file " + file); assertNotNull(fileHandler, "Did not find a handler for file " + file);
try (InputStream stream = new BufferedInputStream(new FileInputStream(new File(ROOT_DIR, file)), 64 * 1024)) { try (InputStream stream = new BufferedInputStream(new FileInputStream(new File(ROOT_DIR, file)), 64 * 1024)) {
Executable exec = () -> fileHandler.handleFile(stream, file); Executable exec = () -> fileHandler.handleFile(stream, file);
verify(file, exec, exClass, exMessage, password, fileHandler); verify(file, exec, exClass, exMessage, password);
} }
} finally { } finally {
Thread.currentThread().setName(threadName); Thread.currentThread().setName(threadName);
@ -263,23 +222,19 @@ public class TestAllFiles {
String threadName = Thread.currentThread().getName(); String threadName = Thread.currentThread().getName();
try { try {
Thread.currentThread().setName("Additional - " + file + " - " + handler); Thread.currentThread().setName("Additional - " + file + " - " + handler);
if (StressTestUtils.excludeFile(file, EXPECTED_FAILURES))
return;
System.out.println("Running additionals on "+file); System.out.println("Running additionals on "+file);
FileHandler fileHandler = handler.getHandler(); FileHandler fileHandler = handler.getHandler();
assertNotNull(fileHandler, "Did not find a handler for file " + file); assertNotNull(fileHandler, "Did not find a handler for file " + file);
Executable exec = () -> fileHandler.handleAdditional(new File(ROOT_DIR, file)); Executable exec = () -> fileHandler.handleAdditional(new File(ROOT_DIR, file));
verify(file, exec, exClass, exMessage, password, fileHandler); verify(file, exec, exClass, exMessage, password);
} finally { } finally {
Thread.currentThread().setName(threadName); Thread.currentThread().setName(threadName);
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private static void verify(String file, Executable exec, Class<? extends Throwable> exClass, String exMessage, String password, private static void verify(String file, Executable exec, Class<? extends Throwable> exClass, String exMessage, String password) {
FileHandler fileHandler) { final String errPrefix = file + " - failed. ";
final String errPrefix = file.replace("\\", "/") + " - failed for handler " + fileHandler.getClass().getSimpleName() + ": ";
// this also removes the password for non encrypted files // this also removes the password for non encrypted files
Biff8EncryptionKey.setCurrentUserPassword(password); Biff8EncryptionKey.setCurrentUserPassword(password);
if (exClass != null && AssertionFailedError.class.isAssignableFrom(exClass)) { if (exClass != null && AssertionFailedError.class.isAssignableFrom(exClass)) {
@ -295,47 +250,20 @@ public class TestAllFiles {
} else if (exClass != null) { } else if (exClass != null) {
Exception e = assertThrows((Class<? extends Exception>)exClass, exec, errPrefix + " expected " + exClass); Exception e = assertThrows((Class<? extends Exception>)exClass, exec, errPrefix + " expected " + exClass);
String actMsg = pathReplace(e.getMessage()); String actMsg = pathReplace(e.getMessage());
// perform special handling of NullPointerException as
// JDK started to add more information in some newer JDK, so
// it sometimes has a message and sometimes not!
if (NullPointerException.class.isAssignableFrom(exClass)) { if (NullPointerException.class.isAssignableFrom(exClass)) {
if (actMsg != null) { if (actMsg != null) {
assertTrue(actMsg.contains(exMessage), errPrefix + "Message: " + actMsg + " - didn't contain: " + exMessage); assertTrue(actMsg.contains(exMessage), errPrefix + "Message: "+actMsg+" - didn't contain: "+exMessage);
} }
} else { } else {
// verify that message is either null for both or set for both assertNotNull(actMsg, errPrefix);
assertTrue(actMsg != null || isBlank(exMessage), assertTrue(actMsg.contains(exMessage),
errPrefix + " for " + exClass + " expected message '" + exMessage + "' but had '" + actMsg + "': " + e); errPrefix + "Message: " + actMsg + " - didn't contain: " + exMessage);
if (actMsg != null &&
// in newer JDK versions IndexOutOfBoundsException switch from empty message
// to more useful content
// so skip the check for this type of exception if expected message is null
(exMessage != null || !IndexOutOfBoundsException.class.isAssignableFrom(exClass))) {
assertNotNull(exMessage,
errPrefix + "Expected message was null, but actMsg wasn't: Message: " + actMsg + ": " + e);
assertTrue(actMsg.contains(exMessage),
errPrefix + "Message: " + actMsg + " - didn't contain: " + exMessage);
}
} }
} else { } else {
assertDoesNotThrow(exec, errPrefix); assertDoesNotThrow(exec, errPrefix);
} }
} }
private static boolean isBlank(final String str) {
if (str != null) {
final int strLen = str.length();
for (int i = 0; i < strLen; i++) {
if (!Character.isWhitespace(str.charAt(i))) {
return false;
}
}
}
return true;
}
private static String pathReplace(String msg) { private static String pathReplace(String msg) {
if (msg == null) return null; if (msg == null) return null;
@ -351,15 +279,4 @@ public class TestAllFiles {
return msg; return msg;
} }
private static boolean isJava8() {
return System.getProperty("java.version").startsWith("1.8");
}
private static String[] concat(String[] a, String[] b) {
String[] result = new String[a.length + b.length];
System.arraycopy(a, 0, result, 0, a.length);
System.arraycopy(b, 0, result, a.length, b.length);
return result;
}
} }

View File

@ -41,11 +41,11 @@ public class XSSFBFileHandler extends AbstractFileHandler {
public void handleFile(InputStream stream, String path) throws Exception { public void handleFile(InputStream stream, String path) throws Exception {
byte[] bytes = IOUtils.toByteArray(stream); byte[] bytes = IOUtils.toByteArray(stream);
try (OPCPackage opcPackage = OPCPackage.open(UnsynchronizedByteArrayInputStream.builder().setByteArray(bytes).get())) { try (OPCPackage opcPackage = OPCPackage.open(new UnsynchronizedByteArrayInputStream(bytes))) {
testOne(opcPackage); testOne(opcPackage);
} }
testNotHandledByWorkbookException(OPCPackage.open(UnsynchronizedByteArrayInputStream.builder().setByteArray(bytes).get())); testNotHandledByWorkbookException(OPCPackage.open(new UnsynchronizedByteArrayInputStream(bytes)));
} }
private void testNotHandledByWorkbookException(OPCPackage pkg) throws IOException { private void testNotHandledByWorkbookException(OPCPackage pkg) throws IOException {
@ -78,7 +78,7 @@ public class XSSFBFileHandler extends AbstractFileHandler {
XSSFBEventBasedExcelExtractor ex = new XSSFBEventBasedExcelExtractor(pkg); XSSFBEventBasedExcelExtractor ex = new XSSFBEventBasedExcelExtractor(pkg);
String txt = ex.getText(); String txt = ex.getText();
if (txt.length() < 1) { if (txt.length() < 1) {
throw new IllegalArgumentException("Should have gotten some text."); throw new RuntimeException("Should have gotten some text.");
} }
} }

View File

@ -16,6 +16,7 @@
==================================================================== */ ==================================================================== */
package org.apache.poi.stress; package org.apache.poi.stress;
import static org.apache.commons.io.output.NullOutputStream.NULL_OUTPUT_STREAM;
import static org.apache.poi.xssf.XSSFTestDataSamples.getSampleFile; import static org.apache.poi.xssf.XSSFTestDataSamples.getSampleFile;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
@ -28,7 +29,6 @@ import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
@ -36,7 +36,6 @@ import java.util.Set;
import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerException;
import org.apache.commons.io.output.NullOutputStream;
import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream; import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
import org.apache.poi.EncryptedDocumentException; import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.examples.ss.ExcelComparator; import org.apache.poi.examples.ss.ExcelComparator;
@ -55,7 +54,6 @@ import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.util.IOUtils; import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.eventusermodel.XSSFReader; import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.extractor.XSSFExportToXml; import org.apache.poi.xssf.extractor.XSSFExportToXml;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFMap; import org.apache.poi.xssf.usermodel.XSSFMap;
import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook;
@ -74,7 +72,7 @@ public class XSSFFileHandler extends SpreadsheetHandler {
// make sure the potentially large byte-array is freed up quickly again // make sure the potentially large byte-array is freed up quickly again
{ {
UnsynchronizedByteArrayOutputStream out = UnsynchronizedByteArrayOutputStream.builder().get(); UnsynchronizedByteArrayOutputStream out = new UnsynchronizedByteArrayOutputStream();
IOUtils.copy(stream, out); IOUtils.copy(stream, out);
if (pass != null) { if (pass != null) {
@ -117,13 +115,6 @@ public class XSSFFileHandler extends SpreadsheetHandler {
// and finally ensure that exporting to XML works // and finally ensure that exporting to XML works
exportToXML(wb); exportToXML(wb);
// also try to read and write the sheet via SXSSF
try (SXSSFWorkbook swb = new SXSSFWorkbook(wb)) {
try (OutputStream out = NullOutputStream.INSTANCE) {
swb.write(out);
}
}
// this allows to trigger a heap-dump at this point to see which memory is still allocated // this allows to trigger a heap-dump at this point to see which memory is still allocated
//HeapDump.dumpHeap("/tmp/poi.hprof", false); //HeapDump.dumpHeap("/tmp/poi.hprof", false);
@ -165,7 +156,7 @@ public class XSSFFileHandler extends SpreadsheetHandler {
TransformerException { TransformerException {
for (XSSFMap map : wb.getCustomXMLMappings()) { for (XSSFMap map : wb.getCustomXMLMappings()) {
XSSFExportToXml exporter = new XSSFExportToXml(map); XSSFExportToXml exporter = new XSSFExportToXml(map);
exporter.exportToXML(NullOutputStream.INSTANCE, true); exporter.exportToXML(NULL_OUTPUT_STREAM, true);
} }
} }
@ -203,7 +194,7 @@ public class XSSFFileHandler extends SpreadsheetHandler {
XLSX2CSV.main(new String[]{file.getAbsolutePath()}); XLSX2CSV.main(new String[]{file.getAbsolutePath()});
ExcelComparator.main(new String[]{file.getAbsolutePath(), file.getAbsolutePath()}); ExcelComparator.main(new String[]{file.getAbsolutePath(), file.getAbsolutePath()});
assertFalse(EXPECTED_ADDITIONAL_FAILURES.contains(testFile), "Expected Extraction to fail for file " + file + " and handler " + this + ", but did not fail!" ); assertFalse( EXPECTED_ADDITIONAL_FAILURES.contains(testFile), "Expected Extraction to fail for file " + file + " and handler " + this + ", but did not fail!" );
} catch (OLE2NotOfficeXmlFileException e) { } catch (OLE2NotOfficeXmlFileException e) {
// we have some files that are not actually OOXML and thus cannot be tested here // we have some files that are not actually OOXML and thus cannot be tested here
@ -226,8 +217,6 @@ public class XSSFFileHandler extends SpreadsheetHandler {
} }
handleExtracting(file); handleExtracting(file);
handleAdditional(file);
} }
@Test @Test

View File

@ -22,7 +22,6 @@ import java.io.FileInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.util.Set; import java.util.Set;
import org.apache.commons.io.output.NullOutputStream;
import org.apache.poi.ooxml.POIXMLException; import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -42,8 +41,6 @@ public class XWPFFileHandler extends AbstractFileHandler {
try (XWPFDocument doc = new XWPFDocument(stream)) { try (XWPFDocument doc = new XWPFDocument(stream)) {
new POIXMLDocumentHandler().handlePOIXMLDocument(doc); new POIXMLDocumentHandler().handlePOIXMLDocument(doc);
POIXMLDocumentHandler.cursorRecursive(doc.getDocument()); POIXMLDocumentHandler.cursorRecursive(doc.getDocument());
doc.write(NullOutputStream.INSTANCE);
} catch (POIXMLException e) { } catch (POIXMLException e) {
Exception cause = (Exception)e.getCause(); Exception cause = (Exception)e.getCause();
throw cause == null ? e : cause; throw cause == null ? e : cause;

Some files were not shown because too many files have changed in this diff Show More