mirror of https://github.com/apache/poi.git
gather necessary .xsb for ooxml-lite jar via intercepting the calls to SchemaTypeSystemImpl.XsbReader
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1884850 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
b0830f9d94
commit
07ba96f023
60
build.xml
60
build.xml
|
@ -157,7 +157,7 @@ under the License.
|
|||
<property name="ooxml.testokfile" location="build/ooxml-testokfile.txt"/>
|
||||
|
||||
<property name="ooxml.lite.agent" location="lib/ooxml-tests/ooxml-lite-agent.jar"/>
|
||||
<property name="ooxml.lite.report" location="build/ooxml-lite-report.txt"/>
|
||||
<property name="ooxml.lite.report" location="build/ooxml-lite-report"/>
|
||||
<property name="ooxml.lite.jar" location="build/dist/maven/poi-ooxml-lite/poi-ooxml-lite-${version.id}.jar"/>
|
||||
<property name="ooxml.lite.includes" value="^(com/microsoft/schemas|org/(etsi|openxmlformats|w3/)|org/apache/poi/schemas)"/>
|
||||
|
||||
|
@ -1157,6 +1157,7 @@ under the License.
|
|||
destdir="${basedir}/src/multimodule/ooxml-lite-agent/java9"
|
||||
includeantruntime="false"
|
||||
fork="true"
|
||||
modulepath="${basedir}/lib/main-tests"
|
||||
unless:true="${isJava8}">
|
||||
<compilerarg line="--patch-module org.apache.poi.ooxml_lite=${ooxml.output.test.dir}"/>
|
||||
</javac>
|
||||
|
@ -1168,6 +1169,7 @@ under the License.
|
|||
<attribute name="Multi-Release" value="true"/>
|
||||
<attribute name="Automatic-Module-Name" value="org.apache.poi.ooxml_lite"/>
|
||||
<attribute name="Premain-Class" value="org.apache.poi.ooxml.lite.OOXMLLiteAgent"/>
|
||||
<!-- attribute name="Can-Retransform-Classes" value="true"/ -->
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
|
@ -1711,7 +1713,7 @@ under the License.
|
|||
<echo message="Create ooxml-lite schemas"/>
|
||||
<local name="lite.exports"/>
|
||||
<loadresource property="lite.exports">
|
||||
<file file="${ooxml.lite.report}"/>
|
||||
<file file="${ooxml.lite.report}.clazz"/>
|
||||
<filterchain>
|
||||
<tokenfilter>
|
||||
<replaceregex pattern="[/\\][^/\\]+$" replace=""/>
|
||||
|
@ -1750,7 +1752,7 @@ under the License.
|
|||
</modulepath>
|
||||
</javac>
|
||||
|
||||
<copy file="${ooxml.lite.report}" tofile="build/ooxml-lite-classes.txt" overwrite="true">
|
||||
<copy file="${ooxml.lite.report}.clazz" tofile="${ooxml.lite.report}.clazz2" overwrite="true">
|
||||
<filterchain>
|
||||
<tokenfilter>
|
||||
<replaceregex pattern="(.*)" replace="\1.class${line.separator}\1$*.class "/>
|
||||
|
@ -1758,62 +1760,22 @@ under the License.
|
|||
</filterchain>
|
||||
</copy>
|
||||
|
||||
<local name="ooxml.lite.xsbs"/>
|
||||
<loadresource property="ooxml.lite.xsbs">
|
||||
<file file="${ooxml.lite.report}"/>
|
||||
<copy file="${ooxml.lite.report}.xsb" tofile="${ooxml.lite.report}.xsb2" overwrite="true">
|
||||
<filterchain>
|
||||
<linecontains negate="true" matchany="true">
|
||||
<contains value="$"/>
|
||||
<contains value="TypeSystemHolder"/>
|
||||
</linecontains>
|
||||
<suffixlines suffix=".java"/>
|
||||
<prefixlines prefix="org/apache/poi/schemas/ooxml/system/ooxml/"/>
|
||||
<suffixlines suffix=".xsb"/>
|
||||
</filterchain>
|
||||
</loadresource>
|
||||
|
||||
<concat dest="build/ooxml-lite-classes.txt" append="true">
|
||||
<filelist dir="build/xmlbean-sources" files="${ooxml.lite.xsbs}"/>
|
||||
<filterchain>
|
||||
<linecontains>
|
||||
<contains value="resolveHandle"/>
|
||||
</linecontains>
|
||||
<replaceregex pattern='.*"([^"]+)".*' replace="org/apache/poi/schemas/ooxml/system/ooxml/\1.xsb"/>
|
||||
</filterchain>
|
||||
</concat>
|
||||
|
||||
<!-- the following xsb files aren't detected, i.e. not directly loaded by XmlBeans interface classes -->
|
||||
<echo file="build/ooxml-lite-classes.txt" append="true">
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/index.xsb
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/picelement.xsb
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/groupelement.xsb
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/group7d3fdoctype.xsb
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/shapelayoutelement.xsb
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/shapetypeelement.xsb
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/shapetypeb89bdoctype.xsb
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/shapeelement.xsb
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/shapeaee1doctype.xsb
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/tblelement.xsb
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/tbleb1bdoctype.xsb
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/relationshipreferenceelement.xsb
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/qualifyingpropertieselement.xsb
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/oleobjelement.xsb
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/oleobj8482doctype.xsb
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/stcellspans60f6type.xsb
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/stcellspanf3a5type.xsb
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/alternatecontentelement.xsb
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/chartelement.xsb
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/chartf85cdoctype.xsb
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/rectelement.xsb
|
||||
org/apache/poi/schemas/ooxml/system/ooxml/rectaf36doctype.xsb
|
||||
</echo>
|
||||
</copy>
|
||||
|
||||
<mkdir dir="build/dist/maven/poi-ooxml-lite"/>
|
||||
|
||||
<jar destfile="${ooxml.lite.jar}" duplicate="preserve">
|
||||
<zipfileset dir="${basedir}/src/multimodule/ooxml-lite/java9" prefix="META-INF/versions/9" excludes="*.java"/>
|
||||
<zipfileset src="${ooxml.xsds.jar}">
|
||||
<patternset includesfile="build/ooxml-lite-classes.txt">
|
||||
<patternset includesfile="${ooxml.lite.report}.clazz2">
|
||||
<include name="org/apache/poi/schemas/ooxml/element/**/*.xsb"/>
|
||||
</patternset>
|
||||
<patternset includesfile="${ooxml.lite.report}.xsb2"/>
|
||||
</zipfileset>
|
||||
<zipfileset dir="src/multimodule/ooxml-full/java9" prefix="META-INF/versions/9" excludes="*.java"/>
|
||||
<manifest>
|
||||
|
|
Binary file not shown.
|
@ -17,6 +17,7 @@
|
|||
|
||||
module org.apache.poi.ooxml_lite {
|
||||
requires java.instrument;
|
||||
requires static net.bytebuddy.agent;
|
||||
|
||||
exports org.apache.poi.ooxml.lite;
|
||||
}
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
package org.apache.poi.ooxml.lite;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.instrument.Instrumentation;
|
||||
|
@ -31,48 +33,108 @@ import java.util.Set;
|
|||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.implementation.MethodDelegation;
|
||||
import net.bytebuddy.implementation.SuperMethodCall;
|
||||
import net.bytebuddy.matcher.ElementMatchers;
|
||||
import org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl;
|
||||
|
||||
/**
|
||||
* 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 static void premain(String agentArgs, Instrumentation inst) throws IOException {
|
||||
String[] args = (agentArgs == null ? "" : agentArgs).split("\\|", 2);
|
||||
String logBase = args.length >= 1 ? args[0] : "ooxml-lite-report";
|
||||
|
||||
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/.*");
|
||||
XsbLogger.load(logBase+".xsb");
|
||||
|
||||
try {
|
||||
if (Files.exists(path)) {
|
||||
try (Stream<String> stream = Files.lines(path)) {
|
||||
stream.forEach((s) -> fileHashes.add(s.hashCode()));
|
||||
}
|
||||
} else {
|
||||
Files.createFile(path);
|
||||
ClazzLogger log = new ClazzLogger();
|
||||
log.load(logBase+".clazz");
|
||||
log.setPattern(args.length >= 2 ? args[1] : ".*/schemas/.*");
|
||||
inst.addTransformer(log);
|
||||
|
||||
new AgentBuilder.Default()
|
||||
// .with(AgentBuilder.Listener.StreamWriting.toSystemOut())
|
||||
.type(named("org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl$XsbReader"))
|
||||
.transform((builder, type, cl, m) ->
|
||||
builder
|
||||
.constructor(ElementMatchers.any())
|
||||
.intercept(MethodDelegation.to(XsbLogger.class).andThen(SuperMethodCall.INSTANCE))
|
||||
)
|
||||
.installOn(inst);
|
||||
}
|
||||
|
||||
/**
|
||||
* This logger intercepts the loading of XmlBeans .xsb
|
||||
*
|
||||
* when ran in the ant junitlauncher, it's not possible to have the interceptor methods as
|
||||
* instance method of ClazzLogger. the junit test will fail ... though it works ok in IntelliJ
|
||||
* probably because of classpath vs. modulepath instantiation
|
||||
*/
|
||||
public static class XsbLogger {
|
||||
private static Path logPath;
|
||||
private static final Set<Integer> hashes = new HashSet<>();
|
||||
|
||||
static void load(String path) throws IOException {
|
||||
logPath = Paths.get(path);
|
||||
if (Files.exists(logPath)) {
|
||||
try (Stream<String> stream = Files.lines(logPath)) {
|
||||
stream.forEach((s) -> hashes.add(s.hashCode()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SchemaTypeSystemImpl.XsbReader::new is delegated to here - method name doesn't matter
|
||||
public static void loadXsb(SchemaTypeSystemImpl parent, String handle) {
|
||||
write(logPath, handle, hashes);
|
||||
}
|
||||
|
||||
public static void loadXsb(SchemaTypeSystemImpl parent, String handle, int filetype) {
|
||||
loadXsb(parent, handle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This logger is used to log the used XmlBeans classes
|
||||
*/
|
||||
public static class ClazzLogger implements ClassFileTransformer {
|
||||
Path logPath;
|
||||
Pattern includes;
|
||||
final Set<Integer> hashes = new HashSet<>();
|
||||
|
||||
public void setPattern(String regex) {
|
||||
includes = Pattern.compile(regex);
|
||||
}
|
||||
|
||||
public void load(String path) throws IOException {
|
||||
this.logPath = Paths.get(path);
|
||||
if (Files.exists(this.logPath)) {
|
||||
try (Stream<String> stream = Files.lines(this.logPath)) {
|
||||
stream.forEach((s) -> hashes.add(s.hashCode()));
|
||||
}
|
||||
} 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) {
|
||||
}
|
||||
if (logPath != null && className != null && includes.matcher(className).find()) {
|
||||
write(logPath, className, hashes);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
|
||||
public static void premain(String agentArgs, Instrumentation inst) {
|
||||
inst.addTransformer(new LoggingTransformer(agentArgs));
|
||||
|
||||
static void write(Path path, String item, Set<Integer> hashes) {
|
||||
if (!hashes.contains(item.hashCode())) {
|
||||
try {
|
||||
// TODO: check if this is atomic ... as transform() is probably called synchronized, it doesn't matter anyway
|
||||
Files.write(path, (item+"\n").getBytes(StandardCharsets.ISO_8859_1), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
|
||||
hashes.add(item.hashCode());
|
||||
} catch (IOException ignroed) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue