diff --git a/src/zutil/net/dns/MulticastDnsServer.java b/src/zutil/net/dns/MulticastDnsServer.java index ba38ad9..d541aad 100755 --- a/src/zutil/net/dns/MulticastDnsServer.java +++ b/src/zutil/net/dns/MulticastDnsServer.java @@ -115,7 +115,7 @@ public class MulticastDnsServer extends ThreadedUDPNetwork implements ThreadedUD DnsPacket dnsPacket = DnsPacket.read(in); // Just handle queries and no responses - if ( ! dnsPacket.getHeader().flagQueryResponse){ + if ( ! dnsPacket.getHeader().flagQueryResponse) { DnsPacket response = handleReceivedPacket(dnsPacket); if (response != null){ ByteArrayOutputStream outBuffer = new ByteArrayOutputStream(); @@ -140,12 +140,15 @@ public class MulticastDnsServer extends ThreadedUDPNetwork implements ThreadedUD response.getHeader().setDefaultResponseData(); for (DnsPacketQuestion question : request.getQuestions()){ if (question.name == null) continue; - switch (question.type){ + switch (question.type){ // Normal Domain Name Resolution case DnsConstants.TYPE.A: if (entries.containsKey(question.name)){ + logger.finer("Received request for domain: " + question.name); response.addAnswerRecord(entries.get(question.name)); + } else { + logger.finest("Received request for unknown domain: " + question.name); } break; @@ -154,19 +157,31 @@ public class MulticastDnsServer extends ThreadedUDPNetwork implements ThreadedUD if (question.name.startsWith("_service.")){ String postFix = question.name.substring(9); for (String domain : entries.keySet()){ - if (domain.endsWith(postFix)) + if (domain.endsWith(postFix)) { + logger.finer("Received request for service: " + question.name); response.addAnswerRecord(entries.get(domain)); + } else { + logger.finest("Received request for unknown service: " + question.name); + } } } else if (entries.containsKey(question.name)){ + logger.finer("Received request for service: " + question.name); response.addAnswerRecord(entries.get(question.name)); + } else { + logger.finer("Received request for unknown pointer: " + question.name); } break; + + default: + logger.finest("Unknown request type: " + question.type); } } + if (response.getAnswerRecords().isEmpty() && response.getNameServers().isEmpty() && - response.getAdditionalRecords().isEmpty()) + response.getAdditionalRecords().isEmpty()) { return null; + } return response; } } diff --git a/src/zutil/plugin/PluginData.java b/src/zutil/plugin/PluginData.java index 66bf302..2dd9368 100755 --- a/src/zutil/plugin/PluginData.java +++ b/src/zutil/plugin/PluginData.java @@ -27,7 +27,6 @@ package zutil.plugin; import zutil.log.LogUtil; import zutil.parser.DataNode; -import java.net.MalformedURLException; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; @@ -43,6 +42,7 @@ public class PluginData { private double pluginVersion; private String pluginName; + private boolean enabled = true; private HashMap, List>> classMap; private HashMap objectMap; @@ -97,19 +97,44 @@ public class PluginData { } + /** + * @return a version number for the plugin (specified in the plugin.json file + */ public double getVersion(){ return pluginVersion; } + /** + * @return the name of the plugin + */ public String getName(){ return pluginName; } + /** + * @return if this plugin is enabled + */ + public boolean isEnabled(){ + return enabled; + } + + /** + * Enables or disables this plugin + */ + public void setEnabled(boolean enabled){ + this.enabled = enabled; + } + /** + * @return a Iterator for all singleton Object instance that implement the specified interface + */ public Iterator getObjectIterator(Class intf){ if(!classMap.containsKey(intf)) return Collections.emptyIterator(); - return new PluginObjectIterator<>(classMap.get(intf).iterator()); + return new PluginSingletonIterator<>(classMap.get(intf).iterator()); } + /** + * @return a Iterator for all classes implementing the interface by the plugin + */ public Iterator> getClassIterator(Class intf){ if(!classMap.containsKey(intf)) return Collections.emptyIterator(); @@ -122,27 +147,32 @@ public class PluginData { objectMap.put(objClass, objClass.newInstance()); return (T) objectMap.get(objClass); } catch (Exception e) { - log.log(Level.WARNING, null, e); + log.log(Level.WARNING, "Unable to instantiate plugin class: " + objClass, e); } return null; } - + /** + * @return true if the specified interface is defined by the plugin + */ public boolean contains(Class intf){ return classMap.containsKey(intf); } public String toString(){ - return getName()+"(ver: "+getVersion()+")"; + return getName()+"(version: "+getVersion()+")"; } - - private class PluginObjectIterator implements Iterator{ + /** + * A Iterator that goes through all defined classes that implements + * a provided interface and returns a singleton instance of that class + */ + private class PluginSingletonIterator implements Iterator{ private Iterator> classIt; private T currentObj; - public PluginObjectIterator(Iterator> it) { + public PluginSingletonIterator(Iterator> it) { classIt = it; } diff --git a/src/zutil/plugin/PluginManager.java b/src/zutil/plugin/PluginManager.java index 4294fa7..fb735c8 100755 --- a/src/zutil/plugin/PluginManager.java +++ b/src/zutil/plugin/PluginManager.java @@ -31,17 +31,24 @@ import zutil.parser.DataNode; import zutil.parser.json.JSONParser; import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.NoSuchElementException; +import java.util.*; import java.util.logging.Logger; /** - * This class will search the file system for files - * with the name "plugin.json" that defines data - * parameters for a single plugin. - * The class will only load the latest version of the specific plugin. + * This class will search the file system for files with the name "plugin.json" + * that defines data parameters for a plugin. + * The class will only load the latest version of a specific plugin with the same name. + *

+ * Example plugin.json content:

+ * {
+ *     "version": 1.0,
+ *     "name": "Nice name of Plugin",
+ *     "interfaces": [
+ *         {"plugin.interface.class": "plugin.implementation.class"},
+ *         {"wa.server.plugin.WAFrontend": "wa.server.plugin.apache.ApacheFrontend"}
+ *     ]
+ * }
+ * 
* * @author Ziver */ @@ -51,13 +58,15 @@ public class PluginManager implements Iterable{ private HashMap plugins; - public static PluginManager load(String path){ - return new PluginManager<>(path); - } - + /** + * Constructor that will look for plugins in the working directory. + */ public PluginManager(){ this("./"); } + /** + * Constructor that will look for plugins in the specified directory. + */ public PluginManager(String path){ plugins = new HashMap<>(); @@ -71,7 +80,7 @@ public class PluginManager implements Iterable{ for(FileSearcher.FileSearchItem file : search){ try { DataNode node = JSONParser.read(IOUtil.readContentAsString(file.getInputStream(), true)); - log.fine("Found plugin: "+file.getPath()); + log.fine("Found plugin: " + file.getPath()); PluginData plugin = new PluginData(node); if (!plugins.containsKey(plugin.getName())){ @@ -93,32 +102,104 @@ public class PluginManager implements Iterable{ } } + /** + * @return a Iterator of all enabled plugins. + */ @Override public Iterator iterator() { - return plugins.values().iterator(); + return new EnabledPluginIterator(toList(plugins.values().iterator())); } - public Iterator getObjectIterator(Class intf) { - return new PluginObjectIterator<>(plugins.values().iterator(), intf); + /** + * @return a Iterator for singleton Objects from all plugins that are enabled and + * has defined implementations of the given interface. + */ + public Iterator getSingletonIterator(Class intf) { + return new PluginSingletonIterator<>(iterator(), intf); } + /** + * @return a Iterator for classes from all plugins that are enabled and has defined + * implementations of the given interface. + */ public Iterator> getClassIterator(Class intf) { - return new PluginClassIterator<>(plugins.values().iterator(), intf); + return new PluginClassIterator<>(iterator(), intf); } - public ArrayList toArray() { - return toGenericArray(iterator()); + /** + * @return a Iterator of all plugins, independently on if they are enabled or disabled. + */ + public Iterator iteratorAll() { + return plugins.values().iterator(); } - public ArrayList toArray(Class intf) { - return toGenericArray(getObjectIterator(intf)); + + /** + * @return a List of enabled plugins. + */ + public List toArray() { + return toList(iterator()); } - private ArrayList toGenericArray(Iterator it) { + /** + * @return a list of enabled plugins that has specified the provided interface in their definition. + */ + public List toArray(Class intf) { + return toList(getSingletonIterator(intf)); + } + + /** + * @return a List of all plugins, independently on if they are enabled or disabled. + */ + public List toArrayAll() { + return toList(iteratorAll()); + } + + + + + private List toList(Iterator it) { ArrayList list = new ArrayList<>(); while(it.hasNext()) list.add(it.next()); return list; } + /** + * @return the PluginData representing the given plugin by name, returns null if + * there is no plugin by that name. + */ + public PluginData getPluginData(String pluginName) { + return plugins.get(pluginName); + } - public static class PluginClassIterator implements Iterator> { + + /** + * A Iterator that only returns enabled plugins. + */ + protected static class EnabledPluginIterator implements Iterator { + private List pluginList; + private int nextIndex = 0; + + EnabledPluginIterator(List pluginList) { + this.pluginList = pluginList; + } + + @Override + public boolean hasNext() { + for (int i = nextIndex; i < pluginList.size(); i++) { + if (pluginList.get(i).isEnabled()) + return true; + } + return false; + } + + @Override + public PluginData next() { + if(!hasNext()) + throw new NoSuchElementException(); + return pluginList.get(nextIndex++); + } + } + + + protected static class PluginClassIterator implements Iterator> { private Class intf; private Iterator pluginIt; private Iterator> classIt; @@ -150,20 +231,15 @@ public class PluginManager implements Iterable{ throw new NoSuchElementException(); return (Class) classIt.next(); } - - @Override - public void remove() { - throw new RuntimeException("Iterator is ReadOnly"); - } } - public static class PluginObjectIterator implements Iterator { + protected static class PluginSingletonIterator implements Iterator { private Class intf; private Iterator pluginIt; private Iterator objectIt; - PluginObjectIterator(Iterator it, Class intf){ + PluginSingletonIterator(Iterator it, Class intf){ this.intf = intf; this.pluginIt = it; } @@ -190,10 +266,5 @@ public class PluginManager implements Iterable{ throw new NoSuchElementException(); return objectIt.next(); } - - @Override - public void remove() { - throw new RuntimeException("Iterator is ReadOnly"); - } } } \ No newline at end of file