package code.loader;

import code.loader.except.*;
import code.modules.CurryModule;
import code.symbols.*;
import code.table.ModuleTable;

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

/**
 * The interface implemented by all module loaders. <P>
 * <p/>
 * <B>Class Responsibilities</B> :
 * <OL>
 * <LI> provide the common interface for all module loaders: CLASS, TXT, XML
 * </LI>
 * </OL>
 * <B>Class Collaborators</B> :
 * <OL>
 * <LI> None </LI>
 * </OL>
 *
 * @author Sunita Marathe 
 * @since Jul 15, 2005
 */
public class ClassModuleLoader implements ModuleLoader {
  /**
   * Load the module specified by moduleFilePath
   *
   * @param moduleName module name (without path)
   * @param moduleFilePath module name with absolute path
   * @throws Exception
   */
  public CurryModule load (String moduleName, String moduleFilePath) throws Exception {
    CurryModule module = null;
      String moduleDirName = null;
      String pkgQualModName = null;
    try {
      // moduleFilePath format : "/d1/d2/../dn/" + "p1.p2....pm." + "c.class"
      int i = moduleFilePath.lastIndexOf ("/");
      moduleDirName = moduleFilePath.substring (0, i);
      File moduleDir = new File (moduleDirName);
      URL moduleUrl = moduleDir.toURL();
      URL [] classPath = { moduleUrl };
      URLClassLoader classLoader = new URLClassLoader (classPath);
      pkgQualModName = moduleFilePath.substring (i+1);
      i = pkgQualModName.lastIndexOf(".");
      pkgQualModName = pkgQualModName.substring(0, i);
      Class moduleClass = classLoader.loadClass (pkgQualModName);
      module = (CurryModule) moduleClass.newInstance ();
    }
    catch (Exception e) {
      String msg = "\nError while loading classfile for module <dir : \"" + moduleDirName + "\", " + "class : " + pkgQualModName + "\".\n" + e.toString();
      throw new LoaderException (msg);
    }

    ModuleTable.installModule (module);
    return module;
  }
}
