]> source.dussan.org Git - poi.git/commitdiff
org.apache.poi.util.OOXMLLite - an utility to build a 'lite' version of the ooxml...
authorYegor Kozlov <yegor@apache.org>
Mon, 16 Nov 2009 15:32:05 +0000 (15:32 +0000)
committerYegor Kozlov <yegor@apache.org>
Mon, 16 Nov 2009 15:32:05 +0000 (15:32 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@880798 13f79535-47bb-0310-9956-ffa450edef68

build.xml
src/ooxml/java/org/apache/poi/util/OOXMLLite.java [new file with mode: 0755]

index 3f7ff7bc12910392f1fc6f0e488a2b3a598317cf..3cfb9aed7e8b0d80ce1ec7c95c180cf9f4ae3f01 100644 (file)
--- a/build.xml
+++ b/build.xml
@@ -184,8 +184,8 @@ under the License.
         <pathelement location="${main.output.dir}"/>
         <pathelement location="${scratchpad.output.dir}"/>
         <fileset dir="${ooxml.lib}">
-                       <include name="*.jar" />
-               </fileset>
+                           <include name="*.jar" />
+               </fileset>
     </path>
 
     <path id="test.classpath">
@@ -408,7 +408,54 @@ under the License.
                        basedir="${ooxml.xsds.src.dir}"
                        destfile="${ooxml.xsds.src.jar}"
                />
-       </target>
+  </target>
+
+  <!-- Build a 'lite' version of the ooxml-schemas.jar-->
+  <target name="ooxml-xsds-lite" depends="test-ooxml">
+    <java classname="org.apache.poi.util.OOXMLLite" fork="yes">
+      <classpath refid="test.ooxml.classpath"/>
+      <sysproperty key="POI.testdata.path" file="${poi.test.dir}"/> 
+      <sysproperty key="user.language" value="en"/> 
+      <sysproperty key="user.country" value="US"/> 
+      <arg line="-ooxml ${ooxml.xsds.jar} -test ${ooxml.output.test.dir} -dest build/ooxml-xsds-lite"/>
+    </java>
+    <echo message="Running ooxml tests against the 'lite' classes"/>
+    <antcall target="test-ooxml-lite"/>
+    <jar basedir="build/ooxml-xsds-lite" destfile="build/dist/ooxml-schemas-lite-${version.id}.jar"/>
+  </target>
+
+  <!-- Run ooxml tests against the 'lite' version of the ooxml-schemas.jar-->
+  <target name="test-ooxml-lite">
+      <junit printsummary="yes" fork="yes" forkmode="once" haltonfailure="${halt.on.test.failure}" failureproperty="ooxml.test.failed">
+          <classpath>
+              <path refid="main.classpath"/>
+              <pathelement location="${main.output.dir}"/>
+              <pathelement location="${scratchpad.output.dir}"/>
+              <fileset dir="${ooxml.lib}">
+                           <include name="*.jar" />
+                           <exclude name="ooxml-schemas-*.jar" />
+               </fileset>
+              <pathelement location="build/ooxml-xsds-lite"/>
+              <pathelement location="${ooxml.output.dir}"/>
+              <pathelement location="${ooxml.output.test.dir}"/>
+              <pathelement location="${main.output.test.dir}"/> 
+              <pathelement location="${scratchpad.output.test.dir}"/> 
+              <pathelement location="${junit.jar1.dir}"/>
+          </classpath>
+          <sysproperty key="user.language" value="en"/> 
+          <sysproperty key="user.country" value="US"/> 
+          <sysproperty key="POI.testdata.path" file="${poi.test.dir}"/> 
+          <sysproperty key="java.awt.headless" value="true"/>
+          <formatter type="plain"/>
+          <formatter type="xml"/>
+          <batchtest todir="${ooxml.reports.test}">
+              <fileset dir="${ooxml.src.test}">
+                  <include name="**/Test*.java"/>
+                  <exclude name="**/All*Tests.java"/>
+              </fileset>
+          </batchtest>
+      </junit>
+  </target>
 
   <target name="compile" depends="init, compile-main, 
     compile-scratchpad, compile-contrib, compile-examples, compile-scratchpad-examples"
diff --git a/src/ooxml/java/org/apache/poi/util/OOXMLLite.java b/src/ooxml/java/org/apache/poi/util/OOXMLLite.java
new file mode 100755 (executable)
index 0000000..881f508
--- /dev/null
@@ -0,0 +1,200 @@
+/* ====================================================================
+   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.util;
+
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.lang.reflect.Field;
+
+/**
+ * Build a 'lite' version of the ooxml-schemas.jar
+ *
+ * @author Yegor Kozlov
+ */
+public final class OOXMLLite {
+
+    private static final Field _classes;
+    static {
+        try {
+            _classes = ClassLoader.class.getDeclaredField("classes");
+            _classes.setAccessible(true);
+        } catch (Throwable e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 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 {
+
+        String dest = null, test = null, ooxml = null;
+
+        for (int i = 0; i < args.length; i++) {
+            if (args[i].equals("-dest")) dest = args[++i];
+            else if (args[i].equals("-test")) test = args[++i];
+            else if (args[i].equals("-ooxml")) ooxml = args[++i];
+        }
+        OOXMLLite builder = new OOXMLLite(dest, test, ooxml);
+        builder.build();
+    }
+
+    void build() throws IOException{
+
+        List<String> lst = new ArrayList<String>();
+        //collect unit tests
+        System.out.println("Collecting unit tests");
+        collectTests(_testDir, _testDir, lst, ".+?\\.Test.+?\\.class$");
+
+        TestSuite suite = new TestSuite();
+        for (String arg : lst) {
+            //ignore inner classes defined in tests
+            if (arg.indexOf('$') != -1) continue;
+
+            String cls = arg.replace(".class", "");
+            try {
+                Class test = Class.forName(cls);
+                suite.addTestSuite(test);
+            } catch (ClassNotFoundException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        //run tests
+        System.out.println("Running tests");
+        TestRunner.run(suite);
+
+        //see what classes from the ooxml-schemas.jar are loaded
+        System.out.println("Copying classes");
+        Map<String, Class<?>> classes = getLoadedClasses(_ooxmlJar.getName());
+        for (Class<?> cls : classes.values()) {
+            String className = cls.getName();
+            String classRef = className.replace('.', '/') + ".class";
+            File destFile = new File(_destDest, classRef);
+            //System.out.println(classRef + "  -->  " + destFile);
+            copyFile(cls.getResourceAsStream('/' + classRef), destFile);
+
+            if(cls.isInterface()){
+                //always copy Factory that accompanies every ooxml schema object
+                String factoryClass = className + "$Factory";
+                if(!classes.containsKey(factoryClass)){
+                    try {
+                        Class fc = Class.forName(factoryClass);
+                        className = fc.getName();
+                        classRef = className.replace('.', '/') + ".class";
+                        destFile = new File(_destDest, classRef);
+                        //System.out.println(classRef + "  -->  " + destFile);
+                        copyFile(fc.getResourceAsStream('/' + classRef), destFile);
+                    } catch(ClassNotFoundException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
+
+        //finally copy the compiled .xsb files
+        System.out.println("Copying .xsb resources");
+        JarFile jar = new  JarFile(_ooxmlJar);
+        for(Enumeration<JarEntry> e = jar.entries(); e.hasMoreElements(); ){
+            JarEntry je = e.nextElement();
+            if(je.getName().matches("schemaorg_apache_xmlbeans/system/\\w+/\\w+\\.xsb")){
+                File destFile = new File(_destDest, je.getName());
+                //System.out.println(je.getName() + "  -->  " + destFile);
+                copyFile(jar.getInputStream(je), destFile);
+            }
+        }
+        jar.close();
+    }
+
+    /**
+     * 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<String> out, String ptrn) {
+        if (arg.isDirectory()) {
+            for (File f : arg.listFiles()) {
+                collectTests(root, f, out, ptrn);
+            }
+        } else {
+            String path = arg.getAbsolutePath();
+            String prefix = root.getAbsolutePath();
+            String cls = path.substring(prefix.length() + 1).replace(File.separator, ".");
+            if(cls.matches(ptrn)) out.add(cls);
+        }
+    }
+
+    /**
+     *
+     * @param ptrn the pattern to filter output 
+     * @return the classes loaded by the system class loader keyed by class name
+     */
+    @SuppressWarnings("unchecked")
+    private static Map<String, Class<?>> getLoadedClasses(String ptrn) {
+        ClassLoader appLoader = ClassLoader.getSystemClassLoader();
+        try {
+            Vector<Class<?>> classes = (Vector<Class<?>>) _classes.get(appLoader);
+            Map<String, Class<?>> map = new HashMap<String, Class<?>>();
+            for (Class<?> cls : classes) {
+                String jar = cls.getProtectionDomain().getCodeSource().getLocation().toString();
+                if(jar.indexOf(ptrn) != -1) map.put(cls.getName(), cls);
+            }
+            return map;
+        } catch (IllegalAccessException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static void copyFile(InputStream srcStream, File destFile) throws IOException {
+        File destDirectory = destFile.getParentFile();
+        destDirectory.mkdirs();
+        OutputStream destStream = new FileOutputStream(destFile);
+        try {
+            IOUtils.copy(srcStream, destStream);
+        } finally {
+            destStream.close();
+        }
+    }
+
+}
\ No newline at end of file