FileDocCategorySizeDatePackage
ProcessJAR.javaAPI DocJMF 2.1.1e19576Mon May 12 12:21:00 BST 2003com.sun.media.customizer

ProcessJAR

public class ProcessJAR extends Thread implements TokenDef
The purpose of this class is to do the real customization work: open the source JMF JAR file, filter out those plugins not selected by the user, create the target JAR file and write out all necessary classes. An object of this class will run on a separate thread.
version
2.0

Fields Summary
public static final String[]
sollibs
public static final String[]
win32libs
public static final Hashtable
cdmap
String
srcJARname
String
dstJARname
String
workDir
int[]
selected
ProgressDiag
progressDlg
CusRegistry
theRegistry
int
release
boolean
twojars
Constructors Summary
public ProcessJAR(String srcJARname, String dstJARname, int[] selected, ProgressDiag progressDlg, CusRegistry theRegistry, int release, boolean twojars)

	this.srcJARname = srcJARname;
	this.dstJARname = dstJARname;
	this.selected = selected;
	this.progressDlg = progressDlg;
	this.theRegistry = theRegistry;
	this.workDir = this.theRegistry.getWorkDir();
	this.release = release;
	this.twojars = twojars;
    
Methods Summary
private static java.lang.Stringbyte2oct(byte b)

	int i=b&0xff;
	int dig3=i%8;
	int dig2=(i/8)%8;
	int dig1=i/64;
    return (""+dig1+""+dig2+""+dig3);
    
private voiderrorMessage(java.lang.String msg)

	progressDlg.sentErr(msg);
	myyield();
    
private booleanisCDSelected(java.lang.String dname)

	DBItem dbentry = null;
	String pname;

	// System.out.println("dname = " + dname);
	pname = (String)(cdmap.get(dname));
	dbentry = (DBItem)CustomDB.get(pname);

	if ( dbentry != null && dbentry.isMarked())
	    return true;
	
	return false;
    
private voidmyyield()

	try {
	    sleep(15);
	} catch (Exception ex) {
	}
    
public voidrun()
run(): The method of the thread to do the real job: Open source JAR file: Open it for reading make sure all mediaFormat/Codecs classes are there to pick display class name/class count/file size while processing Process the request by marking necessary MediaFormat/Codec classes Create destinaton JAR file: create the file, abort if any error for each class from source if this class is needed, write it to the destination JAR/ZIP file otherwise ignore it When done, enable DONE button of the progress bar

Param
N/A
return
N/A

	// Assuming 35% for reading, 15% for updating the registry and 50% for writing, can be adjusted if needed.
	File srcFile, dstFile, dstFile2 = null;
	long srcfilesize, filesizeSoFar;
	int classCountSoFar;
	int progressSoFar = 0;
	ZipFile srcZF = null;
	ZipEntry srcZE;
	
	FileOutputStream fos, fos2;
	ZipOutputStream zos = null, zos2 = null;
	InputStream is = null;
	
	double readRate, writeRate;
	//System.out.println("in ProcessJAR run...");
	//System.out.println("srcname = " + srcJARname);
	//System.out.println("dstname = " + dstJARname);
	//for ( int i = 0; i < selected.length; i++)
	//System.out.println(" " + selected[i]);
	
	// let dialog thread execute first
	try {
	    sleep(30);
	} catch (Exception ex) {
	}
	
	srcFile = new File(srcJARname);
	
	// We will use the file size as the base for the initial segment
	// of the progress bar
	srcfilesize = srcFile.length();
	readRate = 35.0/srcfilesize;
	
	// Open the source file as a ZipFile
	try {
	    srcZF = new ZipFile(srcFile);
	}
	catch (ZipException e) {
	    errorMessage(e.getMessage());
	    return;
	}
	catch (IOException e) {
	    errorMessage(e.getMessage());
	    return;
	}
	
	if ( CustomDB.getSize() == 0 ) 
	    CustomDB.buildDB();
	else 
	    CustomDB.clearAllMarks();
	
	Vector orglist = new Vector();
	Enumeration se = srcZF.entries();
	String clsname;
	long entrysize;
	
	classCountSoFar = 0;
	filesizeSoFar = 0;
	
	// read classes from source jar
	while (se.hasMoreElements()) {
	    srcZE = (ZipEntry)se.nextElement();
	    
	    clsname = srcZE.getName();
	    if (!(clsname.endsWith(".class") || clsname.endsWith(".gif")) ){
		// System.out.println(clsname);
		continue;
	    }
	    orglist.addElement(srcZE);
	    
	    entrysize = srcZE.getCompressedSize();
	    classCountSoFar++;
	    filesizeSoFar += entrysize;
	    
	    if ( classCountSoFar % 5 == 0 ) {
		progressSoFar = (int)(readRate*filesizeSoFar);
		progressDlg.updateValue(progressSoFar);
		progressDlg.updateSourceInfo(filesizeSoFar, classCountSoFar);
		myyield();
	    }
	}
	
	
	progressDlg.updateSourceInfo(srcfilesize, classCountSoFar);
	myyield();
	
	// Finish loading source jar file, start to write target
	int notwanted = CustomDB.markAllClasses(selected);
	writeRate = 50.0/(classCountSoFar - notwanted);
	
	progressDlg.updateNote(I18N.getResource("ProcessJAR.REGISTRY"));
	myyield();
	
	updateRegistry();
	
	// Create the destination file
	if ( !twojars ) {
	    dstFile = new File(dstJARname);
	    try {
		fos = new FileOutputStream(dstFile);
		zos = new ZipOutputStream(fos);
	    } catch (IOException e) {
		try {
		    srcZF.close();
		}
		catch (IOException ex) {
		}
		dstFile.delete();
		errorMessage(e.getMessage());
		return;
	    }
	} else {
	    dstFile = new File(dstJARname);
	    String pp = dstFile.getParent() + File.separator;
	    String fn = dstFile.getName();
	    // System.out.println("pp = " + pp);
	    // System.out.println("fn = " + fn);
	    
	    dstFile = new File(pp + "core_" + fn);
	    dstFile2 = new File(pp + "plugin_" + fn);
	    try {
		fos = new FileOutputStream(dstFile);
		fos2 = new FileOutputStream(dstFile2);
		zos = new ZipOutputStream(fos);
		zos2 = new ZipOutputStream(fos2);
	    } catch (IOException e) {
		try {
		    srcZF.close();
		}
		catch (IOException ex) {
		}
		dstFile.delete();
		dstFile2.delete();
		errorMessage(e.getMessage());
		return;
	    }
	}

	classCountSoFar = 0;
	filesizeSoFar = 0;
	byte buffer[] = new byte[4096];  // Read/Write buffer
	int len;
	DBItem dbentry;
	
	progressDlg.updateNote(I18N.getResource("ProcessJAR.WRT"));
	myyield();
	
	// Traverse all classes from source JAR/ZIp file
	int NNN = orglist.size();
	if ( !twojars ) {
	    for (int nn = 0 ; nn < NNN; nn++ ) {
		srcZE = (ZipEntry)(orglist.elementAt(nn));
		
		clsname = srcZE.getName();
		entrysize = srcZE.getCompressedSize();
		
		if ( (dbentry=(DBItem)CustomDB.get(clsname)) == null || dbentry.isMarked()) { 
		    ++classCountSoFar;
		    // filesizeSoFar += entrysize;
		    ZipEntry newZE;
		    String rClsName = "com/sun/media/util/RegistryLib.class";
		    
		    try {
			if ( clsname.equals(rClsName)) {
			    String fullName = rClsName.replace('/", File.separatorChar);
			    fullName = workDir + File.separator + fullName;
			    is = new FileInputStream(fullName);
			} else {
			    is = srcZF.getInputStream(srcZE);
			}
			
			newZE = new ZipEntry(clsname);
			zos.putNextEntry(newZE);
			while (true) {
			    if (is.available() == 0)
				break;
			    len = is.read(buffer);
			    if (len == -1)
				break;
			    zos.write(buffer, 0, len);
			}
			zos.closeEntry();
			is.close();
			if (clsname.equals("com/sun/media/util/RegistryLib.class")) {
			    System.out.println("Default Registry replaced");
			    entrysize = newZE.getCompressedSize();
			}
		    } catch (IOException e) {
			try {
			    srcZF.close();
			}catch (IOException ex) {
			}
			
			dstFile.delete();
			errorMessage(e.getMessage());
			return;
		    }
		    
		    filesizeSoFar += entrysize;
		}
		
		if ( classCountSoFar % 5 == 0 ) {
		    progressSoFar = (int)(50 + writeRate * classCountSoFar);
		    progressDlg.updateValue(progressSoFar);
		    progressDlg.updateTargetInfo(filesizeSoFar, classCountSoFar);
		    myyield();
		}
		
	    } // end of for nn
	 		
	    // Done
	    try {
		zos.close();
		srcZF.close();
	    } catch ( IOException ex) {
		dstFile.delete();
		errorMessage(ex.getMessage());
		return;
	    }
	    
	} else { // generate two jars
	    for (int nn = 0 ; nn < NNN; nn++ ) {
		srcZE = (ZipEntry)(orglist.elementAt(nn));
		
		clsname = srcZE.getName();
		entrysize = srcZE.getCompressedSize();
		dbentry=(DBItem)CustomDB.get(clsname);

		if ( dbentry == null ) { // core classes
		    ++classCountSoFar;
		    // filesizeSoFar += entrysize;
		    ZipEntry newZE;
		    
		    try {
			is = srcZF.getInputStream(srcZE);
						
			newZE = new ZipEntry(clsname);
			zos.putNextEntry(newZE);
			while (true) {
			    if (is.available() == 0)
				break;
			    len = is.read(buffer);
			    if (len == -1)
				break;
			    zos.write(buffer, 0, len);
			}
			zos.closeEntry();
			is.close();
		    } catch (IOException e) {
			try {
			    srcZF.close();
			}catch (IOException ex) {
			}
			
			dstFile.delete();
			errorMessage(e.getMessage());
			return;
		    }
		    
		} else if ( dbentry.isMarked()) { // plugable classes
		    ++classCountSoFar;
		    // filesizeSoFar += entrysize;
		    ZipEntry newZE;
		    String rClsName = "com/sun/media/util/RegistryLib.class";
		    
		    try {
			if ( clsname.equals(rClsName)) {
			    String fullName = rClsName.replace('/", File.separatorChar);
			    fullName = workDir + File.separator + fullName;
			    is = new FileInputStream(fullName);
			} else {
			    is = srcZF.getInputStream(srcZE);
			}
			
			newZE = new ZipEntry(clsname);
			zos2.putNextEntry(newZE);
			while (true) {
			    if (is.available() == 0)
				break;
			    len = is.read(buffer);
			    if (len == -1)
				break;
			    zos2.write(buffer, 0, len);
			}
			zos2.closeEntry();
			is.close();
			if (clsname.equals("com/sun/media/util/RegistryLib.class")) {
			    System.out.println("Default Registry replaced");
			    entrysize = newZE.getCompressedSize();
			}
		    } catch (IOException e) {
			try {
			    srcZF.close();
			}catch (IOException ex) {
			}
			
			dstFile2.delete();
			errorMessage(e.getMessage());
			return;
		    }

		}
		
		filesizeSoFar += entrysize;

		if ( classCountSoFar % 5 == 0 ) {
		    progressSoFar = (int)(50 + writeRate * classCountSoFar);
		    progressDlg.updateValue(progressSoFar);
		    progressDlg.updateTargetInfo(filesizeSoFar, classCountSoFar);
		    myyield();
		}
		
	    }
	    
	
	    // Done
	    try {
		zos.close();
		zos2.close();
		srcZF.close();
	    } catch ( IOException ex) {
		dstFile.delete();
		dstFile2.delete();
		errorMessage(ex.getMessage());
		return;
	    }
	} // end of else twojars

	// ??
	long dstfilesize = dstFile.length();
	if ( twojars ) {
	    dstfilesize += dstFile2.length();
	}
	progressDlg.updateValue(100);
	progressDlg.updateTargetInfo(dstfilesize, classCountSoFar);
	progressDlg.enableDone();
	
	// Process native libs
	if ( release >= 2 ) {
	    System.out.println("***Needed native modules***");
	}
	
	if ( release == 2 ) { //SPP
	    String libname = null;
	    for (int i = 0; i < sollibs.length; i++) {
		libname = sollibs[i];
		if ( (dbentry=(DBItem)CustomDB.get(libname)) == null || dbentry.isMarked()) { 
		    System.out.println(libname);
		}
	    }
	    System.out.println("libjmutil.so");
	}
	
	if (release == 3 ) {
	    String libname = null;
	    for (int i = 0; i < win32libs.length; i++) {
		libname = win32libs[i];
		if ( (dbentry=(DBItem)CustomDB.get(libname)) == null || dbentry.isMarked()) { 
		    System.out.println(libname);
		}
	    }
	    System.out.println("jmutil.dll");
	}
	
	
    
private voidupdateRegistry()

	Vector v;
	Hashtable newDefHash, newFullHash, theHash;
	boolean b_def, b_full;
	int len;
	String pin, newpin;
	
	
	newFullHash = (Hashtable)(theRegistry.getFullRegistry().clone());
	if ( newFullHash != null && newFullHash.size() > 0 )
	    b_full = true;
	else
	    b_full = false;

	if ( b_full ) {
	    newDefHash = newFullHash;
	    b_def = false;
	} else {
	    newDefHash = (Hashtable)(theRegistry.getDefaultRegistry().clone());
	    
	    if ( newDefHash != null && newDefHash.size() > 0 )
		b_def = true;
	    else
		b_def = false;
	}

	// update DEMUX
	v = PlugInManager.getPlugInList(null, null, PlugInManager.DEMULTIPLEXER);
	len = v.size();
	
	for (int i = 0; i < len; i++) {
	    pin = (String)v.elementAt(i);
	    pin.trim();
	    newpin = pin.replace('.", '/") + ".class";
	    DBItem dbentry = (DBItem)CustomDB.get(newpin);
	    if ( dbentry != null && !dbentry.isMarked()) {
		if ( b_full) {
		    theRegistry.removePlugIn(newFullHash, pin,PlugInManager.DEMULTIPLEXER); 
		} else if ( b_def) {
		    theRegistry.removePlugIn(newDefHash, pin,PlugInManager.DEMULTIPLEXER); 
		}
	    }
	}
	
	// update CODEC
	v = PlugInManager.getPlugInList(null, null, PlugInManager.CODEC);
	len = v.size();
	
	for (int i = 0; i < len; i++) {
	    pin = (String)v.elementAt(i);
	    pin.trim();
	    newpin = pin.replace('.", '/") + ".class";
	    DBItem dbentry = (DBItem)CustomDB.get(newpin);
	    if ( dbentry != null && !dbentry.isMarked()) {
		// PlugInManager.removePlugIn(pin,PlugInManager.CODEC);
		if ( b_full) {
		    theRegistry.removePlugIn(newFullHash,pin,PlugInManager.CODEC);
		} else if ( b_def) {
		    theRegistry.removePlugIn(newDefHash,pin,PlugInManager.CODEC);
		}
	    }
	}
	// update MUX
	v = PlugInManager.getPlugInList(null, null, PlugInManager.MULTIPLEXER);
	len = v.size();
	
	for (int i = 0; i < len; i++) {
	    pin = (String)v.elementAt(i);
	    pin.trim();
	    newpin = pin.replace('.", '/") + ".class";
	    DBItem dbentry = (DBItem)CustomDB.get(newpin);
	    if ( dbentry != null && !dbentry.isMarked()){
		// PlugInManager.removePlugIn(pin,PlugInManager.MULTIPLEXER);
		if ( b_full) {
		    theRegistry.removePlugIn(newFullHash, pin,PlugInManager.MULTIPLEXER); 
		} else if ( b_def) {
		    theRegistry.removePlugIn(newDefHash, pin,PlugInManager.MULTIPLEXER);
		}
	    }
	}

	// update RENDERER
	v = PlugInManager.getPlugInList(null, null, PlugInManager.RENDERER);
	len = v.size();
	
	for (int i = 0; i < len; i++) {
	    pin = (String)v.elementAt(i);
	    pin.trim();
	    newpin = pin.replace('.", '/") + ".class";
	    DBItem dbentry = (DBItem)CustomDB.get(newpin);
	    if ( dbentry != null && !dbentry.isMarked()){ 
		// PlugInManager.removePlugIn(pin,PlugInManager.RENDERER);
		if (b_full) { 
		    theRegistry.removePlugIn(newFullHash, pin,PlugInManager.RENDERER);
		} else if (b_def) {
		    theRegistry.removePlugIn(newDefHash, pin,PlugInManager.RENDERER);
		}
	    }
	}
	
	// update Capture Devices
	v = CaptureDeviceManager.getDeviceList(null);
	len = v.size();
	String dname = null;

	for ( int i = 0; i < len; i++){
	    CaptureDeviceInfo info = (CaptureDeviceInfo)v.elementAt(i);
	    dname = info.getLocator().getProtocol();
	    
	    if ( !isCDSelected(dname)) {
		if ( b_full) { 
		    theRegistry.removeCaptureD(newFullHash, dname);
		} else if (b_def) {
		    theRegistry.removeCaptureD(newDefHash, dname);
		}
	    }
	} 

	
	// generate RegistyLib.java
	if ( b_full ) {
	    writeRegistryLib(newFullHash) ;
	} else if ( b_def) {
	    writeRegistryLib(newDefHash);
	}
	
	// compile RegistryLib
	try {
	    String[] cmdarr = new String[4];
	    cmdarr[0] = theRegistry.getJavacPath() + File.separator + "javac";
	    cmdarr[1] = "-d";
	    cmdarr[2] = workDir;
	    cmdarr[3] = workDir + File.separator + "RegistryLib.java";
	    
	    Process proc = Runtime.getRuntime().exec(cmdarr);
	    proc.waitFor();
	} catch (Exception ex) {
	    ex.printStackTrace();
	}

	// save the full registry to disk
	if (release >= 2 && b_full)
	    theRegistry.saveRegistry(newFullHash);

	progressDlg.updateValue(42);
	myyield();
	
    
private voidwriteRegistryLib(java.util.Hashtable newhash)

	byte[] properties;
	int i,j;
	
	properties = null;
	
	// write the newhash to a ByteOutputStream
	try {
	    ByteArrayOutputStream bos = new ByteArrayOutputStream();
	    ObjectOutputStream oos = new ObjectOutputStream(bos);
	    int tableSize = newhash.size();
	    oos.writeInt(tableSize);
	    oos.writeInt(theRegistry.versionNumber);
	    for (Enumeration e = newhash.keys(); e.hasMoreElements() ;) {
		String key = (String) e.nextElement();
		Object value = newhash.get(key);
		
		oos.writeUTF(key);    // write key as UTF chars.
		
		oos.writeObject(value);
		oos.flush();
	    }
	    oos.close();
	    properties = bos.toByteArray();
	} catch (Exception ex) {
	    ex.printStackTrace();
	    System.out.println("Sth is wrong when saving the registry");
	    return;
    }
	
	
	// write RegistryLib
	try {
	    String registryname = workDir + File.separator + "RegistryLib.java";
	    DataOutputStream ds = new DataOutputStream(new FileOutputStream(registryname));
	    ds.writeBytes("/* Generated by RegistryGen.\n   DO NOT EDIT.*/\n\n");
	    ds.writeBytes("package com.sun.media.util;\n\n");
	    ds.writeBytes("public abstract class ");
	    ds.writeBytes("RegistryLib");
	    ds.writeBytes(" {\n\n");
	    if (properties.length > 0) {
		ds.writeBytes("   public static byte[] getData(){\n");
		ds.writeBytes("       int i;\n");
		ds.writeBytes("       byte[] b= new byte["+properties.length+"];\n");
		ds.writeBytes("       for (i=0;i<b.length;i++)\n");
		// switch back between 255 and 0
		ds.writeBytes("          b[i] = (byte)(s.charAt(i)-1);\n");
		ds.writeBytes("       return b;\n");
		ds.writeBytes("    }\n");
	    } else {
		ds.writeBytes("   public static byte[] getData(){\n");
		ds.writeBytes("       return null;\n");
		ds.writeBytes("    }\n");
	    }
	    
	    ds.writeBytes("    private static String s = \n        ");
	    ds.writeBytes("\"");
	    int len= properties.length;
	    for (j = 0; j < len; j++) {
		// switch between 255 and 0 since 0 is more common
		ds.writeBytes( ("\\"+byte2oct((byte)(1+properties[j]))) );
		if ((j%16)==15) {
		    ds.writeBytes("\"+\n        \""  );
		}
	    }
	    ds.writeBytes("\";\n\n"  );
	    ds.writeBytes("}\n"); //trailer
	    ds.close();
	} catch (Exception ex) {
	    System.out.println("Sth wrong when writing RegsitryLib");
	}