Added ability to disable plugins, and renamed object iterator to singleton iterator.
This commit is contained in:
parent
57bd478e16
commit
ef42d8aa6c
3 changed files with 163 additions and 47 deletions
|
|
@ -140,12 +140,15 @@ public class MulticastDnsServer extends ThreadedUDPNetwork implements ThreadedUD
|
||||||
response.getHeader().setDefaultResponseData();
|
response.getHeader().setDefaultResponseData();
|
||||||
for (DnsPacketQuestion question : request.getQuestions()){
|
for (DnsPacketQuestion question : request.getQuestions()){
|
||||||
if (question.name == null) continue;
|
if (question.name == null) continue;
|
||||||
switch (question.type){
|
|
||||||
|
|
||||||
|
switch (question.type){
|
||||||
// Normal Domain Name Resolution
|
// Normal Domain Name Resolution
|
||||||
case DnsConstants.TYPE.A:
|
case DnsConstants.TYPE.A:
|
||||||
if (entries.containsKey(question.name)){
|
if (entries.containsKey(question.name)){
|
||||||
|
logger.finer("Received request for domain: " + question.name);
|
||||||
response.addAnswerRecord(entries.get(question.name));
|
response.addAnswerRecord(entries.get(question.name));
|
||||||
|
} else {
|
||||||
|
logger.finest("Received request for unknown domain: " + question.name);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -154,19 +157,31 @@ public class MulticastDnsServer extends ThreadedUDPNetwork implements ThreadedUD
|
||||||
if (question.name.startsWith("_service.")){
|
if (question.name.startsWith("_service.")){
|
||||||
String postFix = question.name.substring(9);
|
String postFix = question.name.substring(9);
|
||||||
for (String domain : entries.keySet()){
|
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));
|
response.addAnswerRecord(entries.get(domain));
|
||||||
|
} else {
|
||||||
|
logger.finest("Received request for unknown service: " + question.name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (entries.containsKey(question.name)){
|
} else if (entries.containsKey(question.name)){
|
||||||
|
logger.finer("Received request for service: " + question.name);
|
||||||
response.addAnswerRecord(entries.get(question.name));
|
response.addAnswerRecord(entries.get(question.name));
|
||||||
|
} else {
|
||||||
|
logger.finer("Received request for unknown pointer: " + question.name);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
logger.finest("Unknown request type: " + question.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.getAnswerRecords().isEmpty() &&
|
if (response.getAnswerRecords().isEmpty() &&
|
||||||
response.getNameServers().isEmpty() &&
|
response.getNameServers().isEmpty() &&
|
||||||
response.getAdditionalRecords().isEmpty())
|
response.getAdditionalRecords().isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ package zutil.plugin;
|
||||||
import zutil.log.LogUtil;
|
import zutil.log.LogUtil;
|
||||||
import zutil.parser.DataNode;
|
import zutil.parser.DataNode;
|
||||||
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
@ -43,6 +42,7 @@ public class PluginData {
|
||||||
|
|
||||||
private double pluginVersion;
|
private double pluginVersion;
|
||||||
private String pluginName;
|
private String pluginName;
|
||||||
|
private boolean enabled = true;
|
||||||
private HashMap<Class<?>, List<Class<?>>> classMap;
|
private HashMap<Class<?>, List<Class<?>>> classMap;
|
||||||
private HashMap<Class, Object> objectMap;
|
private HashMap<Class, Object> objectMap;
|
||||||
|
|
||||||
|
|
@ -97,19 +97,44 @@ public class PluginData {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a version number for the plugin (specified in the plugin.json file
|
||||||
|
*/
|
||||||
public double getVersion(){
|
public double getVersion(){
|
||||||
return pluginVersion;
|
return pluginVersion;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @return the name of the plugin
|
||||||
|
*/
|
||||||
public String getName(){
|
public String getName(){
|
||||||
return pluginName;
|
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 <T> Iterator<T> getObjectIterator(Class<T> intf){
|
public <T> Iterator<T> getObjectIterator(Class<T> intf){
|
||||||
if(!classMap.containsKey(intf))
|
if(!classMap.containsKey(intf))
|
||||||
return Collections.emptyIterator();
|
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<Class<?>> getClassIterator(Class<?> intf){
|
public Iterator<Class<?>> getClassIterator(Class<?> intf){
|
||||||
if(!classMap.containsKey(intf))
|
if(!classMap.containsKey(intf))
|
||||||
return Collections.emptyIterator();
|
return Collections.emptyIterator();
|
||||||
|
|
@ -122,27 +147,32 @@ public class PluginData {
|
||||||
objectMap.put(objClass, objClass.newInstance());
|
objectMap.put(objClass, objClass.newInstance());
|
||||||
return (T) objectMap.get(objClass);
|
return (T) objectMap.get(objClass);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.log(Level.WARNING, null, e);
|
log.log(Level.WARNING, "Unable to instantiate plugin class: " + objClass, e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if the specified interface is defined by the plugin
|
||||||
|
*/
|
||||||
public boolean contains(Class<?> intf){
|
public boolean contains(Class<?> intf){
|
||||||
return classMap.containsKey(intf);
|
return classMap.containsKey(intf);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString(){
|
public String toString(){
|
||||||
return getName()+"(ver: "+getVersion()+")";
|
return getName()+"(version: "+getVersion()+")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
private class PluginObjectIterator<T> implements Iterator<T>{
|
* A Iterator that goes through all defined classes that implements
|
||||||
|
* a provided interface and returns a singleton instance of that class
|
||||||
|
*/
|
||||||
|
private class PluginSingletonIterator<T> implements Iterator<T>{
|
||||||
private Iterator<Class<?>> classIt;
|
private Iterator<Class<?>> classIt;
|
||||||
private T currentObj;
|
private T currentObj;
|
||||||
|
|
||||||
public PluginObjectIterator(Iterator<Class<?>> it) {
|
public PluginSingletonIterator(Iterator<Class<?>> it) {
|
||||||
classIt = it;
|
classIt = it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,17 +31,24 @@ import zutil.parser.DataNode;
|
||||||
import zutil.parser.json.JSONParser;
|
import zutil.parser.json.JSONParser;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.NoSuchElementException;
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class will search the file system for files
|
* This class will search the file system for files with the name "plugin.json"
|
||||||
* with the name "plugin.json" that defines data
|
* that defines data parameters for a plugin.
|
||||||
* parameters for a single plugin.
|
* The class will only load the latest version of a specific plugin with the same name.
|
||||||
* The class will only load the latest version of the specific plugin.
|
* <p>
|
||||||
|
* Example plugin.json content:<pre>
|
||||||
|
* {
|
||||||
|
* "version": 1.0,
|
||||||
|
* "name": "Nice name of Plugin",
|
||||||
|
* "interfaces": [
|
||||||
|
* {"plugin.interface.class": "plugin.implementation.class"},
|
||||||
|
* {"wa.server.plugin.WAFrontend": "wa.server.plugin.apache.ApacheFrontend"}
|
||||||
|
* ]
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author Ziver
|
* @author Ziver
|
||||||
*/
|
*/
|
||||||
|
|
@ -51,13 +58,15 @@ public class PluginManager<T> implements Iterable<PluginData>{
|
||||||
private HashMap<String, PluginData> plugins;
|
private HashMap<String, PluginData> plugins;
|
||||||
|
|
||||||
|
|
||||||
public static <T> PluginManager<T> load(String path){
|
/**
|
||||||
return new PluginManager<>(path);
|
* Constructor that will look for plugins in the working directory.
|
||||||
}
|
*/
|
||||||
|
|
||||||
public PluginManager(){
|
public PluginManager(){
|
||||||
this("./");
|
this("./");
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Constructor that will look for plugins in the specified directory.
|
||||||
|
*/
|
||||||
public PluginManager(String path){
|
public PluginManager(String path){
|
||||||
plugins = new HashMap<>();
|
plugins = new HashMap<>();
|
||||||
|
|
||||||
|
|
@ -93,32 +102,104 @@ public class PluginManager<T> implements Iterable<PluginData>{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a Iterator of all enabled plugins.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Iterator<PluginData> iterator() {
|
public Iterator<PluginData> iterator() {
|
||||||
return plugins.values().iterator();
|
return new EnabledPluginIterator(toList(plugins.values().iterator()));
|
||||||
}
|
}
|
||||||
public <K> Iterator<K> getObjectIterator(Class<K> 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 <K> Iterator<K> getSingletonIterator(Class<K> 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 <K> Iterator<Class<? extends K>> getClassIterator(Class<K> intf) {
|
public <K> Iterator<Class<? extends K>> getClassIterator(Class<K> intf) {
|
||||||
return new PluginClassIterator<>(plugins.values().iterator(), intf);
|
return new PluginClassIterator<>(iterator(), intf);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<PluginData> toArray() {
|
/**
|
||||||
return toGenericArray(iterator());
|
* @return a Iterator of all plugins, independently on if they are enabled or disabled.
|
||||||
|
*/
|
||||||
|
public Iterator<PluginData> iteratorAll() {
|
||||||
|
return plugins.values().iterator();
|
||||||
}
|
}
|
||||||
public <K> ArrayList<K> toArray(Class<K> intf) {
|
|
||||||
return toGenericArray(getObjectIterator(intf));
|
/**
|
||||||
|
* @return a List of enabled plugins.
|
||||||
|
*/
|
||||||
|
public List<PluginData> toArray() {
|
||||||
|
return toList(iterator());
|
||||||
}
|
}
|
||||||
private <K> ArrayList<K> toGenericArray(Iterator<K> it) {
|
/**
|
||||||
|
* @return a list of enabled plugins that has specified the provided interface in their definition.
|
||||||
|
*/
|
||||||
|
public <K> List<K> toArray(Class<K> intf) {
|
||||||
|
return toList(getSingletonIterator(intf));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a List of all plugins, independently on if they are enabled or disabled.
|
||||||
|
*/
|
||||||
|
public List<PluginData> toArrayAll() {
|
||||||
|
return toList(iteratorAll());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private <K> List<K> toList(Iterator<K> it) {
|
||||||
ArrayList<K> list = new ArrayList<>();
|
ArrayList<K> list = new ArrayList<>();
|
||||||
while(it.hasNext())
|
while(it.hasNext())
|
||||||
list.add(it.next());
|
list.add(it.next());
|
||||||
return list;
|
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<T> implements Iterator<Class<? extends T>> {
|
|
||||||
|
/**
|
||||||
|
* A Iterator that only returns enabled plugins.
|
||||||
|
*/
|
||||||
|
protected static class EnabledPluginIterator implements Iterator<PluginData> {
|
||||||
|
private List<PluginData> pluginList;
|
||||||
|
private int nextIndex = 0;
|
||||||
|
|
||||||
|
EnabledPluginIterator(List<PluginData> 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<T> implements Iterator<Class<? extends T>> {
|
||||||
private Class<T> intf;
|
private Class<T> intf;
|
||||||
private Iterator<PluginData> pluginIt;
|
private Iterator<PluginData> pluginIt;
|
||||||
private Iterator<Class<?>> classIt;
|
private Iterator<Class<?>> classIt;
|
||||||
|
|
@ -150,20 +231,15 @@ public class PluginManager<T> implements Iterable<PluginData>{
|
||||||
throw new NoSuchElementException();
|
throw new NoSuchElementException();
|
||||||
return (Class<? extends T>) classIt.next();
|
return (Class<? extends T>) classIt.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void remove() {
|
|
||||||
throw new RuntimeException("Iterator is ReadOnly");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class PluginObjectIterator<T> implements Iterator<T> {
|
protected static class PluginSingletonIterator<T> implements Iterator<T> {
|
||||||
private Class<T> intf;
|
private Class<T> intf;
|
||||||
private Iterator<PluginData> pluginIt;
|
private Iterator<PluginData> pluginIt;
|
||||||
private Iterator<T> objectIt;
|
private Iterator<T> objectIt;
|
||||||
|
|
||||||
PluginObjectIterator(Iterator<PluginData> it, Class<T> intf){
|
PluginSingletonIterator(Iterator<PluginData> it, Class<T> intf){
|
||||||
this.intf = intf;
|
this.intf = intf;
|
||||||
this.pluginIt = it;
|
this.pluginIt = it;
|
||||||
}
|
}
|
||||||
|
|
@ -190,10 +266,5 @@ public class PluginManager<T> implements Iterable<PluginData>{
|
||||||
throw new NoSuchElementException();
|
throw new NoSuchElementException();
|
||||||
return objectIt.next();
|
return objectIt.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void remove() {
|
|
||||||
throw new RuntimeException("Iterator is ReadOnly");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue