This commit is contained in:
Ziver Koc 2015-03-23 21:05:51 +00:00
parent e822a4b35c
commit 91cadbb301
20 changed files with 342 additions and 130 deletions

View file

@ -72,6 +72,27 @@ public class Converter {
return (byte)(num & 0xff);
}
/**
* Converts hex string to a byte array
*
* @param hex a String containing data coded in hex
* @return a byte array
*/
public static byte[] hexToByte(String hex){
if(hex == null)
return null;
if(hex.startsWith("0x"))
hex = hex.substring(2);
byte[] b = new byte[(int)Math.ceil(hex.length()/2.0)];
for(int i=hex.length()-1; i>=0; i-=2){
if(i-1 < 0)
b[(hex.length()-i-1)/2] = hexToByte(hex.charAt(i));
else
b[(hex.length()-i-1)/2] = hexToByte(hex.charAt(i-1), hex.charAt(i));
}
return b;
}
/**
* Converts hex chars to a byte
*
@ -79,10 +100,10 @@ public class Converter {
* @param quad2 is the second hex value
* @return a byte that corresponds to the hex
*/
public static int hexToByte( char quad1, char quad2){
public static byte hexToByte( char quad1, char quad2){
byte b = hexToByte( quad2 );
b |= hexToByte( quad1 ) << 4;
return toInt(b);
return b;
}
/**

View file

@ -33,7 +33,8 @@ import java.io.*;
public class IOUtil {
/**
* Reads and returns all the contents of a stream.
* Reads and returns all the content of a stream.
* This function will close the inout stream at the end.
*
* @param stream
* @return the stream contents
@ -45,10 +46,30 @@ public class IOUtil {
while((len = stream.read(buff)) != -1){
dyn_buff.append(buff, 0, len);
}
stream.close();
return dyn_buff.getBytes();
}
/**
* Reads and returns all the content of a stream as a String.
* This function will close the inout stream at the end.
*
* @param stream
* @return a String with the content of the stream
*/
public static String getContentString(InputStream stream) throws IOException{
StringBuilder str = new StringBuilder();
String line;
BufferedReader in = new BufferedReader(new InputStreamReader(stream));
while((line = in.readLine()) != null){
str.append(line).append("\n");
}
in.close();
return str.toString();
}
/**
* Copies all data from the input stream to the output stream
*/

View file

@ -113,18 +113,19 @@ public class FileSearch implements Iterable<FileSearch.FileSearchItem>{
protected class FileSearchIterator implements Iterator<FileSearchItem>{
private ArrayList<FileSearchItem> fileList;
private int currentIndex;
private FileSearchItem nextItem;
public FileSearchIterator(){
fileList = new ArrayList<FileSearchItem>();
currentIndex = 0;
addFiles(root.list());
addFiles(new FileSearchFileItem(root), root.list());
next();
}
@Override
public boolean hasNext() {
return currentIndex != fileList.size();
return currentIndex < fileList.size();
}
@Override
@ -134,28 +135,28 @@ public class FileSearch implements Iterable<FileSearch.FileSearchItem>{
@Override
public FileSearchItem next() {
if(currentIndex < 0)
if(currentIndex < 0 || currentIndex >= fileList.size())
return null;
// Temporarily save the current file
FileSearchItem ret = fileList.get(currentIndex);
currentIndex++;
// Find the next file
for(; currentIndex<fileList.size(); currentIndex++){
FileSearchItem file = fileList.get(currentIndex);
if(recursive && file.isDirectory()){
addFiles(file.listFiles());
addFiles(file, file.listFiles());
if(searchFolders && file.getName().equalsIgnoreCase(fileName))
break;
}
else if(searchCompressedFiles && file.isFile() &&
compressedFileExtensions.contains(FileUtil.getFileExtension(file.getName()).toLowerCase())){
try {
String url = file.getUrl().getFile();
ZipFile zipFile = new ZipFile(url);
ZipFile zipFile = new ZipFile(file.getPath());
Enumeration<? extends ZipEntry> e = zipFile.entries();
while(e.hasMoreElements()){
ZipEntry entry = e.nextElement();
fileList.add(new FileSearchZipItem(url, entry));
fileList.add(new FileSearchZipItem(file.getPath(), entry));
}
zipFile.close();
} catch (IOException e) {
@ -173,9 +174,12 @@ public class FileSearch implements Iterable<FileSearch.FileSearchItem>{
return ret;
}
private void addFiles(String[] list){
private void addFiles(FileSearchItem root, String[] list){
if(root instanceof FileSearchFileItem) {
for (String file : list) {
fileList.add(new FileSearchFileItem(new File(file)));
fileList.add(new FileSearchFileItem(
new File(((FileSearchFileItem)root).file, file)));
}
}
}
@ -186,8 +190,8 @@ public class FileSearch implements Iterable<FileSearch.FileSearchItem>{
public interface FileSearchItem{
/** @return a file or folder name **/
public String getName();
/** @return a URL to the file or folder, in case of a compressed file the URL to the package will be returned **/
public URL getUrl() throws MalformedURLException ;
/** @return a path to the file or folder, in case of a compressed file the path to the package will be returned **/
public String getPath();
public boolean isCompressed();
public boolean isFile();
@ -208,7 +212,7 @@ public class FileSearch implements Iterable<FileSearch.FileSearchItem>{
}
public String getName() { return file.getName(); }
public URL getUrl() throws MalformedURLException { return new URL(file.getAbsolutePath()); }
public String getPath() { return file.getAbsolutePath(); }
public boolean isCompressed() { return false; }
public boolean isFile() { return file.isFile(); }
@ -229,7 +233,7 @@ public class FileSearch implements Iterable<FileSearch.FileSearchItem>{
}
public String getName() { return entry.getName(); }
public URL getUrl() throws MalformedURLException { return new URL(file); }
public String getPath() { return file; }
public boolean isCompressed() { return true; }
public boolean isFile() { return !entry.isDirectory(); }

View file

@ -129,7 +129,7 @@ public class FileUtil {
* @param file
* @return the file content
*/
public static String getFileContent(File file) throws IOException{
public static String getContent(File file) throws IOException{
InputStream in = new FileInputStream(file);
String data = new String(IOUtil.getContent( in ));
in.close();
@ -302,8 +302,8 @@ public class FileUtil {
/**
* Replaces the current extension on the file withe the given one.
*
* @param filename is the name of the file
* @param string is the new extension, without the dot
* @param file is the name of the file
* @param ext is the new extension, without the dot
* @return
*/
public static String changeExtension(String file, String ext) {

View file

@ -199,7 +199,7 @@ public class HttpPrintStream extends PrintStream{
super.print(req_type+" "+req_url+" HTTP/1.0");
else
super.print("HTTP/1.0 "+res_status_code+" "+getStatusString(res_status_code));
super.println();
super.print(System.lineSeparator());
res_status_code = null;
req_type = null;
req_url = null;
@ -207,7 +207,7 @@ public class HttpPrintStream extends PrintStream{
if(headers != null){
for(String key : headers.keySet()){
super.print(key+": "+headers.get(key));
super.println();
super.print(System.lineSeparator());
}
headers = null;
}
@ -218,16 +218,16 @@ public class HttpPrintStream extends PrintStream{
for(String key : cookies.keySet()){
super.print(key+"="+cookies.get(key)+"; ");
}
super.println();
super.print(System.lineSeparator());
}
else{
for(String key : cookies.keySet()){
super.print("Set-Cookie: "+key+"="+cookies.get(key)+";");
super.println();
super.print(System.lineSeparator());
}
}
}
super.println();
super.print(System.lineSeparator());
cookies = null;
}
super.print(s);

View file

@ -53,7 +53,6 @@ public class HttpServer extends ThreadedTCPNetworkServer{
public static final int COOKIE_TTL = 200;
public static final int SESSION_TTL = 10*60*1000; // in milliseconds
public final String server_url;
public final int server_port;
private Map<String,HttpPage> pages;
@ -64,25 +63,22 @@ public class HttpServer extends ThreadedTCPNetworkServer{
/**
* Creates a new instance of the sever
*
* @param url The address to the server
* @param port The port that the server should listen to
*/
public HttpServer(String url, int port){
this(url, port, null, null);
public HttpServer(int port){
this(port, null, null);
}
/**
* Creates a new instance of the sever
*
* @param url The address to the server
* @param port The port that the server should listen to
* @param keyStore If this is not null then the server will use SSL connection with this keyStore file path
* @param keyStorePass If this is not null then the server will use a SSL connection with the given certificate
*/
public HttpServer(String url, int port, File keyStore, String keyStorePass){
public HttpServer(int port, File keyStore, String keyStorePass){
super( port, keyStore, keyStorePass );
this.server_url = url;
this.server_port = port;
pages = new ConcurrentHashMap<String,HttpPage>();

View file

@ -56,7 +56,8 @@ public class SSDPClient extends ThreadedUDPNetwork implements ThreadedUDPNetwork
System.out.println(LogUtil.getCalingClass());
LogUtil.setGlobalLevel(Level.FINEST);
SSDPClient ssdp = new SSDPClient();
ssdp.requestService("upnp:rootdevice");
//ssdp.requestService("upnp:rootdevice");
ssdp.requestService("zap:discover");
ssdp.start();
for(int i=0; true ;++i){
@ -94,6 +95,9 @@ public class SSDPClient extends ThreadedUDPNetwork implements ThreadedUDPNetwork
*
*/
public void requestService(String st){
requestService(st, null);
}
public void requestService(String st, HashMap<String,String> headers){
try {
services_st.put( st, new LinkedList<SSDPServiceInfo>() );
@ -106,9 +110,14 @@ public class SSDPClient extends ThreadedUDPNetwork implements ThreadedUDPNetwork
http.setHeader("ST", st );
http.setHeader("Man", "\"ssdp:discover\"" );
http.setHeader("MX", "3" );
if(headers != null) {
for (String key : headers.keySet()) {
http.setHeader(key, headers.get(key));
}
}
http.flush();
logger.log(Level.FINEST, "***** REQUEST: \n"+msg);
logger.log(Level.FINEST, "Sending Multicast: \n"+msg);
byte[] data = msg.toString().getBytes();
DatagramPacket packet = new DatagramPacket(
data, data.length,
@ -121,6 +130,13 @@ public class SSDPClient extends ThreadedUDPNetwork implements ThreadedUDPNetwork
}
}
/**
* Set a listener that will be notified when new services are detected
*/
public void setListener(SSDPServiceListener listener){
this.listener = listener;
}
/**
* Returns a list of received services by
* the given search target.
@ -176,7 +192,7 @@ public class SSDPClient extends ThreadedUDPNetwork implements ThreadedUDPNetwork
*/
public void receivedPacket(DatagramPacket packet, ThreadedUDPNetwork network) {
HttpHeaderParser header = new HttpHeaderParser( new String( packet.getData() ) );
logger.log(Level.FINEST, "Recived: \n"+header);
logger.log(Level.FINEST, "Recived(from: "+packet.getAddress()+"): \n" + header);
String usn = header.getHeader("USN");
String st = header.getHeader("ST");
@ -199,11 +215,13 @@ public class SSDPClient extends ThreadedUDPNetwork implements ThreadedUDPNetwork
service.setLocation( header.getHeader("LOCATION") );
service.setST( st );
service.setUSN( usn );
service.setInetAddress(packet.getAddress());
if(header.getHeader("Cache-Control") != null) {
service.setExpirationTime(
System.currentTimeMillis() +
1000 * getCacheTime(header.getHeader("Cache-Control")) );
System.currentTimeMillis() + 1000 * getCacheTime(header.getHeader("Cache-Control")));
}
service.setHeaders(header.getHeaders());
logger.log(Level.FINEST, "Recived:\n"+service);
if(listener != null && newService)
listener.newService(service);
}

View file

@ -25,6 +25,7 @@ package zutil.net.ssdp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;
@ -80,10 +81,14 @@ public class SSDPServer extends ThreadedUDPNetwork implements ThreadedUDPNetwork
public static void main(String[] args) throws IOException{
LogUtil.setGlobalLevel(Level.FINEST);
SSDPServer ssdp = new SSDPServer();
StandardSSDPInfo service = new StandardSSDPInfo();
service.setLocation("nowhere");
service.setST("upnp:rootdevice");
service.setST("zep:discover");
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Alias", "Desktop");
headers.put("PublicKey", "SuperDesktopKey");
service.setHeaders(headers);
SSDPServer ssdp = new SSDPServer();
ssdp.addService(service);
ssdp.start();
MultiPrintStream.out.println("SSDP Server running");
@ -178,31 +183,36 @@ public class SSDPServer extends ThreadedUDPNetwork implements ThreadedUDPNetwork
String msg = new String( packet.getData() );
HttpHeaderParser header = new HttpHeaderParser( msg );
logger.log(Level.FINEST, "#### Received:\n"+header);
// ******* Respond
// Check that the message is an ssdp discovery message
if( header.getRequestType() != null && header.getRequestType().equalsIgnoreCase("M-SEARCH") ){
String man = header.getHeader("Man").replace("\"", "");
String man = header.getHeader("Man");
if(man != null)
man = man.replace("\"", "");
String st = header.getHeader("ST");
// Check that its the correct URL and that its an ssdp:discover message
if( header.getRequestURL().equals("*") && man.equalsIgnoreCase("ssdp:discover") ){
if( header.getRequestURL().equals("*") && "ssdp:discover".equalsIgnoreCase(man) ){
// Check if the requested service exists
if( services.containsKey( st ) ){
logger.log(Level.FINEST, "Received Multicast(from: "+packet.getAddress()+"):\n"+header);
// Generate the SSDP response
StringOutputStream response = new StringOutputStream();
HttpPrintStream http = new HttpPrintStream( response );
http.setStatusCode(200);
http.setHeader("Location", services.get(st).getLocation() );
http.setHeader("USN", services.get(st).getUSN() );
http.setHeader("Server", SERVER_INFO );
http.setHeader("ST", st );
http.setHeader("Location", services.get(st).getLocation() );
http.setHeader("EXT", "" );
http.setHeader("Cache-Control", "max-age = "+cache_time );
http.setHeader("USN", services.get(st).getUSN() );
if(services.get(st) instanceof SSDPCustomInfo)
((SSDPCustomInfo)services.get(st)).setHeaders(http);
http.flush();
String strData = response.toString();
logger.log(Level.FINEST, "#### Response:\n"+strData);
logger.log(Level.FINEST, "Response:\n"+strData);
byte[] data = strData.getBytes();
packet = new DatagramPacket(
data, data.length,
@ -269,7 +279,7 @@ public class SSDPServer extends ThreadedUDPNetwork implements ThreadedUDPNetwork
http.setHeader("USN", services.get(searchTarget).getUSN() );
http.close();
logger.log(Level.FINEST, "#### Notification:\n"+msg);
logger.log(Level.FINEST, "Notification:\n" + msg);
byte[] data = msg.toString().getBytes();
DatagramPacket packet = new DatagramPacket(
data, data.length,
@ -318,7 +328,7 @@ public class SSDPServer extends ThreadedUDPNetwork implements ThreadedUDPNetwork
http.setHeader("USN", services.get(searchTarget).getUSN() );
http.close();
logger.log(Level.FINEST, "******** ByeBye:\n"+msg);
logger.log(Level.FINEST, "ByeBye:\n" + msg);
byte[] data = msg.toString().getBytes();
DatagramPacket packet = new DatagramPacket(
data, data.length,

View file

@ -22,6 +22,8 @@
package zutil.net.ssdp;
import zutil.net.http.HttpPrintStream;
/**
* This class contains information about a service from
* or through the SSDP protocol

View file

@ -22,7 +22,11 @@
package zutil.net.ssdp;
import zutil.net.http.HttpPrintStream;
import java.net.InetAddress;
import java.util.Date;
import java.util.HashMap;
import java.util.UUID;
/**
@ -31,11 +35,14 @@ import java.util.UUID;
*
* @author Ziver
*/
public class StandardSSDPInfo implements SSDPServiceInfo{
public class StandardSSDPInfo implements SSDPServiceInfo, SSDPCustomInfo{
private String location;
private String st;
private String usn;
private long expiration_time;
// All header parameters
private HashMap<String, String> headers;
private InetAddress inetAddress;
/**
* @param l is the value to set the Location variable
@ -107,7 +114,6 @@ public class StandardSSDPInfo implements SSDPServiceInfo{
/**
* Generates an unique USN for the service
*
* @param searchTarget is the service ST name
* @return an unique string that corresponds to the service
*/
private String genUSN(){
@ -117,4 +123,30 @@ public class StandardSSDPInfo implements SSDPServiceInfo{
public String toString(){
return "USN: "+usn+"\nLocation: "+location+"\nST: "+st+"\nExpiration-Time: "+new Date(expiration_time);
}
public void setHeaders(HashMap<String, String> headers) {
this.headers = headers;
}
public String getHeader(String header){
return headers.get(header.toUpperCase());
}
@Override
public void setHeaders(HttpPrintStream http) {
if(headers != null) {
for (String key : headers.keySet()) {
http.setHeader(key, headers.get(key));
}
}
}
public InetAddress getInetAddress(){
return inetAddress;
}
public void setInetAddress(InetAddress inetAddress) {
this.inetAddress = inetAddress;
}
}

View file

@ -62,7 +62,7 @@ public class TorrentMetainfo {
public TorrentMetainfo(File torrent) throws IOException{
this(FileUtil.getFileContent( torrent ));
this(FileUtil.getContent(torrent));
}
public TorrentMetainfo(String data){

View file

@ -58,7 +58,7 @@ public abstract class OSAbstractionLayer {
* @param cmd the command to run
* @return first line of the command
*/
protected String getFirstLineFromCommand(String cmd) throws InterruptedException, IOException {
protected String getFirstLineFromCommand(String cmd) {
String[] tmp = runCommand(cmd);
if(tmp.length > 1)
return tmp[0];
@ -71,18 +71,25 @@ public abstract class OSAbstractionLayer {
* @param cmd the command to run
* @return a String list of the output of the command
*/
public String[] runCommand(String cmd) throws InterruptedException, IOException {
public String[] runCommand(String cmd) {
ArrayList<String> ret = new ArrayList<String>();
try {
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec(cmd);
proc.waitFor();
BufferedReader output = new BufferedReader(new InputStreamReader(proc.getInputStream()));
ArrayList<String> ret = new ArrayList<String>();
String line;
while ((line = output.readLine()) != null) {
ret.add(line);
}
output.close();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return ret.toArray(new String[1]);
}

View file

@ -111,15 +111,14 @@ public class JSONParser{
case '\"':
root = new DataNode(DataType.String);
StringBuilder str = new StringBuilder();
while((c=(char)in.read()) != (char)-1 && c != '\"')
while((c=(char)in.read()) >= 0 && c != '\"')
str.append(c);
root.set(str.toString());
break;
// Parse unknown type
default:
StringBuilder tmp = new StringBuilder().append(c);
while((c=(char)in.read()) != (char)-1 && !Character.isWhitespace(c) &&
c != ',' && c != '='){
while((c=(char)in.read()) >= 0 && c != ',' && c != '='){
if(c == ']' || c == '}'){
end.i = 1;
break;
@ -127,7 +126,7 @@ public class JSONParser{
tmp.append(c);
}
// Check what type of type the data is
String data = tmp.toString();
String data = tmp.toString().trim();
if( BOOLEAN_PATTERN.matcher(data).matches() )
root = new DataNode(DataType.Boolean);
else if( NUMBER_PATTERN.matcher(data).matches() )
@ -140,4 +139,6 @@ public class JSONParser{
return root;
}
}

View file

@ -22,9 +22,18 @@
package zutil.plugin;
import zutil.ClassUtil;
import zutil.log.LogUtil;
import zutil.parser.DataNode;
import javax.xml.crypto.Data;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.logging.Logger;
/**
* This class contains information about a plugin
@ -32,18 +41,36 @@ import java.net.URLClassLoader;
*
* @author Ziver
*/
public class PluginData<T> {
public class PluginData {
private static Logger log = LogUtil.getLogger();
private double pluginVersion;
private String pluginName;
private String pluginClass;
private T obj;
private HashMap<Class, Class> classMap;
private HashMap<Class, Object> objectMap;
protected PluginData(String intf, DataNode data){
protected PluginData(DataNode data) throws ClassNotFoundException, MalformedURLException {
classMap = new HashMap<Class, Class>();
objectMap = new HashMap<Class, Object>();
pluginVersion = data.getDouble("version");
pluginName = data.getString("name");
pluginClass = data.get("interfaces").getString(intf);
log.fine("Found plugin: "+pluginName);
DataNode node = data.get("interfaces");
Iterator<String> intfIt = node.keyIterator();
while (intfIt.hasNext()) {
String intf = intfIt.next();
log.finer("Plugin interface: "+ intf+"-->"+node.get(intf).getString());
classMap.put(
getClassByName(intf),
getClassByName(node.get(intf).getString()));
}
}
private static Class getClassByName(String name) throws ClassNotFoundException, MalformedURLException {
return Class.forName(name);
}
public double getVersion(){
@ -53,12 +80,22 @@ public class PluginData<T> {
return pluginName;
}
@SuppressWarnings("unchecked")
public T getObject() throws InstantiationException, IllegalAccessException, ClassNotFoundException{
//if(obj == null)
// new URLClassLoader(pluginClass);
// //obj = (T) Class.forName(pluginClass).newInstance();
return obj;
public <T> T getObject(Class<T> intf) {
if(classMap.containsKey(intf)) {
try {
Class subClass = classMap.get(intf);
if (objectMap.containsKey(subClass))
objectMap.put(intf, subClass.newInstance());
return (T) objectMap.get(subClass);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
public boolean contains(Class<?> intf){
return classMap.containsKey(intf);
}
}

View file

@ -24,11 +24,17 @@ package zutil.plugin;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.logging.Logger;
import com.sun.xml.internal.stream.util.ReadOnlyIterator;
import zutil.io.IOUtil;
import zutil.io.file.FileSearch;
import zutil.io.file.FileUtil;
import zutil.log.LogUtil;
import zutil.parser.DataNode;
import zutil.parser.json.JSONParser;
@ -40,39 +46,85 @@ import zutil.parser.json.JSONParser;
*
* @author Ziver
*/
public class PluginManager<T> implements Iterable<PluginData<T>>{
private HashMap<String, PluginData<T>> plugins;
public class PluginManager<T> implements Iterable<PluginData>{
private static Logger log = LogUtil.getLogger();
public static <T> PluginManager<T> load(Class<T> intfClass) throws IOException{
return new PluginManager<T>(intfClass);
private HashMap<String, PluginData> plugins;
public static <T> PluginManager<T> load(String path){
return new PluginManager<T>(path);
}
public PluginManager(){
this("./");
}
public PluginManager(String path){
plugins = new HashMap<String, PluginData>();
private PluginManager(Class<T> intfClass) throws IOException{
FileSearch search = new FileSearch(new File("."));
FileSearch search = new FileSearch(new File(path));
search.setRecursive(true);
search.searchFolders(false);
search.setFileName("plugin.json");
log.fine("Searching for plugins...");
for(FileSearch.FileSearchItem file : search){
DataNode node = JSONParser.read(FileUtil.getContent(file.getUrl()));
PluginData<T> plugin = new PluginData<T>(intfClass.getName(), node);
try {
DataNode node = JSONParser.read(IOUtil.getContentString(file.getInputStream()));
PluginData plugin = new PluginData(node);
if(node.get("interfaces").getString(intfClass.getName()) != null){
if(plugins.containsKey(plugin.getName())){
if(plugins.get(plugin.getName()).getVersion() < plugin.getVersion())
plugins.put(plugin.getName(), plugin);
}
else{
if (!plugins.containsKey(plugin.getName()) ||
plugins.get(plugin.getName()).getVersion() < plugin.getVersion()){
plugins.put(plugin.getName(), plugin);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public Iterator<PluginData<T>> iterator() {
public Iterator<PluginData> iterator() {
return plugins.values().iterator();
}
public <T> Iterator<T> iterator(Class<T> intf) {
return new PluginInterfaceIterator<T>(plugins.values().iterator(), intf);
}
public class PluginInterfaceIterator<T> implements Iterator<T> {
private Class<T> intf;
private Iterator<PluginData> it;
private PluginData next;
PluginInterfaceIterator(Iterator<PluginData> it, Class<T> intf){
this.intf = intf;
this.it = it;
}
@Override
public boolean hasNext() {
if(next != null)
return true;
while(it.hasNext()) {
next = it.next();
if(next.contains(intf))
return true;
}
next = null;
return false;
}
@Override
public T next() {
if(!hasNext())
throw new NoSuchElementException();
return next.getObject(intf);
}
@Override
public void remove() {
throw new RuntimeException("Iterator is ReadOnly");
}
}
}

View file

@ -43,17 +43,28 @@ public class ConverterTest {
assertEquals( 0x00, Converter.hexToByte('0','0') );
assertEquals( 0x11, Converter.hexToByte('1','1') );
assertEquals( 0x75, Converter.hexToByte('7','5') );
assertEquals( 0xDA, Converter.hexToByte('D','A') );
assertEquals( 0xFA, Converter.hexToByte('F','a') );
assertEquals( 0xFF, Converter.hexToByte('f','f') );
assertEquals( 0xDA, Converter.hexToByte('D','A') & 0xFF );
assertEquals( 0xFA, Converter.hexToByte('F','a') & 0xFF );
assertEquals( 0xFF, Converter.hexToByte('f','f') & 0xFF );
}
@Test
public void testHexStringToByte() {
assertArrayEquals( null, Converter.hexToByte(null) );
assertArrayEquals( new byte[]{}, Converter.hexToByte("") );
assertArrayEquals( new byte[]{0x00}, Converter.hexToByte("0x00") );
assertArrayEquals( new byte[]{0x00}, Converter.hexToByte("00") );
assertArrayEquals(new byte[]{0x07,0x06,0x05,0x04,0x03,0x02,0x01},
Converter.hexToByte("01020304050607") );
assertArrayEquals( new byte[]{0x11,0x0F}, Converter.hexToByte("F11") );
}
@Test
public void testUrlEncode() {
assertEquals( "fas8dg7%20a0d1%2313f9g8d7%200h9a%a4%25h0",
Converter.urlEncode("fas8dg7 a0d1#13f9g8d7 0h9a<39>%h0") );
assertEquals( "9i34%e5%202y92%a452%25%2623%20463765%a4(%2f%26(",
Converter.urlEncode("9i34<EFBFBD> 2y92<39>52%&23 463765<36>(/&(") );
assertEquals( "fas8dg7%20a0d1%2313f9g8d7%200h9a%25h0",
Converter.urlEncode("fas8dg7 a0d1#13f9g8d7 0h9a%h0") );
assertEquals( "9i34%202y9252%25%2623%20463765(%2f%26(",
Converter.urlEncode("9i34 2y9252%&23 463765(/&(") );
}
@ -61,8 +72,8 @@ public class ConverterTest {
public void testUrlDecode() {
assertEquals( "fas8dg7 a0d1#13f9g8d7 0h9a%h0",
Converter.urlDecode("fas8dg7%20a0d1%2313f9g8d7%200h9a%25h0") );
assertEquals( "9i34<EFBFBD> 2y9252%&23 463765(/&(",
Converter.urlDecode("9i34%e5%202y9252%25%2623%20463765(%2f%26(") );
assertEquals( "9i34 2y9252%&23 463765(/&(",
Converter.urlDecode("9i34%202y9252%25%2623%20463765(%2f%26(") );
}
}

View file

@ -35,7 +35,7 @@ public class HTTPGuessTheNumber implements HttpPage{
public static void main(String[] args) throws IOException{
//HttpServer server = new HttpServer("localhost", 443, FileFinder.find("keySSL"), "rootroot");//SSL
HttpServer server = new HttpServer("localhost", 8080);
HttpServer server = new HttpServer(8080);
server.setDefaultPage(new HTTPGuessTheNumber());
server.run();
}

View file

@ -35,7 +35,7 @@ import zutil.net.http.HttpServer;
public class HTTPUploaderTest implements HttpPage{
public static void main(String[] args) throws IOException{
HttpServer server = new HttpServer("localhost", 80);
HttpServer server = new HttpServer(80);
server.setDefaultPage(new HTTPUploaderTest());
server.run();
}

View file

@ -42,7 +42,7 @@ public class UPnPServerTest {
UPnPContentDirectory cds = new UPnPContentDirectory(new File("C:\\Users\\Ziver\\Desktop\\lan"));
WebServiceDef ws = new WebServiceDef( UPnPContentDirectory.class );
HttpServer http = new HttpServer("http://192.168.0.60/", 8080);
HttpServer http = new HttpServer(8080);
//http.setDefaultPage(upnp);
http.setPage("/RootDesc", upnp );
http.setPage("/SCP/ContentDir", cds );