// ResourceUpgrader.java
// $Id: ResourceUpgrader.java,v 1.2 1997/07/30 14:02:25 ylafon Exp $  
// (c) COPYRIGHT MIT and INRIA, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html

package w3c.jigsaw.upgrade.from2to3;

import java.io.*;
import java.util.*;

import w3c.jigsaw.upgrade.from1to2.ClassLooker;

class UpgraderData {
    String cls      = null;
    String upgrader = null;

    UpgraderData(String cls, String upgrader) {
	this.cls      = cls;
	this.upgrader = upgrader;
    }
}

public abstract class ResourceUpgrader {
    public static UpgraderData upgraders[] = null;

    static {
	// WARNING: order of declarations matter (all hacked allow here)
	upgraders = new UpgraderData[1];
	// All filtered resources sub-classes need fix:
	upgraders[0] = new UpgraderData(
	    "w3c.jigsaw.resources.FilteredResource"
	    , "w3c.jigsaw.upgrade.from2to3.FilteredResourceUpgrader");
    }

    public static ResourceUpgrader getUpgrader(String clsname) 
	throws ResourceUpgraderException
    {
	try {
	    String upname  = null;
	    for (int i = 0 ; i < upgraders.length ; i++) {
		if (ClassLooker.isSubclass(clsname, upgraders[i].cls)) {
		    upname = upgraders[i].upgrader;
		    break;
		}
	    }
	    if (upname != null) {
		Class c = Class.forName(upname);
		return (ResourceUpgrader) c.newInstance();
	    } 
	} catch (ClassNotFoundException ex) {
	    throw new ResourceUpgraderException("unable to load class \""
						+ clsname
						+ "\"");
	} catch (Exception ex) {
	    throw new ResourceUpgraderException("unable to upgrade class \""
						+ clsname
						+ "\"");
	}
	return null;
    }

    public static ResourceUpgrader getUpgrader(Class cls) 
	throws ResourceUpgraderException
    {
	return getUpgrader(cls.getName());
    }

    public static ResourceUpgrader getUpgrader(byte oldbits[])
	throws ResourceUpgraderException
    {
	// Get the class name out of the bits:
	try {
	    DataInputStream in = (new DataInputStream
				  (new ByteArrayInputStream(oldbits)));
	    String clsname = in.readUTF();
	    return getUpgrader(clsname);
	} catch (Exception ex) {
	    // ex.printStackTrace();
	}
	return null;
    }

    abstract public byte[] upgrade(byte oldbits[], int off, int len);
    abstract public byte[] upgrade(Class cls, DataInputStream in);

}
