git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846809 13f79535-47bb-0310-9956-ffa450edef68pull/134/head
<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"/> |
/* ==================================================================== | |||||
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); | |||||
} | |||||
} | |||||
} |
/* ==================================================================== | |||||
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)); | |||||
} | |||||
} |
@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 |
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 |
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())); | ||||
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())); | ||||
} | } |
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); | ||||
} | } | ||||
} | } |