.
+ *
+ * l2jserver is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * l2jserver is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with l2jserver. If not, see .
+ */
+
+package com.l2jserver.service.game.scripting.scriptmanager;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.l2jserver.service.game.scripting.ScriptContext;
+import com.l2jserver.service.game.scripting.ScriptContextFactory;
+
+/**
+ * Class that represents managers of script contexes. It loads, reloads and
+ * unload script contexes. In the future it may be extended to support
+ * programatic manipulation of contexes, but for now it's not needed.
+ *
+ * Example:
+ *
+ *
+ * ScriptManager sm = new ScriptManager();
+ * sm.load(new File("st/contexts.xml"));
+ * ...
+ * sm.shutdown();
+ *
+ *
+ * @author Rogiel
+ */
+public class ScriptManager {
+ /**
+ * Logger for script context
+ */
+ private static final Logger log = LoggerFactory
+ .getLogger(ScriptManager.class);
+
+ /**
+ * Collection of script contexts
+ */
+ private Set contexts = new HashSet();
+
+ /**
+ * Loads script contexes from descriptor
+ *
+ * @param scriptDescriptor
+ * xml file that describes contexes
+ * @throws Exception
+ * if can't load file
+ */
+ public synchronized void load(File scriptDescriptor) throws Exception {
+
+ JAXBContext c = JAXBContext.newInstance(ScriptInfo.class,
+ ScriptList.class);
+ Unmarshaller u = c.createUnmarshaller();
+ ScriptList list = (ScriptList) u.unmarshal(scriptDescriptor);
+
+ for (ScriptInfo si : list.getScriptInfos()) {
+ ScriptContext context = createContext(si, null);
+ if (context != null) {
+ contexts.add(context);
+ context.init();
+ }
+ }
+ }
+
+ /**
+ * Creates new context and checks to not produce copies
+ *
+ * @param si
+ * script context descriptor
+ * @param parent
+ * parent script context
+ * @return created script context
+ * @throws Exception
+ * if can't create context
+ */
+ private ScriptContext createContext(ScriptInfo si, ScriptContext parent)
+ throws Exception {
+ ScriptContext context = ScriptContextFactory.getScriptContext(
+ si.getRoot(), parent);
+ context.setLibraries(si.getLibraries());
+ context.setCompilerClassName(si.getCompilerClass());
+
+ if (parent == null && contexts.contains(context)) {
+ log.warn("Double root script context definition: "
+ + si.getRoot().getAbsolutePath());
+ return null;
+ }
+
+ if (si.getScriptInfos() != null && !si.getScriptInfos().isEmpty()) {
+ for (ScriptInfo child : si.getScriptInfos()) {
+ createContext(child, context);
+ }
+ }
+
+ return context;
+ }
+
+ /**
+ * Initializes shutdown on all contexes
+ */
+ public synchronized void shutdown() {
+ for (ScriptContext context : contexts) {
+ context.shutdown();
+ }
+
+ contexts.clear();
+ }
+
+ /**
+ * Reloads all contexes
+ */
+ public synchronized void reload() {
+ for (ScriptContext context : contexts) {
+ context.reload();
+ }
+ }
+
+ /**
+ * Returns unmodifiable set with script contexes
+ *
+ * @return unmodifiable set of script contexes
+ */
+ public synchronized Collection getScriptContexts() {
+ return Collections.unmodifiableSet(contexts);
+ }
+}
diff --git a/src/main/java/com/l2jserver/util/ClassUtils.java b/src/main/java/com/l2jserver/util/ClassUtils.java
new file mode 100644
index 000000000..36efad22e
--- /dev/null
+++ b/src/main/java/com/l2jserver/util/ClassUtils.java
@@ -0,0 +1,94 @@
+/*
+ * This file is part of l2jserver .
+ *
+ * l2jserver is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * l2jserver is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with l2jserver. If not, see .
+ */
+
+package com.l2jserver.util;
+
+/**
+ * This class contains utilities that are used when we are working with classes
+ *
+ * @author Rogiel
+ */
+public class ClassUtils {
+ /**
+ * Return true if class a is either equivalent to class b, or if class a is
+ * a subclass of class b, i.e. if a either "extends" or "implements" b. Note
+ * tht either or both "Class" objects may represent interfaces.
+ *
+ * @param a
+ * class
+ * @param b
+ * class
+ * @return true if a == b or a extends b or a implements b
+ */
+ public static boolean isSubclass(Class> a, Class> b) {
+ // We rely on the fact that for any given java class or
+ // primtitive type there is a unqiue Class object, so
+ // we can use object equivalence in the comparisons.
+ if (a == b) {
+ return true;
+ }
+ if (a == null || b == null) {
+ return false;
+ }
+ for (Class> x = a; x != null; x = x.getSuperclass()) {
+ if (x == b) {
+ return true;
+ }
+ if (b.isInterface()) {
+ Class> interfaces[] = x.getInterfaces();
+ for (Class> anInterface : interfaces) {
+ if (isSubclass(anInterface, b)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks if class in member of the package
+ *
+ * @param clazz
+ * class to check
+ * @param packageName
+ * package
+ * @return true if is member
+ */
+ public static boolean isPackageMember(Class> clazz, String packageName) {
+ return isPackageMember(clazz.getName(), packageName);
+ }
+
+ /**
+ * Checks if classNames belongs to package
+ *
+ * @param className
+ * class name
+ * @param packageName
+ * package
+ * @return true if belongs
+ */
+ public static boolean isPackageMember(String className, String packageName) {
+ if (!className.contains(".")) {
+ return packageName == null || packageName.isEmpty();
+ } else {
+ String classPackage = className.substring(0,
+ className.lastIndexOf('.'));
+ return packageName.equals(classPackage);
+ }
+ }
+}
diff --git a/src/test/java/com/l2jserver/model/id/factory/IDFactoryTest.java b/src/test/java/com/l2jserver/model/id/factory/IDFactoryTest.java
index b1a0a81af..3d1676996 100644
--- a/src/test/java/com/l2jserver/model/id/factory/IDFactoryTest.java
+++ b/src/test/java/com/l2jserver/model/id/factory/IDFactoryTest.java
@@ -4,9 +4,10 @@ import junit.framework.Assert;
import org.junit.Test;
+import script.dao.mysql5.DAOModuleMySQL5;
+
import com.google.inject.Guice;
import com.google.inject.Injector;
-import com.l2jserver.db.dao.mysql5.DAOModuleMySQL5;
import com.l2jserver.model.id.CharacterID;
import com.l2jserver.model.id.ID;
import com.l2jserver.model.world.L2Character;
diff --git a/src/test/java/com/l2jserver/service/world/WorldEventDispatcherImplTest.java b/src/test/java/com/l2jserver/service/world/WorldEventDispatcherImplTest.java
index 4fbda3f3f..416f0fbad 100644
--- a/src/test/java/com/l2jserver/service/world/WorldEventDispatcherImplTest.java
+++ b/src/test/java/com/l2jserver/service/world/WorldEventDispatcherImplTest.java
@@ -7,11 +7,12 @@ import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
+import script.dao.mysql5.DAOModuleMySQL5;
+
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Scopes;
-import com.l2jserver.db.dao.mysql5.DAOModuleMySQL5;
import com.l2jserver.model.id.factory.CharacterIDFactory;
import com.l2jserver.model.id.factory.IDFactoryModule;
import com.l2jserver.model.id.factory.ItemIDFactory;