Sfoglia il codice sorgente

#62921 - Provide OOXMLLite alternative for Java 12+

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846809 13f79535-47bb-0310-9956-ffa450edef68
pull/134/head
Andreas Beeker 5 anni fa
parent
commit
0d052def85

+ 68
- 79
build.xml Vedi File

<property name="ooxml.output.dir" location="build/ooxml-classes"/> <property name="ooxml.output.dir" location="build/ooxml-classes"/>
<property name="ooxml.output.test.dir" location="build/ooxml-test-classes"/> <property name="ooxml.output.test.dir" location="build/ooxml-test-classes"/>
<property name="ooxml.testokfile" location="build/ooxml-testokfile.txt"/> <property name="ooxml.testokfile" location="build/ooxml-testokfile.txt"/>
<property name="ooxml.lite.output.dir" location="build/ooxml-lite-classes"/>
<property name="ooxml.lite.testokfile" location="build/ooxml-lite-testokfile.txt"/>

<property name="ooxml.lite.agent" location="build/ooxml-lite-agent.jar"/>
<property name="ooxml.lite.report" location="build/ooxml-lite-report.txt"/>
<property name="ooxml.lite.jar" location="build/ooxml-lite-classes.jar"/>
<property name="ooxml.lite.includes" value="^(com/microsoft/schemas|org/(etsi|openxmlformats|w3/)|schemaorg_apache_xmlbeans)"/>



<!-- Integration testing: --> <!-- Integration testing: -->
<property name="integration.src.test" location="src/integrationtest"/> <property name="integration.src.test" location="src/integrationtest"/>


<path id="ooxml-lite.classpath"> <path id="ooxml-lite.classpath">
<path refid="ooxml.base.classpath"/> <path refid="ooxml.base.classpath"/>
<pathelement location="${ooxml.lite.output.dir}"/> <!-- instead of ooxml-xsds.jar use the filtered classes-->
<!-- instead of ooxml-xsds.jar use the filtered classes-->
<pathelement location="${ooxml.lite.jar}"/>
<pathelement location="${ooxml.output.dir}"/> <pathelement location="${ooxml.output.dir}"/>
<pathelement location="${ooxml.output.test.dir}"/> <pathelement location="${ooxml.output.test.dir}"/>
<pathelement location="${main.output.test.dir}"/> <pathelement location="${main.output.test.dir}"/>
compile-scratchpad, compile-examples, compile-excelant" compile-scratchpad, compile-examples, compile-excelant"
description="Compiles the POI main classes, scratchpad and examples"/> description="Compiles the POI main classes, scratchpad and examples"/>


<target name="compile-all" depends="compile,compile-ooxml-lite"/>

<target name="compile-main" depends="init"> <target name="compile-main" depends="init">
<!-- compile the sources --> <!-- compile the sources -->
<javac target="${jdk.version.class}" <javac target="${jdk.version.class}"
<!-- Section: test (execute junit tests on test suites) --> <!-- Section: test (execute junit tests on test suites) -->
<target name="test" depends="compile,jacocotask,test-main,test-scratchpad,test-ooxml,test-excelant" <target name="test" depends="compile,jacocotask,test-main,test-scratchpad,test-ooxml,test-excelant"
description="Tests main, scratchpad and ooxml"/> description="Tests main, scratchpad and ooxml"/>
<target name="test-all" depends="test,test-ooxml-lite,testcoveragereport"
<target name="test-all" depends="test,test-integration,test-ooxml-lite,testcoveragereport"
description="Tests main, scratchpad, ooxml, ooxml-lite, and coveragereport"/> description="Tests main, scratchpad, ooxml, ooxml-lite, and coveragereport"/>


<target name="testcoveragereport" depends="init,jacocotask" description="create test-report" xmlns:jacoco="antlib:org.jacoco.ant" if="coverage.enabled"> <target name="testcoveragereport" depends="init,jacocotask" description="create test-report" xmlns:jacoco="antlib:org.jacoco.ant" if="coverage.enabled">
<group name="OOXML"> <group name="OOXML">
<classfiles> <classfiles>
<fileset dir="${ooxml.output.dir}"/> <fileset dir="${ooxml.output.dir}"/>
<!-- there are no actual POI classes in build/ooxml-lite-classes, only generated code...
<fileset dir="${ooxml.lite.output.dir}"/>
-->
<!-- there are no actual POI classes in build/ooxml-lite-classes, only generated code... -->
</classfiles> </classfiles>
<sourcefiles encoding="UTF-8"> <sourcefiles encoding="UTF-8">
<fileset dir="${ooxml.src}"/> <fileset dir="${ooxml.src}"/>
<sysproperty key="java.io.tmpdir" value="${tempdir}"/> <sysproperty key="java.io.tmpdir" value="${tempdir}"/>
<jvmarg value="-Xmx768M"/> <jvmarg value="-Xmx768M"/>
<jvmarg value="-ea"/> <jvmarg value="-ea"/>
<jvmarg value="-javaagent:${ooxml.lite.agent}=${ooxml.lite.report}|${ooxml.lite.includes}"/>
<jvmarg value="${java9addmods}" /> <jvmarg value="${java9addmods}" />
<jvmarg value="${java9addmodsvalue}" /> <jvmarg value="${java9addmodsvalue}" />
<jvmarg value="${java9addopens1}" /> <jvmarg value="${java9addopens1}" />
</classpath> </classpath>
<syspropertyset refid="junit.properties"/> <syspropertyset refid="junit.properties"/>
<sysproperty key="java.io.tmpdir" value="${tempdir}"/> <sysproperty key="java.io.tmpdir" value="${tempdir}"/>
<jvmarg value="-javaagent:${ooxml.lite.agent}=${ooxml.lite.report}|${ooxml.lite.includes}"/>
<jvmarg value="-Xmx768M"/> <jvmarg value="-Xmx768M"/>
<jvmarg value="-ea"/> <jvmarg value="-ea"/>
<jvmarg value="${java9addmods}" /> <jvmarg value="${java9addmods}" />
</sequential> </sequential>
</macrodef> </macrodef>


<target name="test-ooxml" depends="compile-main,compile-ooxml,-test-ooxml-check,jacocotask" unless="ooxml.test.notRequired"
<target name="test-ooxml" depends="compile-main,compile-ooxml,-test-ooxml-check,jacocotask,-ooxml-lite-agent" unless="ooxml.test.notRequired"
description="test OOXML classes"> description="test OOXML classes">
<ooxml-test-runner classpath="test.ooxml.classpath" type="ooxml"/> <ooxml-test-runner classpath="test.ooxml.classpath" type="ooxml"/>
<delete file="${ooxml.testokfile}"/> <delete file="${ooxml.testokfile}"/>
</uptodate> </uptodate>
</target> </target>


<target name="test-integration" depends="compile-integration,-test-integration-check,jacocotask"
<target name="test-integration" depends="compile-integration,-test-integration-check,jacocotask,-ooxml-lite-agent"
unless="integration.test.notRequired" xmlns:jacoco="antlib:org.jacoco.ant"> unless="integration.test.notRequired" xmlns:jacoco="antlib:org.jacoco.ant">
<propertyreset name="org.apache.poi.util.POILogger" value="org.apache.poi.util.CommonsLogger"/> <propertyreset name="org.apache.poi.util.POILogger" value="org.apache.poi.util.CommonsLogger"/>
<delete dir="build" includes="test-integration.log*"/> <delete dir="build" includes="test-integration.log*"/>
<sysproperty key="java.io.tmpdir" value="${tempdir}"/> <sysproperty key="java.io.tmpdir" value="${tempdir}"/>
<jvmarg value="-ea"/> <jvmarg value="-ea"/>
<jvmarg value="-Xmx1512M"/> <jvmarg value="-Xmx1512M"/>
<jvmarg value="-javaagent:${ooxml.lite.agent}=${ooxml.lite.report}|${ooxml.lite.includes}"/>
<jvmarg value="${java9addmods}" /> <jvmarg value="${java9addmods}" />
<jvmarg value="${java9addmodsvalue}" /> <jvmarg value="${java9addmodsvalue}" />
<jvmarg value="${java9addopens1}" /> <jvmarg value="${java9addopens1}" />
<echo file="${integration.testokfile}" append="false" message="testok"/> <echo file="${integration.testokfile}" append="false" message="testok"/>
</target> </target>


<!-- Section: test-ooxml-lite -->
<target name="-compile-ooxml-lite-check">
<uptodate property="ooxml.lite.test.notRequired" targetfile="${ooxml.lite.testokfile}">
<srcfiles dir="${ooxml.src}"/>
<srcfiles dir="${ooxml.src.test}"/>
<srcfiles file="${ooxml.xsds.jar}"/>
<srcfiles file="${ooxml.security.jar}"/>
</uptodate>
</target>
<!-- the ooxml lite agent collects referenced schema files while other junit tests are run, -->
<!-- therefore its best to compile the ooxml lite jar after all usual tests are done -->
<target name="compile-ooxml-lite" depends="compile-ooxml,-ooxml-lite-agent,test-ooxml">
<echo message="Create ooxml-lite schemas"/>


<target name="compile-ooxml-lite" depends="-compile-ooxml-lite-check,compile-ooxml"
unless="ooxml.lite.test.notRequired">
<delete file="${ooxml.lite.testokfile}"/>
<echo message="Running ooxml-lite generator"/>
<copy file="${ooxml.lite.report}" tofile="${ooxml.lite.report}-pat" overwrite="true"/>
<replaceregexp file="${ooxml.lite.report}-pat" byline="true" match="(.*)" replace="\1.class${line.separator}\1$*.class"/>


<property name="ooxml.lite-merged.dir" location="build/ooxml-lite-merged"/>
<mkdir dir="${ooxml.lite-merged.dir}"/>
<patternset id="xsbfiles">
<includesfile name="${ooxml.lite.report}-pat"/>
<include name="schemaorg_apache_xmlbeans/system/**/*.xsb"/>
<include name="schemaorg_apache_xmlbeans/element/**/*.xsb"/>
</patternset>


<jar destfile="${ooxml.lite-merged.dir}/ooxml-lite-merged.jar">
<zipfileset includes="**/*" src="${ooxml.xsds.jar}"/>
<zipfileset includes="**/*" src="${ooxml.security.jar}"/>
<jar destfile="${ooxml.lite.jar}" duplicate="preserve">
<zipfileset src="${ooxml.xsds.jar}">
<patternset refid="xsbfiles"/>
</zipfileset>
<zipfileset src="${ooxml.security.jar}">
<patternset refid="xsbfiles"/>
</zipfileset>
</jar> </jar>

<java classname="org.apache.poi.ooxml.util.OOXMLLite" fork="yes"
failonerror="true">
<classpath>
<pathelement path="${ooxml.lite-merged.dir}/ooxml-lite-merged.jar"/>
</classpath>
<classpath refid="test.ooxml.classpath"/>
<classpath refid="ooxml.xmlsec.classpath"/>
<syspropertyset refid="junit.properties"/>
<sysproperty key="java.io.tmpdir" value="${tempdir}"/>
<jvmarg value="-Xmx512m"/>
<jvmarg value="${java9addmods}" />
<jvmarg value="${java9addmodsvalue}" />
<jvmarg value="${java9addopens1}" />
<jvmarg value="${java9addopens2}" />
<jvmarg value="${java9addopens3}" />
<jvmarg value="${java9addopens4}" />
<jvmarg value="${java9addopens5}" />
<jvmarg value="${java9addopens6}" />
<jvmarg value="${file.leak.detector}" />
<arg value="-ooxml"/>
<arg value="${ooxml.lite-merged.dir}/ooxml-lite-merged.jar"/>
<arg value="-test"/>
<arg value="${ooxml.output.test.dir}"/>
<arg value="-dest"/>
<arg value="${ooxml.lite.output.dir}"/>
</java>

<echo file="${ooxml.lite.testokfile}" append="false" message="testok"/>
</target> </target>


<target name="test-ooxml-lite" depends="jacocotask,compile-ooxml-xsds,compile-ooxml-lite"> <target name="test-ooxml-lite" depends="jacocotask,compile-ooxml-xsds,compile-ooxml-lite">
<ooxml-test-runner classpath="ooxml-lite.classpath" type="ooxml-lite"/> <ooxml-test-runner classpath="ooxml-lite.classpath" type="ooxml-lite"/>
</target> </target>


<target name="-ooxml-lite-agent" depends="jacocotask,compile-ooxml-xsds,compile-ooxml">
<jar destfile="${ooxml.lite.agent}">
<fileset dir="${ooxml.output.test.dir}" includes="org/apache/poi/ooxml/util/OOXMLLiteAgent*.class"/>
<manifest>
<attribute name="Premain-Class" value="org.apache.poi.ooxml.util.OOXMLLiteAgent"/>
</manifest>
</jar>
</target>

<!-- Section: test-excelant --> <!-- Section: test-excelant -->
<target name="-test-excelant-check"> <target name="-test-excelant-check">
<uptodate property="excelant.test.notRequired" targetfile="${excelant.testokfile}"> <uptodate property="excelant.test.notRequired" targetfile="${excelant.testokfile}">
</target> </target>


<macrodef name="maven-jar"> <macrodef name="maven-jar">
<attribute name="dir"/>
<attribute name="src"/>
<sequential> <sequential>
<local name="destfile"/> <local name="destfile"/>
<pathconvert property="destfile" targetos="unix"> <pathconvert property="destfile" targetos="unix">
<path><pathelement path="@{dir}"/></path>
<path><pathelement path="@{src}"/></path>
<mapper> <mapper>
<chainedmapper> <chainedmapper>
<filtermapper> <filtermapper>
</chainedmapper> </chainedmapper>
</mapper> </mapper>
</pathconvert> </pathconvert>
<local name="isjar"/>
<condition property="isjar">
<contains string="@{src}" substring=".jar"/>
</condition>

<jar destfile="build/dist/maven/${destfile}.jar" <jar destfile="build/dist/maven/${destfile}.jar"
manifest="build/poi-manifest.mf"> manifest="build/poi-manifest.mf">
<fileset dir="@{dir}"/>
<fileset dir="@{src}" unless:true="${isjar}"/>
<zipfileset src="@{src}" if:true="${isjar}"/>
<metainf dir="legal/"/> <metainf dir="legal/"/>
</jar> </jar>
</sequential> </sequential>
</macrodef> </macrodef>


<target name="jar" depends="compile-all, compile-version, -manifest" description="Creates jar files for distribution">
<maven-jar dir="${main.output.dir}"/>
<maven-jar dir="${scratchpad.output.dir}"/>
<maven-jar dir="${ooxml.output.dir}"/>
<maven-jar dir="${examples.output.dir}"/>
<maven-jar dir="${excelant.output.dir}"/>
<maven-jar dir="${ooxml.lite.output.dir}"/>
<target name="jar" depends="compile, compile-version, -manifest" description="Creates jar files for distribution">
<maven-jar src="${main.output.dir}"/>
<maven-jar src="${scratchpad.output.dir}"/>
<maven-jar src="${ooxml.output.dir}"/>
<maven-jar src="${examples.output.dir}"/>
<maven-jar src="${excelant.output.dir}"/>
<maven-jar src="${ooxml.lite.jar}"/>
</target> </target>


<target name="jar-src" depends="compile-all, compile-version, -manifest" description="Sources for Maven">
<maven-jar dir="${main.src}"/>
<maven-jar dir="${scratchpad.src}"/>
<maven-jar dir="${ooxml.src}"/>
<maven-jar dir="${examples.src}"/>
<maven-jar dir="${excelant.src}"/>
<target name="jar-src" depends="compile, compile-version, -manifest" description="Sources for Maven">
<maven-jar src="${main.src}"/>
<maven-jar src="${scratchpad.src}"/>
<maven-jar src="${ooxml.src}"/>
<maven-jar src="${examples.src}"/>
<maven-jar src="${excelant.src}"/>
</target> </target>


<target name="integration-test-jar" depends="compile-integration,-manifest" description="target for packaging the integration-test code for mass regression test runs"> <target name="integration-test-jar" depends="compile-integration,-manifest" description="target for packaging the integration-test code for mass regression test runs">
<maven-jar dir="${integration.output.test.dir}"/>
<maven-jar src="${integration.output.test.dir}"/>
</target> </target>


<target name="-do-jar-check-javadocs-package-list"> <target name="-do-jar-check-javadocs-package-list">
lib/**, lib/**,
bin/**, bin/**,
out/**, out/**,
tmp/**,
sonar/**/target/**, sonar/**/target/**,
sonar/*/src/**, sonar/*/src/**,
compile-lib/**, compile-lib/**,
</mvn:mvn> </mvn:mvn>
</target> </target>


<target name="dist" depends="clean, compile-all, test-all, rat-check, forbidden-apis-check, docs, jar, release-notes, assemble"
<target name="dist" depends="clean, compile, test-all, rat-check, forbidden-apis-check, docs, jar, release-notes, assemble"
description="Creates the entire distribution into build/dist, from scratch"> description="Creates the entire distribution into build/dist, from scratch">
</target> </target>


<!-- continuous integration targets --> <!-- continuous integration targets -->
<target name="gump" depends="compile-all, test-all, jar"
description="Target for running with Apache Gump continuous integration. Builds and tests POI and generates jar artifacts." />
<target name="jenkins" depends="compile-all, test-all, test-integration, jar, javadocs, assemble, findbugs, release-notes, rat-check, forbidden-apis-check"
<target name="jenkins" depends="compile, test-all, jar, javadocs, assemble, findbugs, release-notes, rat-check, forbidden-apis-check"
description="Target run by Jenkins on a continuous basis. Builds and tests POI, generates artifacts and documentation, and searches for problems."/> description="Target run by Jenkins on a continuous basis. Builds and tests POI, generates artifacts and documentation, and searches for problems."/>


<available property="maven.ant.tasks.present" classname="org.apache.maven.artifact.ant.Pom"/> <available property="maven.ant.tasks.present" classname="org.apache.maven.artifact.ant.Pom"/>

+ 0
- 375
src/ooxml/testcases/org/apache/poi/ooxml/util/OOXMLLite.java Vedi File

/* ====================================================================
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.ooxml.util;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Pattern;

import org.apache.poi.util.IOUtils;
import org.apache.poi.util.StringUtil;
import org.apache.poi.util.SuppressForbidden;
import org.apache.xmlbeans.StringEnumAbstractBase;
import org.junit.Test;
import org.junit.internal.TextListener;
import org.junit.runner.Description;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.reflections.Reflections;

import junit.framework.TestCase;

/**
* Build a 'lite' version of the ooxml-schemas.jar
*
* @author Yegor Kozlov
*/
public final class OOXMLLite {
private static final Pattern SCHEMA_PATTERN = Pattern.compile("schemaorg_apache_xmlbeans/(system|element)/.*\\.xsb");

/**
* Destination directory to copy filtered classes
*/
private File _destDest;

/**
* Directory with the compiled ooxml tests
*/
private File _testDir;

/**
* Reference to the ooxml-schemas.jar
*/
private File _ooxmlJar;


OOXMLLite(String dest, String test, String ooxmlJar) {
_destDest = new File(dest);
_testDir = new File(test);
_ooxmlJar = new File(ooxmlJar);
}

public static void main(String[] args) throws IOException {
System.out.println("Free memory (bytes): " +
Runtime.getRuntime().freeMemory());
long maxMemory = Runtime.getRuntime().maxMemory();
System.out.println("Maximum memory (bytes): " +
(maxMemory == Long.MAX_VALUE ? "no limit" : maxMemory));
System.out.println("Total memory (bytes): " +
Runtime.getRuntime().totalMemory());

String dest = null, test = null, ooxml = null;

for (int i = 0; i < args.length; i++) {
switch (args[i]) {
case "-dest":
dest = args[++i]; // lgtm[java/index-out-of-bounds]
break;
case "-test":
test = args[++i]; // lgtm[java/index-out-of-bounds]
break;
case "-ooxml":
ooxml = args[++i]; // lgtm[java/index-out-of-bounds]
break;
}
}
OOXMLLite builder = new OOXMLLite(dest, test, ooxml);
builder.build();
}

void build() throws IOException {
List<Class<?>> lst = new ArrayList<>();
//collect unit tests
String exclude = StringUtil.join("|",
"BaseTestXWorkbook",
"BaseTestXSheet",
"BaseTestXRow",
"BaseTestXCell",
"BaseTestXSSFPivotTable",
"TestSXSSFWorkbook\\$\\d",
"TestUnfixedBugs",
"MemoryUsage",
"TestDataProvider",
"TestDataSamples",
"All.+Tests",
"ZipFileAssert",
"AesZipFileZipEntrySource",
"TempFileRecordingSXSSFWorkbookWithCustomZipEntrySource",
"PkiTestUtils",
"TestCellFormatPart\\$\\d",
"TestSignatureInfo\\$\\d",
"TestCertificateEncryption\\$CertData",
"TestPOIXMLDocument\\$OPCParser",
"TestPOIXMLDocument\\$TestFactory",
"TestXSLFTextParagraph\\$DrawTextParagraphProxy",
"TestXSSFExportToXML\\$\\d",
"TestXSSFExportToXML\\$DummyEntityResolver",
"TestFormulaEvaluatorOnXSSF\\$Result",
"TestFormulaEvaluatorOnXSSF\\$SS",
"TestMultiSheetFormulaEvaluatorOnXSSF\\$Result",
"TestMultiSheetFormulaEvaluatorOnXSSF\\$SS",
"TestXSSFBugs\\$\\d",
"AddImageBench",
"AddImageBench_jmhType_B\\d",
"AddImageBench_benchCreatePicture_jmhTest",
"TestEvilUnclosedBRFixingInputStream\\$EvilUnclosedBRFixingInputStream",
"TempFileRecordingSXSSFWorkbookWithCustomZipEntrySource\\$TempFileRecordingSheetDataWriterWithDecorator",
"TestXSSFBReader\\$1",
"TestXSSFBReader\\$TestSheetHandler",
"TestFormulaEvaluatorOnXSSF\\$1",
"TestMultiSheetFormulaEvaluatorOnXSSF\\$1",
"TestZipPackagePropertiesMarshaller\\$1",
"SLCommonUtils",
"TestPPTX2PNG\\$1",
"TestMatrixFormulasFromXMLSpreadsheet\\$1",
"TestMatrixFormulasFromXMLSpreadsheet\\$Navigator",
"TestPOIXMLDocument\\$UncaughtHandler",
"TestOleShape\\$Api",
"TestOleShape\\$1",
"TestPOIXMLDocument\\$1",
"TestXMLSlideShow\\$1",
"TestXMLSlideShow\\$BufAccessBAOS",
"TestXDDFChart\\$1",
"TestOOXMLLister\\$1",
"TestOOXMLPrettyPrint\\$1"
);
System.out.println("Collecting unit tests from " + _testDir);
collectTests(_testDir, _testDir, lst, ".+.class$", ".+(" + exclude + ").class");
System.out.println("Found " + lst.size() + " classes");

//run tests
JUnitCore jUnitCore = new JUnitCore();
jUnitCore.addListener(new TextListener(System.out) {
private final Set<String> classes = new HashSet<>();
private int count;

@Override
public void testStarted(Description description) {
// count how many test-classes we already saw
classes.add(description.getClassName());
count++;
if(count % 100 == 0) {
System.out.println();
System.out.println(classes.size() + "/" + lst.size() + ": " + description.getDisplayName());
}

super.testStarted(description);
}
});
Result result = jUnitCore.run(lst.toArray(new Class<?>[0]));
if (!result.wasSuccessful()) {
throw new RuntimeException("Tests did not succeed, cannot build ooxml-lite jar");
}

//see what classes from the ooxml-schemas.jar are loaded
System.out.println("Copying classes to " + _destDest);
Set<Class<?>> classes = getLoadedClasses(_ooxmlJar.getName());
Set<String> packages = new HashSet<>();
for (Class<?> cls : classes) {
copyFile(cls);
packages.add(cls.getPackage().getName());

if (cls.isInterface()) {
/// Copy classes and interfaces declared as members of this class
for (Class<?> fc : cls.getDeclaredClasses()) {
copyFile(fc);
}
}
}
for (String pkg : packages) {
Reflections reflections = new Reflections(pkg);
Set<Class<? extends List>> listClasses = reflections.getSubTypesOf(List.class);
listClasses.removeAll(classes);
for (Class listClass : listClasses) {
for (Class<?> compare : classes) {
if (listClass.getName().startsWith(compare.getName())) {
copyFile(listClass);
}
}
}
Set<Class<? extends StringEnumAbstractBase>> enumClasses = reflections.getSubTypesOf(StringEnumAbstractBase.class);
listClasses.removeAll(classes);
for (Class enumClass : enumClasses) {
for (Class<?> compare : classes) {
if (enumClass.getName().startsWith(compare.getName())) {
copyFile(enumClass);
}
}
}
}

//finally copy the compiled .xsb files
System.out.println("Copying .xsb resources");
try (JarFile jar = new JarFile(_ooxmlJar)) {
for (Enumeration<JarEntry> e = jar.entries(); e.hasMoreElements(); ) {
JarEntry je = e.nextElement();
if (SCHEMA_PATTERN.matcher(je.getName()).matches()) {
File destFile = new File(_destDest, je.getName());
IOUtils.copy(jar.getInputStream(je), destFile);
}
}
}
}

private void copyFile(Class<?> cls) throws IOException {
String className = cls.getName();
String classRef = className.replace('.', '/') + ".class";
File destFile = new File(_destDest, classRef);
IOUtils.copy(cls.getResourceAsStream('/' + classRef), destFile);
}

private static boolean checkForTestAnnotation(Class<?> testclass) {
for (Method m : testclass.getDeclaredMethods()) {
if(m.isAnnotationPresent(Test.class)) {
return true;
}
}

// also check super classes
if(testclass.getSuperclass() != null) {
for (Method m : testclass.getSuperclass().getDeclaredMethods()) {
if(m.isAnnotationPresent(Test.class)) {
return true;
}
}
}

System.out.println("Class " + testclass.getName() + " does not derive from TestCase and does not have a @Test annotation");

// Should we also look at superclasses to find cases
// where we have abstract base classes with derived tests?
// if(checkForTestAnnotation(testclass.getSuperclass())) return true;

return false;
}

/**
* Recursively collect classes from the supplied directory
*
* @param arg the directory to search in
* @param out output
* @param ptrn the pattern (regexp) to filter found files
*/
private static void collectTests(File root, File arg, List<Class<?>> out, String ptrn, String exclude) {
if (arg.isDirectory()) {
File files[] = arg.listFiles();
if (files != null) {
for (File f : files) {
collectTests(root, f, out, ptrn, exclude);
}
}
} else {
String path = arg.getAbsolutePath();
String prefix = root.getAbsolutePath();
String cls = path.substring(prefix.length() + 1).replace(File.separator, ".");
if(!cls.matches(ptrn)) {
return;
}
if (cls.matches(exclude)) {
return;
}
//ignore inner classes defined in tests
if (cls.indexOf('$') != -1) {
System.out.println("Inner class " + cls + " not included");
return;
}

cls = cls.replace(".class", "");

try {
Class<?> testclass = Class.forName(cls);
if (TestCase.class.isAssignableFrom(testclass)
|| checkForTestAnnotation(testclass)) {
out.add(testclass);
}
} catch (Throwable e) { // NOSONAR
System.out.println("Class " + cls + " is not in classpath");
}
}
}

/**
*
* @param ptrn the pattern to filter output
* @return the classes loaded by the system class loader
*/
@SuppressWarnings("unchecked")
private static Set<Class<?>> getLoadedClasses(String ptrn) {
// make the field accessible, we defer this from static initialization to here to
// allow JDKs which do not have this field (e.g. IBM JDK) to at least load the class
// without failing, see https://issues.apache.org/bugzilla/show_bug.cgi?id=56550
final Field _classes = AccessController.doPrivileged(new PrivilegedAction<Field>() {
@Override
@SuppressForbidden("TODO: Reflection works until Java 8 on Oracle/Sun JDKs, but breaks afterwards (different classloader types, access checks)")
public Field run() {
try {
Field fld = ClassLoader.class.getDeclaredField("classes");
fld.setAccessible(true);
return fld;
} catch (Exception e) {
throw new RuntimeException(e);
}

}
});

ClassLoader appLoader = ClassLoader.getSystemClassLoader();
try {
Vector<Class<?>> classes = (Vector<Class<?>>) _classes.get(appLoader);
Set<Class<?>> set = new HashSet<>();
for (Class<?> cls : classes) {
// e.g. proxy-classes, ...
ProtectionDomain pd = cls.getProtectionDomain();
if (pd == null) {
continue;
}
CodeSource cs = pd.getCodeSource();
if (cs == null) {
continue;
}
URL loc = cs.getLocation();
if (loc == null) {
continue;
}

String jar = loc.toString();
if (jar.contains(ptrn)) {
set.add(cls);
}
}
return set;
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}

+ 78
- 0
src/ooxml/testcases/org/apache/poi/ooxml/util/OOXMLLiteAgent.java Vedi File

/* ====================================================================
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.ooxml.util;

import java.io.IOException;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.Instrumentation;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.security.ProtectionDomain;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Stream;

/**
* OOXMLLiteAgent is the replacement for the former OOXMLLite, because in Java 12
* it isn't possible to access the privates :) of the ClassLoader
*/
public class OOXMLLiteAgent {

static class LoggingTransformer implements ClassFileTransformer {
final Path path;
final Pattern includes;
final Set<Integer> fileHashes = new HashSet<>();

public LoggingTransformer(String agentArgs) {
String args[] = (agentArgs == null ? "" : agentArgs).split("\\|",2);
path = Paths.get(args.length >= 1 ? args[0] : "ooxml-lite.out");
includes = Pattern.compile(args.length >= 2 ? args[1] : ".*/schemas/.*");

try {
if (Files.exists(path)) {
try (Stream<String> stream = Files.lines(path)) {
stream.forEach((s) -> fileHashes.add(s.hashCode()));
}
} else {
Files.createFile(path);
}
} catch (IOException ignored) {
}
}

public byte[] transform(ClassLoader loader, String className, Class redefiningClass, ProtectionDomain domain, byte[] bytes) {
if (path != null && className != null && !fileHashes.contains(className.hashCode()) && includes.matcher(className).find()) {
try {
// TODO: check if this is atomic ... as transform() is probably called synchronized, it doesn't matter anyway
Files.write(path, (className+"\n").getBytes(StandardCharsets.ISO_8859_1), StandardOpenOption.APPEND);
fileHashes.add(className.hashCode());
} catch (IOException ignroed) {
}
}
return bytes;
}
}

public static void premain(String agentArgs, Instrumentation inst) {
inst.addTransformer(new LoggingTransformer(agentArgs));
}
}

+ 1
- 1
src/ooxml/testcases/org/apache/poi/ss/format/TestCellFormatPart.java Vedi File

@BeforeClass @BeforeClass
public static void setLocale() { public static void setLocale() {
userLocale = LocaleUtil.getUserLocale(); userLocale = LocaleUtil.getUserLocale();
LocaleUtil.setUserLocale(Locale.ROOT);
LocaleUtil.setUserLocale(Locale.UK);
} }
@AfterClass @AfterClass

+ 2
- 3
src/scratchpad/testcases/org/apache/poi/hmef/TestAttachments.java Vedi File

package org.apache.poi.hmef; package org.apache.poi.hmef;


import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;


List<Attachment> attachments = quick.getAttachments(); List<Attachment> attachments = quick.getAttachments();
// Pick a predictable date format + timezone // Pick a predictable date format + timezone
DateFormat fmt = DateFormat.getDateTimeInstance(
DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.UK
);
DateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy hh:mm:ss", Locale.UK);
fmt.setTimeZone(LocaleUtil.TIMEZONE_UTC); fmt.setTimeZone(LocaleUtil.TIMEZONE_UTC);
// They should all have the same date on them // They should all have the same date on them

+ 2
- 3
src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestMAPIAttributes.java Vedi File

import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Locale; import java.util.Locale;


import org.apache.poi.POIDataSamples; import org.apache.poi.POIDataSamples;
assertEquals(MAPIDateAttribute.class, attr.getClass()); assertEquals(MAPIDateAttribute.class, attr.getClass());
MAPIDateAttribute date = (MAPIDateAttribute)attr; MAPIDateAttribute date = (MAPIDateAttribute)attr;
DateFormat fmt = DateFormat.getDateTimeInstance(
DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.UK
);
DateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss", Locale.UK);
fmt.setTimeZone(LocaleUtil.TIMEZONE_UTC); fmt.setTimeZone(LocaleUtil.TIMEZONE_UTC);
assertEquals("15-Dec-2010 14:46:31", fmt.format(date.getDate())); assertEquals("15-Dec-2010 14:46:31", fmt.format(date.getDate()));

+ 2
- 3
src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestTNEFAttributes.java Vedi File



import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Locale; import java.util.Locale;


import org.apache.poi.POIDataSamples; import org.apache.poi.POIDataSamples;
// Ask for it as a Java date, and have it converted // Ask for it as a Java date, and have it converted
// Pick a predictable format + location + timezone // Pick a predictable format + location + timezone
TNEFDateAttribute date = (TNEFDateAttribute)attr; TNEFDateAttribute date = (TNEFDateAttribute)attr;
DateFormat fmt = DateFormat.getDateTimeInstance(
DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.UK
);
DateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss", Locale.UK);
fmt.setTimeZone(LocaleUtil.TIMEZONE_UTC); fmt.setTimeZone(LocaleUtil.TIMEZONE_UTC);
assertEquals("28-Apr-2010 12:40:56", fmt.format(date.getDate())); assertEquals("28-Apr-2010 12:40:56", fmt.format(date.getDate()));
} }

+ 70
- 89
src/testcases/org/apache/poi/ss/usermodel/TestExcelStyleDateFormatter.java Vedi File

import java.text.FieldPosition; import java.text.FieldPosition;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;


import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.LocaleUtil;
import org.junit.Test; import org.junit.Test;


public class TestExcelStyleDateFormatter { public class TestExcelStyleDateFormatter {
private static final String EXCEL_DATE_FORMAT = "MMMMM"; private static final String EXCEL_DATE_FORMAT = "MMMMM";
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd", Locale.ROOT);
private final int jreVersion;

public TestExcelStyleDateFormatter() {
jreVersion = Integer.parseInt(System.getProperty("java.version")
.replace("1.8", "8").replaceAll("(\\d+).*", "$1"));
}


/** /**
* [Bug 60369] Month format 'MMMMM' issue with TEXT-formula and Java 8 * [Bug 60369] Month format 'MMMMM' issue with TEXT-formula and Java 8
*/ */
@Test @Test
public void test60369() throws ParseException {
Map<Locale, List<String>> testMap = initializeLocales();
public void test60369() {
Map<Locale, String> testMap = initializeLocales();


// We have to set up dates as well. // We have to set up dates as well.
SimpleDateFormat testDateFormat = new SimpleDateFormat("dd.MM.yyyy", Locale.ROOT);
List<Date> testDates = Arrays.asList(
testDateFormat.parse("12.01.1980"),
testDateFormat.parse("11.02.1995"),
testDateFormat.parse("10.03.2045"),
testDateFormat.parse("09.04.2016"),
testDateFormat.parse("08.05.2017"),
testDateFormat.parse("07.06.1945"),
testDateFormat.parse("06.07.1998"),
testDateFormat.parse("05.08.2099"),
testDateFormat.parse("04.09.1988"),
testDateFormat.parse("03.10.2023"),
testDateFormat.parse("02.11.1978"),
testDateFormat.parse("01.12.1890"));
List<Date> testDates = Stream.of("1980-01-12", "1995-02-11", "2045-03-10", "2016-04-09", "2017-05-08",
"1945-06-07", "1998-07-06", "2099-08-05", "1988-09-04", "2023-10-03", "1978-11-02", "1890-12-01")
.map(this::parseDate).collect(Collectors.toList());


// Let's iterate over the test setup. // Let's iterate over the test setup.
for (Locale locale : testMap.keySet()) {
ExcelStyleDateFormatter formatter = new ExcelStyleDateFormatter(EXCEL_DATE_FORMAT, new DateFormatSymbols(locale));
for (int i = 0; i < testDates.size(); i++) {
// Call the method to be tested!
String result =
formatter.format(testDates.get(i),
new StringBuffer(),
new FieldPosition(java.text.DateFormat.MONTH_FIELD)).toString();
//System.err.println(result + " - " + getUnicode(result.charAt(0)));
assertEquals("Failed for locale " + locale + ", provider: " + System.getProperty("java.locale.providers") +
" and date " + testDates.get(i) + ", having: " + result,
getUnicode(testMap.get(locale).get(i).charAt(0)), getUnicode(result.charAt(0)));
final String provider = System.getProperty("java.locale.providers");
final FieldPosition fp = new FieldPosition(java.text.DateFormat.MONTH_FIELD);
final ExcelStyleDateFormatter formatter = new ExcelStyleDateFormatter(EXCEL_DATE_FORMAT);
final StringBuffer sb = new StringBuffer();

for (Map.Entry<Locale,String> me : testMap.entrySet()) {
final Locale locale = me.getKey();
final String expected = me.getValue();
formatter.setDateFormatSymbols(DateFormatSymbols.getInstance(locale));
int month = 0;
for (Date d : testDates) {
sb.setLength(0);
String result = formatter.format(d, sb, fp).toString();
String msg = "Failed testDates for locale " + locale + ", provider: " + provider +
" and date " + d + ", having: " + result;

int actIdx = (Locale.CHINESE.equals(locale) && jreVersion >= 12) ? 1 : 0;

assertEquals(msg, expected.charAt(month), result.charAt(actIdx));
month++;
} }
} }
} }


private Map<Locale, List<String>> initializeLocales() {
// Setting up the locale to be tested together with a list of asserted unicode-formatted results and put them in a map.
Locale germanLocale = Locale.GERMAN;
List<String> germanResultList = Arrays.asList("\u004a", "\u0046", "\u004d", "\u0041", "\u004d",
"\u004a", "\u004a", "\u0041", "\u0053", "\u004f", "\u004e", "\u0044");

Locale russianLocale = new Locale("ru", "RU");
List<String> russianResultList = Arrays.asList("\u044f", "\u0444", "\u043c", "\u0430", "\u043c",
"\u0438", "\u0438", "\u0430", "\u0441", "\u043e", "\u043d", "\u0434");

Locale austrianLocale = new Locale("de", "AT");
List<String> austrianResultList = Arrays.asList("\u004a", "\u0046", "\u004d", "\u0041", "\u004d",
"\u004a", "\u004a", "\u0041", "\u0053", "\u004f", "\u004e", "\u0044");

Locale englishLocale = Locale.UK;
List<String> englishResultList = Arrays.asList("\u004a", "\u0046", "\u004d", "\u0041", "\u004d",
"\u004a", "\u004a", "\u0041", "\u0053", "\u004f", "\u004e", "\u0044");

Locale frenchLocale = Locale.FRENCH;
List<String> frenchResultList = Arrays.asList("\u006a", "\u0066", "\u006d", "\u0061", "\u006d",
"\u006a", "\u006a", "\u0061", "\u0073", "\u006f", "\u006e", "\u0064");

Locale chineseLocale = Locale.CHINESE;
List<String> chineseResultList = Arrays.asList("\u4e00", "\u4e8c", "\u4e09", "\u56db", "\u4e94",
"\u516d", "\u4e03", "\u516b", "\u4e5d", "\u5341", "\u5341", "\u5341");

Locale turkishLocale = new Locale("tr", "TR");
List<String> turkishResultList = Arrays.asList("\u004f", "\u015e", "\u004d", "\u004e", "\u004d",
"\u0048", "\u0054", "\u0041", "\u0045", "\u0045", "\u004b", "\u0041");

Locale hungarianLocale = new Locale("hu", "HU");
List<String> hungarianResultList = Arrays.asList("\u006a", "\u0066", "\u006d", "\u00e1", "\u006d",
"\u006a", "\u006a", "\u0061", "\u0073", "\u006f", "\u006e", "\u0064");

Locale indianLocale = new Locale("en", "IN");
List<String> indianResultList = Arrays.asList("\u004a", "\u0046", "\u004d", "\u0041", "\u004d",
"\u004a", "\u004a", "\u0041", "\u0053", "\u004f", "\u004e", "\u0044");

Locale indonesianLocale = new Locale("in", "ID");
List<String> indonesianResultList = Arrays.asList("\u004a", "\u0046", "\u004d", "\u0041", "\u004d",
"\u004a", "\u004a", "\u0041", "\u0053", "\u004f", "\u004e", "\u0044");


Map<Locale, List<String>> testMap = new HashMap<>();
testMap.put(germanLocale, germanResultList);
testMap.put(russianLocale, russianResultList);
testMap.put(austrianLocale, austrianResultList);
testMap.put(englishLocale, englishResultList);
testMap.put(frenchLocale, frenchResultList);
testMap.put(chineseLocale, chineseResultList);
testMap.put(turkishLocale, turkishResultList);
testMap.put(hungarianLocale, hungarianResultList);
testMap.put(indianLocale, indianResultList);
testMap.put(indonesianLocale, indonesianResultList);

return testMap;
private Date parseDate(String dateStr) {
try {
return DATE_FORMAT.parse(dateStr);
} catch (ParseException e) {
return new Date(0);
}
} }


private String getUnicode(char c) {
return "\\u" + Integer.toHexString(c | 0x10000).substring(1);
/**
* Setting up the locale to be tested together with a list of asserted
* unicode-formatted results and put them in a map.
*/
private Map<Locale, String> initializeLocales() {
Map<Locale, String> testMap = new HashMap<>();

testMap.put(Locale.GERMAN, "JFMAMJJASOND");
testMap.put(new Locale("de", "AT"), "JFMAMJJASOND");
testMap.put(Locale.UK, "JFMAMJJASOND");
testMap.put(new Locale("en", "IN"), "JFMAMJJASOND");
testMap.put(new Locale("in", "ID"), "JFMAMJJASOND");
testMap.put(Locale.FRENCH, "jfmamjjasond");

testMap.put(new Locale("ru", "RU"),
"\u044f\u0444\u043c\u0430\u043c\u0438\u0438\u0430\u0441\u043e\u043d\u0434");

testMap.put(Locale.CHINESE, jreVersion < 12
? "\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d\u5341\u5341\u5341"
: "123456789111");

testMap.put(new Locale("tr", "TR"),
"\u004f\u015e\u004d\u004e\u004d\u0048\u0054\u0041\u0045\u0045\u004b\u0041");

testMap.put(new Locale("hu", "HU"),
"\u006a\u0066\u006d\u00e1\u006d\u006a\u006a\u0061\u0073\u006f\u006e\u0064");

return testMap;
} }


@Test @Test
try { try {
LocaleUtil.setUserLocale(Locale.GERMAN); LocaleUtil.setUserLocale(Locale.GERMAN);
String dateStr = new ExcelStyleDateFormatter(EXCEL_DATE_FORMAT).format( String dateStr = new ExcelStyleDateFormatter(EXCEL_DATE_FORMAT).format(
new SimpleDateFormat("yyyy-MM-dd", Locale.ROOT).parse("2016-03-26"));
DATE_FORMAT.parse("2016-03-26"));
assertEquals("M", dateStr); assertEquals("M", dateStr);
} finally { } finally {
LocaleUtil.setUserLocale(before); LocaleUtil.setUserLocale(before);
@Test @Test
public void testWithPattern() throws ParseException { public void testWithPattern() throws ParseException {
String dateStr = new ExcelStyleDateFormatter("yyyy|" + EXCEL_DATE_FORMAT + "|").format( String dateStr = new ExcelStyleDateFormatter("yyyy|" + EXCEL_DATE_FORMAT + "|").format(
new SimpleDateFormat("yyyy-MM-dd", Locale.ROOT).parse("2016-03-26"));
DATE_FORMAT.parse("2016-03-26"));
assertEquals("2016|M|", dateStr); assertEquals("2016|M|", dateStr);
} }
} }

Loading…
Annulla
Salva