Allot of fixes
This commit is contained in:
parent
694e3081bb
commit
952a388cf1
22 changed files with 1197 additions and 408 deletions
|
|
@ -111,10 +111,10 @@ public class FileFinder {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a ArrayList with all the files in a folder and sub folders
|
* Returns a List with all the files in a folder and sub folders
|
||||||
*
|
*
|
||||||
* @param dir is the directory to search in
|
* @param dir is the directory to search in
|
||||||
* @return The ArrayList with the files
|
* @return The List with the files
|
||||||
*/
|
*/
|
||||||
public static List<File> search(File dir){
|
public static List<File> search(File dir){
|
||||||
return search(dir, new LinkedList<File>(), true);
|
return search(dir, new LinkedList<File>(), true);
|
||||||
|
|
@ -124,22 +124,42 @@ public class FileFinder {
|
||||||
* Returns a ArrayList with all the files in a folder and sub folders
|
* Returns a ArrayList with all the files in a folder and sub folders
|
||||||
*
|
*
|
||||||
* @param dir is the directory to search in
|
* @param dir is the directory to search in
|
||||||
* @param fileList is the ArrayList to add the files to
|
* @param fileList is the List to add the files to
|
||||||
* @param recursice is if the method should search the sub directories to.
|
* @param recursive is if the method should search the sub directories to.
|
||||||
* @return The ArrayList with the files
|
* @return A List with the files
|
||||||
*/
|
*/
|
||||||
public static List<File> search(File dir, List<File> fileList, boolean recursive){
|
public static List<File> search(File dir, List<File> fileList, boolean recursive){
|
||||||
String[] temp = dir.list();
|
return search(dir, new LinkedList<File>(), false, (recursive ? Integer.MAX_VALUE : 0));
|
||||||
File file;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a ArrayList with all the files in a folder and sub folders
|
||||||
|
*
|
||||||
|
* @param dir is the directory to search in
|
||||||
|
* @param fileList is the List to add the files to
|
||||||
|
* @param folders is if the method should add the folders to the List
|
||||||
|
* @param recurse is how many times it should recurse into folders
|
||||||
|
* @return A List with the files and/or folders
|
||||||
|
*/
|
||||||
|
public static List<File> search(File dir, List<File> fileList, boolean folders, int recurse){
|
||||||
|
if(recurse<0)
|
||||||
|
return fileList;
|
||||||
|
--recurse;
|
||||||
|
if(folders){
|
||||||
|
MultiPrintStream.out.println("Dir Found : "+dir);
|
||||||
|
fileList.add( dir );
|
||||||
|
}
|
||||||
|
|
||||||
|
File file;
|
||||||
|
String[] temp = dir.list();
|
||||||
if(temp != null){
|
if(temp != null){
|
||||||
for(int i=0; i<temp.length ;i++){
|
for(int i=0; i<temp.length ;i++){
|
||||||
file = new File(dir.getPath()+File.separator+temp[i]);
|
file = new File(dir.getPath()+File.separator+temp[i]);
|
||||||
if(recursive && file.isDirectory()){
|
if(file.isDirectory()){
|
||||||
search(new File(dir.getPath()+File.separator+temp[i]+File.separator), fileList, recursive);
|
search(new File(dir.getPath()+File.separator+temp[i]+File.separator), fileList, folders, recurse);
|
||||||
}
|
}
|
||||||
else if(file.isFile()){
|
else if(file.isFile()){
|
||||||
//MultiPrintStream.out.println("File Found: "+file);
|
MultiPrintStream.out.println("File Found: "+file);
|
||||||
fileList.add(file);
|
fileList.add(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
261
src/zutil/db/DBConnection.java
Normal file
261
src/zutil/db/DBConnection.java
Normal file
|
|
@ -0,0 +1,261 @@
|
||||||
|
package zutil.db;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import javax.naming.InitialContext;
|
||||||
|
import javax.naming.NamingException;
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
public class DBConnection{
|
||||||
|
public enum DBMS{
|
||||||
|
MySQL
|
||||||
|
}
|
||||||
|
// The connection
|
||||||
|
private Connection conn = null;
|
||||||
|
// The pool that this connection belongs to
|
||||||
|
private DBConnectionPool pool;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an Connection from JNDI
|
||||||
|
*
|
||||||
|
* @param jndi the name of the connection, e.g. "jdbc/mysql"
|
||||||
|
*/
|
||||||
|
public DBConnection(String jndi) throws NamingException, SQLException{
|
||||||
|
InitialContext ctx = new InitialContext();
|
||||||
|
DataSource ds = (DataSource)ctx.lookup("java:comp/env/"+jndi);
|
||||||
|
conn = ds.getConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an Connection to a MySQL server
|
||||||
|
*
|
||||||
|
* @param url is the URL of the MySQL server
|
||||||
|
* @param db is the database to connect to
|
||||||
|
* @param user is the user name
|
||||||
|
* @param password is the password
|
||||||
|
*/
|
||||||
|
public DBConnection(String url, String db, String user, String password) throws Exception{
|
||||||
|
this(DBMS.MySQL, url, db, user, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an Connection to a DB server
|
||||||
|
*
|
||||||
|
* @param dbms is the DB type
|
||||||
|
* @param url is the URL of the MySQL server
|
||||||
|
* @param db is the database to connect to
|
||||||
|
* @param user is the user name
|
||||||
|
* @param password is the password
|
||||||
|
*/
|
||||||
|
public DBConnection(DBMS dbms, String url, String db, String user, String password) throws Exception{
|
||||||
|
String dbms_name = initDriver(dbms);
|
||||||
|
conn = DriverManager.getConnection ("jdbc:"+dbms_name+"://"+url+"/"+db, user, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the underlying connection
|
||||||
|
*/
|
||||||
|
public Connection getConnection(){
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initiates the DB driver and returns its protocol name.
|
||||||
|
*
|
||||||
|
* @param db is the DB type
|
||||||
|
* @return the protocol name of the DBMS
|
||||||
|
*/
|
||||||
|
public String initDriver(DBMS db) throws InstantiationException, IllegalAccessException, ClassNotFoundException{
|
||||||
|
switch(db){
|
||||||
|
case MySQL:
|
||||||
|
Class.forName ("com.mysql.jdbc.Driver").newInstance();
|
||||||
|
DriverManager.setLoginTimeout(10);
|
||||||
|
return "mysql";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the last inserted id or -1 if there was an error
|
||||||
|
*/
|
||||||
|
public int getLastInsertID() throws SQLException{
|
||||||
|
Statement s = null;
|
||||||
|
try{
|
||||||
|
s = conn.createStatement ();
|
||||||
|
s.executeQuery("SELECT LAST_INSERT_ID()");
|
||||||
|
ResultSet result = s.getResultSet();
|
||||||
|
if(result.next()){
|
||||||
|
return result.getInt(1);
|
||||||
|
}
|
||||||
|
}finally{
|
||||||
|
if(s!=null)
|
||||||
|
s.close();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs a Prepared Statement.<br>
|
||||||
|
* <b>NOTE:</b> Don't forget to close the PreparedStatement or it can lead to memory leaks
|
||||||
|
*
|
||||||
|
* @param sql is the SQL query to run
|
||||||
|
* @return An PreparedStatement
|
||||||
|
*/
|
||||||
|
public PreparedStatement getPreparedStatement(String sql) throws SQLException{
|
||||||
|
return conn.prepareStatement(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>NOTE:</b> Don't forget to close the Statement or it can lead to memory leaks
|
||||||
|
*
|
||||||
|
* @return an Statement for the DB
|
||||||
|
*/
|
||||||
|
public Statement getStatement() throws SQLException{
|
||||||
|
return conn.createStatement();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes an query and cleans up after itself.
|
||||||
|
*
|
||||||
|
* @param query is the query
|
||||||
|
* @return update count or -1 if the query is not an update query
|
||||||
|
*/
|
||||||
|
public int exec(String query) throws SQLException {
|
||||||
|
PreparedStatement stmt = getPreparedStatement( query );
|
||||||
|
return exec(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes an query and cleans up after itself.
|
||||||
|
*
|
||||||
|
* @param stmt is the query
|
||||||
|
* @return update count or -1 if the query is not an update query
|
||||||
|
*/
|
||||||
|
public static int exec(PreparedStatement stmt) throws SQLException {
|
||||||
|
return exec(stmt, new SQLResultHandler<Integer>(){
|
||||||
|
public Integer handle(Statement stmt, ResultSet result) {
|
||||||
|
try {
|
||||||
|
return stmt.getUpdateCount();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes an query and cleans up after itself.
|
||||||
|
* @param <T>
|
||||||
|
*
|
||||||
|
* @param query is the query
|
||||||
|
* @param handler is the result handler
|
||||||
|
* @return update count or -1 if the query is not an update query
|
||||||
|
*/
|
||||||
|
public <T> T exec(String query, SQLResultHandler<T> handler) throws SQLException {
|
||||||
|
PreparedStatement stmt = getPreparedStatement( query );
|
||||||
|
return exec(stmt, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes an query and cleans up after itself.
|
||||||
|
*
|
||||||
|
* @param stmt is the query
|
||||||
|
* @param handler is the result handler
|
||||||
|
* @return the object from the handler
|
||||||
|
*/
|
||||||
|
public static <T> T exec(PreparedStatement stmt, SQLResultHandler<T> handler) throws SQLException{
|
||||||
|
try{
|
||||||
|
// Execute
|
||||||
|
stmt.execute();
|
||||||
|
|
||||||
|
// Handle result
|
||||||
|
if( handler != null ){
|
||||||
|
ResultSet result = null;
|
||||||
|
try{
|
||||||
|
result = stmt.getResultSet();
|
||||||
|
return handler.handle(stmt, result);
|
||||||
|
}finally{
|
||||||
|
if(result != null){
|
||||||
|
try {
|
||||||
|
result.close();
|
||||||
|
} catch (SQLException e) { }
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Cleanup
|
||||||
|
} finally {
|
||||||
|
if (stmt != null) {
|
||||||
|
try {
|
||||||
|
stmt.close();
|
||||||
|
} catch (SQLException sqlex) { }
|
||||||
|
stmt = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the pool that this connection belongs to
|
||||||
|
*
|
||||||
|
* @param pool is the pool
|
||||||
|
*/
|
||||||
|
protected void setPool(DBConnectionPool pool){
|
||||||
|
if( pool != null )
|
||||||
|
pool.removeConnection(this);
|
||||||
|
this.pool = pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the DB Connection is valid and functioning
|
||||||
|
*
|
||||||
|
* @return true or false depending on the validity of the connection
|
||||||
|
*/
|
||||||
|
public boolean valid(){
|
||||||
|
boolean ret = true;
|
||||||
|
try {
|
||||||
|
conn.getMetaData();
|
||||||
|
ret = ret && !conn.isClosed();
|
||||||
|
}catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects from the database or releases the connection back to the pool
|
||||||
|
*/
|
||||||
|
public void close() throws SQLException{
|
||||||
|
if(pool!=null){
|
||||||
|
pool.releaseConnection(this);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
forceClose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects from the database
|
||||||
|
*/
|
||||||
|
public void forceClose(){
|
||||||
|
if (conn != null) {
|
||||||
|
try {
|
||||||
|
conn.close();
|
||||||
|
} catch (SQLException sqlex) {
|
||||||
|
sqlex.printStackTrace();
|
||||||
|
}
|
||||||
|
conn = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o){
|
||||||
|
return conn.equals(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
174
src/zutil/db/DBConnectionPool.java
Normal file
174
src/zutil/db/DBConnectionPool.java
Normal file
|
|
@ -0,0 +1,174 @@
|
||||||
|
package zutil.db;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
import zutil.db.DBConnection.DBMS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is an connection pool
|
||||||
|
*
|
||||||
|
* @author Ziver
|
||||||
|
*/
|
||||||
|
public class DBConnectionPool extends TimerTask {
|
||||||
|
public static final long DEFAULT_TIMEOUT = 10*60*60*1000; // 10 minutes;
|
||||||
|
public static final int DEFAULT_MAX_SIZE = 5;
|
||||||
|
|
||||||
|
// DB details
|
||||||
|
private DBMS dbms;
|
||||||
|
private String url;
|
||||||
|
private String db;
|
||||||
|
private String user;
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
// Pool details
|
||||||
|
private int max_conn;
|
||||||
|
private long timeout;
|
||||||
|
private Timer timeout_timer;
|
||||||
|
|
||||||
|
protected class PoolItem{
|
||||||
|
public DBConnection conn;
|
||||||
|
public long timestamp;
|
||||||
|
|
||||||
|
public boolean equals(Object o){
|
||||||
|
return conn.equals(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The pool
|
||||||
|
private LinkedList<PoolItem> inusePool;
|
||||||
|
private LinkedList<PoolItem> readyPool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new pool of DB connections
|
||||||
|
*
|
||||||
|
* @param dbms is the DB type
|
||||||
|
* @param url is the URL to the DB
|
||||||
|
* @param db is the name of the database
|
||||||
|
* @param user is the user name to the DB
|
||||||
|
* @param password is the password to the DB
|
||||||
|
*/
|
||||||
|
public DBConnectionPool(DBMS dbms, String url, String db, String user, String password) throws Exception{
|
||||||
|
this.dbms = dbms;
|
||||||
|
this.url = url;
|
||||||
|
this.db = db;
|
||||||
|
this.user = user;
|
||||||
|
this.password = password;
|
||||||
|
|
||||||
|
inusePool = new LinkedList<PoolItem>();
|
||||||
|
readyPool = new LinkedList<PoolItem>();
|
||||||
|
|
||||||
|
this.setTimeout(DEFAULT_TIMEOUT);
|
||||||
|
this.setMaxSize(DEFAULT_MAX_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a Connection to the pool
|
||||||
|
*
|
||||||
|
* @param conn is the Connection to register
|
||||||
|
*/
|
||||||
|
protected void addConnection(DBConnection conn){
|
||||||
|
PoolItem item = new PoolItem();
|
||||||
|
item.conn = conn;
|
||||||
|
readyPool.addLast(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an connection from the pool
|
||||||
|
*
|
||||||
|
* @param conn is the connection to remove
|
||||||
|
*/
|
||||||
|
protected void removeConnection(DBConnection conn){
|
||||||
|
inusePool.remove(conn);
|
||||||
|
readyPool.remove(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lease one connection from the pool
|
||||||
|
*
|
||||||
|
* @return an DB connection or null if the pool is empty
|
||||||
|
*/
|
||||||
|
public synchronized DBConnection getConnection() throws Exception{
|
||||||
|
if(readyPool.isEmpty()){
|
||||||
|
if( size() < max_conn ){
|
||||||
|
DBConnection conn = new DBConnection(dbms, url, db, user, password);
|
||||||
|
conn.setPool( this );
|
||||||
|
addConnection( conn );
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
PoolItem item = readyPool.poll();
|
||||||
|
inusePool.addLast(item);
|
||||||
|
item.timestamp = System.currentTimeMillis();
|
||||||
|
return item.conn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the Connection as not used
|
||||||
|
*
|
||||||
|
* @param conn is the connection that is not used anymore
|
||||||
|
*/
|
||||||
|
protected synchronized void releaseConnection(DBConnection conn){
|
||||||
|
int index = inusePool.indexOf(conn);
|
||||||
|
PoolItem item = inusePool.remove(index);
|
||||||
|
readyPool.addLast(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the current size of the pool
|
||||||
|
*/
|
||||||
|
public int size(){
|
||||||
|
return inusePool.size() + readyPool.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes all the connections
|
||||||
|
*/
|
||||||
|
public synchronized void close() throws SQLException{
|
||||||
|
for( PoolItem item : inusePool ){
|
||||||
|
item.conn.forceClose();
|
||||||
|
}
|
||||||
|
inusePool.clear();
|
||||||
|
for( PoolItem item : readyPool ){
|
||||||
|
item.conn.forceClose();
|
||||||
|
}
|
||||||
|
readyPool.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the max size of the pool
|
||||||
|
*/
|
||||||
|
public void setMaxSize(int max){
|
||||||
|
this.max_conn = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the timeout of the Connections
|
||||||
|
*/
|
||||||
|
public synchronized void setTimeout(long timeout){
|
||||||
|
this.timeout = timeout;
|
||||||
|
if(timeout_timer!=null)
|
||||||
|
timeout_timer.cancel();
|
||||||
|
timeout_timer = new Timer();
|
||||||
|
timeout_timer.schedule(this, 0, timeout / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks every DB connection if they are valid and has not timed out
|
||||||
|
*/
|
||||||
|
public void run(){
|
||||||
|
long stale = System.currentTimeMillis() - timeout;
|
||||||
|
|
||||||
|
for(PoolItem item : inusePool){
|
||||||
|
if( !item.conn.valid() && stale > item.timestamp ) {
|
||||||
|
removeConnection(item.conn);
|
||||||
|
item.conn.forceClose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ package zutil.db;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
|
|
@ -21,29 +22,28 @@ import zutil.converters.Converter;
|
||||||
* @author Ziver
|
* @author Ziver
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class MySQLQueue<E> implements Queue<E>{
|
public class DBQueue<E> implements Queue<E>{
|
||||||
// GO TO KNOW = SELECT LAST_INSERT_ID() as pos_id
|
// GO TO KNOW = SELECT LAST_INSERT_ID() as pos_id
|
||||||
private MySQLConnection db;
|
private DBConnection db;
|
||||||
private String table;
|
private String table;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initiats the queue.
|
* Initiates the queue.<br>
|
||||||
* WARNING!! this will erase all rows i the table
|
* <b>WARNING!!<b> this will erase all rows in the table
|
||||||
* @param db The connection to the db
|
*
|
||||||
* @param table The name of the table
|
* @param db is the connection to the DB
|
||||||
* @throws SQLException
|
* @param table is the name of the table
|
||||||
*/
|
*/
|
||||||
public MySQLQueue(MySQLConnection db, String table){
|
public DBQueue(DBConnection db, String table){
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.table = table;
|
this.table = table;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean add(Object arg0){
|
public boolean add(Object arg0){
|
||||||
try {
|
try {
|
||||||
PreparedStatement sql = db.prepareStatement("INSERT INTO "+table+" (data) VALUES(?)");
|
PreparedStatement sql = db.getPreparedStatement("INSERT INTO "+table+" (data) VALUES(?)");
|
||||||
sql.setObject(1, arg0);
|
sql.setObject(1, arg0);
|
||||||
sql.executeUpdate();
|
DBConnection.exec(sql);
|
||||||
sql.close();
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace(MultiPrintStream.out);
|
e.printStackTrace(MultiPrintStream.out);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -56,18 +56,23 @@ public class MySQLQueue<E> implements Queue<E>{
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean offer(Object arg0) {
|
public boolean offer(Object arg0) {
|
||||||
// TODO Auto-generated method stub
|
return add(arg0);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public synchronized E peek() {
|
public synchronized E peek() {
|
||||||
try {
|
try {
|
||||||
ResultSet rs = db.query("SELECT * FROM "+table+" LIMIT 1");
|
return db.exec("SELECT * FROM "+table+" LIMIT 1", new SQLResultHandler<E>(){
|
||||||
if (rs.next()) {
|
public E handle(Statement stmt, ResultSet rs) throws SQLException{
|
||||||
return (E) Converter.toObject(rs.getBytes("data"));
|
if (rs.next())
|
||||||
}
|
try {
|
||||||
rs.getStatement().close();
|
return (E) Converter.toObject(rs.getBytes("data"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace(MultiPrintStream.out);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace(MultiPrintStream.out);
|
e.printStackTrace(MultiPrintStream.out);
|
||||||
}
|
}
|
||||||
|
|
@ -77,12 +82,19 @@ public class MySQLQueue<E> implements Queue<E>{
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public synchronized E poll() {
|
public synchronized E poll() {
|
||||||
try {
|
try {
|
||||||
ResultSet rs = db.query("SELECT * FROM "+table+" LIMIT 1");
|
return db.exec("SELECT * FROM "+table+" LIMIT 1", new SQLResultHandler<E>(){
|
||||||
if (rs.next()) {
|
public E handle(Statement stmt, ResultSet rs) {
|
||||||
db.updateQuery("DELETE FROM "+table+" WHERE id="+rs.getInt("id")+" LIMIT 1");
|
try{
|
||||||
return (E) Converter.toObject(rs.getBytes("data"));
|
if (rs.next()) {
|
||||||
}
|
db.exec("DELETE FROM "+table+" WHERE id="+rs.getInt("id")+" LIMIT 1");
|
||||||
rs.getStatement().close();
|
return (E) Converter.toObject(rs.getBytes("data"));
|
||||||
|
}
|
||||||
|
}catch(Exception e){
|
||||||
|
e.printStackTrace(MultiPrintStream.out);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace(MultiPrintStream.out);
|
e.printStackTrace(MultiPrintStream.out);
|
||||||
}
|
}
|
||||||
|
|
@ -100,7 +112,7 @@ public class MySQLQueue<E> implements Queue<E>{
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
try {
|
try {
|
||||||
db.updateQuery("TRUNCATE TABLE `"+table+"`");
|
db.exec("TRUNCATE TABLE `"+table+"`");
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace(MultiPrintStream.out);
|
e.printStackTrace(MultiPrintStream.out);
|
||||||
}
|
}
|
||||||
|
|
@ -108,11 +120,11 @@ public class MySQLQueue<E> implements Queue<E>{
|
||||||
|
|
||||||
public boolean contains(Object arg0) {
|
public boolean contains(Object arg0) {
|
||||||
try {
|
try {
|
||||||
ResultSet rs = db.query("SELECT data FROM "+table+" WHERE data='"+Converter.toBytes(arg0)+"' LIMIT 1");
|
return db.exec("SELECT data FROM "+table+" WHERE data='"+Converter.toBytes(arg0)+"' LIMIT 1", new SQLResultHandler<Boolean>(){
|
||||||
if (rs.next()) {
|
public Boolean handle(Statement stmt, ResultSet rs) throws SQLException{
|
||||||
return true;
|
return rs.next();
|
||||||
}
|
}
|
||||||
rs.getStatement().close();
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace(MultiPrintStream.out);
|
e.printStackTrace(MultiPrintStream.out);
|
||||||
}
|
}
|
||||||
|
|
@ -135,8 +147,7 @@ public class MySQLQueue<E> implements Queue<E>{
|
||||||
|
|
||||||
public synchronized boolean remove(Object arg0) {
|
public synchronized boolean remove(Object arg0) {
|
||||||
try {
|
try {
|
||||||
ResultSet rs = db.query("DELETE FROM "+table+" WHERE data='"+Converter.toBytes(arg0)+"' LIMIT 1");
|
db.exec("DELETE FROM "+table+" WHERE data='"+Converter.toBytes(arg0)+"' LIMIT 1");
|
||||||
rs.getStatement().close();
|
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace(MultiPrintStream.out);
|
e.printStackTrace(MultiPrintStream.out);
|
||||||
|
|
@ -156,11 +167,13 @@ public class MySQLQueue<E> implements Queue<E>{
|
||||||
|
|
||||||
public int size() {
|
public int size() {
|
||||||
try {
|
try {
|
||||||
ResultSet rs = db.query("SELECT count(*) FROM "+table);
|
return db.exec("SELECT count(*) FROM "+table, new SQLResultHandler<Integer>(){
|
||||||
if (rs.next()) {
|
public Integer handle(Statement stmt, ResultSet rs) throws SQLException{
|
||||||
return rs.getInt(1);
|
if (rs.next())
|
||||||
}
|
return rs.getInt(1);
|
||||||
rs.getStatement().close();
|
return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace(MultiPrintStream.out);
|
e.printStackTrace(MultiPrintStream.out);
|
||||||
}
|
}
|
||||||
|
|
@ -1,108 +0,0 @@
|
||||||
package zutil.db;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DriverManager;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
|
|
||||||
public class MySQLConnection {
|
|
||||||
Connection conn = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Connects to a MySQL server
|
|
||||||
*
|
|
||||||
* @param url is the URL of the MySQL server
|
|
||||||
* @param db is the database to connect to
|
|
||||||
* @param user is the user name
|
|
||||||
* @param password is the password
|
|
||||||
*/
|
|
||||||
public MySQLConnection(String url, String db, String user, String password)
|
|
||||||
throws SQLException, InstantiationException, IllegalAccessException, ClassNotFoundException{
|
|
||||||
Class.forName ("com.mysql.jdbc.Driver").newInstance();
|
|
||||||
DriverManager.setLoginTimeout(10);
|
|
||||||
conn = DriverManager.getConnection ("jdbc:mysql://"+url+"/"+db, user, password);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs a query and returns the result.<br>
|
|
||||||
* <b>NOTE:</b> Don't forget to close the ResultSet and the Statement or it
|
|
||||||
* can lead to memory leak: rows.getStatement().close();
|
|
||||||
*
|
|
||||||
* @param sql is the query to execute
|
|
||||||
* @return the data that the DB returned
|
|
||||||
*/
|
|
||||||
public synchronized ResultSet query(String sql) throws SQLException{
|
|
||||||
Statement s = conn.createStatement ();
|
|
||||||
s.executeQuery(sql);
|
|
||||||
return s.getResultSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the first cell of the first row of the query
|
|
||||||
*
|
|
||||||
* @param sql is the SQL query to run, preferably with the LIMIT 1 at the end
|
|
||||||
* @return A SQL row if it exists or else null
|
|
||||||
*/
|
|
||||||
public synchronized String simpleQuery(String sql) throws SQLException{
|
|
||||||
Statement s = conn.createStatement ();
|
|
||||||
s.executeQuery(sql);
|
|
||||||
ResultSet result = s.getResultSet();
|
|
||||||
if(result.next()){
|
|
||||||
String tmp = result.getString(1);
|
|
||||||
result.close();
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs a query in the MySQL server and returns effected rows
|
|
||||||
*
|
|
||||||
* @param sql is the query to execute
|
|
||||||
* @return the number of rows effected
|
|
||||||
*/
|
|
||||||
public synchronized int updateQuery(String sql) throws SQLException{
|
|
||||||
Statement s = conn.createStatement ();
|
|
||||||
int ret = s.executeUpdate(sql);
|
|
||||||
s.close();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the last inserted id or -1 if there was an error
|
|
||||||
* @throws SQLException
|
|
||||||
*/
|
|
||||||
public int getLastInsertID() throws SQLException{
|
|
||||||
Statement s = conn.createStatement ();
|
|
||||||
s.executeQuery("SELECT LAST_INSERT_ID()");
|
|
||||||
ResultSet result = s.getResultSet();
|
|
||||||
if(result.next()){
|
|
||||||
int tmp = result.getInt(1);
|
|
||||||
result.close();
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs a Prepared Statement.<br>
|
|
||||||
* <b>NOTE:</b> Don't forget to close the PreparedStatement or it can lead to memory leak
|
|
||||||
*
|
|
||||||
* @param sql is the SQL query to run
|
|
||||||
* @return The PreparedStatement
|
|
||||||
*/
|
|
||||||
public synchronized PreparedStatement prepareStatement(String sql) throws SQLException{
|
|
||||||
return conn.prepareStatement(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disconnects from the database
|
|
||||||
*/
|
|
||||||
public synchronized void close() throws SQLException{
|
|
||||||
if (conn != null){
|
|
||||||
conn.close ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
15
src/zutil/db/SQLResultHandler.java
Normal file
15
src/zutil/db/SQLResultHandler.java
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
package zutil.db;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
|
public interface SQLResultHandler<T> {
|
||||||
|
/**
|
||||||
|
* Is called to handle an result from an query.
|
||||||
|
*
|
||||||
|
* @param stmt is the query
|
||||||
|
* @param result is the ResultSet
|
||||||
|
*/
|
||||||
|
public T handle(Statement stmt, ResultSet result) throws SQLException;
|
||||||
|
}
|
||||||
126
src/zutil/log/CompactLogFormatter.java
Normal file
126
src/zutil/log/CompactLogFormatter.java
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
package zutil.log;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.logging.Formatter;
|
||||||
|
import java.util.logging.LogRecord;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class CompactLogFormatter extends Formatter{
|
||||||
|
// The split pattern where the
|
||||||
|
private static final Pattern splitter = Pattern.compile("\n");
|
||||||
|
// the stream should print time stamp
|
||||||
|
private boolean timeStamp = true;
|
||||||
|
//The time stamp style
|
||||||
|
private SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss ");
|
||||||
|
// If displaying class names are enabled
|
||||||
|
private boolean className = true;
|
||||||
|
// If displaying method names are enabled
|
||||||
|
private boolean methodName = false;
|
||||||
|
// Specifies the max length of the longest class name
|
||||||
|
private int max_class_name = 0;
|
||||||
|
// Cache for the class padding
|
||||||
|
private static HashMap<String,String> padd_cache = new HashMap<String,String>();
|
||||||
|
// Date temp file
|
||||||
|
private Date date = new Date();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String format(LogRecord record) {
|
||||||
|
StringBuilder data = new StringBuilder();
|
||||||
|
|
||||||
|
if( timeStamp ){
|
||||||
|
date.setTime( record.getMillis() );
|
||||||
|
data.append( dateFormatter.format(date) );
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( record.getLevel().intValue() ){
|
||||||
|
case /* SEVERE */ 1000: data.append("SEVERE "); break;
|
||||||
|
case /* WARNING */ 900 : data.append("WARNING "); break;
|
||||||
|
case /* INFO */ 800 : data.append("INFO "); break;
|
||||||
|
case /* CONFIG */ 700 : data.append("CONFIG "); break;
|
||||||
|
case /* FINE */ 500 : data.append("FINE "); break;
|
||||||
|
case /* FINER */ 400 : data.append("FINER "); break;
|
||||||
|
case /* FINEST */ 300 : data.append("FINEST "); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( className ){
|
||||||
|
data.append( paddClassName(record.getSourceClassName()) );
|
||||||
|
}
|
||||||
|
if(methodName){
|
||||||
|
data.append( record.getSourceMethodName() );
|
||||||
|
}
|
||||||
|
data.append( ": " );
|
||||||
|
|
||||||
|
StringBuffer ret = new StringBuffer();
|
||||||
|
String[] array = splitter.split( record.getMessage() );
|
||||||
|
for( int i=0; i<array.length ;++i ){
|
||||||
|
if( i!=0 )
|
||||||
|
ret.append( '\n' );
|
||||||
|
if( data.length() > 0 )
|
||||||
|
ret.append( data );
|
||||||
|
ret.append( array[i] );
|
||||||
|
}
|
||||||
|
ret.append( '\n' );
|
||||||
|
return ret.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the formatter should add a time stamp in front of the log message
|
||||||
|
*
|
||||||
|
* @param enable set to True to activate time stamp
|
||||||
|
*/
|
||||||
|
public void enableTimeStamp(boolean enable){
|
||||||
|
timeStamp = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The DateFormat to print in the time stamp
|
||||||
|
*
|
||||||
|
* @param ts is the String to send to SimpleDateFormat
|
||||||
|
*/
|
||||||
|
public void setTimeStamp(String ts){
|
||||||
|
dateFormatter = new SimpleDateFormat(ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the formatter should add the class/source name in front of the log message
|
||||||
|
*
|
||||||
|
* @param enable set to True to activate class/source name
|
||||||
|
*/
|
||||||
|
public void enableClassName(boolean enable){
|
||||||
|
className = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the formatter should add the class/source name in front of the log message
|
||||||
|
*
|
||||||
|
* @param enable set to True to activate class/source name
|
||||||
|
*/
|
||||||
|
public void enableMethodName(boolean enable){
|
||||||
|
methodName = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the Class name
|
||||||
|
*/
|
||||||
|
private String paddClassName(String source){
|
||||||
|
String tmp = padd_cache.get(source);
|
||||||
|
if( tmp != null )
|
||||||
|
return tmp;
|
||||||
|
|
||||||
|
String c_name = source.substring( source.lastIndexOf('.')+1 );
|
||||||
|
if( c_name.length() > max_class_name )
|
||||||
|
max_class_name = c_name.length();
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder( c_name );
|
||||||
|
for( int i=c_name.length(); i<max_class_name; ++i ) {
|
||||||
|
sb.append( ' ' );
|
||||||
|
}
|
||||||
|
tmp = sb.toString();
|
||||||
|
padd_cache.put(source, tmp);
|
||||||
|
return tmp;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package zutil.log;
|
package zutil.log;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
|
@ -8,44 +10,43 @@ public class StandardLogFormatter implements LogFormatter{
|
||||||
// The split pattern where the
|
// The split pattern where the
|
||||||
private static final Pattern splitter = Pattern.compile("\n");
|
private static final Pattern splitter = Pattern.compile("\n");
|
||||||
// the stream should print time stamp
|
// the stream should print time stamp
|
||||||
private boolean timeStamp = false;
|
private boolean timeStamp = true;
|
||||||
//The time stamp style
|
//The time stamp style
|
||||||
private String timeStampString = "yyyy-MM-dd HH:mm:ss:SSS#";
|
private SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss ");
|
||||||
// If displaying class names are enabled
|
// If displaying class names are enabled
|
||||||
private boolean className = true;
|
private boolean className = true;
|
||||||
// Specifies the max length of the longest class name
|
// Specifies the max length of the longest class name
|
||||||
private int max_class_name = 0;
|
private int max_class_name = 0;
|
||||||
|
// Cache for the class padding
|
||||||
|
private static HashMap<String,String> padd_cache = new HashMap<String,String>();
|
||||||
|
// Date temp file
|
||||||
|
private Date date = new Date();
|
||||||
|
|
||||||
|
|
||||||
public String format(String source, Level level, String msg) {
|
public String format(String source, Level level, String msg) {
|
||||||
StringBuilder data = new StringBuilder();
|
StringBuilder data = new StringBuilder();
|
||||||
|
|
||||||
switch(level.intValue()){
|
if( timeStamp ){
|
||||||
case /* SEVERE */ 1000: data.append("SEVERE : "); break;
|
date.setTime( System.currentTimeMillis() );
|
||||||
case /* WARNING */ 900 : data.append("WARNING: "); break;
|
data.append( dateFormatter.format(date) );
|
||||||
case /* INFO */ 800 : data.append("INFO : "); break;
|
|
||||||
case /* CONFIG */ 700 : data.append("CONFIG : "); break;
|
|
||||||
case /* FINE */ 500 : data.append("FINE : "); break;
|
|
||||||
case /* FINER */ 400 : data.append("FINER : "); break;
|
|
||||||
case /* FINEST */ 300 : data.append("FINEST : "); break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( timeStamp && className ){
|
switch( level.intValue() ){
|
||||||
data.append( getTime() );
|
case /* SEVERE */ 1000: data.append("SEVERE "); break;
|
||||||
data.append( " " );
|
case /* WARNING */ 900 : data.append("WARNING "); break;
|
||||||
data.append( paddSourceName(source) );
|
case /* INFO */ 800 : data.append("INFO "); break;
|
||||||
data.append( ": " );
|
case /* CONFIG */ 700 : data.append("CONFIG "); break;
|
||||||
}
|
case /* FINE */ 500 : data.append("FINE "); break;
|
||||||
else if( timeStamp ){
|
case /* FINER */ 400 : data.append("FINER "); break;
|
||||||
data.append( getTime() );
|
case /* FINEST */ 300 : data.append("FINEST "); break;
|
||||||
data.append( " " );
|
|
||||||
}
|
|
||||||
else if( className ){
|
|
||||||
data.append( paddSourceName(source) );
|
|
||||||
data.append( ": " );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder ret = new StringBuilder();
|
if( className ){
|
||||||
|
data.append( paddSourceName(source) );
|
||||||
|
}
|
||||||
|
data.append( ": " );
|
||||||
|
|
||||||
|
StringBuffer ret = new StringBuffer();
|
||||||
String[] array = splitter.split( msg );
|
String[] array = splitter.split( msg );
|
||||||
for( int i=0; i<array.length ;++i ){
|
for( int i=0; i<array.length ;++i ){
|
||||||
if( i!=0 )
|
if( i!=0 )
|
||||||
|
|
@ -54,6 +55,7 @@ public class StandardLogFormatter implements LogFormatter{
|
||||||
ret.append( data );
|
ret.append( data );
|
||||||
ret.append( array[i] );
|
ret.append( array[i] );
|
||||||
}
|
}
|
||||||
|
ret.append( '\n' );
|
||||||
return ret.toString();
|
return ret.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,14 +74,7 @@ public class StandardLogFormatter implements LogFormatter{
|
||||||
* @param ts is the String to send to SimpleDateFormat
|
* @param ts is the String to send to SimpleDateFormat
|
||||||
*/
|
*/
|
||||||
public void setTimeStamp(String ts){
|
public void setTimeStamp(String ts){
|
||||||
timeStampString = ts;
|
dateFormatter = new SimpleDateFormat(ts);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the time stamp
|
|
||||||
*/
|
|
||||||
private String getTime(){
|
|
||||||
return (new SimpleDateFormat(timeStampString)).format(new java.util.Date()).toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -95,6 +90,10 @@ public class StandardLogFormatter implements LogFormatter{
|
||||||
* @return the Class name
|
* @return the Class name
|
||||||
*/
|
*/
|
||||||
private String paddSourceName(String source){
|
private String paddSourceName(String source){
|
||||||
|
String tmp = padd_cache.get(source);
|
||||||
|
if( tmp != null )
|
||||||
|
return tmp;
|
||||||
|
|
||||||
if( source.length() > max_class_name )
|
if( source.length() > max_class_name )
|
||||||
max_class_name = source.length();
|
max_class_name = source.length();
|
||||||
|
|
||||||
|
|
@ -102,7 +101,9 @@ public class StandardLogFormatter implements LogFormatter{
|
||||||
for( int i=source.length(); i<max_class_name; ++i ) {
|
for( int i=source.length(); i<max_class_name; ++i ) {
|
||||||
sb.append( ' ' );
|
sb.append( ' ' );
|
||||||
}
|
}
|
||||||
return sb.toString();
|
tmp = sb.toString();
|
||||||
|
padd_cache.put(source, tmp);
|
||||||
|
return tmp;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,8 @@ public class HTTPHeaderParser {
|
||||||
else{
|
else{
|
||||||
url = line;
|
url = line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
url = url.replaceAll("//", "/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ import zutil.network.threaded.ThreadedTCPNetworkServerThread;
|
||||||
* @author Ziver
|
* @author Ziver
|
||||||
*/
|
*/
|
||||||
public class HttpServer extends ThreadedTCPNetworkServer{
|
public class HttpServer extends ThreadedTCPNetworkServer{
|
||||||
public static final boolean DEBUG = false;
|
public static final boolean DEBUG = true;
|
||||||
public static final String SERVER_VERSION = "StaticInt HttpServer 1.0";
|
public static final String SERVER_VERSION = "Ziver HttpServer 1.0";
|
||||||
public static final int COOKIE_TTL = 200;
|
public static final int COOKIE_TTL = 200;
|
||||||
public static final int SESSION_TTL = 10*60*1000; // in milliseconds
|
public static final int SESSION_TTL = 10*60*1000; // in milliseconds
|
||||||
|
|
||||||
|
|
@ -88,7 +88,6 @@ public class HttpServer extends ThreadedTCPNetworkServer{
|
||||||
if(DEBUG) MultiPrintStream.out.println("Removing Session: "+key);
|
if(DEBUG) MultiPrintStream.out.println("Removing Session: "+key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -142,7 +141,6 @@ public class HttpServer extends ThreadedTCPNetworkServer{
|
||||||
public void run(){
|
public void run(){
|
||||||
String tmp = null;
|
String tmp = null;
|
||||||
|
|
||||||
String page_url = "";
|
|
||||||
HashMap<String,String> client_info = new HashMap<String,String>();
|
HashMap<String,String> client_info = new HashMap<String,String>();
|
||||||
HashMap<String,String> cookie = new HashMap<String,String>();
|
HashMap<String,String> cookie = new HashMap<String,String>();
|
||||||
HashMap<String,String> request = new HashMap<String,String>();
|
HashMap<String,String> request = new HashMap<String,String>();
|
||||||
|
|
@ -212,7 +210,7 @@ public class HttpServer extends ThreadedTCPNetworkServer{
|
||||||
}
|
}
|
||||||
// Debug
|
// Debug
|
||||||
if(DEBUG){
|
if(DEBUG){
|
||||||
MultiPrintStream.out.println( "# page_url: "+page_url );
|
MultiPrintStream.out.println( "# page_url: "+parser.getRequestURL() );
|
||||||
MultiPrintStream.out.println( "# cookie: "+cookie );
|
MultiPrintStream.out.println( "# cookie: "+cookie );
|
||||||
MultiPrintStream.out.println( "# client_session: "+client_session );
|
MultiPrintStream.out.println( "# client_session: "+client_session );
|
||||||
MultiPrintStream.out.println( "# client_info: "+client_info );
|
MultiPrintStream.out.println( "# client_info: "+client_info );
|
||||||
|
|
@ -225,8 +223,8 @@ public class HttpServer extends ThreadedTCPNetworkServer{
|
||||||
out.setHeader( "Content-Type", "text/html" );
|
out.setHeader( "Content-Type", "text/html" );
|
||||||
out.setCookie( "session_id", ""+client_session.get("session_id") );
|
out.setCookie( "session_id", ""+client_session.get("session_id") );
|
||||||
|
|
||||||
if( !page_url.isEmpty() && pages.containsKey(page_url) ){
|
if( !parser.getRequestURL().isEmpty() && pages.containsKey(parser.getRequestURL()) ){
|
||||||
pages.get(page_url).respond(out, client_info, client_session, cookie, request);
|
pages.get(parser.getRequestURL()).respond(out, client_info, client_session, cookie, request);
|
||||||
}
|
}
|
||||||
else if( defaultPage != null ){
|
else if( defaultPage != null ){
|
||||||
defaultPage.respond(out, client_info, client_session, cookie, request);
|
defaultPage.respond(out, client_info, client_session, cookie, request);
|
||||||
|
|
@ -234,6 +232,7 @@ public class HttpServer extends ThreadedTCPNetworkServer{
|
||||||
else{
|
else{
|
||||||
out.setStatusCode( 404 );
|
out.setStatusCode( 404 );
|
||||||
out.println( "404 Page Not Found" );
|
out.println( "404 Page Not Found" );
|
||||||
|
if(DEBUG) MultiPrintStream.out.println("404 Page Not Found");
|
||||||
}
|
}
|
||||||
|
|
||||||
//********************************************************************************
|
//********************************************************************************
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ import com.sun.org.apache.xerces.internal.dom.DocumentImpl;
|
||||||
* This is an HTTPPage for the HTTPServer that
|
* This is an HTTPPage for the HTTPServer that
|
||||||
* handles soap messages.
|
* handles soap messages.
|
||||||
*
|
*
|
||||||
|
* TODO: Header should be variables not methods
|
||||||
* TODO: Read SOAPObjects as input parameter
|
* TODO: Read SOAPObjects as input parameter
|
||||||
* TODO: Ability to have multiple arrays of same SOAPObject
|
* TODO: Ability to have multiple arrays of same SOAPObject
|
||||||
*
|
*
|
||||||
|
|
@ -75,6 +76,7 @@ import com.sun.org.apache.xerces.internal.dom.DocumentImpl;
|
||||||
*
|
*
|
||||||
* Output:
|
* Output:
|
||||||
* <br>-SOAPObjects
|
* <br>-SOAPObjects
|
||||||
|
* <br>-SOAPReturnObjectList
|
||||||
* <br>-byte[]
|
* <br>-byte[]
|
||||||
* <br>-int
|
* <br>-int
|
||||||
* <br>-double
|
* <br>-double
|
||||||
|
|
@ -93,7 +95,8 @@ public class SOAPHttpPage implements HttpPage{
|
||||||
private class MethodCache{
|
private class MethodCache{
|
||||||
String[] paramName;
|
String[] paramName;
|
||||||
boolean[] paramOptional;
|
boolean[] paramOptional;
|
||||||
String returnName;
|
String[] returnName;
|
||||||
|
Class<?>[] returnClass;
|
||||||
Method method;
|
Method method;
|
||||||
boolean header;
|
boolean header;
|
||||||
|
|
||||||
|
|
@ -102,6 +105,20 @@ public class SOAPHttpPage implements HttpPage{
|
||||||
paramName = new String[method.getParameterTypes().length];
|
paramName = new String[method.getParameterTypes().length];
|
||||||
paramOptional = new boolean[method.getParameterTypes().length];
|
paramOptional = new boolean[method.getParameterTypes().length];
|
||||||
header = false;
|
header = false;
|
||||||
|
|
||||||
|
Class<?> tmp = m.getReturnType();
|
||||||
|
if( SOAPReturnValueList.class.isAssignableFrom( tmp )){
|
||||||
|
returnName = new String[ tmp.getFields().length ];
|
||||||
|
returnClass = new Class<?>[ tmp.getFields().length ];
|
||||||
|
}
|
||||||
|
else if( !tmp.isAssignableFrom( void.class )){
|
||||||
|
returnName = new String[1];
|
||||||
|
returnClass = new Class<?>[1];
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
returnName = new String[0];
|
||||||
|
returnClass = new Class<?>[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// The object that the functions will be invoked from
|
// The object that the functions will be invoked from
|
||||||
|
|
@ -148,12 +165,28 @@ public class SOAPHttpPage implements HttpPage{
|
||||||
tmp.append(m.getParameterTypes()[i].getSimpleName()+" "+chasch.paramName[i]);
|
tmp.append(m.getParameterTypes()[i].getSimpleName()+" "+chasch.paramName[i]);
|
||||||
if( i<paramAnnotation.length-1 ) tmp.append(", ");
|
if( i<paramAnnotation.length-1 ) tmp.append(", ");
|
||||||
}
|
}
|
||||||
tmp.append(")");
|
tmp.append(") => ");
|
||||||
|
|
||||||
// the return param name
|
// the return parameter name
|
||||||
SOAPInterface.SOAPReturnName returnName = m.getAnnotation(SOAPInterface.SOAPReturnName.class);
|
SOAPInterface.SOAPReturnName returnName = m.getAnnotation(SOAPInterface.SOAPReturnName.class);
|
||||||
if(returnName != null) chasch.returnName = returnName.value();
|
if( SOAPReturnValueList.class.isAssignableFrom( m.getReturnType() ) ){
|
||||||
else chasch.returnName = "return";
|
Class<?> retClass = m.getReturnType();
|
||||||
|
for(int i=0; i<retClass.getFields().length ;i++){
|
||||||
|
if(i!=0) tmp.append(", ");
|
||||||
|
SOAPReturnValueList.SOAPValueName retValName = retClass.getFields()[i]
|
||||||
|
.getAnnotation( SOAPReturnValueList.SOAPValueName.class );
|
||||||
|
if(retValName != null) chasch.returnName[i] = retValName.value();
|
||||||
|
else chasch.returnName[i] = retClass.getFields()[i].getName();
|
||||||
|
chasch.returnClass[i] = retClass.getFields()[i].getType();
|
||||||
|
tmp.append(chasch.returnClass[i].getSimpleName()+" "+chasch.returnName[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( chasch.returnName.length>0 ){
|
||||||
|
if(returnName != null) chasch.returnName[0] = returnName.value();
|
||||||
|
else chasch.returnName[0] = "return";
|
||||||
|
chasch.returnClass[0] = m.getReturnType();
|
||||||
|
tmp.append(chasch.returnClass[0].getSimpleName()+" "+chasch.returnName[0]);
|
||||||
|
}
|
||||||
|
|
||||||
// SOAP header?
|
// SOAP header?
|
||||||
if(m.getAnnotation(SOAPInterface.SOAPHeader.class) != null)
|
if(m.getAnnotation(SOAPInterface.SOAPHeader.class) != null)
|
||||||
|
|
@ -184,6 +217,13 @@ public class SOAPHttpPage implements HttpPage{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables session support, if enabled then a new instance
|
||||||
|
* of the SOAPInterface will be created, if disabled then
|
||||||
|
* only the given object will be used as an static interface
|
||||||
|
*
|
||||||
|
* @param enabled is if session should be enabled
|
||||||
|
*/
|
||||||
public void enableSession(boolean enabled){
|
public void enableSession(boolean enabled){
|
||||||
this.session_enabled = enabled;
|
this.session_enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
@ -210,27 +250,33 @@ public class SOAPHttpPage implements HttpPage{
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
SOAPInterface obj = null;
|
SOAPInterface obj = null;
|
||||||
if(session_enabled && session.containsKey("SOAPInterface"))
|
if(session_enabled){
|
||||||
obj = (SOAPInterface)session.get("SOAPInterface");
|
if( session.containsKey("SOAPInterface"))
|
||||||
|
obj = (SOAPInterface)session.get("SOAPInterface");
|
||||||
|
else{
|
||||||
|
obj = interf.getClass().newInstance();
|
||||||
|
session.put("SOAPInterface", obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
else{
|
else{
|
||||||
obj = interf.getClass().newInstance();
|
obj = interf;
|
||||||
if(session_enabled) session.put("SOAPInterface", obj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Document document = soapResponse( request.get(""), obj);
|
Document document = genSOAPResponse( request.get(""), obj);
|
||||||
|
|
||||||
OutputFormat format = OutputFormat.createPrettyPrint();
|
OutputFormat format = OutputFormat.createCompactFormat();
|
||||||
XMLWriter writer = new XMLWriter( out, format );
|
XMLWriter writer = new XMLWriter( out, format );
|
||||||
writer.write( document );
|
writer.write( document );
|
||||||
|
|
||||||
/*
|
|
||||||
// DEBUG
|
// DEBUG
|
||||||
System.err.println("Request");
|
OutputFormat format2 = OutputFormat.createPrettyPrint();
|
||||||
|
System.err.println("********** Request");
|
||||||
System.err.println(request);
|
System.err.println(request);
|
||||||
System.out.println("Response");
|
System.out.println("********** Response");
|
||||||
writer = new XMLWriter( System.out, format );
|
writer = new XMLWriter( System.out, format2 );
|
||||||
writer.write( document );
|
writer.write( document );
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace(MultiPrintStream.out);
|
e.printStackTrace(MultiPrintStream.out);
|
||||||
|
|
@ -238,20 +284,24 @@ public class SOAPHttpPage implements HttpPage{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a soap response for the given
|
* Generates a soap response for the given XML
|
||||||
* @param xml is the XML request
|
* @param xml is the XML request
|
||||||
* @return a Document with the response
|
* @return a Document with the response
|
||||||
*/
|
*/
|
||||||
public Document soapResponse(String xml){
|
public Document genSOAPResponse(String xml){
|
||||||
try {
|
try {
|
||||||
return soapResponse(xml, interf.getClass().newInstance());
|
SOAPInterface o = null;
|
||||||
|
if(session_enabled) o = interf.getClass().newInstance();
|
||||||
|
else o = interf;
|
||||||
|
|
||||||
|
return genSOAPResponse(xml, o );
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace(MultiPrintStream.out);
|
e.printStackTrace(MultiPrintStream.out);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Document soapResponse(String xml, SOAPInterface obj){
|
protected Document genSOAPResponse(String xml, SOAPInterface obj){
|
||||||
Document document = DocumentHelper.createDocument();
|
Document document = DocumentHelper.createDocument();
|
||||||
Element envelope = document.addElement("soap:Envelope");
|
Element envelope = document.addElement("soap:Envelope");
|
||||||
try {
|
try {
|
||||||
|
|
@ -295,16 +345,30 @@ public class SOAPHttpPage implements HttpPage{
|
||||||
return document;
|
return document;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an String XML to an Element
|
||||||
|
*
|
||||||
|
* @param msg is the string XML
|
||||||
|
* @return the XML root Element
|
||||||
|
*/
|
||||||
|
private Element getXMLRoot(String xml) throws Exception {
|
||||||
|
if(xml != null && !xml.isEmpty()){
|
||||||
|
Document document = DocumentHelper.parseText(xml);
|
||||||
|
return document.getRootElement();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes an XML Element and invokes all the
|
* Takes an XML Element and invokes all the
|
||||||
* chide Elements as methods.
|
* Child Elements as methods.
|
||||||
*
|
*
|
||||||
* @param obj is the object that the methods will be called from
|
* @param obj is the object that the methods will be called from
|
||||||
* @param requestRoot is the Element where the children lies
|
* @param requestRoot is the Element where the children lies
|
||||||
* @param responseRoot is the root element of the response
|
* @param responseRoot is the root element of the response
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void prepareInvoke(Object obj, Element requestRoot, Element responseRoot) throws Throwable{
|
private void prepareInvoke(SOAPInterface obj, Element requestRoot, Element responseRoot) throws Throwable{
|
||||||
Iterator<Element> it = requestRoot.elementIterator();
|
Iterator<Element> it = requestRoot.elementIterator();
|
||||||
while( it.hasNext() ){
|
while( it.hasNext() ){
|
||||||
Element e = it.next();
|
Element e = it.next();
|
||||||
|
|
@ -312,7 +376,7 @@ public class SOAPHttpPage implements HttpPage{
|
||||||
MethodCache m = methods.get(e.getQName().getName());
|
MethodCache m = methods.get(e.getQName().getName());
|
||||||
Object[] params = new Object[m.paramName.length];
|
Object[] params = new Object[m.paramName.length];
|
||||||
|
|
||||||
// Get the param values
|
// Get the parameter values
|
||||||
for(int i=0; i<m.paramName.length ;i++){
|
for(int i=0; i<m.paramName.length ;i++){
|
||||||
if(e.element(m.paramName[i]) != null)
|
if(e.element(m.paramName[i]) != null)
|
||||||
params[i] = convertToClass(
|
params[i] = convertToClass(
|
||||||
|
|
@ -323,11 +387,24 @@ public class SOAPHttpPage implements HttpPage{
|
||||||
// Invoke
|
// Invoke
|
||||||
Object ret = invoke(obj, m.method, params);
|
Object ret = invoke(obj, m.method, params);
|
||||||
|
|
||||||
// generate response xml
|
// generate response XML
|
||||||
if(m.method.getReturnType() != void.class){
|
if( m.returnClass.length>0 ){
|
||||||
responseRoot.addNamespace("m", url+""+m.method.getName());
|
SOAPInterface.SOAPNameSpace namespace = m.method.getAnnotation(SOAPInterface.SOAPNameSpace.class);
|
||||||
Element response = responseRoot.addElement("m:"+m.method.getName()+"Response");
|
Element response = responseRoot.addElement("");
|
||||||
generateReturnXML(response, ret, m.returnName, m);
|
if( namespace != null )
|
||||||
|
response.addNamespace("m", namespace.value());
|
||||||
|
else
|
||||||
|
response.addNamespace("m", url+""+m.method.getName());
|
||||||
|
response.setName("m:"+m.method.getName()+"Response");
|
||||||
|
if( ret instanceof SOAPReturnValueList ){
|
||||||
|
Field[] f = ret.getClass().getFields();
|
||||||
|
for(int i=0; i<m.returnName.length ;i++ ){
|
||||||
|
generateReturnXML(response,((SOAPReturnValueList)ret).getValue(f[i]) , m.returnName[i], m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
generateReturnXML(response, ret, m.returnName[0], m);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
|
@ -336,59 +413,6 @@ public class SOAPHttpPage implements HttpPage{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates an return XML Element. This function can
|
|
||||||
* handle return values as XML Elements, SOAPObject and the
|
|
||||||
* Java basic data types.
|
|
||||||
*
|
|
||||||
* @param root is the parent Element
|
|
||||||
* @param ret is the object that is the return value
|
|
||||||
* @param ename is the name of the parent Element
|
|
||||||
* @param m is the method that returned the ret
|
|
||||||
*/
|
|
||||||
private void generateReturnXML(Element root, Object ret, String ename, MethodCache m) throws IllegalArgumentException, IllegalAccessException{
|
|
||||||
if(ret == null) return;
|
|
||||||
if(byte[].class.isAssignableFrom(ret.getClass())){
|
|
||||||
Element valueE = root.addElement( ename );
|
|
||||||
valueE.addAttribute("type", "xsd:"+getClassSOAPName(ret.getClass()));
|
|
||||||
String tmp = new sun.misc.BASE64Encoder().encode((byte[])ret);
|
|
||||||
tmp = tmp.replaceAll("\\s", "");
|
|
||||||
valueE.setText(tmp);
|
|
||||||
}
|
|
||||||
// return an array
|
|
||||||
else if(ret.getClass().isArray()){
|
|
||||||
Element array = root.addElement( (ename.equals("element") ? "Array" : ename) );
|
|
||||||
String arrayType = "xsd:"+getClassSOAPName(ret.getClass());
|
|
||||||
arrayType = arrayType.replaceFirst("\\[\\]", "["+Array.getLength(ret)+"]");
|
|
||||||
|
|
||||||
array.addAttribute("type", "soap:Array");
|
|
||||||
array.addAttribute("soap:arrayType", arrayType);
|
|
||||||
for(int i=0; i<Array.getLength(ret) ;i++){
|
|
||||||
generateReturnXML(array, Array.get(ret, i), "element", m);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if(ret instanceof Element)
|
|
||||||
root.add( (Element)ret );
|
|
||||||
if(ret instanceof SOAPObject){
|
|
||||||
Element objectE = root.addElement( ename ); //getClassSOAPName(ret.getClass())
|
|
||||||
Field[] fields = ret.getClass().getFields();
|
|
||||||
for(int i=0; i<fields.length ;i++){
|
|
||||||
SOAPFieldName tmp = fields[i].getAnnotation(SOAPObject.SOAPFieldName.class);
|
|
||||||
String name;
|
|
||||||
if(tmp != null) name = tmp.value();
|
|
||||||
else name = "field"+i;
|
|
||||||
generateReturnXML(objectE, fields[i].get(ret), name, m);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Element valueE = root.addElement( ename );
|
|
||||||
valueE.addAttribute("type", "xsd:"+getClassSOAPName(ret.getClass()));
|
|
||||||
valueE.addText( ""+ret );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts an given String to a specified class
|
* Converts an given String to a specified class
|
||||||
*/
|
*/
|
||||||
|
|
@ -434,19 +458,58 @@ public class SOAPHttpPage implements HttpPage{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts an String XML to an Element
|
* Generates an return XML Element. This function can
|
||||||
|
* handle return values as XML Elements, SOAPObject and the
|
||||||
|
* Java basic data types.
|
||||||
*
|
*
|
||||||
* @param msg is the string XML
|
* @param root is the parent Element
|
||||||
* @return the XML root Element
|
* @param ret is the object that is the return value
|
||||||
|
* @param ename is the name of the parent Element
|
||||||
|
* @param m is the method that returned the ret value
|
||||||
*/
|
*/
|
||||||
private Element getXMLRoot(String xml) throws Exception {
|
private void generateReturnXML(Element root, Object ret, String ename, MethodCache m) throws IllegalArgumentException, IllegalAccessException{
|
||||||
if(xml != null && !xml.isEmpty()){
|
if(ret == null) return;
|
||||||
Document document = DocumentHelper.parseText(xml);
|
if(byte[].class.isAssignableFrom(ret.getClass())){
|
||||||
return document.getRootElement();
|
Element valueE = root.addElement( ename );
|
||||||
|
valueE.addAttribute("type", "xsd:"+getClassSOAPName(ret.getClass()));
|
||||||
|
String tmp = new sun.misc.BASE64Encoder().encode((byte[])ret);
|
||||||
|
tmp = tmp.replaceAll("\\s", "");
|
||||||
|
valueE.setText(tmp);
|
||||||
|
}
|
||||||
|
// return an array
|
||||||
|
else if(ret.getClass().isArray()){
|
||||||
|
Element array = root.addElement( (ename.equals("element") ? "Array" : ename) );
|
||||||
|
String arrayType = "xsd:"+getClassSOAPName(ret.getClass());
|
||||||
|
arrayType = arrayType.replaceFirst("\\[\\]", "["+Array.getLength(ret)+"]");
|
||||||
|
|
||||||
|
array.addAttribute("type", "soap:Array");
|
||||||
|
array.addAttribute("soap:arrayType", arrayType);
|
||||||
|
for(int i=0; i<Array.getLength(ret) ;i++){
|
||||||
|
generateReturnXML(array, Array.get(ret, i), "element", m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Element objectE = root.addElement( ename ); //getClassSOAPName(ret.getClass())
|
||||||
|
if(ret instanceof Element)
|
||||||
|
objectE.add( (Element)ret );
|
||||||
|
else if(ret instanceof SOAPObject){
|
||||||
|
Field[] fields = ret.getClass().getFields();
|
||||||
|
for(int i=0; i<fields.length ;i++){
|
||||||
|
SOAPFieldName tmp = fields[i].getAnnotation(SOAPObject.SOAPFieldName.class);
|
||||||
|
String name;
|
||||||
|
if(tmp != null) name = tmp.value();
|
||||||
|
else name = "field"+i;
|
||||||
|
generateReturnXML(objectE, fields[i].get(ret), name, m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
objectE.addAttribute("type", "xsd:"+getClassSOAPName(ret.getClass()));
|
||||||
|
objectE.addText( ""+ret );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private String getClassSOAPName(Class<?> c){
|
private String getClassSOAPName(Class<?> c){
|
||||||
Class<?> cTmp = getClass(c);
|
Class<?> cTmp = getClass(c);
|
||||||
if(byte[].class.isAssignableFrom(c)){
|
if(byte[].class.isAssignableFrom(c)){
|
||||||
|
|
@ -465,6 +528,9 @@ public class SOAPHttpPage implements HttpPage{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//********************************************************
|
||||||
|
//********* WSDL Generation *************************
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates an WSDL document for the class
|
* Generates an WSDL document for the class
|
||||||
*
|
*
|
||||||
|
|
@ -516,7 +582,7 @@ public class SOAPHttpPage implements HttpPage{
|
||||||
imp.setLocationURI(td);
|
imp.setLocationURI(td);
|
||||||
wsdl.addImport(imp);
|
wsdl.addImport(imp);
|
||||||
|
|
||||||
// PrtType
|
// PortType
|
||||||
PortType portType = wsdl.createPortType();
|
PortType portType = wsdl.createPortType();
|
||||||
portType.setQName(new QName(tns, portTypeName));
|
portType.setQName(new QName(tns, portTypeName));
|
||||||
portType.setUndefined(false);
|
portType.setUndefined(false);
|
||||||
|
|
@ -559,38 +625,43 @@ public class SOAPHttpPage implements HttpPage{
|
||||||
operation.setInput(input);
|
operation.setInput(input);
|
||||||
}
|
}
|
||||||
//********** Response Message
|
//********** Response Message
|
||||||
if(!m.method.getReturnType().equals( void.class )){
|
if( m.returnName.length>0 ){
|
||||||
Message msgOut = wsdl.createMessage();
|
Message msgOut = wsdl.createMessage();
|
||||||
msgOut.setQName(new QName(tns, m.method.getName()+"Response"));
|
msgOut.setQName(new QName(tns, m.method.getName()+"Response"));
|
||||||
msgOut.setUndefined(false);
|
msgOut.setUndefined(false);
|
||||||
|
|
||||||
// Parts
|
for( int i=0; i<m.returnName.length ;i++ ){
|
||||||
Part part = wsdl.createPart();
|
Class<?> retClass = m.returnClass[i];
|
||||||
part.setName(m.returnName);
|
//MultiPrintStream.out.println(m.method.getName()+"=>"+m.returnName[i]+"="+retClass);
|
||||||
msgOut.addPart(part);
|
|
||||||
|
|
||||||
// Generate new type if the object is an SOAPObject
|
// Parts
|
||||||
Class<?> cTmp = getClass(m.method.getReturnType());
|
Part part = wsdl.createPart();
|
||||||
if(byte[].class.isAssignableFrom(m.method.getReturnType())){
|
part.setName( m.returnName[i] );
|
||||||
part.setTypeName(new QName(xsd, "base64Binary"));
|
msgOut.addPart(part);
|
||||||
}
|
|
||||||
// is an array?
|
Class<?> cTmp = getClass( retClass );
|
||||||
else if(m.method.getReturnType().isArray()){
|
// is an binary array
|
||||||
part.setTypeName(new QName(td,
|
if(byte[].class.isAssignableFrom( retClass )){
|
||||||
"ArrayOf"+getClassSOAPName(m.method.getReturnType()).replaceAll("[\\[\\]]", "")));
|
part.setTypeName(new QName(xsd, "base64Binary"));
|
||||||
// add to type generation list
|
}
|
||||||
if(!types.contains(m.method.getReturnType()))
|
// is an array?
|
||||||
types.add(m.method.getReturnType());
|
else if( retClass.isArray()){
|
||||||
}
|
part.setTypeName(new QName(td,
|
||||||
else if( SOAPObject.class.isAssignableFrom(cTmp) ){
|
"ArrayOf"+getClassSOAPName( retClass ).replaceAll("[\\[\\]]", "")));
|
||||||
// its an SOAPObject
|
// add to type generation list
|
||||||
part.setTypeName(new QName(td, getClassSOAPName(m.method.getReturnType())));
|
if(!types.contains( retClass ))
|
||||||
// add to type generation list
|
types.add( retClass );
|
||||||
if(!types.contains(cTmp))
|
}
|
||||||
types.add(cTmp);
|
else if( SOAPObject.class.isAssignableFrom(cTmp) ){
|
||||||
}
|
// its an SOAPObject
|
||||||
else{// its an Object
|
part.setTypeName(new QName(td, getClassSOAPName( retClass )));
|
||||||
part.setTypeName(new QName(xsd, getClassSOAPName(m.method.getReturnType())));
|
// add to type generation list
|
||||||
|
if(!types.contains(cTmp))
|
||||||
|
types.add(cTmp);
|
||||||
|
}
|
||||||
|
else{// its an Object
|
||||||
|
part.setTypeName(new QName(xsd, getClassSOAPName( retClass )));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wsdl.addMessage(msgOut);
|
wsdl.addMessage(msgOut);
|
||||||
|
|
@ -794,7 +865,7 @@ public class SOAPHttpPage implements HttpPage{
|
||||||
}
|
}
|
||||||
|
|
||||||
private Class<?> getClass(Class<?> c){
|
private Class<?> getClass(Class<?> c){
|
||||||
if(c.isArray()){
|
if(c!=null && c.isArray()){
|
||||||
return getClass(c.getComponentType());
|
return getClass(c.getComponentType());
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package zutil.network.http.soap;
|
package zutil.network.http.soap;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Specifies SOAP parameters names an other things.
|
* Specifies SOAP parameters names an other things.
|
||||||
|
|
@ -99,4 +98,15 @@ public interface SOAPInterface {
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.METHOD)
|
@Target(ElementType.METHOD)
|
||||||
public @interface SOAPHeader { }
|
public @interface SOAPHeader { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the namespace for the method.
|
||||||
|
*
|
||||||
|
* @author Ziver
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
public @interface SOAPNameSpace {
|
||||||
|
String value();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
51
src/zutil/network/http/soap/SOAPReturnObjectList.java
Normal file
51
src/zutil/network/http/soap/SOAPReturnObjectList.java
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
package zutil.network.http.soap;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interface is for returning multiple object.
|
||||||
|
* All the public fields in the class that implements
|
||||||
|
* this class will be set as return values. And the
|
||||||
|
* implementing class will be transparent.
|
||||||
|
*
|
||||||
|
* @author Ziver
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface SOAPReturnObjectList {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method comments for the WSDL.
|
||||||
|
* These comments are put in the operation part of the WSDL
|
||||||
|
*
|
||||||
|
* @author Ziver
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface WSDLDocumentation{
|
||||||
|
String value();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables SOAP publication of the given field.
|
||||||
|
*
|
||||||
|
* @author Ziver
|
||||||
|
*/
|
||||||
|
/*@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
public @interface SOAPDisabledValue { }*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotation that assigns a name to the return value
|
||||||
|
* to the field.
|
||||||
|
*
|
||||||
|
* @author Ziver
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
public @interface SOAPValueName {
|
||||||
|
String value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
57
src/zutil/network/http/soap/SOAPReturnValueList.java
Normal file
57
src/zutil/network/http/soap/SOAPReturnValueList.java
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
package zutil.network.http.soap;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interface is for returning multiple object.
|
||||||
|
* All the public fields in the class that implements
|
||||||
|
* this class will be set as return values. And the
|
||||||
|
* implementing class will be transparent.
|
||||||
|
*
|
||||||
|
* @author Ziver
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SOAPReturnValueList {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method comments for the WSDL.
|
||||||
|
* These comments are put in the operation part of the WSDL
|
||||||
|
*
|
||||||
|
* @author Ziver
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface WSDLDocumentation{
|
||||||
|
String value();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables SOAP publication of the given field.
|
||||||
|
*
|
||||||
|
* @author Ziver
|
||||||
|
*/
|
||||||
|
/*@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
public @interface SOAPDisabledValue { }*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotation that assigns a name to the return value
|
||||||
|
* to the field.
|
||||||
|
*
|
||||||
|
* @author Ziver
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
public @interface SOAPValueName {
|
||||||
|
String value();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected Object getValue(Field field) throws IllegalArgumentException, IllegalAccessException{
|
||||||
|
return field.get(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package zutil.test;
|
package zutil.network.http.soap;
|
||||||
|
|
||||||
import javax.wsdl.WSDLException;
|
import javax.wsdl.WSDLException;
|
||||||
|
|
||||||
|
|
@ -6,9 +6,6 @@ import org.dom4j.Document;
|
||||||
import org.dom4j.io.OutputFormat;
|
import org.dom4j.io.OutputFormat;
|
||||||
import org.dom4j.io.XMLWriter;
|
import org.dom4j.io.XMLWriter;
|
||||||
|
|
||||||
import zutil.network.http.soap.SOAPHttpPage;
|
|
||||||
import zutil.network.http.soap.SOAPInterface;
|
|
||||||
import zutil.network.http.soap.SOAPObject;
|
|
||||||
|
|
||||||
public class SOAPTest {
|
public class SOAPTest {
|
||||||
//*******************************************************************************************
|
//*******************************************************************************************
|
||||||
|
|
@ -20,7 +17,7 @@ public class SOAPTest {
|
||||||
|
|
||||||
// Response
|
// Response
|
||||||
try {
|
try {
|
||||||
Document document = soap.soapResponse(
|
Document document = soap.genSOAPResponse(
|
||||||
"<?xml version=\"1.0\"?>" +
|
"<?xml version=\"1.0\"?>" +
|
||||||
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
|
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
|
||||||
" <soap:Body xmlns:m=\"http://www.example.org/stock\">\n" +
|
" <soap:Body xmlns:m=\"http://www.example.org/stock\">\n" +
|
||||||
|
|
@ -35,7 +32,7 @@ public class SOAPTest {
|
||||||
" </m:pubB>\n" +
|
" </m:pubB>\n" +
|
||||||
" </soap:Body>\n" +
|
" </soap:Body>\n" +
|
||||||
"</soap:Envelope>");
|
"</soap:Envelope>");
|
||||||
System.out.println();
|
System.out.println( "****************** RESPONSE *********************" );
|
||||||
|
|
||||||
OutputFormat format = OutputFormat.createPrettyPrint();
|
OutputFormat format = OutputFormat.createPrettyPrint();
|
||||||
XMLWriter writer = new XMLWriter( System.out, format );
|
XMLWriter writer = new XMLWriter( System.out, format );
|
||||||
|
|
@ -65,13 +62,20 @@ class SOAPTestClass2 implements SOAPObject{
|
||||||
public SOAPTestClass3 l = new SOAPTestClass3();
|
public SOAPTestClass3 l = new SOAPTestClass3();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SOAPTestRetClass implements SOAPReturnObjectList{
|
||||||
|
@SOAPValueName("retTest")
|
||||||
|
public String lol = "lol1";
|
||||||
|
public String lol2 = "lol2";
|
||||||
|
}
|
||||||
|
|
||||||
class SOAPTestClass implements SOAPInterface{
|
class SOAPTestClass implements SOAPInterface{
|
||||||
public SOAPTestClass(){}
|
public SOAPTestClass(){}
|
||||||
|
|
||||||
@SOAPHeader()
|
@SOAPHeader()
|
||||||
@WSDLDocumentation("hello")
|
@WSDLDocumentation("hello")
|
||||||
public void pubZ(
|
public void pubZ(
|
||||||
@SOAPParamName(value="olle", optional=true) int lol) throws Exception{
|
@SOAPParamName(value="olle", optional=true) int lol,
|
||||||
|
@SOAPParamName(value="olle2", optional=true) int lol2) throws Exception{
|
||||||
//System.out.println("Param: "+lol);
|
//System.out.println("Param: "+lol);
|
||||||
throw new Exception("Ziver is the fizle");
|
throw new Exception("Ziver is the fizle");
|
||||||
}
|
}
|
||||||
|
|
@ -93,9 +97,12 @@ class SOAPTestClass implements SOAPInterface{
|
||||||
|
|
||||||
@SOAPReturnName("zivarray")
|
@SOAPReturnName("zivarray")
|
||||||
@WSDLParamDocumentation("null is the shizzle")
|
@WSDLParamDocumentation("null is the shizzle")
|
||||||
public byte[] pubB (
|
public SOAPTestRetClass pubB (
|
||||||
@SOAPParamName("byte") String lol) throws Exception{
|
@SOAPParamName("byte") String lol) throws Exception{
|
||||||
return new byte[]{0x12, 0x23};
|
SOAPTestRetClass tmp = new SOAPTestRetClass();
|
||||||
|
tmp.lol = "test";
|
||||||
|
tmp.lol2 = "test2";
|
||||||
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SOAPDisabled()
|
@SOAPDisabled()
|
||||||
|
|
@ -5,8 +5,9 @@ import java.net.DatagramPacket;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import zutil.MultiPrintStream;
|
import zutil.log.Logger;
|
||||||
import zutil.network.http.HTTPHeaderParser;
|
import zutil.network.http.HTTPHeaderParser;
|
||||||
import zutil.network.http.HttpPrintStream;
|
import zutil.network.http.HttpPrintStream;
|
||||||
import zutil.network.threaded.ThreadedUDPNetwork;
|
import zutil.network.threaded.ThreadedUDPNetwork;
|
||||||
|
|
@ -20,20 +21,22 @@ import zutil.wrapper.StringOutputStream;
|
||||||
* @author Ziver
|
* @author Ziver
|
||||||
*/
|
*/
|
||||||
public class SSDPClient extends ThreadedUDPNetwork implements ThreadedUDPNetworkThread{
|
public class SSDPClient extends ThreadedUDPNetwork implements ThreadedUDPNetworkThread{
|
||||||
|
public static final Logger logger = new Logger();
|
||||||
// Contains all the received services
|
// Contains all the received services
|
||||||
private HashMap<String, LinkedList<SSDPServiceInfo>> services_st;
|
private HashMap<String, LinkedList<SSDPServiceInfo>> services_st;
|
||||||
private HashMap<String, SSDPServiceInfo> services_usn;
|
private HashMap<String, SSDPServiceInfo> services_usn;
|
||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException{
|
public static void main(String[] args) throws IOException{
|
||||||
|
Logger.setGlobalLogLevel(Level.FINEST);
|
||||||
SSDPClient ssdp = new SSDPClient();
|
SSDPClient ssdp = new SSDPClient();
|
||||||
ssdp.requestService("upnp:rootdevice");
|
ssdp.requestService("upnp:rootdevice");
|
||||||
ssdp.start();
|
ssdp.start();
|
||||||
|
|
||||||
for(int i=0; true ;++i){
|
for(int i=0; true ;++i){
|
||||||
while( i==ssdp.getServicesCount("upnp:rootdevice") ){ try{Thread.sleep(100);}catch(Exception e){} }
|
while( i==ssdp.getServicesCount("upnp:rootdevice") ){ try{Thread.sleep(100);}catch(Exception e){} }
|
||||||
MultiPrintStream.out.println( "************************" );
|
logger.log(Level.FINEST, "************************" );
|
||||||
MultiPrintStream.out.println( ssdp.getServices("upnp:rootdevice").get(i) );
|
logger.log(Level.FINEST, ""+ssdp.getServices("upnp:rootdevice").get(i) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,14 +82,13 @@ public class SSDPClient extends ThreadedUDPNetwork implements ThreadedUDPNetwork
|
||||||
http.setHeader("MX", "3" );
|
http.setHeader("MX", "3" );
|
||||||
|
|
||||||
http.close();
|
http.close();
|
||||||
//MultiPrintStream.out.println("***** REQUEST: \n"+msg);
|
logger.log(Level.FINEST, "***** REQUEST: \n"+msg);
|
||||||
byte[] data = msg.toString().getBytes();
|
byte[] data = msg.toString().getBytes();
|
||||||
DatagramPacket packet = new DatagramPacket(
|
DatagramPacket packet = new DatagramPacket(
|
||||||
data, data.length,
|
data, data.length,
|
||||||
InetAddress.getByName( SSDPServer.SSDP_MULTICAST_ADDR ),
|
InetAddress.getByName( SSDPServer.SSDP_MULTICAST_ADDR ),
|
||||||
SSDPServer.SSDP_PORT );
|
SSDPServer.SSDP_PORT );
|
||||||
super.send( packet );
|
super.send( packet );
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
@ -147,18 +149,18 @@ public class SSDPClient extends ThreadedUDPNetwork implements ThreadedUDPNetwork
|
||||||
*/
|
*/
|
||||||
public void receivedPacket(DatagramPacket packet, ThreadedUDPNetwork network) {
|
public void receivedPacket(DatagramPacket packet, ThreadedUDPNetwork network) {
|
||||||
HTTPHeaderParser header = new HTTPHeaderParser( new String( packet.getData() ) );
|
HTTPHeaderParser header = new HTTPHeaderParser( new String( packet.getData() ) );
|
||||||
//MultiPrintStream.out.println("*********** Recived\n"+header);
|
logger.log(Level.FINEST, "*********** Recived\n"+header);
|
||||||
|
|
||||||
String usn = header.getHTTPAttribute("USN");
|
String usn = header.getHTTPAttribute("USN");
|
||||||
String st = header.getHTTPAttribute("ST");
|
String st = header.getHTTPAttribute("ST");
|
||||||
SSDPServiceInfo service;
|
StandardSSDPInfo service;
|
||||||
// Get existing service
|
// Get existing service
|
||||||
if( services_usn.containsKey( usn )){
|
if( services_usn.containsKey( usn )){
|
||||||
service = services_usn.get( usn );
|
service = (StandardSSDPInfo)services_usn.get( usn );
|
||||||
}
|
}
|
||||||
// Add new service
|
// Add new service
|
||||||
else{
|
else{
|
||||||
service = new SSDPServiceInfo();
|
service = new StandardSSDPInfo();
|
||||||
services_usn.put( usn, service);
|
services_usn.put( usn, service);
|
||||||
if( !services_st.containsKey(st) )
|
if( !services_st.containsKey(st) )
|
||||||
services_st.put( st, new LinkedList<SSDPServiceInfo>() );
|
services_st.put( st, new LinkedList<SSDPServiceInfo>() );
|
||||||
|
|
@ -171,7 +173,7 @@ public class SSDPClient extends ThreadedUDPNetwork implements ThreadedUDPNetwork
|
||||||
service.setExpirationTime(
|
service.setExpirationTime(
|
||||||
System.currentTimeMillis() +
|
System.currentTimeMillis() +
|
||||||
1000 * getCacheTime(header.getHTTPAttribute("Cache-Control")) );
|
1000 * getCacheTime(header.getHTTPAttribute("Cache-Control")) );
|
||||||
//MultiPrintStream.out.println("*********** Recived\n"+service);
|
logger.log(Level.FINEST, "*********** Recived\n"+service);
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getCacheTime(String cache_control){
|
private long getCacheTime(String cache_control){
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,10 @@ import java.net.InetAddress;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import zutil.MultiPrintStream;
|
import zutil.MultiPrintStream;
|
||||||
|
import zutil.log.Logger;
|
||||||
import zutil.network.http.HTTPHeaderParser;
|
import zutil.network.http.HTTPHeaderParser;
|
||||||
import zutil.network.http.HttpPrintStream;
|
import zutil.network.http.HttpPrintStream;
|
||||||
import zutil.network.threaded.ThreadedUDPNetworkThread;
|
import zutil.network.threaded.ThreadedUDPNetworkThread;
|
||||||
|
|
@ -39,6 +41,7 @@ import zutil.wrapper.StringOutputStream;
|
||||||
* NTS: same as Man but for Notify messages
|
* NTS: same as Man but for Notify messages
|
||||||
*/
|
*/
|
||||||
public class SSDPServer extends ThreadedUDPNetwork implements ThreadedUDPNetworkThread{
|
public class SSDPServer extends ThreadedUDPNetwork implements ThreadedUDPNetworkThread{
|
||||||
|
public static final Logger logger = new Logger();
|
||||||
public static final String SERVER_INFO = "SSDP Java Server by Ziver Koc";
|
public static final String SERVER_INFO = "SSDP Java Server by Ziver Koc";
|
||||||
public static final int DEFAULT_CACHE_TIME = 60*30; // 30 min
|
public static final int DEFAULT_CACHE_TIME = 60*30; // 30 min
|
||||||
public static final int BUFFER_SIZE = 512;
|
public static final int BUFFER_SIZE = 512;
|
||||||
|
|
@ -54,7 +57,7 @@ public class SSDPServer extends ThreadedUDPNetwork implements ThreadedUDPNetwork
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException{
|
public static void main(String[] args) throws IOException{
|
||||||
SSDPServer ssdp = new SSDPServer();
|
SSDPServer ssdp = new SSDPServer();
|
||||||
SSDPServiceInfo service = new SSDPServiceInfo();
|
StandardSSDPInfo service = new StandardSSDPInfo();
|
||||||
service.setLocation("nowhere");
|
service.setLocation("nowhere");
|
||||||
service.setST("upnp:rootdevice");
|
service.setST("upnp:rootdevice");
|
||||||
ssdp.addService(service);
|
ssdp.addService(service);
|
||||||
|
|
@ -152,7 +155,7 @@ public class SSDPServer extends ThreadedUDPNetwork implements ThreadedUDPNetwork
|
||||||
String msg = new String( packet.getData() );
|
String msg = new String( packet.getData() );
|
||||||
|
|
||||||
HTTPHeaderParser header = new HTTPHeaderParser( msg );
|
HTTPHeaderParser header = new HTTPHeaderParser( msg );
|
||||||
//MultiPrintStream.out.println("**** Received:\n"+header);
|
logger.log(Level.FINEST, "**** Received:\n"+header);
|
||||||
|
|
||||||
// ******* Respond
|
// ******* Respond
|
||||||
// Check that the message is an ssdp discovery message
|
// Check that the message is an ssdp discovery message
|
||||||
|
|
@ -175,7 +178,7 @@ public class SSDPServer extends ThreadedUDPNetwork implements ThreadedUDPNetwork
|
||||||
http.setHeader("USN", services.get(st).getUSN() );
|
http.setHeader("USN", services.get(st).getUSN() );
|
||||||
|
|
||||||
http.close();
|
http.close();
|
||||||
//MultiPrintStream.out.println("********** Response:\n"+response);
|
logger.log(Level.FINEST, "********** Response:\n"+response);
|
||||||
byte[] data = response.toString().getBytes();
|
byte[] data = response.toString().getBytes();
|
||||||
packet = new DatagramPacket(
|
packet = new DatagramPacket(
|
||||||
data, data.length,
|
data, data.length,
|
||||||
|
|
@ -241,7 +244,7 @@ public class SSDPServer extends ThreadedUDPNetwork implements ThreadedUDPNetwork
|
||||||
http.setHeader("USN", services.get(searchTarget).getUSN() );
|
http.setHeader("USN", services.get(searchTarget).getUSN() );
|
||||||
|
|
||||||
http.close();
|
http.close();
|
||||||
//MultiPrintStream.out.println("******** Notification:\n"+msg);
|
logger.log(Level.FINEST, "******** Notification:\n"+msg);
|
||||||
byte[] data = msg.toString().getBytes();
|
byte[] data = msg.toString().getBytes();
|
||||||
DatagramPacket packet = new DatagramPacket(
|
DatagramPacket packet = new DatagramPacket(
|
||||||
data, data.length,
|
data, data.length,
|
||||||
|
|
@ -290,7 +293,7 @@ public class SSDPServer extends ThreadedUDPNetwork implements ThreadedUDPNetwork
|
||||||
http.setHeader("USN", services.get(searchTarget).getUSN() );
|
http.setHeader("USN", services.get(searchTarget).getUSN() );
|
||||||
|
|
||||||
http.close();
|
http.close();
|
||||||
//MultiPrintStream.out.println("******** ByeBye:\n"+msg);
|
logger.log(Level.FINEST, "******** ByeBye:\n"+msg);
|
||||||
byte[] data = msg.toString().getBytes();
|
byte[] data = msg.toString().getBytes();
|
||||||
DatagramPacket packet = new DatagramPacket(
|
DatagramPacket packet = new DatagramPacket(
|
||||||
data, data.length,
|
data, data.length,
|
||||||
|
|
|
||||||
|
|
@ -1,89 +1,35 @@
|
||||||
package zutil.network.ssdp;
|
package zutil.network.ssdp;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class contains information about a service from
|
* This class contains information about a service from
|
||||||
* or through the SSDP protocol
|
* or through the SSDP protocol
|
||||||
*
|
*
|
||||||
* @author Ziver
|
* @author Ziver
|
||||||
*/
|
*/
|
||||||
public class SSDPServiceInfo {
|
public interface SSDPServiceInfo {
|
||||||
private String location;
|
|
||||||
private String st;
|
|
||||||
private String usn;
|
|
||||||
private long expiration_time;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param l is the value to set the Location variable
|
|
||||||
*/
|
|
||||||
public void setLocation(String l) {
|
|
||||||
location = l;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param st is the value to set the SearchTarget variable
|
|
||||||
*/
|
|
||||||
public void setST(String st) {
|
|
||||||
this.st = st;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param usn is the value to set the USN variable
|
|
||||||
*/
|
|
||||||
protected void setUSN(String usn) {
|
|
||||||
this.usn = usn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param time sets the expiration time of values in this object
|
|
||||||
*/
|
|
||||||
protected void setExpirationTime(long time) {
|
|
||||||
expiration_time = time;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The URL to the Service, e.g. "http://192.168.0.1:80/index.html"
|
* @return The URL to the Service, e.g. "http://192.168.0.1:80/index.html"
|
||||||
*/
|
*/
|
||||||
public String getLocation(){
|
public String getLocation();
|
||||||
return location;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the Search Target, e.g. "upnp:rootdevice"
|
* @return the Search Target, e.g. "upnp:rootdevice"
|
||||||
*/
|
*/
|
||||||
public String getSearchTarget(){
|
public String getSearchTarget();
|
||||||
return st;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the expiration time for the values in this object
|
* @return the expiration time for the values in this object
|
||||||
*/
|
*/
|
||||||
public long getExpirationTime(){
|
public long getExpirationTime();
|
||||||
return expiration_time;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the USN value, e.g. "uuid:abcdefgh-7dec-11d0-a765-00a0c91e6bf6 "
|
* @return the USN value, e.g. "uuid:abcdefgh-7dec-11d0-a765-00a0c91e6bf6 "
|
||||||
*/
|
*/
|
||||||
public String getUSN(){
|
public String getUSN();
|
||||||
if( usn==null )
|
|
||||||
usn = genUSN();
|
|
||||||
return usn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates an unique USN for the service
|
* @return only the USN UUID String
|
||||||
*
|
|
||||||
* @param searchTarget is the service ST name
|
|
||||||
* @return an unique string that corresponds to the service
|
|
||||||
*/
|
*/
|
||||||
private String genUSN(){
|
public String getUUID();
|
||||||
return "uuid:" + UUID.nameUUIDFromBytes( (st+location).getBytes() ) +"::"+st;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString(){
|
|
||||||
return "USN: "+usn+"\nLocation: "+location+"\nST: "+st+"\nExpiration-Time: "+new Date(expiration_time);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
98
src/zutil/network/ssdp/StandardSSDPInfo.java
Normal file
98
src/zutil/network/ssdp/StandardSSDPInfo.java
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
package zutil.network.ssdp;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class contains information about a service from
|
||||||
|
* or through the SSDP protocol
|
||||||
|
*
|
||||||
|
* @author Ziver
|
||||||
|
*/
|
||||||
|
public class StandardSSDPInfo implements SSDPServiceInfo{
|
||||||
|
private String location;
|
||||||
|
private String st;
|
||||||
|
private String usn;
|
||||||
|
private long expiration_time;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param l is the value to set the Location variable
|
||||||
|
*/
|
||||||
|
public void setLocation(String l) {
|
||||||
|
location = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param st is the value to set the SearchTarget variable
|
||||||
|
*/
|
||||||
|
public void setST(String st) {
|
||||||
|
this.st = st;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param usn is the value to set the USN variable
|
||||||
|
*/
|
||||||
|
protected void setUSN(String usn) {
|
||||||
|
this.usn = usn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param time sets the expiration time of values in this object
|
||||||
|
*/
|
||||||
|
protected void setExpirationTime(long time) {
|
||||||
|
expiration_time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The URL to the Service, e.g. "http://192.168.0.1:80/index.html"
|
||||||
|
*/
|
||||||
|
public String getLocation(){
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the Search Target, e.g. "upnp:rootdevice"
|
||||||
|
*/
|
||||||
|
public String getSearchTarget(){
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the expiration time for the values in this object
|
||||||
|
*/
|
||||||
|
public long getExpirationTime(){
|
||||||
|
return expiration_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the USN value, e.g. "uuid:abcdefgh-7dec-11d0-a765-00a0c91e6bf6 "
|
||||||
|
*/
|
||||||
|
public String getUSN(){
|
||||||
|
if( usn==null )
|
||||||
|
usn = genUSN();
|
||||||
|
return usn+"::"+st;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return only the USN UUID String
|
||||||
|
*/
|
||||||
|
public String getUUID(){
|
||||||
|
if( usn==null )
|
||||||
|
usn = genUSN();
|
||||||
|
return usn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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(){
|
||||||
|
return "uuid:" + UUID.nameUUIDFromBytes( (st+location+Math.random()).getBytes() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString(){
|
||||||
|
return "USN: "+usn+"\nLocation: "+location+"\nST: "+st+"\nExpiration-Time: "+new Date(expiration_time);
|
||||||
|
}
|
||||||
|
}
|
||||||
42
src/zutil/test/UPnPServerTest.java
Normal file
42
src/zutil/test/UPnPServerTest.java
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
package zutil.test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import javax.wsdl.WSDLException;
|
||||||
|
|
||||||
|
import zutil.MultiPrintStream;
|
||||||
|
import zutil.log.Logger;
|
||||||
|
import zutil.network.http.HttpServer;
|
||||||
|
import zutil.network.http.soap.SOAPHttpPage;
|
||||||
|
import zutil.network.ssdp.SSDPServer;
|
||||||
|
import zutil.network.upnp.UPnPMediaServer;
|
||||||
|
import zutil.network.upnp.services.UPnPContentDirectory;
|
||||||
|
|
||||||
|
public class UPnPServerTest {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException, WSDLException{
|
||||||
|
//Logger.setGlobalLogLevel(Level.FINEST);
|
||||||
|
|
||||||
|
UPnPMediaServer upnp = new UPnPMediaServer("http://192.168.0.60:8080/");
|
||||||
|
MultiPrintStream.out.println("UPNP Server running");
|
||||||
|
|
||||||
|
UPnPContentDirectory cds = new UPnPContentDirectory(new File("C:\\Users\\Ziver\\Desktop\\lan"));
|
||||||
|
|
||||||
|
HttpServer http = new HttpServer("http://192.168.0.60/", 8080);
|
||||||
|
//http.setDefaultPage(upnp);
|
||||||
|
http.setPage("/RootDesc", upnp );
|
||||||
|
http.setPage("/SCP/ContentDir", cds );
|
||||||
|
SOAPHttpPage soap = new SOAPHttpPage("Action/ContentDir", cds);
|
||||||
|
soap.enableSession(false);
|
||||||
|
http.setPage("/Action/ContentDir", soap );
|
||||||
|
http.start();
|
||||||
|
MultiPrintStream.out.println("HTTP Server running");
|
||||||
|
|
||||||
|
SSDPServer ssdp = new SSDPServer();
|
||||||
|
ssdp.addService( upnp );
|
||||||
|
ssdp.start();
|
||||||
|
MultiPrintStream.out.println("SSDP Server running");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -32,7 +32,7 @@ import zutil.ui.wizard.listener.BlockingWizardListener;
|
||||||
* @author Ziver
|
* @author Ziver
|
||||||
*/
|
*/
|
||||||
public class Wizard implements ActionListener{
|
public class Wizard implements ActionListener{
|
||||||
public static final boolean DEBUG = true;
|
public static final boolean DEBUG = false;
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/** Some defoult backgrounds for the sidebar */
|
/** Some defoult backgrounds for the sidebar */
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package zutil.wrapper;
|
package zutil.wrapper;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -21,7 +20,7 @@ public class StringOutputStream extends OutputStream{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(int b) throws IOException {
|
public void write(int b) {
|
||||||
buffer.append( b );
|
buffer.append( b );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue