org.docx4j.utils.JarCheck Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of docx4j Show documentation
Show all versions of docx4j Show documentation
docx4j is a library which helps you to work with the Office Open
XML file format as used in docx
documents, pptx presentations, and xlsx spreadsheets.
/*
* [JarCheck.java]
*
* Summary: Ensures javac -target versions of the class files in a jar are as expected.
*
* Copyright: (c) 2006-2011 Roedy Green, Canadian Mind Products, http://mindprod.com
*
* Licence: This software may be copied and used freely for any purpose but military.
* http://mindprod.com/contact/nonmil.html
*
* Requires: JDK 1.5+
*
* Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/
*
* Version History:
* 1.0 2006-01-16 initial version
* 1.1 2006-01-16
* 1.2 2006-03-05 reformat with IntelliJ, add Javadoc
* 1.3 2008-04-21 display version number of each class file checked.
*/
package org.docx4j.utils;
import static java.lang.System.err;
import static java.lang.System.out;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* Ensures javac -target versions of the class files in a jar are as expected.
*
* @author Roedy Green, Canadian Mind Products
* @version 1.3 2008-04-21 display version number of each class file checked.
* @since 2006-01-16
*
* Modified by Jason Harrop 2011 06 25
* Note re Java 1.5, 1.6 behaviour.
* In 1.5, you can't put @Override on something which merely
* implements an interface
* Eclipse will give an error if you do (and have source set to 1.5).
* Maven and ant won't give an error, and if you have target=1.5
* (as we do for docx4j), will correctly produce 1.5 code.
* This class allows us to check that all our dependencies are
* also 1.5.
* An alternative way of doing it would be to use clirr.sourceforge.net
* which can run as an ant task, or from a command line, but I haven't
* tried that.
*
*/
public final class JarCheck
{
// ------------------------------ CONSTANTS ------------------------------
/**
* how many bytes at beginning of class file we read
4=ca-fe-ba-be + 2=minor + 2=major
*/
private static final int chunkLength = 8;
/**
* undisplayed copyright notice
*/
public static final String EMBEDDED_COPYRIGHT =
"Copyright: (c) 2006-2011 Roedy Green, Canadian Mind Products, http://mindprod.com";
private static final String RELEASE_DATE = "2008-04-21";
/**
* embedded version string.
*/
public static final String VERSION_STRING = "1.3";
/**
* translate class file major version number to human JVM version
*/
private static final HashMap convertMachineToHuman =
new HashMap( 23 );
/**
* translate from human JDK version to class file major version number
*/
private static final HashMap convertHumanToMachine =
new HashMap( 23 );
/**
* expected first 4 bytes of a class file
*/
private static final byte[] expectedMagicNumber =
{ ( byte ) 0xca, ( byte ) 0xfe, ( byte ) 0xba, ( byte ) 0xbe };
// -------------------------- STATIC METHODS --------------------------
static
{
convertHumanToMachine.put( "1.0", 44 );
convertHumanToMachine.put( "1.1", 45 );
convertHumanToMachine.put( "1.2", 46 );
convertHumanToMachine.put( "1.3", 47 );
convertHumanToMachine.put( "1.4", 48 );
convertHumanToMachine.put( "1.5", 49 );
convertHumanToMachine.put( "1.6", 50 );
convertHumanToMachine.put( "1.7", 51 );
convertHumanToMachine.put( "1.8", 52 );
}
static
{
convertMachineToHuman.put( 44, "1.0" );
convertMachineToHuman.put( 45, "1.1" );
convertMachineToHuman.put( 46, "1.2" );
convertMachineToHuman.put( 47, "1.3" );
convertMachineToHuman.put( 48, "1.4" );
convertMachineToHuman.put( 49, "1.5" );
convertMachineToHuman.put( 50, "1.6" );
convertMachineToHuman.put( 51, "1.7" );
convertMachineToHuman.put( 52, "1.8" );
}
/**
* check one jar to make sure all class files have compatible versions.
*
* @param jarFilename name of jar file whose classes are to be tested.
* @param low low bound for major version e.g. 44
* @param high high bound for major version. e.g. 50
*
* @return true if all is ok. False if not, with long on System.err of problems.
*/
private static boolean checkJar( String jarFilename, int low, int high )
{
out.println( "Checking jar " + jarFilename );
boolean success = true;
FileInputStream fis;
ZipInputStream zip = null;
int lowest = 1000;
int highest = 0;
try
{
try
{
fis = new FileInputStream( jarFilename );
zip = new ZipInputStream( fis );
// loop for each jar entry
entryLoop:
while ( true )
{
ZipEntry entry = zip.getNextEntry();
if ( entry == null )
{
break;
}
// relative name with slashes to separate dirnames.
String elementName = entry.getName();
//System.out.println(elementName);
if ( !elementName.endsWith( ".class" ) )
{
// ignore anything but a .final class file
continue;
}
byte[] chunk = new byte[ chunkLength ];
int bytesRead = zip.read( chunk, 0, chunkLength );
zip.closeEntry();
if ( bytesRead != chunkLength )
{
err.println( ">> Corrupt class file: "
+ elementName );
success = false;
continue;
}
// make sure magic number signature is as expected.
for ( int i = 0; i < expectedMagicNumber.length; i++ )
{
if ( chunk[ i ] != expectedMagicNumber[ i ] )
{
err.println( ">> Bad magic number in "
+ elementName );
success = false;
continue entryLoop;
}
}
/*
* pick out big-endian ushort major version in last two
* bytes of chunk
*/
int major =
( ( chunk[ chunkLength - 2 ] & 0xff ) << 8 ) + (
chunk[ chunkLength - 1 ]
& 0xff );
/* F I N A L L Y. All this has been leading up to this TEST */
if (major>highest) highest=major;
if (major high ) {
err.println( ">> Wrong Version " );
err.println( convertMachineToHuman.get( major )
+ " ("
+ major
+ ") "
+ elementName );
success = false;
} else
{
// Suppress low version error
// err.println( ">> Wrong Version " );
// err.println( convertMachineToHuman.get( major )
// + " ("
// + major
// + ") "
// + elementName );
// success = false;
}
}
// end while
}
catch ( EOFException e )
{
// normal exit
}
zip.close();
if (lowest==highest) {
System.out.println( convertMachineToHuman.get( highest ));
} else {
System.out.println( convertMachineToHuman.get( lowest ) + "-" + convertMachineToHuman.get( highest ));
}
return success;
}
catch ( IOException e )
{
err.println( ">> Problem reading jar file." );
return false;
}
}
// --------------------------- main() method ---------------------------
/**
* Main command line jarfileName lowVersion highVersion e.g. myjar.jar 1.0 1.6
*
* @param args rot used
*/
public static void main( String[] args )
{
// if ( args.length != 3 )
// {
// err.println( "usage: java -ea -jar jarcheck.jar jarFileName.jar 1.1 1.6" );
// System.exit( 2 );
// }
// String jarFilename = args[ 0 ];
// int low = convertHumanToMachine.get( args[ 1 ] );
// int high = convertHumanToMachine.get( args[ 2 ] );
int low = convertHumanToMachine.get( "1.3" );
int high = convertHumanToMachine.get( "1.6" );
String dirPath = System.getProperty("user.dir") + "/dist/";
File dir = new File(dirPath);
if (dir.isDirectory() ) {
File[] files = dir.listFiles();
for (int i=0 ; i