diff --git a/core/pom.xml b/core/pom.xml index 5380301..cc6c69c 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -7,13 +7,13 @@ Core core - 0.4 + 0.18 bundle asys asys - ${asys.version} + 0.5 @@ -22,6 +22,11 @@ commons-io 2.5 + + org.apache.felix + org.apache.felix.gogo.runtime + 0.10.0 + @@ -30,11 +35,11 @@ org.apache.felix maven-bundle-plugin - 2.3.5 + 3.0.1 true - ASys: ${project.name} ${project.version} + ASys: ${project.name} ${project.groupId}.${project.artifactId} asys.core.ASysCoreActivator asys.core.api diff --git a/core/src/main/java/asys/core/ASysCore.java b/core/src/main/java/asys/core/ASysCore.java index d8c879e..3540946 100644 --- a/core/src/main/java/asys/core/ASysCore.java +++ b/core/src/main/java/asys/core/ASysCore.java @@ -12,10 +12,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; class ASysCore implements ICore { private Logger logger = LoggerFactory.getLogger(ASysCore.class.getName()); @@ -30,16 +27,20 @@ class ASysCore implements ICore { void init() { // Загрузка библиотек logger.trace("Load libraries"); - startBundles(loadJars("lib")); + String dir = getProperty("asys.core.library.dir", "lib"); + logger.debug("lib directory = {}", dir); + startBundles(loadJars(dir)); // Загрузка модулей logger.trace("Load modules"); - modules = loadJars("modules"); + dir = getProperty("asys.core.modules.dir", "modules"); + logger.debug("modules directory = {}", dir); + modules = loadJars(dir); startBundles(modules); } private List loadJars(String directory) { - List bundlesList = new ArrayList<>(); + ArrayList bundlesList = new ArrayList<>(); File libsDir = new File(directory); String[] jarsList = libsDir.list(); @@ -49,7 +50,27 @@ class ASysCore implements ICore { try { logger.trace("Load jar \"{}/{}\"", directory, jar); Bundle bundle = bundleContext.installBundle(String.format("file:%s/%s", directory, jar)); - bundlesList.add(bundle); + Dictionary metaHeaders = bundle.getHeaders(); + String serviceProvide = metaHeaders.get("Service-Provide"); + if (serviceProvide != null) { + logger.trace("Module \"{}\" provide service: \"{}\"", bundle.getSymbolicName(), serviceProvide); + + int idx = bundlesList.size(); + int j = idx; + ListIterator iterator = bundlesList.listIterator(bundlesList.size()); + while(iterator.hasPrevious()) { + Bundle bndl = iterator.previous(); + j--; + metaHeaders = bndl.getHeaders(); + String serviceRequest = metaHeaders.get("Service-Request"); + if (serviceRequest.equals(serviceProvide)) { + idx = j; + } + } + bundlesList.add(idx, bundle); + } else { + bundlesList.add(bundle); + } } catch (BundleException e) { logger.error(String.format("Error load jar \"%s/%s\"", directory, jar), e); } @@ -64,6 +85,7 @@ class ASysCore implements ICore { try { logger.trace("Start module \"{}\"", bundle.getSymbolicName()); bundle.start(); + logger.trace("Module \"{}\" started", bundle.getSymbolicName()); } catch (BundleException e) { logger.error(String.format("Error start bundle \"%s\"", bundle.getSymbolicName()), e); } @@ -71,7 +93,9 @@ class ASysCore implements ICore { } private void stopBundles(List bundleList) { - for (Bundle bundle : bundleList) { + ListIterator iterator = bundleList.listIterator(bundleList.size()); + while(iterator.hasPrevious()) { + Bundle bundle = iterator.previous(); try { logger.trace("Stop module \"{}\"", bundle.getSymbolicName()); bundle.stop(); @@ -81,6 +105,18 @@ class ASysCore implements ICore { } } + private void uninstallBundles(List bundleList) { + ListIterator iterator = bundleList.listIterator(bundleList.size()); + while(iterator.hasPrevious()) { + Bundle bundle = iterator.previous(); + try { + bundle.uninstall(); + } catch (BundleException e) { + logger.error(String.format("Error uninstall bundle \"%s\"", bundle.getSymbolicName()), e); + } + } + } + @Override public void reloadMoludes() { logger.trace("Reload modules - start"); @@ -88,6 +124,9 @@ class ASysCore implements ICore { // Остановка модулей stopBundles(modules); + // Деинсталяция + uninstallBundles(modules); + // Загрузка модулей по-новой modules = loadJars("modules"); @@ -106,4 +145,12 @@ class ASysCore implements ICore { public Object loadObject(String name) { return bankObjects.remove(name); } + + private String getProperty(String name, String defValue) { + try { + return bundleContext.getProperty(name); + } catch (NullPointerException e) { + return defValue; + } + } } diff --git a/core/src/main/java/asys/core/ASysCoreActivator.java b/core/src/main/java/asys/core/ASysCoreActivator.java index 3038bb8..5be7bd2 100644 --- a/core/src/main/java/asys/core/ASysCoreActivator.java +++ b/core/src/main/java/asys/core/ASysCoreActivator.java @@ -10,7 +10,7 @@ import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; public class ASysCoreActivator implements BundleActivator { - private ServiceRegistration service; + private ServiceRegistration service, cmdService; @Override public void start(BundleContext bundleContext) throws Exception { @@ -21,10 +21,15 @@ public class ASysCoreActivator implements BundleActivator { // Инициализация Ядра core.init(); + + // Регистрация комманд для Gogo Shell + cmdService = bundleContext.registerService( + Commands.class.getName(), new Commands(core, bundleContext.getBundle(0L)), Commands.getDictionary()); } @Override public void stop(BundleContext bundleContext) throws Exception { + cmdService.unregister(); service.unregister(); } } diff --git a/core/src/main/java/asys/core/Commands.java b/core/src/main/java/asys/core/Commands.java new file mode 100644 index 0000000..d8ad0d1 --- /dev/null +++ b/core/src/main/java/asys/core/Commands.java @@ -0,0 +1,44 @@ +/* + * DmitriyMX + * 2016-08-07 + */ +package asys.core; + +import asys.core.api.ICore; +import org.apache.felix.service.command.Descriptor; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleException; + +import java.util.Dictionary; +import java.util.Hashtable; + +public class Commands { + private ICore core; + private Bundle sysBundle; + + public static Dictionary getDictionary() { + Hashtable dictionary = new Hashtable<>(); + dictionary.put("osgi.command.scope", "asys.core"); + dictionary.put("osgi.command.function", new String[] { "reload", "exit" }); + return dictionary; + } + + public Commands(ICore core, Bundle sysBundle) { + this.core = core; + this.sysBundle = sysBundle; + } + + @Descriptor("Reload modules") + public void reload() { + core.reloadMoludes(); + } + + @Descriptor("Close ASys") + public void exit() { + try { + sysBundle.stop(); + } catch (BundleException e) { + e.printStackTrace(); + } + } +} diff --git a/core/src/main/java/asys/core/api/IMinecraftServer.java b/core/src/main/java/asys/core/api/IMinecraftServer.java new file mode 100644 index 0000000..5950f9a --- /dev/null +++ b/core/src/main/java/asys/core/api/IMinecraftServer.java @@ -0,0 +1,13 @@ +/* + * DmitriyMX + * 2016-07-30 + */ +package asys.core.api; + +public interface IMinecraftServer { + void start(); + void stop(); + void forceStop(); + boolean isAlive(); + void sendCommand(String command); +} diff --git a/core/src/main/java/asys/core/api/IServerManager.java b/core/src/main/java/asys/core/api/IServerManager.java new file mode 100644 index 0000000..05baff1 --- /dev/null +++ b/core/src/main/java/asys/core/api/IServerManager.java @@ -0,0 +1,10 @@ +/* + * DmitriyMX + * 2016-07-30 + */ +package asys.core.api; + +public interface IServerManager { + IMinecraftServer developServer(String serverName); + IMinecraftServer getServer(String serverName); +}