/
area/
classes/net/sourceforge/pain/logic/
classes/net/sourceforge/pain/logic/event/
classes/net/sourceforge/pain/logic/fn/util/
classes/net/sourceforge/pain/network/console/
classes/net/sourceforge/pain/plugin/
classes/net/sourceforge/pain/plugin/reset/
classes/net/sourceforge/pain/plugin/shutdown/
classes/net/sourceforge/pain/plugin/social/
classest/net/sourceforge/pain/db/data/
doc/
doc/paindb/resources/
src/net/sourceforge/pain/logic/
src/net/sourceforge/pain/logic/event/
src/net/sourceforge/pain/logic/fn/util/
src/net/sourceforge/pain/network/console/
src/net/sourceforge/pain/network/console/telnet/
src/net/sourceforge/pain/plugin/
src/net/sourceforge/pain/plugin/command/
src/net/sourceforge/pain/plugin/reset/
src/net/sourceforge/pain/plugin/shutdown/
src/net/sourceforge/pain/plugin/social/
src/net/sourceforge/pain/util/
tests/
tests/net/sourceforge/pain/db/data/
package net.sourceforge.pain;


import net.sourceforge.pain.plugin.*;
import net.sourceforge.pain.util.*;

import java.io.*;


public class LogicLoadingManager {

	private static final String EVENTS_PACKAGE = "net.sourceforge.pain.logic.event.";
	private static int counter = 0;// for debug use

	/** path where to look for logic class files*/
	protected String dirPath;

	/** classloaders by classname */
	private LogicClassLoader loader = new LogicClassLoader();

	protected LogicLoadingManager(String dirPath) {
		this.dirPath = dirPath;
	}

	public synchronized Class provideClass(String className) throws ClassNotFoundException {
		Class c = loader._findLoadedClass(className);
		if (c != null) {
			Log.debug("findLoadedClass works!:" + className);
			return c;
		}
		// net.sourceforge.pain.logic.Event is not reloadable system class!
		if (!className.startsWith("net.sourceforge.pain.logic.") || className.equals("net.sourceforge.pain.logic.Event")) {
			if (isPluginImpl(className)) {
				Log.debug("Asking plugin from LOGIC LOADER:" + className);
				return Core.getPluginManager().loadClassByPluginClassloader(null, className);
			}
			try {
				c = Class.forName(className);
			} catch (LinkageError error) {
				if (error instanceof NoClassDefFoundError && error.getMessage().indexOf("wrong name:") > 0) {
					// case insensitive filesystem -> we will hide this errors
				} else {
					// this will not stop server but will panic!
					Log.error("PANIC!!!", error);
				}
				throw new ClassNotFoundException("Error during systen class loading!", error);
			}
			Log.debug("findSystemClass works!:" + className);
			return c;
		}

		Log.debug("LLM:asking logic class:" + className);
		c = loader.defineClassFromFile(className);
		return c;
	}


	private static boolean isPluginImpl(String className) {
		return (className.startsWith(PluginManager.PLUGINS_HOME)
		        && className.lastIndexOf('.') > PluginManager.PLUGINS_HOME_LENGTH);
	}

	public synchronized void reload() {
		loader = new LogicClassLoader();
		System.gc();
	}

	public ClassLoader getActiveClassLoader() {
		return loader;
	}

	public Class provideEventClass(String eventClassSuffix) throws ClassNotFoundException {
		return provideClass(EVENTS_PACKAGE + eventClassSuffix);
	}

	public class LogicClassLoader extends ClassLoader {

		int number = counter;

		protected LogicClassLoader() {
		}

		public synchronized Class loadClass(String className) throws ClassNotFoundException {
			Log.debug("LOGIC LOADER[" + number + "]: ask load:" + className);
			return provideClass(className);
		}

		protected Class defineClassFromFile(String className) throws ClassNotFoundException {
			try {
				byte[] data = Core.getFileData(dirPath + "/" + className.replace('.', '/') + ".class");
				return super.defineClass(className, data, 0, data.length);
			} catch (IOException e) {
				Log.warn("Can't load class file! " + e.getMessage());
				throw new ClassNotFoundException("Class File Not Found:" + dirPath + "/" + className + ".class");
			}
		}

		protected Class _findLoadedClass(String className) {
			return super.findLoadedClass(className);
		}

		protected void finalize() {
			Log.debug("LOGIC LOADER[" + number + "]:finalizing");
		}
	}
}